_Z29continuation_handler_void_ptrIN14EventProcessor10ThreadInitE5EventEM12ContinuationFiiPvEMT_FiiPT0_E:
   72|      2|{
   73|      2|  auto fp2 = reinterpret_cast<int (C::*)(int, void *)>(fp);
   74|       |
   75|       |  // We keep this a static_cast for added static type analysis from the
   76|       |  // compiler. If a compiler warning is generated for the following line of
   77|       |  // code of the type "-Werror=shift-negative-value", then this may be an issue
   78|       |  // with multiple inheritance of the C templated type. Make sure that for type
   79|       |  // C the Continuation parent is listed first (either directly or indirectly
   80|       |  // via the inheritance tree) before any other parent in the multiple class
   81|       |  // hierarchy of C.
   82|      2|  return static_cast<ContinuationHandler>(fp2);
   83|      2|}
_ZN12ContinuationC2EP10ProxyMutex:
  277|      6|inline Continuation::Continuation(ProxyMutex *amutex) : mutex(amutex)
  278|      6|{
  279|       |  // Pick up the control flags from the creating thread
  280|      6|  this->control_flags.set_flags(get_cont_flags().get_flags());
  281|      6|}
_Z29continuation_handler_void_ptrI25ThreadAffinityInitializer5EventEM12ContinuationFiiPvEMT_FiiPT0_E:
   72|      2|{
   73|      2|  auto fp2 = reinterpret_cast<int (C::*)(int, void *)>(fp);
   74|       |
   75|       |  // We keep this a static_cast for added static type analysis from the
   76|       |  // compiler. If a compiler warning is generated for the following line of
   77|       |  // code of the type "-Werror=shift-negative-value", then this may be an issue
   78|       |  // with multiple inheritance of the C templated type. Make sure that for type
   79|       |  // C the Continuation parent is listed first (either directly or indirectly
   80|       |  // via the inheritance tree) before any other parent in the multiple class
   81|       |  // hierarchy of C.
   82|      2|  return static_cast<ContinuationHandler>(fp2);
   83|      2|}
UnixEventProcessor.cc:_Z29continuation_handler_void_ptrIN12_GLOBAL__N_116ThreadInitByFuncE5EventEM12ContinuationFiiPvEMT_FiiPT0_E:
   72|      2|{
   73|      2|  auto fp2 = reinterpret_cast<int (C::*)(int, void *)>(fp);
   74|       |
   75|       |  // We keep this a static_cast for added static type analysis from the
   76|       |  // compiler. If a compiler warning is generated for the following line of
   77|       |  // code of the type "-Werror=shift-negative-value", then this may be an issue
   78|       |  // with multiple inheritance of the C templated type. Make sure that for type
   79|       |  // C the Continuation parent is listed first (either directly or indirectly
   80|       |  // via the inheritance tree) before any other parent in the multiple class
   81|       |  // hierarchy of C.
   82|      2|  return static_cast<ContinuationHandler>(fp2);
   83|      2|}

_Z12this_ethreadv:
  715|  33.4k|{
  716|  33.4k|  return EThread::this_ethread_ptr;
  717|  33.4k|}

_ZN14EventProcessor10ThreadInitC2EPS_:
  385|      2|    explicit ThreadInit(EventProcessor *evp) : _evp(evp) { SET_HANDLER(&self::init); }
  ------------------
  |  |  253|      2|#define SET_HANDLER(_h) (handler = continuation_handler_void_ptr(_h))
  ------------------

_Z11this_threadv:
  179|  33.4k|{
  180|  33.4k|  return Thread::this_thread_ptr;
  181|  33.4k|}

_ZN7HTTPHdrC2Ev:
  485|  18.7k|  HTTPHdr() = default; // Force the creation of the default constructor
_ZN7HTTPHdr6createE8HTTPType11HTTPVersionP7HdrHeap:
  673|  18.7k|{
  674|  18.7k|  if (heap) {
  ------------------
  |  Branch (674:7): [True: 0, False: 18.7k]
  ------------------
  675|      0|    m_heap = heap;
  676|  18.7k|  } else if (!m_heap) {
  ------------------
  |  Branch (676:14): [True: 18.7k, False: 0]
  ------------------
  677|  18.7k|    m_heap = new_HdrHeap();
  678|  18.7k|  }
  679|       |
  680|  18.7k|  m_http = http_hdr_create(m_heap, polarity, version);
  681|  18.7k|  m_mime = m_http->m_fields_impl;
  682|  18.7k|}
_ZN7HTTPHdr9parse_reqEP10HTTPParserPPKcS3_bimm:
 1155|  9.36k|{
 1156|  9.36k|  ink_assert(valid());
  ------------------
  |  |   45|  9.36k|#define ink_assert(EX) (void)(EX)
  ------------------
 1157|  9.36k|  ink_assert(m_http->m_polarity == HTTPType::REQUEST);
  ------------------
  |  |   45|  9.36k|#define ink_assert(EX) (void)(EX)
  ------------------
 1158|       |
 1159|  9.36k|  return http_parser_parse_req(parser, m_heap, m_http, start, end, true, eof, strict_uri_parsing, max_request_line_size,
 1160|  9.36k|                               max_hdr_field_size);
 1161|  9.36k|}
_ZNK7HTTPHdr5validEv:
  664|  18.7k|{
  665|  18.7k|  return (m_http && m_mime && m_heap);
  ------------------
  |  Branch (665:11): [True: 18.7k, False: 0]
  |  Branch (665:21): [True: 18.7k, False: 0]
  |  Branch (665:31): [True: 18.7k, False: 0]
  ------------------
  666|  18.7k|}
_ZN7HTTPHdr10parse_respEP10HTTPParserPPKcS3_b:
 1168|  9.36k|{
 1169|  9.36k|  ink_assert(valid());
  ------------------
  |  |   45|  9.36k|#define ink_assert(EX) (void)(EX)
  ------------------
 1170|  9.36k|  ink_assert(m_http->m_polarity == HTTPType::RESPONSE);
  ------------------
  |  |   45|  9.36k|#define ink_assert(EX) (void)(EX)
  ------------------
 1171|       |
 1172|  9.36k|  return http_parser_parse_resp(parser, m_heap, m_http, start, end, true, eof);
 1173|  9.36k|}

_ZN16HdrHeapSDKHandleC2Ev:
  467|  37.4k|  HdrHeapSDKHandle() {}
_ZN16HdrHeapSDKHandleD2Ev:
  468|  37.4k|  ~HdrHeapSDKHandle() { clear(); }
_ZN16HdrHeapSDKHandle5clearEv:
  499|  56.1k|{
  500|  56.1k|  m_heap = nullptr;
  501|  56.1k|}
_ZN16HdrHeapSDKHandle7destroyEv:
  490|  18.7k|{
  491|  18.7k|  if (m_heap) {
  ------------------
  |  Branch (491:7): [True: 18.7k, False: 0]
  ------------------
  492|  18.7k|    m_heap->destroy();
  493|  18.7k|  }
  494|  18.7k|  clear();
  495|  18.7k|}
_Z14obj_is_alignedP14HdrHeapObjImpl:
   79|  47.7k|{
   80|  47.7k|  return (((((uintptr_t)obj) & HDR_PTR_ALIGNMENT_MASK) == 0) && ((obj->m_length & HDR_PTR_ALIGNMENT_MASK) == 0));
  ------------------
  |  Branch (80:11): [True: 47.7k, False: 0]
  |  Branch (80:65): [True: 47.7k, False: 0]
  ------------------
   81|  47.7k|}
_Z14obj_clear_dataP14HdrHeapObjImpl:
   85|  9.36k|{
   86|  9.36k|  char *ptr        = (char *)obj;
   87|  9.36k|  int   hdr_length = sizeof(HdrHeapObjImpl);
   88|  9.36k|  memset(ptr + hdr_length, '\0', obj->m_length - hdr_length);
   89|  9.36k|}
_Z15obj_init_headerP14HdrHeapObjImpl14HdrHeapObjTypejj:
  112|  66.5k|{
  113|  66.5k|  obj->m_type      = static_cast<uint32_t>(type);
  114|  66.5k|  obj->m_length    = nbytes;
  115|  66.5k|  obj->m_obj_flags = obj_flags;
  116|  66.5k|}
_ZNK10HdrStrHeap10total_sizeEv:
  139|  14.7k|  {
  140|  14.7k|    return _total_size;
  141|  14.7k|  }
_ZN10HdrStrHeapC2Ej:
  148|  14.7k|  HdrStrHeap(uint32_t total_size) : _total_size{total_size} {}
_ZNK10HdrStrHeap8containsEPKc:
  156|  39.6k|{
  157|  39.6k|  return reinterpret_cast<char const *>(this + 1) <= str && str < reinterpret_cast<char const *>(this) + _total_size;
  ------------------
  |  Branch (157:10): [True: 1.02k, False: 38.6k]
  |  Branch (157:61): [True: 0, False: 1.02k]
  ------------------
  158|  39.6k|}
_ZNK11StrHeapDesc8containsEPKc:
  170|   163k|  {
  171|   163k|    return (str >= m_heap_start && str < (m_heap_start + m_heap_len));
  ------------------
  |  Branch (171:13): [True: 163k, False: 0]
  |  Branch (171:36): [True: 0, False: 163k]
  ------------------
  172|   163k|  }
_ZN7HdrHeap9HeapGuardC2EPS_PKc:
  304|  54.4k|    {
  305|  54.4k|      if (heap->m_read_write_heap && heap->m_read_write_heap->contains(str)) {
  ------------------
  |  Branch (305:11): [True: 39.6k, False: 14.7k]
  |  Branch (305:38): [True: 0, False: 39.6k]
  ------------------
  306|      0|        _ptr = heap->m_read_write_heap.get();
  307|  54.4k|      } else {
  308|   163k|        for (auto &i : heap->m_ronly_heap) {
  ------------------
  |  Branch (308:22): [True: 163k, False: 54.4k]
  ------------------
  309|   163k|          if (i.contains(str)) {
  ------------------
  |  Branch (309:15): [True: 0, False: 163k]
  ------------------
  310|      0|            _ptr = i.m_ref_count_ptr;
  311|      0|            break;
  312|      0|          }
  313|   163k|        }
  314|  54.4k|      }
  315|  54.4k|    }
_ZN7HdrHeap11free_stringEPKci:
  336|  37.3k|{
  337|  37.3k|  if (s && len > 0) {
  ------------------
  |  Branch (337:7): [True: 2.19k, False: 35.1k]
  |  Branch (337:12): [True: 1.24k, False: 949]
  ------------------
  338|  1.24k|    m_lost_string_space += len;
  339|  1.24k|  }
  340|  37.3k|}

_Zor17HdrTokenInfoFlagsS_:
   62|     68|{
   63|     68|  return static_cast<HdrTokenInfoFlags>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
   64|     68|}
_Z15hdrtoken_is_wksPKc:
  125|   134k|{
  126|   134k|  extern const char *_hdrtoken_strs_heap_f;
  127|   134k|  extern const char *_hdrtoken_strs_heap_l;
  128|       |
  129|   134k|  return ((str >= _hdrtoken_strs_heap_f) && (str <= _hdrtoken_strs_heap_l));
  ------------------
  |  Branch (129:11): [True: 102k, False: 31.5k]
  |  Branch (129:45): [True: 57.5k, False: 44.9k]
  ------------------
  130|   134k|}
_Z25hdrtoken_is_valid_wks_idxi:
  137|  12.0k|{
  138|  12.0k|  return ((wks_idx >= 0) && (wks_idx < hdrtoken_num_wks));
  ------------------
  |  Branch (138:11): [True: 12.0k, False: 0]
  |  Branch (138:29): [True: 12.0k, False: 0]
  ------------------
  139|  12.0k|}
_Z22hdrtoken_wks_to_prefixPKc:
  147|  29.0k|{
  148|  29.0k|  ink_assert(hdrtoken_is_wks(wks));
  ------------------
  |  |   45|  29.0k|#define ink_assert(EX) (void)(EX)
  ------------------
  149|  29.0k|  return reinterpret_cast<HdrTokenHeapPrefix *>(const_cast<char *>(wks) - sizeof(HdrTokenHeapPrefix));
  150|  29.0k|}
_Z21hdrtoken_index_to_wksi:
  157|  7.37k|{
  158|  7.37k|  ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
  ------------------
  |  |   45|  7.37k|#define ink_assert(EX) (void)(EX)
  ------------------
  159|  7.37k|  return hdrtoken_strs[wks_idx];
  160|  7.37k|}
_Z24hdrtoken_index_to_lengthi:
  164|     13|{
  165|     13|  ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
  ------------------
  |  |   45|     13|#define ink_assert(EX) (void)(EX)
  ------------------
  166|     13|  return hdrtoken_str_lengths[wks_idx];
  167|     13|}
_Z24hdrtoken_index_to_slotidi:
  178|  2.67k|{
  179|  2.67k|  ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
  ------------------
  |  |   45|  2.67k|#define ink_assert(EX) (void)(EX)
  ------------------
  180|  2.67k|  return hdrtoken_str_slotids[wks_idx];
  181|  2.67k|}
_Z24hdrtoken_index_to_prefixi:
  199|    254|{
  200|    254|  ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
  ------------------
  |  |   45|    254|#define ink_assert(EX) (void)(EX)
  ------------------
  201|    254|  return hdrtoken_wks_to_prefix(hdrtoken_index_to_wks(wks_idx));
  202|    254|}
_Z21hdrtoken_wks_to_indexPKc:
  209|  5.19k|{
  210|  5.19k|  ink_assert(hdrtoken_is_wks(wks));
  ------------------
  |  |   45|  5.19k|#define ink_assert(EX) (void)(EX)
  ------------------
  211|  5.19k|  return hdrtoken_wks_to_prefix(wks)->wks_idx;
  212|  5.19k|}
_Z22hdrtoken_wks_to_lengthPKc:
  216|  5.29k|{
  217|  5.29k|  ink_assert(hdrtoken_is_wks(wks));
  ------------------
  |  |   45|  5.29k|#define ink_assert(EX) (void)(EX)
  ------------------
  218|  5.29k|  return hdrtoken_wks_to_prefix(wks)->wks_length;
  219|  5.29k|}
_Z26hdrtoken_wks_to_token_typePKc:
  223|     50|{
  224|     50|  ink_assert(hdrtoken_is_wks(wks));
  ------------------
  |  |   45|     50|#define ink_assert(EX) (void)(EX)
  ------------------
  225|     50|  return hdrtoken_wks_to_prefix(wks)->wks_token_type;
  226|     50|}
_Z20hdrtoken_wks_to_maskPKc:
  237|  2.67k|{
  238|  2.67k|  ink_assert(hdrtoken_is_wks(wks));
  ------------------
  |  |   45|  2.67k|#define ink_assert(EX) (void)(EX)
  ------------------
  239|  2.67k|  HdrTokenHeapPrefix *prefix = hdrtoken_wks_to_prefix(wks);
  240|  2.67k|  return prefix->wks_info.mask;
  241|  2.67k|}

_ZN10HdrCsvIterC2Ec:
   53|  1.41k|  HdrCsvIter(char s = ',') : m_separator(s) {}
_ZN10HdrCsvIter9get_firstEPK9MIMEFieldPib:
  131|  1.41k|{
  132|  1.41k|  auto tv = this->get_first(m, follow_dups);
  133|  1.41k|  *len    = static_cast<int>(tv.size());
  134|  1.41k|  return tv.data();
  135|  1.41k|}
_ZN10HdrCsvIter9get_firstEPK9MIMEFieldb:
  139|  1.41k|{
  140|  1.41k|  field_init(m);
  141|  1.41k|  m_follow_dups = follow_dups;
  142|  1.41k|  this->find_csv();
  143|  1.41k|  return m_csv;
  144|  1.41k|}
_ZN10HdrCsvIter10field_initEPK9MIMEField:
  124|  11.6k|{
  125|  11.6k|  m_cur_field = m;
  126|  11.6k|  m_value.assign(m->m_ptr_value, m->m_len_value);
  127|  11.6k|}
_ZN10HdrCsvIter8get_nextEPi:
  155|  5.25k|{
  156|  5.25k|  auto tv = this->get_next();
  157|  5.25k|  *len    = static_cast<int>(tv.size());
  158|  5.25k|  return tv.data();
  159|  5.25k|}
_ZN10HdrCsvIter8get_nextEv:
  148|  5.25k|{
  149|  5.25k|  this->find_csv();
  150|  5.25k|  return m_csv;
  151|  5.25k|}

_ZN7MIMEHdrC2Ev:
 1003|  18.7k|  MIMEHdr() = default; // Force the creation of the default constructor
_ZNK9MIMEField11is_dup_headEv:
  115|  15.3k|  {
  116|  15.3k|    return (m_flags & MIME_FIELD_SLOT_FLAGS_DUP_HEAD);
  ------------------
  |  |   83|  15.3k|#define MIME_FIELD_SLOT_FLAGS_DUP_HEAD (1 << 0)
  ------------------
  117|  15.3k|  }
_ZNK9MIMEField9is_cookedEv:
  121|  21.0k|  {
  122|  21.0k|    return (m_flags & MIME_FIELD_SLOT_FLAGS_COOKED) ? true : false;
  ------------------
  |  |   84|  21.0k|#define MIME_FIELD_SLOT_FLAGS_COOKED   (1 << 1)
  ------------------
  |  Branch (122:12): [True: 1.45k, False: 19.5k]
  ------------------
  123|  21.0k|  }
_ZNK9MIMEField7is_liveEv:
  127|   350k|  {
  128|   350k|    return (m_readiness == MIME_FIELD_SLOT_READINESS_LIVE);
  ------------------
  |  |   80|   350k|#define MIME_FIELD_SLOT_READINESS_LIVE     2
  ------------------
  129|   350k|  }
_ZNK9MIMEField11is_detachedEv:
  133|  52.2k|  {
  134|  52.2k|    return (m_readiness == MIME_FIELD_SLOT_READINESS_DETACHED);
  ------------------
  |  |   79|  52.2k|#define MIME_FIELD_SLOT_READINESS_DETACHED 1
  ------------------
  135|  52.2k|  }
_ZNK11MIMEScanner22get_buffered_line_sizeEv:
  480|  18.7k|{
  481|  18.7k|  return m_line.size();
  482|  18.7k|}
_ZN11MIMEScanner5clearEv:
  486|  18.7k|{
  487|  18.7k|  std::string empty;        // GAH! @c swap isn't defined to take r-value reference!
  488|  18.7k|  std::swap(m_line, empty); // make sure the memory is released.
  489|  18.7k|  m_state = INITIAL_PARSE_STATE;
  490|  18.7k|}
_ZNK9MIMEField8has_dupsEv:
  971|  2.08k|{
  972|  2.08k|  return (m_next_dup != nullptr);
  973|  2.08k|}

_ZN3URLC2Ev:
  339|  18.7k|inline URL::URL() {}

_ZN17FreelistAllocator10alloc_voidEv:
   61|  33.4k|  {
   62|  33.4k|    return ink_freelist_new(this->fl);
   63|  33.4k|  }
_ZN17FreelistAllocator9free_voidEPv:
   72|  33.4k|  {
   73|  33.4k|    ink_freelist_free(this->fl, ptr);
   74|  33.4k|  }
_ZN17FreelistAllocatorC2EPKcjjjb:
  101|     12|  {
  102|     12|    ink_freelist_init(&fl, name, element_size, chunk_size, alignment, use_hugepages);
  103|     12|  }
_ZN17FreelistAllocator18destroy_if_enabledEPv:
  116|  33.4k|  {
  117|  33.4k|  }
_ZN17FreelistAllocator3rawEv:
  120|  33.4k|  {
  121|  33.4k|    return *this;
  122|  33.4k|  }
_ZN14ClassAllocatorI12HTTPCacheAltLb0E17FreelistAllocatorEC2EPKcjj:
  370|      2|    : BaseAllocator(name, static_cast<unsigned int>(RND16(sizeof(C))), chunk_size, static_cast<unsigned int>(RND16(alignment)))
  ------------------
  |  |   49|      2|#define RND16(_x) (((_x) + 15) & ~15)
  ------------------
                  : BaseAllocator(name, static_cast<unsigned int>(RND16(sizeof(C))), chunk_size, static_cast<unsigned int>(RND16(alignment)))
  ------------------
  |  |   49|      2|#define RND16(_x) (((_x) + 15) & ~15)
  ------------------
  371|      2|  {
  372|      2|  }
_ZN14ClassAllocatorI10ProxyMutexLb0E17FreelistAllocatorEC2EPKcjj:
  370|      2|    : BaseAllocator(name, static_cast<unsigned int>(RND16(sizeof(C))), chunk_size, static_cast<unsigned int>(RND16(alignment)))
  ------------------
  |  |   49|      2|#define RND16(_x) (((_x) + 15) & ~15)
  ------------------
                  : BaseAllocator(name, static_cast<unsigned int>(RND16(sizeof(C))), chunk_size, static_cast<unsigned int>(RND16(alignment)))
  ------------------
  |  |   49|      2|#define RND16(_x) (((_x) + 15) & ~15)
  ------------------
  371|      2|  {
  372|      2|  }
_ZN14ClassAllocatorI5EventLb0E17FreelistAllocatorEC2EPKcjj:
  370|      2|    : BaseAllocator(name, static_cast<unsigned int>(RND16(sizeof(C))), chunk_size, static_cast<unsigned int>(RND16(alignment)))
  ------------------
  |  |   49|      2|#define RND16(_x) (((_x) + 15) & ~15)
  ------------------
                  : BaseAllocator(name, static_cast<unsigned int>(RND16(sizeof(C))), chunk_size, static_cast<unsigned int>(RND16(alignment)))
  ------------------
  |  |   49|      2|#define RND16(_x) (((_x) + 15) & ~15)
  ------------------
  371|      2|  {
  372|      2|  }

_ZN11BaseLogFile7is_openEv:
  190|  6.24k|  {
  191|  6.24k|    return (m_fp != nullptr);
  192|  6.24k|  }

_ZN9ContFlagsC2Ev:
   44|      8|  ContFlags() {}
_ZN9ContFlags9set_flagsEj:
   49|      6|  {
   50|      6|    raw_flags = new_flags;
   51|      6|  }
_ZNK9ContFlags9get_flagsEv:
   61|      6|  {
   62|      6|    return raw_flags;
   63|      6|  }

_Z5diagsv:
   72|  6.24k|{
   73|  6.24k|  return DiagsPtr::_diags_ptr;
   74|  6.24k|}

_ZNK5Diags19debug_tag_activatedEPKc:
  169|  40.5k|  {
  170|  40.5k|    return tag_activated(tag);
  171|  40.5k|  }
_ZNK5Diags4lockEv:
  268|  87.3k|  {
  269|  87.3k|    ink_mutex_acquire(&tag_table_lock);
  270|  87.3k|  }
_ZNK5Diags6unlockEv:
  274|  87.3k|  {
  275|  87.3k|    ink_mutex_release(&tag_table_lock);
  276|  87.3k|  }

_ZN11HTTPVersionC2Ev:
   29|  1.26k|  HTTPVersion() {}
_ZNK11HTTPVersion9get_majorEv:
   71|  34.9k|{
   72|  34.9k|  return vmajor;
   73|  34.9k|}
_ZNK11HTTPVersion9get_minorEv:
   80|  15.5k|{
   81|  15.5k|  return vminor;
   82|  15.5k|}
_ZNK11HTTPVersioneqERKS_:
   98|  32.6k|{
   99|  32.6k|  return vmajor == hv.get_major() && vminor == hv.get_minor();
  ------------------
  |  Branch (99:10): [True: 13.1k, False: 19.4k]
  |  Branch (99:38): [True: 12.5k, False: 592]
  ------------------
  100|  32.6k|}
_ZN11HTTPVersionC2Ehh:
   64|  2.36k|inline constexpr HTTPVersion::HTTPVersion(uint8_t ver_major, uint8_t ver_minor) : vmajor(ver_major), vminor(ver_minor) {}

_ZNK7ATSHash6nocaseclEh:
   47|   319k|    {
   48|   319k|      return toupper(byte);
   49|   319k|    }

_ZN14ATSHash32FNV1a6updateIN7ATSHash6nocaseEEEvPKvmT_:
   55|  58.9k|{
   56|  58.9k|  uint8_t *bp = (uint8_t *)data;
   57|  58.9k|  uint8_t *be = bp + len;
   58|       |
   59|   378k|  for (; bp < be; ++bp) {
  ------------------
  |  Branch (59:10): [True: 319k, False: 58.9k]
  ------------------
   60|   319k|    hval ^= (uint32_t)xfrm(*bp);
   61|   319k|    hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
   62|   319k|  }
   63|  58.9k|}

_ZN5QueueI5EventNS0_9Link_linkEEC2Ev:
  567|     16|  Queue() : tail(nullptr) {}
_ZN3DLLI5EventNS0_9Link_linkEEC2Ev:
  264|     16|  DLL() : head(nullptr) {}
_ZN4LinkI12ContinuationEC2Ev:
  103|      6|  Link() : prev(nullptr) {}
_ZN5SLinkI12ContinuationEC2Ev:
   69|      6|  SLink() : next(nullptr){};

_ZN10ParseRules8is_alphaEc:
  210|    254|{
  211|    254|#ifndef COMPILE_PARSE_RULES
  212|    254|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_alpha_BIT);
  ------------------
  |  |   41|    254|#define is_alpha_BIT           (1 << 3)
  ------------------
  213|       |#else
  214|       |  return (is_upalpha(c) || is_loalpha(c));
  215|       |#endif
  216|    254|}
_ZN10ParseRules8is_digitEc:
  220|    747|{
  221|    747|#ifndef COMPILE_PARSE_RULES
  222|    747|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_digit_BIT);
  ------------------
  |  |   42|    747|#define is_digit_BIT           (1 << 4)
  ------------------
  223|       |#else
  224|       |  return (c >= '0' && c <= '9');
  225|       |#endif
  226|    747|}
_ZN10ParseRules8is_alnumEc:
  230|  19.4k|{
  231|  19.4k|#ifndef COMPILE_PARSE_RULES
  232|  19.4k|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_alnum_BIT);
  ------------------
  |  |   64|  19.4k|#define is_alnum_BIT           (1 << 26)
  ------------------
  233|       |#else
  234|       |  return (is_alpha(c) || is_digit(c));
  235|       |#endif
  236|  19.4k|}
_ZN10ParseRules5is_wsEc:
  250|  80.9k|{
  251|  80.9k|#ifndef COMPILE_PARSE_RULES
  252|  80.9k|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_ws_BIT);
  ------------------
  |  |   44|  80.9k|#define is_ws_BIT              (1 << 6)
  ------------------
  253|       |#else
  254|       |  return (c == CHAR_SP || c == CHAR_HT);
  255|       |#endif
  256|  80.9k|}
_ZN10ParseRules5is_crEc:
  270|  36.3k|{
  271|  36.3k|  return (c == CHAR_CR);
  272|  36.3k|}
_ZN10ParseRules5is_lfEc:
  276|  36.4k|{
  277|  36.4k|  return (c == CHAR_LF);
  278|  36.4k|}
_ZN10ParseRules9is_wslfcrEc:
  302|  27.4k|{
  303|  27.4k|#ifndef COMPILE_PARSE_RULES
  304|  27.4k|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_wslfcr_BIT);
  ------------------
  |  |   58|  27.4k|#define is_wslfcr_BIT          (1 << 20)
  ------------------
  305|       |#else
  306|       |  return ParseRules::is_ws(c) || ParseRules::is_splf(c) || ParseRules::is_spcr(c);
  307|       |#endif
  308|  27.4k|}
_ZN10ParseRules8is_tokenEc:
  543|  42.7k|{
  544|  42.7k|#ifndef COMPILE_PARSE_RULES
  545|  42.7k|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_token_BIT);
  ------------------
  |  |   60|  42.7k|#define is_token_BIT           (1 << 22)
  ------------------
  546|       |#else
  547|       |  return (is_char(c) && !(is_ctl(c) || is_tspecials(c)));
  548|       |#endif
  549|  42.7k|}
_ZN10ParseRules11ink_tolowerEc:
  569|  1.31k|{
  570|  1.31k|#ifndef COMPILE_PARSE_RULES
  571|  1.31k|  return parseRulesCTypeToLower[static_cast<unsigned char>(c)];
  572|       |#else
  573|       |  int       lo_case      = c;
  574|       |  const int lo_case_diff = 'a' - 'A';
  575|       |
  576|       |  if (c >= 'A' && c <= 'Z') {
  577|       |    lo_case = c + lo_case_diff;
  578|       |  }
  579|       |  return (lo_case);
  580|       |#endif
  581|  1.31k|}
_ZN10ParseRules8is_spaceEc:
  655|    751|{
  656|    751|#ifndef COMPILE_PARSE_RULES
  657|    751|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_space_BIT);
  ------------------
  |  |   65|    751|#define is_space_BIT           (1 << 27)
  ------------------
  658|       |#else
  659|       |  switch (c) {
  660|       |  case CHAR_SP:
  661|       |  case CHAR_HT:
  662|       |  case CHAR_LF:
  663|       |  case CHAR_VT:
  664|       |  case CHAR_NP:
  665|       |  case CHAR_CR:
  666|       |    return (true);
  667|       |  }
  668|       |  return (false);
  669|       |#endif
  670|    751|}
_ZN10ParseRules10is_controlEc:
  678|  46.2k|{
  679|  46.2k|#ifndef COMPILE_PARSE_RULES
  680|  46.2k|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_control_BIT);
  ------------------
  |  |   66|  46.2k|#define is_control_BIT         (1 << 28)
  ------------------
  681|       |#else
  682|       |  if (c == CHAR_HT || c == CHAR_SP) {
  683|       |    return false;
  684|       |  }
  685|       |
  686|       |  if ((static_cast<unsigned char>(c)) < 0x20 || c == 0x7f) {
  687|       |    return true;
  688|       |  }
  689|       |
  690|       |  return false;
  691|       |#endif
  692|  46.2k|}
_ZN10ParseRules18is_http_field_nameEc:
  711|  22.0k|{
  712|  22.0k|#ifndef COMPILE_PARSE_RULES
  713|  22.0k|  return (parseRulesCType[static_cast<unsigned char>(c)] & is_http_field_name_BIT);
  ------------------
  |  |   68|  22.0k|#define is_http_field_name_BIT (1 << 30)
  ------------------
  714|       |#else
  715|       |  if (!is_char(c) || is_control(c) || (is_mime_sep(c) && c != '@') || c == '=' || c == ':') {
  716|       |    return false;
  717|       |  }
  718|       |  return true;
  719|       |#endif
  720|  22.0k|}
HTTP.cc:_ZL8ink_atoiPKci:
  878|     44|{
  879|     44|  int64_t val = ink_atoi64(str, len);
  880|       |
  881|     44|  if (val > INT_MAX) {
  ------------------
  |  Branch (881:7): [True: 0, False: 44]
  ------------------
  882|      0|    return INT_MAX;
  883|     44|  } else if (val < INT_MIN) {
  ------------------
  |  Branch (883:14): [True: 0, False: 44]
  ------------------
  884|      0|    return INT_MIN;
  885|     44|  } else {
  886|     44|    return static_cast<int>(val);
  887|     44|  }
  888|     44|}

_ZN11RefCountObjC2Ev:
   49|  14.7k|  RefCountObj() {}
_ZN11RefCountObj12refcount_incEv:
   58|  14.7k|  {
   59|  14.7k|    return ++m_refcount;
   60|  14.7k|  }
_ZN11RefCountObj12refcount_decEv:
   65|  14.7k|  {
   66|  14.7k|    return --m_refcount;
   67|  14.7k|  }
_ZNK11RefCountObj8refcountEv:
   71|  14.7k|  {
   72|  14.7k|    return m_refcount;
   73|  14.7k|  }
_ZN3PtrI11RefCountObjEaSEPS0_:
  236|  56.6k|{
  237|  56.6k|  T *temp_ptr = m_ptr;
  238|       |
  239|  56.6k|  if (m_ptr == p) {
  ------------------
  |  Branch (239:7): [True: 56.6k, False: 0]
  ------------------
  240|  56.6k|    return (*this);
  241|  56.6k|  }
  242|       |
  243|      0|  m_ptr = p;
  244|       |
  245|      0|  if (m_ptr) {
  ------------------
  |  Branch (245:7): [True: 0, False: 0]
  ------------------
  246|      0|    m_ptr->refcount_inc();
  247|      0|  }
  248|       |
  249|      0|  if (temp_ptr && temp_ptr->refcount_dec() == 0) {
  ------------------
  |  Branch (249:7): [True: 0, False: 0]
  |  Branch (249:19): [True: 0, False: 0]
  ------------------
  250|      0|    temp_ptr->free();
  251|      0|  }
  252|       |
  253|      0|  return (*this);
  254|  56.6k|}
_ZNK3PtrI10HdrStrHeapEptEv:
  117|  94.1k|  {
  118|  94.1k|    return (m_ptr);
  119|  94.1k|  }
_ZNK3PtrI10HdrStrHeapEcvbEv:
  129|   108k|  {
  130|   108k|    return m_ptr != nullptr;
  131|   108k|  }
_ZN3PtrI10HdrStrHeapEaSEPS0_:
  236|  33.6k|{
  237|  33.6k|  T *temp_ptr = m_ptr;
  238|       |
  239|  33.6k|  if (m_ptr == p) {
  ------------------
  |  Branch (239:7): [True: 4.12k, False: 29.5k]
  ------------------
  240|  4.12k|    return (*this);
  241|  4.12k|  }
  242|       |
  243|  29.5k|  m_ptr = p;
  244|       |
  245|  29.5k|  if (m_ptr) {
  ------------------
  |  Branch (245:7): [True: 14.7k, False: 14.7k]
  ------------------
  246|  14.7k|    m_ptr->refcount_inc();
  247|  14.7k|  }
  248|       |
  249|  29.5k|  if (temp_ptr && temp_ptr->refcount_dec() == 0) {
  ------------------
  |  Branch (249:7): [True: 14.7k, False: 14.7k]
  |  Branch (249:19): [True: 14.7k, False: 0]
  ------------------
  250|  14.7k|    temp_ptr->free();
  251|  14.7k|  }
  252|       |
  253|  29.5k|  return (*this);
  254|  33.6k|}
_ZN3PtrI11RefCountObjEC2EPS0_:
  207|  54.4k|template <class T> inline Ptr<T>::Ptr(T *ptr /* = 0 */) : m_ptr(ptr)
  208|  54.4k|{
  209|  54.4k|  if (m_ptr) {
  ------------------
  |  Branch (209:7): [True: 0, False: 54.4k]
  ------------------
  210|      0|    m_ptr->refcount_inc();
  211|      0|  }
  212|  54.4k|}
_ZN3PtrI11RefCountObjED2Ev:
  227|  54.4k|{
  228|  54.4k|  if (m_ptr && m_ptr->refcount_dec() == 0) {
  ------------------
  |  Branch (228:7): [True: 0, False: 54.4k]
  |  Branch (228:16): [True: 0, False: 0]
  ------------------
  229|      0|    m_ptr->free();
  230|      0|  }
  231|  54.4k|}
_ZN3PtrI10HdrStrHeapE6detachEv:
  176|  18.8k|  {
  177|  18.8k|    T *tmp = m_ptr;
  178|  18.8k|    m_ptr  = nullptr;
  179|  18.8k|    return tmp;
  180|  18.8k|  }
_ZN3PtrI11RefCountObjE6detachEv:
  176|  56.6k|  {
  177|  56.6k|    T *tmp = m_ptr;
  178|  56.6k|    m_ptr  = nullptr;
  179|  56.6k|    return tmp;
  180|  56.6k|  }
_ZN3PtrI10ProxyMutexEC2EPS0_:
  207|      6|template <class T> inline Ptr<T>::Ptr(T *ptr /* = 0 */) : m_ptr(ptr)
  208|      6|{
  209|      6|  if (m_ptr) {
  ------------------
  |  Branch (209:7): [True: 0, False: 6]
  ------------------
  210|      0|    m_ptr->refcount_inc();
  211|      0|  }
  212|      6|}

ink_queue.cc:_ZL20ink_atomic_incrementIijET_PS0_T0_:
   77|      2|{
   78|      2|  return __sync_fetch_and_add(mem, (Type)count);
   79|      2|}
ink_queue.cc:_ZL20ink_atomic_incrementIiiET_PS0_T0_:
   77|  33.4k|{
   78|  33.4k|  return __sync_fetch_and_add(mem, (Type)count);
   79|  33.4k|}
ink_queue.cc:_ZL14ink_atomic_casInEbPT_S0_S0_:
   68|  67.2k|{
   69|  67.2k|  return __sync_bool_compare_and_swap(mem, prev, next);
   70|  67.2k|}
ink_queue.cc:_ZL20ink_atomic_decrementIiiET_PS0_T0_:
   86|  33.4k|{
   87|  33.4k|  return __sync_fetch_and_sub(mem, (Type)count);
   88|  33.4k|}

_ZN6IpAddrC2Ev:
 1288|  3.12k|  IpAddr() {}
_ZN6IpAddr4AddrC2Ev:
 1443|  3.12k|    constexpr Addr() : _ip4(0) {}

_ZN14ats_scoped_strC2EPc:
  533|  6.24k|  explicit ats_scoped_str(char *s) : super(s) {}
_ZN10c_str_viewC2Ev:
  650|    324|  c_str_view() : c_str_view(nullptr, 0) {}
_ZN10c_str_viewC2EPKcm:
  652|    486|    : c_str_view{
  653|    486|        std::string_view{data, length}
  654|    486|  }
  655|    486|  {
  656|    486|  }
_ZN10c_str_viewC2ENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEE:
  657|    486|  explicit c_str_view(std::string_view sv) : sv_{sv}
  658|    486|  {
  659|    486|    ink_assert(sv_.data() == nullptr ? sv_.length() == 0 : sv_.data()[sv_.length()] == '\0');
  ------------------
  |  |   45|    972|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 324, False: 162]
  |  |  ------------------
  ------------------
  660|    486|  }
_ZNK10c_str_view5c_strEv:
  669|    698|  {
  670|    698|    return sv_.data();
  671|    698|  }
_ZNK10c_str_viewcvNSt3__117basic_string_viewIcNS0_11char_traitsIcEEEEEv:
  679|  11.4k|  {
  680|  11.4k|    return sv_;
  681|  11.4k|  }
_ZN19ats_scoped_resourceIN6detail20SCOPED_MALLOC_TRAITSIcEEE5clearEv:
  317|  12.4k|  {
  318|  12.4k|    if (Traits::isValid(_r)) {
  ------------------
  |  Branch (318:9): [True: 6.24k, False: 6.24k]
  ------------------
  319|  6.24k|      Traits::destroy(_r);
  320|  6.24k|    }
  321|  12.4k|    _r = Traits::initValue();
  322|  12.4k|  }
_ZN6detail20SCOPED_MALLOC_TRAITSIcE7isValidEPc:
  471|  12.4k|  {
  472|  12.4k|    return nullptr != t;
  473|  12.4k|  }
_ZN6detail20SCOPED_MALLOC_TRAITSIcE7destroyEPc:
  476|  6.24k|  {
  477|  6.24k|    ats_free(t);
  478|  6.24k|  }
_ZN6detail20SCOPED_MALLOC_TRAITSIcE9initValueEv:
  466|  18.7k|  {
  467|  18.7k|    return nullptr;
  468|  18.7k|  }
_ZN19ats_scoped_resourceIN6detail20SCOPED_MALLOC_TRAITSIcEEEC2EPc:
  308|  6.24k|  explicit ats_scoped_resource(value_type rt) : _r(rt) {}
_ZN14ats_scoped_strC2Ev:
  516|  6.24k|  ats_scoped_str() = default;
_ZN19ats_scoped_resourceIN6detail20SCOPED_MALLOC_TRAITSIcEEEC2Ev:
  306|  6.24k|  ats_scoped_resource() : _r(Traits::initValue()) {}
_ZN19ats_scoped_resourceIN6detail20SCOPED_MALLOC_TRAITSIcEEED2Ev:
  310|  12.4k|  ~ats_scoped_resource() { this->clear(); }
_ZNK19ats_scoped_resourceIN6detail20SCOPED_MALLOC_TRAITSIcEEE3getEv:
  331|  15.6k|  {
  332|  15.6k|    return _r;
  333|  15.6k|  }
ink_queue.cc:_ZL12ats_pagesizev:
  112|     26|{
  113|     26|  static size_t page_size;
  114|       |
  115|     26|  if (page_size) {
  ------------------
  |  Branch (115:7): [True: 24, False: 2]
  ------------------
  116|     24|    return page_size;
  117|     24|  }
  118|       |
  119|      2|#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
  120|      2|  long ret  = sysconf(_SC_PAGESIZE);
  121|      2|  page_size = static_cast<size_t>((ret > -1) ? ret : 8192);
  ------------------
  |  Branch (121:35): [True: 2, False: 0]
  ------------------
  122|       |#elif defined(HAVE_GETPAGESIZE)
  123|       |  page_size = (size_t)getpagesize();
  124|       |#else
  125|       |  page_size = static_cast<size_t>(8192);
  126|       |#endif
  127|       |
  128|      2|  return page_size;
  129|     26|}
_Z8ink_zeroI12_InkFreeListEvRT_:
  213|     12|{
  214|     12|  memset(static_cast<void *>(&t), 0, sizeof(t));
  215|     12|}
_Z8ink_zeroIA4096_P7EThreadEvRT_:
  213|      4|{
  214|      4|  memset(static_cast<void *>(&t), 0, sizeof(t));
  215|      4|}

Diags.cc:_ZL17ink_mutex_acquireP15pthread_mutex_t:
   47|  87.3k|{
   48|  87.3k|  int error = pthread_mutex_lock(m);
   49|  87.3k|  if (unlikely(error != 0)) {
  ------------------
  |  |   31|  87.3k|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (31:21): [True: 0, False: 87.3k]
  |  |  ------------------
  ------------------
   50|      0|    ink_abort("pthread_mutex_lock(%p) failed: %s (%d)", static_cast<void *>(m), strerror(error), error);
   51|      0|  }
   52|  87.3k|}
Diags.cc:_ZL17ink_mutex_releaseP15pthread_mutex_t:
   56|  87.3k|{
   57|  87.3k|  int error = pthread_mutex_unlock(m);
   58|  87.3k|  if (unlikely(error != 0)) {
  ------------------
  |  |   31|  87.3k|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (31:21): [True: 0, False: 87.3k]
  |  |  ------------------
  ------------------
   59|      0|    ink_abort("pthread_mutex_unlock(%p) failed: %s (%d)", static_cast<void *>(m), strerror(error), error);
   60|      0|  }
   61|  87.3k|}

_ZN6head_pC2Ev:
   77|   134k|  head_p() : data(){};

_Z15ptr_len_casecmpPKciS0_i:
   91|    706|{
   92|    706|  if (l1 < l2) {
  ------------------
  |  Branch (92:7): [True: 286, False: 420]
  ------------------
   93|    286|    return -1;
   94|    420|  } else if (l1 > l2) {
  ------------------
  |  Branch (94:14): [True: 280, False: 140]
  ------------------
   95|    280|    return 1;
   96|    280|  }
   97|       |
   98|    693|  while (l1) {
  ------------------
  |  Branch (98:10): [True: 656, False: 37]
  ------------------
   99|    656|    char p1c = ParseRules::ink_tolower(*p1);
  100|    656|    char p2c = ParseRules::ink_tolower(*p2);
  101|       |
  102|    656|    if (p1c != p2c) {
  ------------------
  |  Branch (102:9): [True: 103, False: 553]
  ------------------
  103|    103|      if (p1c > p2c) {
  ------------------
  |  Branch (103:11): [True: 40, False: 63]
  ------------------
  104|     40|        return 1;
  105|     63|      } else {
  106|     63|        return -1;
  107|     63|      }
  108|    103|    }
  109|       |
  110|    553|    p1++;
  111|    553|    p2++;
  112|    553|    l1--;
  113|    553|  }
  114|       |
  115|     37|  return 0;
  116|    140|}

_ZN6DbgCtlC2EPKc:
   64|     34|  DbgCtl(char const *tag) : _ptr{_new_reference(tag)} {}
_ZNK6DbgCtl2onEv:
  104|  54.1k|  {
  105|  54.1k|    auto m{_config_mode.load(std::memory_order_relaxed)};
  106|  54.1k|    if (!m) {
  ------------------
  |  Branch (106:9): [True: 54.1k, False: 0]
  ------------------
  107|  54.1k|      return false;
  108|  54.1k|    }
  109|      0|    if (!_ptr->second) {
  ------------------
  |  Branch (109:9): [True: 0, False: 0]
  ------------------
  110|      0|      return false;
  111|      0|    }
  112|      0|    if (m & 1) {
  ------------------
  |  Branch (112:9): [True: 0, False: 0]
  ------------------
  113|      0|      return true;
  114|      0|    }
  115|      0|    return (2 == m) && (_override_global_on());
  ------------------
  |  Branch (115:12): [True: 0, False: 0]
  |  Branch (115:24): [True: 0, False: 0]
  ------------------
  116|      0|  }
_ZN14DebugInterfaceD2Ev:
   42|  3.12k|  virtual ~DebugInterface()                            = default;

_ZN3DFA7PatternC2EO5RegexONSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  284|    135|    Pattern(Regex &&rxp, std::string &&s) : _re(std::move(rxp)), _p(std::move(s)) {}
_ZN3DFAC2Ev:
  265|      1|  DFA() = default;
_ZN5RegexC2Ev:
  136|    135|  Regex() = default;

_ZN2ts7iequalsENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEES4_:
   42|   230k|{
   43|   230k|  if (lhs.size() != rhs.size()) {
  ------------------
  |  Branch (43:7): [True: 55.6k, False: 174k]
  ------------------
   44|  55.6k|    return false;
   45|  55.6k|  }
   46|       |
   47|   174k|  return ::strncasecmp(lhs.data(), rhs.data(), lhs.size()) == 0;
   48|   230k|}

_ZN2ts10UnitParserC2EON4swoc7_1_5_157LexiconImEEb:
   91|      2|  : _unit_required_p(unit_required_p), _units(std::move(units))
   92|      2|{
   93|      2|  _units.set_default(value_type{0}); // Used to check for bad unit names.
   94|      2|}

_ZN4swoc7_1_5_157IP6AddrC2Emm:
  488|      4|    : _addr{
  489|      4|        {msw, lsw}
  490|      4|  } {}

_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE4headEv:
 1019|    104|IntrusiveDList<L>::head() -> value_type * {
 1020|    104|  return _head;
 1021|    104|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEE5clearEv:
 1031|      2|IntrusiveDList<L>::clear() -> self_type & {
 1032|      2|  _head = _tail = nullptr;
 1033|      2|  _count        = 0;
 1034|      2|  return *this;
 1035|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_16IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE6Bucket7LinkageEE5clearEv:
 1031|      2|IntrusiveDList<L>::clear() -> self_type & {
 1032|      2|  _head = _tail = nullptr;
 1033|      2|  _count        = 0;
 1034|      2|  return *this;
 1035|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE5clearEv:
 1031|      2|IntrusiveDList<L>::clear() -> self_type & {
 1032|      2|  _head = _tail = nullptr;
 1033|      2|  _count        = 0;
 1034|      2|  return *this;
 1035|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_16IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE6Bucket7LinkageEE5clearEv:
 1031|      2|IntrusiveDList<L>::clear() -> self_type & {
 1032|      2|  _head = _tail = nullptr;
 1033|      2|  _count        = 0;
 1034|      2|  return *this;
 1035|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEEC2EOS6_:
  676|      2|IntrusiveDList<L>::IntrusiveDList(self_type &&that) : _head(that._head), _tail(that._tail), _count(that._count) {
  677|      2|  that.clear();
  678|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_16IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE6Bucket7LinkageEEC2EOSA_:
  676|      2|IntrusiveDList<L>::IntrusiveDList(self_type &&that) : _head(that._head), _tail(that._tail), _count(that._count) {
  677|      2|  that.clear();
  678|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEEC2EOS6_:
  676|      2|IntrusiveDList<L>::IntrusiveDList(self_type &&that) : _head(that._head), _tail(that._tail), _count(that._count) {
  677|      2|  that.clear();
  678|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_16IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE6Bucket7LinkageEEC2EOSA_:
  676|      2|IntrusiveDList<L>::IntrusiveDList(self_type &&that) : _head(that._head), _tail(that._tail), _count(that._count) {
  677|      2|  that.clear();
  678|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEE3endEv:
  989|     96|IntrusiveDList<L>::end() -> iterator {
  990|     96|  return iterator{this, nullptr};
  991|     96|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEE8iteratorC2EPS6_PS4_:
  575|     96|template <typename L> IntrusiveDList<L>::iterator::iterator(list_type *list, value_type *v) : super_type(list, v) {}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEE14const_iteratorC2EPKS6_PKS4_:
  571|     96|  : _list(const_cast<list_type *>(list)), _v(const_cast<typename list_type::value_type *>(v)) {}
_ZNK4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEE14const_iteratorneERKS7_:
  704|     48|IntrusiveDList<L>::const_iterator::operator!=(self_type const &that) const {
  705|     48|  return this->_v != that._v;
  706|     48|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEEC2Ev:
  227|      4|  IntrusiveDList() = default;
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEEC2Ev:
  227|      2|  IntrusiveDList() = default;
_ZN4swoc7_1_5_1514IntrusiveDListINS0_16IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE6Bucket7LinkageEEC2Ev:
  227|      2|  IntrusiveDList() = default;
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEEC2Ev:
  227|      2|  IntrusiveDList() = default;
_ZN4swoc7_1_5_1514IntrusiveDListINS0_16IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE6Bucket7LinkageEEC2Ev:
  227|      2|  IntrusiveDList() = default;
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEE6appendEPS4_:
  748|     24|IntrusiveDList<L>::append(value_type *v) -> self_type & {
  749|     24|  L::next_ptr(v) = nullptr;
  750|     24|  if (nullptr != (L::prev_ptr(v) = _tail)) {
  ------------------
  |  Branch (750:7): [True: 22, False: 2]
  ------------------
  751|     22|    L::next_ptr(_tail) = v;
  752|     22|  } else {
  753|      2|    _head = v; // transition empty -> non-empty
  754|      2|  }
  755|     24|  _tail = v;
  756|     24|  ++_count;
  757|     24|  return *this;
  758|     24|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_16IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE6Bucket7LinkageEE6appendEPS8_:
  748|     14|IntrusiveDList<L>::append(value_type *v) -> self_type & {
  749|     14|  L::next_ptr(v) = nullptr;
  750|     14|  if (nullptr != (L::prev_ptr(v) = _tail)) {
  ------------------
  |  Branch (750:7): [True: 12, False: 2]
  ------------------
  751|     12|    L::next_ptr(_tail) = v;
  752|     12|  } else {
  753|      2|    _head = v; // transition empty -> non-empty
  754|      2|  }
  755|     14|  _tail = v;
  756|     14|  ++_count;
  757|     14|  return *this;
  758|     14|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEE13insert_beforeEPS4_S7_:
  819|     34|IntrusiveDList<L>::insert_before(value_type *target, value_type *v) -> self_type & {
  820|     34|  if (target) {
  ------------------
  |  Branch (820:7): [True: 24, False: 10]
  ------------------
  821|     24|    if (nullptr != (L::prev_ptr(v) = L::prev_ptr(target))) {
  ------------------
  |  Branch (821:9): [True: 24, False: 0]
  ------------------
  822|     24|      L::next_ptr(L::prev_ptr(v)) = v;
  823|     24|    } else if (target == _head) {
  ------------------
  |  Branch (823:16): [True: 0, False: 0]
  ------------------
  824|      0|      _head = v;
  825|      0|    }
  826|     24|    L::next_ptr(v)      = target;
  827|     24|    L::prev_ptr(target) = v;
  828|       |
  829|     24|    ++_count;
  830|     24|  } else {
  831|     10|    this->append(v);
  832|     10|  }
  833|     34|  return *this;
  834|     34|}
_ZNK4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item11NameLinkageEE5countEv:
  965|     48|IntrusiveDList<L>::count() const {
  966|     48|  return _count;
  967|     48|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE3endEv:
  989|     64|IntrusiveDList<L>::end() -> iterator {
  990|     64|  return iterator{this, nullptr};
  991|     64|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE8iteratorC2EPS6_PS4_:
  575|     96|template <typename L> IntrusiveDList<L>::iterator::iterator(list_type *list, value_type *v) : super_type(list, v) {}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE14const_iteratorC2EPKS6_PKS4_:
  571|     96|  : _list(const_cast<list_type *>(list)), _v(const_cast<typename list_type::value_type *>(v)) {}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE12iterator_forEPS4_:
  995|     32|IntrusiveDList<L>::iterator_for(value_type *v) -> iterator {
  996|     32|  return iterator{this, v};
  997|     32|}
_ZNK4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE14const_iteratoreqERKS7_:
  698|     48|IntrusiveDList<L>::const_iterator::operator==(self_type const &that) const {
  699|     48|  return this->_v == that._v;
  700|     48|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE6appendEPS4_:
  748|     12|IntrusiveDList<L>::append(value_type *v) -> self_type & {
  749|     12|  L::next_ptr(v) = nullptr;
  750|     12|  if (nullptr != (L::prev_ptr(v) = _tail)) {
  ------------------
  |  Branch (750:7): [True: 10, False: 2]
  ------------------
  751|     10|    L::next_ptr(_tail) = v;
  752|     10|  } else {
  753|      2|    _head = v; // transition empty -> non-empty
  754|      2|  }
  755|     12|  _tail = v;
  756|     12|  ++_count;
  757|     12|  return *this;
  758|     12|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_16IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE6Bucket7LinkageEE6appendEPS8_:
  748|     10|IntrusiveDList<L>::append(value_type *v) -> self_type & {
  749|     10|  L::next_ptr(v) = nullptr;
  750|     10|  if (nullptr != (L::prev_ptr(v) = _tail)) {
  ------------------
  |  Branch (750:7): [True: 8, False: 2]
  ------------------
  751|      8|    L::next_ptr(_tail) = v;
  752|      8|  } else {
  753|      2|    _head = v; // transition empty -> non-empty
  754|      2|  }
  755|     10|  _tail = v;
  756|     10|  ++_count;
  757|     10|  return *this;
  758|     10|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE13insert_beforeEPS4_S7_:
  819|      6|IntrusiveDList<L>::insert_before(value_type *target, value_type *v) -> self_type & {
  820|      6|  if (target) {
  ------------------
  |  Branch (820:7): [True: 4, False: 2]
  ------------------
  821|      4|    if (nullptr != (L::prev_ptr(v) = L::prev_ptr(target))) {
  ------------------
  |  Branch (821:9): [True: 4, False: 0]
  ------------------
  822|      4|      L::next_ptr(L::prev_ptr(v)) = v;
  823|      4|    } else if (target == _head) {
  ------------------
  |  Branch (823:16): [True: 0, False: 0]
  ------------------
  824|      0|      _head = v;
  825|      0|    }
  826|      4|    L::next_ptr(v)      = target;
  827|      4|    L::prev_ptr(target) = v;
  828|       |
  829|      4|    ++_count;
  830|      4|  } else {
  831|      2|    this->append(v);
  832|      2|  }
  833|      6|  return *this;
  834|      6|}
_ZNK4swoc7_1_5_1514IntrusiveDListINS0_7LexiconImE4Item12ValueLinkageEE5countEv:
  965|     16|IntrusiveDList<L>::count() const {
  966|     16|  return _count;
  967|     16|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE14const_iteratorC2EPKS5_PKS3_:
  571|    382|  : _list(const_cast<list_type *>(list)), _v(const_cast<typename list_type::value_type *>(v)) {}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE7prependEPS3_:
  734|      2|IntrusiveDList<L>::prepend(value_type *v) -> self_type & {
  735|      2|  L::prev_ptr(v) = nullptr;
  736|      2|  if (nullptr != (L::next_ptr(v) = _head)) {
  ------------------
  |  Branch (736:7): [True: 0, False: 2]
  ------------------
  737|      0|    L::prev_ptr(_head) = v;
  738|      2|  } else {
  739|      2|    _tail = v; // transition empty -> non-empty
  740|      2|  }
  741|      2|  _head = v;
  742|      2|  ++_count;
  743|      2|  return *this;
  744|      2|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEEC2EOS5_:
  676|      4|IntrusiveDList<L>::IntrusiveDList(self_type &&that) : _head(that._head), _tail(that._tail), _count(that._count) {
  677|      4|  that.clear();
  678|      4|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE5beginEv:
  977|    190|IntrusiveDList<L>::begin() -> iterator {
  978|    190|  return iterator{this, _head};
  979|    190|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE8iteratorC2EPS5_PS3_:
  575|    382|template <typename L> IntrusiveDList<L>::iterator::iterator(list_type *list, value_type *v) : super_type(list, v) {}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE3endEv:
  989|    192|IntrusiveDList<L>::end() -> iterator {
  990|    192|  return iterator{this, nullptr};
  991|    192|}
_ZNK4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE14const_iteratorneERKS6_:
  704|    190|IntrusiveDList<L>::const_iterator::operator!=(self_type const &that) const {
  705|    190|  return this->_v != that._v;
  706|    190|}
_ZNK4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE8iteratorptEv:
  649|     94|IntrusiveDList<L>::iterator::operator->() const -> value_type * {
  650|     94|  return super_type::_v;
  651|     94|}
_ZNK4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE14const_iteratoreqERKS6_:
  698|     96|IntrusiveDList<L>::const_iterator::operator==(self_type const &that) const {
  699|     96|  return this->_v == that._v;
  700|     96|}
_ZN4swoc7_1_5_1514IntrusiveDListINS0_8MemArena5Block7LinkageEE5clearEv:
 1031|     12|IntrusiveDList<L>::clear() -> self_type & {
 1032|     12|  _head = _tail = nullptr;
 1033|     12|  _count        = 0;
 1034|     12|  return *this;
 1035|     12|}

_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEEC2EOS6_:
  179|      2|  IntrusiveHashMap(self_type &&that) = default;
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEEC2EOS6_:
  179|      2|  IntrusiveHashMap(self_type &&that) = default;
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE4findENSt3__117basic_string_viewIcNS7_11char_traitsIcEEEE:
  434|     48|IntrusiveHashMap<H>::find(key_type key) -> iterator {
  435|     48|  Bucket *b         = this->bucket_for(key);
  436|     48|  value_type *v     = b->_v;
  437|     48|  value_type *limit = b->limit();
  438|    140|  while (v != limit && !H::equal(key, H::key_of(v))) {
  ------------------
  |  Branch (438:10): [True: 92, False: 48]
  |  Branch (438:10): [True: 92, False: 48]
  |  Branch (438:24): [True: 92, False: 0]
  ------------------
  439|     92|    v = H::next_ptr(v);
  440|     92|  }
  441|     48|  return v == limit ? _list.end() : _list.iterator_for(v);
  ------------------
  |  Branch (441:10): [True: 48, False: 0]
  ------------------
  442|     48|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE10bucket_forENSt3__117basic_string_viewIcNS7_11char_traitsIcEEEE:
  392|     96|IntrusiveHashMap<H>::bucket_for(key_type key) -> Bucket * {
  393|     96|  return &_table[H::hash_of(key) % _table.size()];
  394|     96|}
_ZNK4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE6Bucket5limitEv:
  331|     82|IntrusiveHashMap<H>::Bucket::limit() const -> value_type * {
  332|     82|  Bucket *n{_link._next};
  333|     82|  return n ? n->_v : nullptr;
  ------------------
  |  Branch (333:10): [True: 48, False: 34]
  ------------------
  334|     82|};
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEEC2Em:
  384|      2|template <typename H> IntrusiveHashMap<H>::IntrusiveHashMap(size_t n) {
  385|      2|  if (n) {
  ------------------
  |  Branch (385:7): [True: 2, False: 0]
  ------------------
  386|      2|    _table.resize(*std::lower_bound(PRIME.begin(), PRIME.end(), n));
  387|      2|  }
  388|      2|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEEC2Em:
  384|      2|template <typename H> IntrusiveHashMap<H>::IntrusiveHashMap(size_t n) {
  385|      2|  if (n) {
  ------------------
  |  Branch (385:7): [True: 2, False: 0]
  ------------------
  386|      2|    _table.resize(*std::lower_bound(PRIME.begin(), PRIME.end(), n));
  387|      2|  }
  388|      2|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE3endEv:
  410|     48|IntrusiveHashMap<H>::end() -> iterator {
  411|     48|  return _list.end();
  412|     48|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE6insertEPS4_:
  497|     48|IntrusiveHashMap<H>::insert(value_type *v) {
  498|     48|  auto key         = H::key_of(v);
  499|     48|  Bucket *bucket   = this->bucket_for(key);
  500|     48|  value_type *spot = bucket->_v;
  501|     48|  bool mixed_p     = false; // Found a different key in the bucket.
  502|       |
  503|     48|  if (nullptr == spot) { // currently empty bucket, set it and add to active list.
  ------------------
  |  Branch (503:7): [True: 14, False: 34]
  ------------------
  504|     14|    _list.append(v);
  505|     14|    bucket->_v = v;
  506|     14|    _active_buckets.append(bucket);
  507|     34|  } else {
  508|     34|    value_type *limit = bucket->limit();
  509|       |
  510|       |    // First search the bucket to see if the key is already in it.
  511|    126|    while (spot != limit && !H::equal(key, H::key_of(spot))) {
  ------------------
  |  Branch (511:12): [True: 92, False: 34]
  |  Branch (511:12): [True: 92, False: 34]
  |  Branch (511:29): [True: 92, False: 0]
  ------------------
  512|     92|      spot = H::next_ptr(spot);
  513|     92|    }
  514|     34|    if (spot != bucket->_v) {
  ------------------
  |  Branch (514:9): [True: 34, False: 0]
  ------------------
  515|     34|      mixed_p = true; // found some other key, it's going to be mixed.
  516|     34|    }
  517|     34|    if (spot != limit) {
  ------------------
  |  Branch (517:9): [True: 0, False: 34]
  ------------------
  518|       |      // If an equal key was found, walk past those to insert at the upper end of the range.
  519|      0|      do {
  520|      0|        spot = H::next_ptr(spot);
  521|      0|      } while (spot != limit && H::equal(key, H::key_of(spot)));
  ------------------
  |  Branch (521:16): [True: 0, False: 0]
  |  Branch (521:16): [True: 0, False: 0]
  |  Branch (521:33): [True: 0, False: 0]
  ------------------
  522|      0|      if (spot != limit) { // something not equal past last equivalent, it's going to be mixed.
  ------------------
  |  Branch (522:11): [True: 0, False: 0]
  ------------------
  523|      0|        mixed_p = true;
  524|      0|      }
  525|      0|    }
  526|       |
  527|     34|    _list.insert_before(spot, v);
  528|     34|    if (spot == bucket->_v) { // added before the bucket start, update the start.
  ------------------
  |  Branch (528:9): [True: 0, False: 34]
  ------------------
  529|      0|      bucket->_v = v;
  530|      0|    }
  531|     34|    bucket->_mixed_p = mixed_p;
  532|     34|  }
  533|     48|  ++bucket->_count;
  534|       |
  535|       |  // auto expand if appropriate.
  536|     48|  if ((AVERAGE == _expansion_policy && (_list.count() / _table.size()) > _expansion_limit) ||
  ------------------
  |  Branch (536:8): [True: 48, False: 0]
  |  Branch (536:40): [True: 0, False: 48]
  ------------------
  537|     48|      (MAXIMUM == _expansion_policy && bucket->_count > _expansion_limit && bucket->_mixed_p)) {
  ------------------
  |  Branch (537:8): [True: 0, False: 48]
  |  Branch (537:40): [True: 0, False: 0]
  |  Branch (537:77): [True: 0, False: 0]
  ------------------
  538|      0|    this->expand();
  539|      0|  }
  540|     48|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE6Bucket7Linkage8next_ptrEPS7_:
  317|     26|IntrusiveHashMap<H>::Bucket::Linkage::next_ptr(Bucket *b) -> Bucket *& {
  318|     26|  return b->_link._next;
  319|     26|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item11NameLinkageEE6Bucket7Linkage8prev_ptrEPS7_:
  323|     14|IntrusiveHashMap<H>::Bucket::Linkage::prev_ptr(Bucket *b) -> Bucket *& {
  324|     14|  return b->_link._prev;
  325|     14|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE4findEm:
  434|     48|IntrusiveHashMap<H>::find(key_type key) -> iterator {
  435|     48|  Bucket *b         = this->bucket_for(key);
  436|     48|  value_type *v     = b->_v;
  437|     48|  value_type *limit = b->limit();
  438|     72|  while (v != limit && !H::equal(key, H::key_of(v))) {
  ------------------
  |  Branch (438:10): [True: 56, False: 16]
  |  Branch (438:24): [True: 24, False: 32]
  ------------------
  439|     24|    v = H::next_ptr(v);
  440|     24|  }
  441|     48|  return v == limit ? _list.end() : _list.iterator_for(v);
  ------------------
  |  Branch (441:10): [True: 16, False: 32]
  ------------------
  442|     48|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE10bucket_forEm:
  392|     64|IntrusiveHashMap<H>::bucket_for(key_type key) -> Bucket * {
  393|     64|  return &_table[H::hash_of(key) % _table.size()];
  394|     64|}
_ZNK4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE6Bucket5limitEv:
  331|     54|IntrusiveHashMap<H>::Bucket::limit() const -> value_type * {
  332|     54|  Bucket *n{_link._next};
  333|     54|  return n ? n->_v : nullptr;
  ------------------
  |  Branch (333:10): [True: 16, False: 38]
  ------------------
  334|     54|};
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE3endEv:
  410|     48|IntrusiveHashMap<H>::end() -> iterator {
  411|     48|  return _list.end();
  412|     48|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE6insertEPS4_:
  497|     16|IntrusiveHashMap<H>::insert(value_type *v) {
  498|     16|  auto key         = H::key_of(v);
  499|     16|  Bucket *bucket   = this->bucket_for(key);
  500|     16|  value_type *spot = bucket->_v;
  501|     16|  bool mixed_p     = false; // Found a different key in the bucket.
  502|       |
  503|     16|  if (nullptr == spot) { // currently empty bucket, set it and add to active list.
  ------------------
  |  Branch (503:7): [True: 10, False: 6]
  ------------------
  504|     10|    _list.append(v);
  505|     10|    bucket->_v = v;
  506|     10|    _active_buckets.append(bucket);
  507|     10|  } else {
  508|      6|    value_type *limit = bucket->limit();
  509|       |
  510|       |    // First search the bucket to see if the key is already in it.
  511|     14|    while (spot != limit && !H::equal(key, H::key_of(spot))) {
  ------------------
  |  Branch (511:12): [True: 8, False: 6]
  |  Branch (511:29): [True: 8, False: 0]
  ------------------
  512|      8|      spot = H::next_ptr(spot);
  513|      8|    }
  514|      6|    if (spot != bucket->_v) {
  ------------------
  |  Branch (514:9): [True: 6, False: 0]
  ------------------
  515|      6|      mixed_p = true; // found some other key, it's going to be mixed.
  516|      6|    }
  517|      6|    if (spot != limit) {
  ------------------
  |  Branch (517:9): [True: 0, False: 6]
  ------------------
  518|       |      // If an equal key was found, walk past those to insert at the upper end of the range.
  519|      0|      do {
  520|      0|        spot = H::next_ptr(spot);
  521|      0|      } while (spot != limit && H::equal(key, H::key_of(spot)));
  ------------------
  |  Branch (521:16): [True: 0, False: 0]
  |  Branch (521:33): [True: 0, False: 0]
  ------------------
  522|      0|      if (spot != limit) { // something not equal past last equivalent, it's going to be mixed.
  ------------------
  |  Branch (522:11): [True: 0, False: 0]
  ------------------
  523|      0|        mixed_p = true;
  524|      0|      }
  525|      0|    }
  526|       |
  527|      6|    _list.insert_before(spot, v);
  528|      6|    if (spot == bucket->_v) { // added before the bucket start, update the start.
  ------------------
  |  Branch (528:9): [True: 0, False: 6]
  ------------------
  529|      0|      bucket->_v = v;
  530|      0|    }
  531|      6|    bucket->_mixed_p = mixed_p;
  532|      6|  }
  533|     16|  ++bucket->_count;
  534|       |
  535|       |  // auto expand if appropriate.
  536|     16|  if ((AVERAGE == _expansion_policy && (_list.count() / _table.size()) > _expansion_limit) ||
  ------------------
  |  Branch (536:8): [True: 16, False: 0]
  |  Branch (536:40): [True: 0, False: 16]
  ------------------
  537|     16|      (MAXIMUM == _expansion_policy && bucket->_count > _expansion_limit && bucket->_mixed_p)) {
  ------------------
  |  Branch (537:8): [True: 0, False: 16]
  |  Branch (537:40): [True: 0, False: 0]
  |  Branch (537:77): [True: 0, False: 0]
  ------------------
  538|      0|    this->expand();
  539|      0|  }
  540|     16|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE6Bucket7Linkage8next_ptrEPS7_:
  317|     18|IntrusiveHashMap<H>::Bucket::Linkage::next_ptr(Bucket *b) -> Bucket *& {
  318|     18|  return b->_link._next;
  319|     18|}
_ZN4swoc7_1_5_1516IntrusiveHashMapINS0_7LexiconImE4Item12ValueLinkageEE6Bucket7Linkage8prev_ptrEPS7_:
  323|     10|IntrusiveHashMap<H>::Bucket::Linkage::prev_ptr(Bucket *b) -> Bucket *& {
  324|     10|  return b->_link._prev;
  325|     10|}

_ZN4swoc7_1_5_157LexiconImE11set_defaultERKNSt3__17variantIJNS3_9monostateEmNS0_8TextViewENS3_8functionIFmS6_EEENS7_IFS6_mEEEEEE:
  692|      6|Lexicon<E>::set_default(Default const &handler) -> self_type & {
  693|      6|  switch (handler.index()) {
  ------------------
  |  Branch (693:11): [True: 6, False: 0]
  ------------------
  694|      4|  case 0:
  ------------------
  |  Branch (694:3): [True: 4, False: 2]
  ------------------
  695|      4|    break;
  696|      2|  case 1:
  ------------------
  |  Branch (696:3): [True: 2, False: 4]
  ------------------
  697|      2|    _value_default = std::get<1>(handler);
  698|      2|    break;
  699|      0|  case 3:
  ------------------
  |  Branch (699:3): [True: 0, False: 6]
  ------------------
  700|      0|    _value_default = std::get<3>(handler);
  701|      0|    break;
  702|      0|  case 2:
  ------------------
  |  Branch (702:3): [True: 0, False: 6]
  ------------------
  703|      0|    _name_default = std::get<2>(handler);
  704|      0|    break;
  705|      0|  case 4:
  ------------------
  |  Branch (705:3): [True: 0, False: 6]
  ------------------
  706|      0|    _name_default = std::get<4>(handler);
  707|      0|    break;
  708|      6|  }
  709|      6|  return *this;
  710|      6|}
_ZN4swoc7_1_5_157LexiconImEC2EOS2_:
  187|      2|  Lexicon(self_type &&that) = default;
_ZN4swoc7_1_5_157LexiconImE4Item11NameLinkage7hash_ofENSt3__117basic_string_viewIcNS5_11char_traitsIcEEEE:
  570|     96|Lexicon<E>::Item::NameLinkage::hash_of(std::string_view s) {
  571|     96|  return Hash32FNV1a().hash_immediate(transform_view_of(&::toupper, s));
  572|     96|}
_ZN4swoc7_1_5_157LexiconImE4Item11NameLinkage5equalERKNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEESB_:
  582|    184|Lexicon<E>::Item::NameLinkage::equal(std::string_view const &lhs, std::string_view const &rhs) {
  583|    184|  return 0 == strcasecmp(lhs, rhs);
  584|    184|}
_ZN4swoc7_1_5_157LexiconImE4Item11NameLinkage6key_ofEPS3_:
  558|    232|Lexicon<E>::Item::NameLinkage::key_of(Item *item) {
  559|    232|  return item->_payload._name;
  560|    232|}
_ZN4swoc7_1_5_157LexiconImE4Item11NameLinkage8next_ptrEPS3_:
  534|    278|Lexicon<E>::Item::NameLinkage::next_ptr(Item *item) -> Item *& {
  535|    278|  return item->_name_link._next;
  536|    278|}
_ZN4swoc7_1_5_157LexiconImEC2ERKSt16initializer_listINS2_10DefinitionEENSt3__17variantIJNS8_9monostateEmNS0_8TextViewENS8_8functionIFmSB_EEENSC_IFSB_mEEEEEESH_:
  598|      2|template <typename E> Lexicon<E>::Lexicon(with_multi items, Default handler_1, Default handler_2) {
  599|     16|  for (auto const &item : items) {
  ------------------
  |  Branch (599:25): [True: 16, False: 2]
  ------------------
  600|     16|    this->define(item.value, item.names);
  601|     16|  }
  602|       |
  603|      4|  for (auto &&h : {handler_1, handler_2}) {
  ------------------
  |  Branch (603:17): [True: 4, False: 2]
  ------------------
  604|      4|    this->set_default(h);
  605|      4|  }
  606|      2|}
_ZN4swoc7_1_5_157LexiconImE6defineEmRKSt16initializer_listINS0_8TextViewEE:
  652|     16|Lexicon<E>::define(E value, const std::initializer_list<TextView> &names) -> self_type & {
  653|     16|  if (names.size() < 1) {
  ------------------
  |  Branch (653:7): [True: 0, False: 16]
  ------------------
  654|      0|    throw std::invalid_argument("A defined value must have at least a primary name");
  655|      0|  }
  656|     48|  for (auto const &name : names) {
  ------------------
  |  Branch (656:25): [True: 48, False: 16]
  ------------------
  657|     48|    if (_by_name.find(name) != _by_name.end()) {
  ------------------
  |  Branch (657:9): [True: 0, False: 48]
  ------------------
  658|      0|      throw std::invalid_argument(detail::what("Duplicate name '{}' in Lexicon", name));
  659|      0|    }
  660|     48|    auto i = _arena.make<Item>(value, this->localize(name));
  661|     48|    _by_name.insert(i);
  662|       |    // Only put primary names in the value table.
  663|     48|    if (_by_value.find(value) == _by_value.end()) {
  ------------------
  |  Branch (663:9): [True: 16, False: 32]
  ------------------
  664|     16|      _by_value.insert(i);
  665|     16|    }
  666|     48|  }
  667|     16|  return *this;
  668|     16|}
_ZN4swoc7_1_5_157LexiconImE4ItemC2EmNS0_8TextViewE:
  529|     48|template <typename E> Lexicon<E>::Item::Item(E value, TextView name) : _payload{value, name} {}
_ZN4swoc7_1_5_156detail17lexicon_pair_typeImEC2EmNS0_8TextViewE:
   52|     48|  lexicon_pair_type(E value, TextView name) : _value(value), _name(name) {}
_ZN4swoc7_1_5_157LexiconImE8localizeERKNS0_8TextViewE:
  626|     48|Lexicon<E>::localize(TextView const &name) {
  627|     48|  auto span = _arena.alloc_span<char>(name.size());
  628|     48|  memcpy(span, name);
  629|     48|  return {span.data(), span.size()};
  630|     48|}
_ZN4swoc7_1_5_157LexiconImE4Item11NameLinkage8prev_ptrEPS3_:
  540|    120|Lexicon<E>::Item::NameLinkage::prev_ptr(Item *item) -> Item *& {
  541|    120|  return item->_name_link._prev;
  542|    120|}
_ZN4swoc7_1_5_157LexiconImE4Item12ValueLinkage7hash_ofEm:
  576|     64|Lexicon<E>::Item::ValueLinkage::hash_of(E value) {
  577|     64|  return Lexicon_Hash<E>(value);
  578|     64|}
_ZN4swoc7_1_5_1512Lexicon_HashImEEmT_:
   61|     64|Lexicon_Hash(E e) {
   62|     64|  static constexpr std::hash<E> hasher;
   63|     64|  return hasher(e);
   64|     64|}
_ZN4swoc7_1_5_157LexiconImE4Item12ValueLinkage5equalEmm:
  588|     64|Lexicon<E>::Item::ValueLinkage::equal(E lhs, E rhs) {
  589|     64|  return lhs == rhs;
  590|     64|}
_ZN4swoc7_1_5_157LexiconImE4Item12ValueLinkage6key_ofEPS3_:
  564|     80|Lexicon<E>::Item::ValueLinkage::key_of(Item *item) {
  565|     80|  return item->_payload._value;
  566|     80|}
_ZN4swoc7_1_5_157LexiconImE4Item12ValueLinkage8next_ptrEPS3_:
  546|     62|Lexicon<E>::Item::ValueLinkage::next_ptr(Item *item) -> Item *& {
  547|     62|  return item->_value_link._next;
  548|     62|}
_ZN4swoc7_1_5_157LexiconImE4Item12ValueLinkage8prev_ptrEPS3_:
  552|     28|Lexicon<E>::Item::ValueLinkage::prev_ptr(Item *item) -> Item *& {
  553|     28|  return item->_value_link._prev;
  554|     28|}

_ZN4swoc7_1_5_158MemArena5Block4dataEv:
  605|    192|MemArena::Block::data() {
  606|    192|  return reinterpret_cast<char *>(this + 1);
  607|    192|}
_ZNK4swoc7_1_5_158MemArena5Block9remainingEv:
  631|    382|MemArena::Block::remaining() const {
  632|    382|  return size - allocated;
  633|    382|}
_ZN4swoc7_1_5_158MemArena5Block7remnantEv:
  654|     96|MemArena::Block::remnant() {
  655|     96|  return {this->data() + allocated, this->remaining()};
  656|     96|}
_ZN4swoc7_1_5_158MemArenaC2Em:
  701|      2|inline MemArena::MemArena(size_t n) : _reserve_hint(n) {}
_ZN4swoc7_1_5_158MemArena4makeINS0_7LexiconImE4ItemEJRmNS0_8TextViewEEEEPT_DpOT0_:
  711|     48|MemArena::make(Args &&...args) {
  712|     48|  return new (this->alloc(sizeof(T), alignof(T)).data()) T(std::forward<Args>(args)...);
  713|     48|}
_ZN4swoc7_1_5_158MemArena10alloc_spanIcEENS0_7MemSpanIT_EEm:
  705|     48|MemArena::alloc_span(size_t n) {
  706|     48|  return this->alloc(sizeof(T) * n, alignof(T)).rebind<T>();
  707|     48|}
_ZN4swoc7_1_5_158MemArena5Block7Linkage8next_ptrEPS2_:
  593|      2|MemArena::Block::Linkage::next_ptr(Block *b) -> Block *& {
  594|      2|  return b->_link._next;
  595|      2|}
_ZN4swoc7_1_5_158MemArena5Block7Linkage8prev_ptrEPS2_:
  598|      2|MemArena::Block::Linkage::prev_ptr(Block *b) -> Block *& {
  599|      2|  return b->_link._prev;
  600|      2|}
_ZNK4swoc7_1_5_158MemArena5Block4dataEv:
  610|     94|MemArena::Block::data() const {
  611|     94|  return reinterpret_cast<const char *>(this + 1);
  612|     94|}
_ZNK4swoc7_1_5_158MemArena5Block7is_fullEv:
  636|     96|MemArena::Block::is_full() const {
  637|     96|  return this->remaining() < MIN_FREE_SPACE;
  638|     96|}
_ZN4swoc7_1_5_158MemArena5Block5allocEmm:
  641|     96|MemArena::Block::alloc(size_t n, size_t align) {
  642|     96|  auto base = this->data() + allocated;
  643|     96|  auto pad  = align_padding(base, align);
  644|     96|  if ((n + pad) > this->remaining()) {
  ------------------
  |  Branch (644:7): [True: 0, False: 96]
  ------------------
  645|      0|    throw(std::invalid_argument{"MemArena::Block::alloc size is more than remaining."});
  646|      0|  }
  647|     96|  MemSpan<void> zret = this->remnant().prefix(n + pad);
  648|     96|  zret.remove_prefix(pad);
  649|     96|  allocated += n + pad;
  650|     96|  return zret;
  651|     96|}
_ZN4swoc7_1_5_158MemArena5BlocknwEmm:
  666|      2|{
  667|      2|  if (n < block_size) {
  ------------------
  |  Branch (667:7): [True: 0, False: 2]
  ------------------
  668|      0|    throw std::invalid_argument("MemArena::Block::operator new size is less than object size.");
  669|      0|  }
  670|       |  // In theory we could use ::operator new(n) but this causes a size mismatch during ::operator delete.
  671|       |  // Easier to use malloc here and also override @c delete.
  672|      2|  auto b = static_cast<Block *>(::malloc(n));
  673|      2|  if (b == nullptr) {
  ------------------
  |  Branch (673:7): [True: 0, False: 2]
  ------------------
  674|      0|    throw std::bad_alloc();
  675|      0|  }
  676|      2|  return b;
  677|      2|}
_ZN4swoc7_1_5_158MemArena5BlockdlEPv:
  685|      2|MemArena::Block::operator delete(void *ptr) noexcept {
  686|      2|  ::free(ptr);
  687|      2|}
_ZN4swoc7_1_5_158MemArena5Block13align_paddingEPKvm:
  694|    190|MemArena::Block::align_padding(void const *ptr, size_t align) {
  695|    190|  if (auto delta = uintptr_t(ptr) & (align - 1); delta > 0) {
  ------------------
  |  Branch (695:50): [True: 88, False: 102]
  ------------------
  696|     88|    return align - delta;
  697|     88|  }
  698|    102|  return 0;
  699|    190|}
_ZN4swoc7_1_5_158MemArena5BlockC2Em:
  602|      2|inline MemArena::Block::Block(size_t n) noexcept : size(n) {}

_ZN4swoc7_1_5_157MemSpanIcEC2EPcm:
 1064|     48|template <typename T> constexpr MemSpan<T>::MemSpan(T *ptr, size_t count) : _ptr{ptr}, _count{count} {}
_ZNK4swoc7_1_5_157MemSpanIcE4dataEv:
 1154|     96|MemSpan<T>::data() const {
 1155|     96|  return _ptr;
 1156|     96|}
_ZNK4swoc7_1_5_157MemSpanIcE4sizeEv:
 1178|     48|MemSpan<T>::size() const {
 1179|     48|  return _count;
 1180|     48|}
_ZN4swoc7_1_5_156memcpyERNS0_7MemSpanIcEENSt3__117basic_string_viewIcNS4_11char_traitsIcEEEE:
 1002|     48|memcpy(MemSpan<char> &span, std::string_view view) {
 1003|     48|  return static_cast<char *>(std::memcpy(span.data(), view.data(), std::min(view.size(), view.size())));
 1004|     48|}
_ZNK4swoc7_1_5_157MemSpanIvE4dataEv:
 1467|     48|MemSpan<void>::data() const {
 1468|     48|  return _ptr;
 1469|     48|}
_ZNK4swoc7_1_5_157MemSpanIvE6rebindIcEENS1_IT_EEv:
 1658|     48|MemSpan<void>::rebind() const {
 1659|     48|  return {static_cast<U *>(_ptr), detail::is_span_compatible<value_type, U>::count(_size)};
 1660|     48|}
_ZN4swoc7_1_5_156detail18is_span_compatibleIvcE5countEm:
  920|     48|is_span_compatible<T, U>::count(size_t size) {
  921|     48|  if (size % sizeof(U)) {
  ------------------
  |  Branch (921:7): [True: 0, False: 48]
  ------------------
  922|      0|    throw std::invalid_argument("MemSpan rebind where span size is not a multiple of the element size");
  923|      0|  }
  924|     48|  return size / sizeof(U);
  925|     48|}
_ZN4swoc7_1_5_157MemSpanIvEC2Ev:
  660|     96|  constexpr MemSpan() = default;
_ZN4swoc7_1_5_157MemSpanIKvEC2Ev:
  400|     96|  constexpr MemSpan() = default;
_ZN4swoc7_1_5_157MemSpanIvEC2EPvm:
 1342|    192|inline constexpr MemSpan<void>::MemSpan(value_type *ptr, size_t n) : super_type(ptr, n) {}
_ZN4swoc7_1_5_157MemSpanIKvEC2EPS2_m:
 1341|    192|inline constexpr MemSpan<void const>::MemSpan(value_type *ptr, size_t n) : _ptr{const_cast<void *>(ptr)}, _size{n} {}
_ZN4swoc7_1_5_156detail7ptr_addEPvm:
  880|     96|ptr_add(void *ptr, size_t count) {
  881|     96|  return static_cast<char *>(ptr) + count;
  882|     96|}
_ZNK4swoc7_1_5_157MemSpanIvE6prefixEm:
 1512|     96|MemSpan<void>::prefix(size_t n) const -> self_type {
 1513|     96|  return {_ptr, std::min(n, _size)};
 1514|     96|}
_ZN4swoc7_1_5_157MemSpanIKvE13remove_prefixEm:
 1517|     96|MemSpan<void const>::remove_prefix(size_t n) -> self_type & {
 1518|     96|  n      = std::min(_size, n);
 1519|     96|  _size -= n;
 1520|     96|  _ptr   = detail::ptr_add(_ptr, n);
 1521|     96|  return *this;
 1522|     96|}
_ZN4swoc7_1_5_157MemSpanIvE13remove_prefixEm:
 1525|     96|MemSpan<void>::remove_prefix(size_t n) -> self_type & {
 1526|     96|  super_type::remove_prefix(n);
 1527|     96|  return *this;
 1528|     96|}

_ZNK4swoc7_1_5_156ScalarILl8EiNS0_3tag7genericEEcviEv:
  443|  85.5k|template <intmax_t N, typename C, typename T> constexpr Scalar<N, C, T>::operator Counter() const {
  444|  85.5k|  return _n * SCALE;
  445|  85.5k|}
_ZN4swoc7_1_5_158round_upIiEENS0_6detail22scalar_unit_round_up_tIT_EES4_:
  559|  47.7k|round_up(C n) {
  560|  47.7k|  return {n};
  561|  47.7k|}
_ZN4swoc7_1_5_156ScalarILl8EiNS0_3tag7genericEEC2IiEENS0_6detail22scalar_unit_round_up_tIT_EE:
  425|  47.7k|constexpr Scalar<N, C, T>::Scalar(detail::scalar_unit_round_up_t<I> v) : _n(v.template scale<N, C>()) {}
_ZNK4swoc7_1_5_156detail22scalar_unit_round_up_tIiE5scaleILl8EiEET0_v:
  106|  47.7k|  scale() const {
  107|  47.7k|    return static_cast<I>(_n / N + (0 != (_n % N)));
  108|  47.7k|  }
_ZN4swoc7_1_5_158round_upImEENS0_6detail22scalar_unit_round_up_tIT_EES4_:
  559|      4|round_up(C n) {
  560|      4|  return {n};
  561|      4|}
_ZNK4swoc7_1_5_156detail22scalar_unit_round_up_tImE5scaleILl16EiEET0_v:
  106|      2|  scale() const {
  107|      2|    return static_cast<I>(_n / N + (0 != (_n % N)));
  108|      2|  }
_ZNK4swoc7_1_5_156ScalarILl16EiNS0_3tag7genericEEcviEv:
  443|      2|template <intmax_t N, typename C, typename T> constexpr Scalar<N, C, T>::operator Counter() const {
  444|      2|  return _n * SCALE;
  445|      2|}
_ZN4swoc7_1_5_156ScalarILl16EiNS0_3tag7genericEEC2ImEENS0_6detail22scalar_unit_round_up_tIT_EE:
  425|      2|constexpr Scalar<N, C, T>::Scalar(detail::scalar_unit_round_up_t<I> v) : _n(v.template scale<N, C>()) {}
_ZN4swoc7_1_5_156ScalarILl1024EiNS0_3tag7genericEEC2ImEENS0_6detail22scalar_unit_round_up_tIT_EE:
  425|      2|constexpr Scalar<N, C, T>::Scalar(detail::scalar_unit_round_up_t<I> v) : _n(v.template scale<N, C>()) {}
_ZNK4swoc7_1_5_156detail22scalar_unit_round_up_tImE5scaleILl1024EiEET0_v:
  106|      2|  scale() const {
  107|      2|    return static_cast<I>(_n / N + (0 != (_n % N)));
  108|      2|  }
_ZNK4swoc7_1_5_156ScalarILl1024EiNS0_3tag7genericEEcviEv:
  443|      2|template <intmax_t N, typename C, typename T> constexpr Scalar<N, C, T>::operator Counter() const {
  444|      2|  return _n * SCALE;
  445|      2|}

_ZN4swoc7_1_5_158TextView5clearEv:
 1147|  6.67k|TextView::clear() -> self_type & {
 1148|  6.67k|  new (this) self_type();
 1149|  6.67k|  return *this;
 1150|  6.67k|}
_ZNK4swoc7_1_5_158TextViewdeEv:
 1153|   114k|TextView::operator*() const {
 1154|   114k|  return this->empty() ? char(0) : *(this->data());
  ------------------
  |  Branch (1154:10): [True: 0, False: 114k]
  ------------------
 1155|   114k|}
_ZNK4swoc7_1_5_158TextViewntEv:
 1158|  1.51k|TextView::operator!() const noexcept {
 1159|  1.51k|  return this->empty();
 1160|  1.51k|}
_ZNK4swoc7_1_5_158TextViewcvbEv:
 1162|  40.1k|inline constexpr TextView::operator bool() const noexcept {
 1163|  40.1k|  return !this->empty();
 1164|  40.1k|}
_ZN4swoc7_1_5_158TextViewppEv:
 1167|  3.17k|TextView::operator++() -> self_type & {
 1168|  3.17k|  this->remove_prefix(1);
 1169|  3.17k|  return *this;
 1170|  3.17k|}
_ZN4swoc7_1_5_158TextViewaSERKNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
 1192|  64.0k|TextView::operator=(super_type const &that) -> self_type & {
 1193|  64.0k|  this->super_type::operator=(that);
 1194|  64.0k|  return *this;
 1195|  64.0k|}
_ZN4swoc7_1_5_158TextViewaSERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
 1210|  1.03k|TextView::operator=(const std::string &s) -> self_type & {
 1211|  1.03k|  this->super_type::operator=(s);
 1212|  1.03k|  return *this;
 1213|  1.03k|}
_ZN4swoc7_1_5_158TextView6assignEPKcm:
 1232|  51.6k|TextView::assign(char const *ptr, size_t n) {
 1233|  51.6k|  *this = super_type(ptr, n == npos ? (ptr ? ::strlen(ptr) : 0) : n);
  ------------------
  |  Branch (1233:27): [True: 0, False: 51.6k]
  |  Branch (1233:40): [True: 0, False: 0]
  ------------------
 1234|  51.6k|  return *this;
 1235|  51.6k|}
_ZN4swoc7_1_5_158TextView6assignEPKcS3_:
 1238|  12.4k|TextView::assign(char const *b, char const *e) {
 1239|  12.4k|  *this = super_type(b, e - b);
 1240|  12.4k|  return *this;
 1241|  12.4k|}
_ZNK4swoc7_1_5_158TextView6prefixEm:
 1250|  26.5k|TextView::prefix(size_t n) const noexcept -> self_type {
 1251|  26.5k|  return {this->data(), std::min(n, this->size())};
 1252|  26.5k|}
_ZN4swoc7_1_5_158TextView13remove_prefixEm:
 1288|   132k|TextView::remove_prefix(size_t n) -> self_type & {
 1289|   132k|  this->super_type::remove_prefix(std::min(n, this->size()));
 1290|   132k|  return *this;
 1291|   132k|}
_ZN4swoc7_1_5_158TextView12split_prefixEm:
 1319|  22.2k|TextView::split_prefix(size_t n) {
 1320|  22.2k|  self_type zret; // default to empty return.
 1321|  22.2k|  if (n < this->size()) {
  ------------------
  |  Branch (1321:7): [True: 20.0k, False: 2.25k]
  ------------------
 1322|  20.0k|    zret = this->prefix(n);
 1323|  20.0k|    this->remove_prefix(std::min(n + 1, this->size()));
 1324|  20.0k|  }
 1325|  22.2k|  return zret;
 1326|  22.2k|}
_ZN4swoc7_1_5_158TextView15split_prefix_atEc:
 1334|  22.2k|TextView::split_prefix_at(char c) {
 1335|  22.2k|  return this->split_prefix(this->find(c));
 1336|  22.2k|}
_ZN4swoc7_1_5_158TextView11take_prefixEm:
 1350|  6.49k|TextView::take_prefix(size_t n) {
 1351|  6.49k|  n              = std::min(n, this->size());
 1352|  6.49k|  self_type zret = this->prefix(n);
 1353|  6.49k|  this->remove_prefix(std::min(n + 1, this->size()));
 1354|  6.49k|  return zret;
 1355|  6.49k|}
_ZNK4swoc7_1_5_158TextView6suffixEm:
 1374|  19.7k|TextView::suffix(size_t n) const noexcept {
 1375|  19.7k|  n = std::min(n, this->size());
 1376|  19.7k|  return {this->data_end() - n, n};
 1377|  19.7k|}
_ZNK4swoc7_1_5_158TextView6suffixEi:
 1380|  19.7k|TextView::suffix(int n) const noexcept {
 1381|  19.7k|  return this->suffix(size_t(n));
 1382|  19.7k|}
_ZN4swoc7_1_5_158TextView13remove_suffixEm:
 1416|  27.5k|TextView::remove_suffix(size_t n) -> self_type & {
 1417|  27.5k|  this->super_type::remove_suffix(std::min(n, this->size()));
 1418|  27.5k|  return *this;
 1419|  27.5k|}
_ZNK4swoc7_1_5_158TextView4dataEv:
 1639|   573k|TextView::data() const noexcept -> value_type const * {
 1640|   573k|  return super_type::data();
 1641|   573k|}
_ZNK4swoc7_1_5_158TextView8data_endEv:
 1644|   105k|TextView::data_end() const noexcept -> value_type const * {
 1645|   105k|  return this->data() + this->size();
 1646|   105k|}
_ZN4swoc7_1_5_158TextViewC2Ev:
  100|  93.0k|  constexpr TextView() noexcept = default;
_ZN4swoc7_1_5_158TextViewC2ERKNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEE:
 1135|    377|inline constexpr TextView::TextView(super_type const &that) noexcept : super_type(that) {}
_ZN4swoc7_1_5_158TextView8ltrim_ifIPFjcEEERS1_RKT_:
 1612|  26.8k|TextView::ltrim_if(F const &pred) {
 1613|  26.8k|  const char *spot;
 1614|  26.8k|  const char *limit;
 1615|  29.7k|  for (spot = this->data(), limit = this->data_end(); spot < limit && pred(*spot); ++spot)
  ------------------
  |  Branch (1615:55): [True: 29.3k, False: 439]
  |  Branch (1615:71): [True: 2.92k, False: 26.4k]
  ------------------
 1616|  2.92k|    ;
 1617|  26.8k|  this->remove_prefix(spot - this->data());
 1618|  26.8k|  return *this;
 1619|  26.8k|}
_ZN4swoc7_1_5_158TextView8rtrim_ifIPFjcEEERS1_RKT_:
 1623|  27.1k|TextView::rtrim_if(F const &pred) {
 1624|  27.1k|  const char *spot  = this->data_end();
 1625|  27.1k|  const char *limit = this->data();
 1626|  51.1k|  while (limit < spot-- && pred(*spot))
  ------------------
  |  Branch (1626:10): [True: 32.4k, False: 18.7k]
  |  Branch (1626:28): [True: 24.0k, False: 8.38k]
  ------------------
 1627|  24.0k|    ;
 1628|  27.1k|  this->remove_suffix(this->data_end() - (spot + 1));
 1629|  27.1k|  return *this;
 1630|  27.1k|}
_ZN4swoc7_1_5_158TextViewC2IPKcEET_NSt3__19enable_ifIXaaaantsr3stdE10is_array_vIS5_Esr3stdE12is_pointer_vIS5_Esr3stdE16is_convertible_vIS5_S4_EES5_E4typeE:
  170|  80.0k|    : super_type(first, last - first) {}
_ZN4swoc7_1_5_158TextViewC2EPKcm:
 1127|  46.3k|  : super_type(ptr, n == npos ? (ptr ? ::strlen(ptr) : 0) : n) {}
  ------------------
  |  Branch (1127:21): [True: 0, False: 46.3k]
  |  Branch (1127:34): [True: 0, False: 0]
  ------------------
_ZN4swoc7_1_5_158TextViewC2EPKci:
 1132|  1.01k|  : super_type(ptr, n < 0 ? (ptr ? ::strlen(ptr) : 0) : size_t(n)) {}
  ------------------
  |  Branch (1132:21): [True: 0, False: 1.01k]
  |  Branch (1132:30): [True: 0, False: 0]
  ------------------
_ZN4swoc7_1_5_158TextView7trim_ifIPFjcEEERS1_RKT_:
 1634|  6.49k|TextView::trim_if(F const &pred) {
 1635|  6.49k|  return this->ltrim_if(pred).rtrim_if(pred);
 1636|  6.49k|}
_ZNK4swoc7_1_5_1513TransformViewIPDoFiiENSt3__117basic_string_viewIcNS4_11char_traitsIcEEEEEcvbEv:
 1907|    552|template <typename X, typename V> TransformView<X, V>::operator bool() const {
 1908|    552|  return _spot != _limit;
 1909|    552|}
_ZNK4swoc7_1_5_1513TransformViewIPDoFiiENSt3__117basic_string_viewIcNS4_11char_traitsIcEEEEEdeEv:
 1882|    456|TransformView<X, V>::operator*() const -> value_type {
 1883|    456|  return _xf(*_spot);
 1884|    456|}
_ZN4swoc7_1_5_1513TransformViewIPDoFiiENSt3__117basic_string_viewIcNS4_11char_traitsIcEEEEEppEv:
 1888|    456|TransformView<X, V>::operator++() -> self_type & {
 1889|    456|  ++_spot;
 1890|    456|  return *this;
 1891|    456|}
_ZN4swoc7_1_5_1517transform_view_ofIPDoFiiENSt3__117basic_string_viewIcNS4_11char_traitsIcEEEEEENS0_13TransformViewIT_T0_EERKSA_RKSB_:
 1933|     96|transform_view_of(X const &xf, V const &src) {
 1934|     96|  return TransformView<X, V>(xf, src);
 1935|     96|}
_ZN4swoc7_1_5_1513TransformViewIPDoFiiENSt3__117basic_string_viewIcNS4_11char_traitsIcEEEEEC2ERKS3_RKS8_:
 1878|     96|  : _xf(xf), _spot(v.begin()), _limit(v.end()) {}

_ZNK4swoc7_1_5_1511Hash32FNV1a3getEv:
  197|     96|Hash32FNV1a::get() const -> value_type {
  198|     96|  return hval;
  199|     96|}
_ZN4swoc7_1_5_1511Hash32FNV1aC2Ev:
   41|     96|  Hash32FNV1a() = default;
_ZN4swoc7_1_5_1511Hash32FNV1a14hash_immediateIPDoFiiENSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEEjRKNS0_13TransformViewIT_T0_EE:
  203|     96|Hash32FNV1a::hash_immediate(swoc::TransformView<X, V> const &view) -> value_type {
  204|     96|  return this->update(view).get();
  205|     96|}
_ZN4swoc7_1_5_1511Hash32FNV1a6updateIPDoFiiENSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEEERS1_NS0_13TransformViewIT_T0_EE:
  178|     96|Hash32FNV1a::update(TransformView<X, V> view) -> self_type & {
  179|    552|  for (; view; ++view) {
  ------------------
  |  Branch (179:10): [True: 456, False: 96]
  ------------------
  180|    456|    hval ^= static_cast<value_type>(*view);
  181|    456|    hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
  182|    456|  }
  183|     96|  return *this;
  184|     96|}

_ZN4swoc7_1_5_158MemArenaC2EOS1_:
   38|      2|  : _active_allocated(that._active_allocated),
   39|      2|    _active_reserved(that._active_reserved),
   40|      2|    _frozen_allocated(that._frozen_allocated),
   41|      2|    _frozen_reserved(that._frozen_reserved),
   42|      2|    _reserve_hint(that._reserve_hint),
   43|      2|    _frozen(std::move(that._frozen)),
   44|      2|    _active(std::move(that._active)),
   45|      2|    _static_block(that._static_block) {
   46|       |  // Clear data in @a that to indicate all of the memory has been moved.
   47|      2|  that._active_allocated = that._active_reserved = 0;
   48|      2|  that._frozen_allocated = that._frozen_reserved = 0;
   49|      2|  that._reserve_hint                             = 0;
   50|      2|  that._static_block                             = nullptr;
   51|      2|}
_ZN4swoc7_1_5_158MemArena10make_blockEm:
   73|      2|MemArena::make_block(size_t n) {
   74|       |  // If there's no reservation hint, use the extent. This is transient because the hint is cleared.
   75|      2|  if (_reserve_hint == 0) {
  ------------------
  |  Branch (75:7): [True: 0, False: 2]
  ------------------
   76|      0|    if (_active_reserved) {
  ------------------
  |  Branch (76:9): [True: 0, False: 0]
  ------------------
   77|      0|      _reserve_hint = _active_reserved;
   78|      0|    } else if (_frozen_allocated) { // immediately after freezing - use that extent.
  ------------------
  |  Branch (78:16): [True: 0, False: 0]
  ------------------
   79|      0|      _reserve_hint = _frozen_allocated;
   80|      0|    }
   81|      0|  }
   82|      2|  n             = std::max<size_t>(n, _reserve_hint);
   83|      2|  _reserve_hint = 0; // did this, clear for next time.
   84|       |  // Add in overhead and round up to paragraph units.
   85|      2|  n = Paragraph{round_up(n + ALLOC_HEADER_SIZE + sizeof(Block))};
   86|       |  // If more than a page or withing a quarter page of a full page,
   87|       |  // round up to page unit size and clip back to account for alloc header.
   88|      2|  if (n >= (Page::SCALE - QuarterPage::SCALE)) {
  ------------------
  |  Branch (88:7): [True: 0, False: 2]
  ------------------
   89|      0|    n = Page{round_up(n)} - ALLOC_HEADER_SIZE;
   90|      2|  } else if (n >= QuarterPage::SCALE) { // if at least a quarter page, round up to quarter pages.
  ------------------
  |  Branch (90:14): [True: 2, False: 0]
  ------------------
   91|      2|    n = QuarterPage{round_up(n)};
   92|      2|  }
   93|       |
   94|       |  // Allocate space for the Block instance and the requested memory and construct a Block at the front.
   95|      2|  auto free_space   = n - sizeof(Block);
   96|      2|  _active_reserved += free_space;
   97|      2|  return new (n) Block(free_space);
   98|      2|}
_ZN4swoc7_1_5_158MemArena5allocEmm:
  101|     96|MemArena::alloc(size_t n, size_t align) {
  102|     96|  MemSpan<void> zret;
  103|     96|  this->require(n, align);
  104|     96|  auto block         = _active.head();
  105|     96|  zret               = block->alloc(n, align);
  106|     96|  _active_allocated += n;
  107|       |  // If this block is now full, move it to the back.
  108|     96|  if (block->is_full() && block != _active.tail()) {
  ------------------
  |  Branch (108:7): [True: 0, False: 96]
  |  Branch (108:27): [True: 0, False: 0]
  ------------------
  109|      0|    _active.erase(block);
  110|      0|    _active.append(block);
  111|      0|  }
  112|     96|  return zret;
  113|     96|}
_ZN4swoc7_1_5_158MemArena7requireEmm:
  150|     96|MemArena::require(size_t n, size_t align) {
  151|     96|  auto spot = _active.begin();
  152|     96|  Block *block{nullptr};
  153|       |
  154|       |  // Search back through the list until a full block is hit, which is a miss.
  155|     96|  while (spot != _active.end() && !spot->satisfies(n, align)) {
  ------------------
  |  Branch (155:10): [True: 94, False: 2]
  |  Branch (155:10): [True: 0, False: 96]
  |  Branch (155:35): [True: 0, False: 94]
  ------------------
  156|      0|    if (spot->is_full()) {
  ------------------
  |  Branch (156:9): [True: 0, False: 0]
  ------------------
  157|      0|      spot = _active.end();
  158|      0|    } else {
  159|      0|      ++spot;
  160|      0|    }
  161|      0|  }
  162|     96|  if (spot == _active.end()) {   // no block has enough free space
  ------------------
  |  Branch (162:7): [True: 2, False: 94]
  ------------------
  163|      2|    block = this->make_block(n); // assuming a new block is sufficiently aligned.
  164|      2|    _active.prepend(block);
  165|     94|  } else if (spot != _active.begin()) {
  ------------------
  |  Branch (165:14): [True: 0, False: 94]
  ------------------
  166|       |    // big enough space, move to the head of the list.
  167|      0|    block = spot;
  168|      0|    _active.erase(block);
  169|      0|    _active.prepend(block);
  170|      0|  }
  171|       |  // Invariant - the head active block has at least @a n bytes of free storage.
  172|     96|  return *this;
  173|     96|}
_ZN4swoc7_1_5_158MemArenaD2Ev:
  254|      4|MemArena::~MemArena() {
  255|       |  // Destruct in a way that makes it safe for the instance to be in one of its own memory blocks.
  256|       |  // This means copying members that will be used during the delete.
  257|      4|  Block *ba = _active.head();
  258|      4|  Block *bf = _frozen.head();
  259|      4|  Block *sb = _static_block;
  260|       |
  261|      4|  _active.clear();
  262|      4|  _frozen.clear();
  263|      4|  while (bf) {
  ------------------
  |  Branch (263:10): [True: 0, False: 4]
  ------------------
  264|      0|    Block *b = bf;
  265|      0|    bf       = bf->_link._next;
  266|      0|    if (b != sb) {
  ------------------
  |  Branch (266:9): [True: 0, False: 0]
  ------------------
  267|      0|      delete b;
  268|      0|    }
  269|      0|  }
  270|      6|  while (ba) {
  ------------------
  |  Branch (270:10): [True: 2, False: 4]
  ------------------
  271|      2|    Block *b = ba;
  272|      2|    ba       = ba->_link._next;
  273|      2|    if (b != sb) {
  ------------------
  |  Branch (273:9): [True: 2, False: 0]
  ------------------
  274|      2|      delete b;
  275|      2|    }
  276|      2|  }
  277|      4|}
_ZNK4swoc7_1_5_158MemArena5Block9satisfiesEmm:
   16|     94|MemArena::Block::satisfies(size_t n, size_t align) const {
   17|     94|  auto r = this->remaining();
   18|     94|  return r >= (n + align_padding(this->data() + allocated, align));
   19|     94|}

_Z10strcasecmpRKNSt3__117basic_string_viewIcNS_11char_traitsIcEEEES5_:
   30|    184|strcasecmp(const std::string_view &lhs, const std::string_view &rhs) {
   31|    184|  int zret = 0;
   32|    184|  size_t n = rhs.size();
   33|       |
   34|       |  // Seems a bit ugly but size comparisons must be done anyway to get the @c strncasecmp args.
   35|    184|  if (lhs.size() < rhs.size()) {
  ------------------
  |  Branch (35:7): [True: 92, False: 92]
  ------------------
   36|     92|    zret = 1;
   37|     92|    n    = lhs.size();
   38|     92|  } else if (lhs.size() > rhs.size()) {
  ------------------
  |  Branch (38:14): [True: 72, False: 20]
  ------------------
   39|     72|    zret = -1;
   40|     72|  } else if (lhs.data() == rhs.data()) { // the same memory, obviously equal.
  ------------------
  |  Branch (40:14): [True: 0, False: 20]
  ------------------
   41|      0|    return 0;
   42|      0|  }
   43|       |
   44|    184|  int r = ::strncasecmp(lhs.data(), rhs.data(), n);
   45|       |
   46|    184|  return r ? r : zret;
  ------------------
  |  Branch (46:10): [True: 168, False: 16]
  ------------------
   47|    184|}

_ZN9ProcessorC2Ev:
   54|      4|Processor::Processor() {} /* End Processor::Processor() */

_Z12thread_allocR17FreelistAllocatorR14ProxyAllocator:
   32|  33.4k|{
   33|  33.4k|  if (!cmd_disable_pfreelist && l.freelist) {
  ------------------
  |  Branch (33:7): [True: 0, False: 33.4k]
  |  Branch (33:33): [True: 0, False: 0]
  ------------------
   34|      0|    void *v    = l.freelist;
   35|      0|    l.freelist = *static_cast<void **>(l.freelist);
   36|      0|    --(l.allocated);
   37|      0|    return v;
   38|      0|  }
   39|  33.4k|  return a.alloc_void();
   40|  33.4k|}

_ZN14EventProcessorC2Ev:
  366|      2|EventProcessor::EventProcessor() : thread_initializer(this)
  367|      2|{
  368|      2|  ink_zero(all_ethreads);
  369|      2|  ink_zero(all_dthreads);
  370|      2|  ink_mutex_init(&dedicated_thread_spawn_mutex);
  371|       |  // Because ET_NET is compile time set to 0 it *must* be the first type registered.
  372|      2|  this->register_event_type("ET_NET");
  373|      2|}
_ZN14EventProcessor19register_event_typeEPKc:
  416|      2|{
  417|      2|  ThreadGroupDescriptor *tg = &(thread_group[n_thread_groups++]);
  418|      2|  ink_release_assert(n_thread_groups <= MAX_EVENT_TYPES); // check for overflow
  ------------------
  |  |   48|      2|#define ink_release_assert(EX) ((void)(__builtin_expect(!!(EX), 0) ? (void)0 : _ink_assert(#EX, __FILE__, __LINE__)))
  |  |  ------------------
  |  |  |  Branch (48:40): [True: 2, False: 0]
  |  |  ------------------
  ------------------
  419|       |
  420|      2|  tg->_name = name;
  421|      2|  return n_thread_groups - 1;
  422|      2|}
_ZN25ThreadAffinityInitializerC2Ev:
   59|      2|  ThreadAffinityInitializer() { SET_HANDLER(&self::set_affinity); }
  ------------------
  |  |  253|      2|#define SET_HANDLER(_h) (handler = continuation_handler_void_ptr(_h))
  ------------------
UnixEventProcessor.cc:_ZN12_GLOBAL__N_116ThreadInitByFuncC2Ev:
  160|      2|  ThreadInitByFunc() { SET_HANDLER(&ThreadInitByFunc::invoke); }
  ------------------
  |  |  253|      2|#define SET_HANDLER(_h) (handler = continuation_handler_void_ptr(_h))
  ------------------

_Z9http_initv:
  137|  3.12k|{
  138|  3.12k|  static int init = 1;
  139|       |
  140|  3.12k|  if (init) {
  ------------------
  |  Branch (140:7): [True: 1, False: 3.12k]
  ------------------
  141|      1|    init = 0;
  142|       |
  143|      1|    mime_init();
  144|      1|    url_init();
  145|       |
  146|      1|    HTTP_METHOD_CONNECT = hdrtoken_string_to_wks_sv("CONNECT");
  147|      1|    HTTP_METHOD_DELETE  = hdrtoken_string_to_wks_sv("DELETE");
  148|      1|    HTTP_METHOD_GET     = hdrtoken_string_to_wks_sv("GET");
  149|      1|    HTTP_METHOD_HEAD    = hdrtoken_string_to_wks_sv("HEAD");
  150|      1|    HTTP_METHOD_OPTIONS = hdrtoken_string_to_wks_sv("OPTIONS");
  151|      1|    HTTP_METHOD_POST    = hdrtoken_string_to_wks_sv("POST");
  152|      1|    HTTP_METHOD_PURGE   = hdrtoken_string_to_wks_sv("PURGE");
  153|      1|    HTTP_METHOD_PUT     = hdrtoken_string_to_wks_sv("PUT");
  154|      1|    HTTP_METHOD_TRACE   = hdrtoken_string_to_wks_sv("TRACE");
  155|      1|    HTTP_METHOD_PUSH    = hdrtoken_string_to_wks_sv("PUSH");
  156|       |
  157|       |    // HTTP methods index calculation. Don't forget to count them!
  158|       |    // Don't change the order of calculation! Each index has related bitmask (see http quick filter)
  159|      1|    HTTP_WKSIDX_CONNECT = hdrtoken_wks_to_index(HTTP_METHOD_CONNECT.c_str());
  160|      1|    HTTP_WKSIDX_METHODS_CNT++;
  161|      1|    HTTP_WKSIDX_DELETE = hdrtoken_wks_to_index(HTTP_METHOD_DELETE.c_str());
  162|      1|    HTTP_WKSIDX_METHODS_CNT++;
  163|      1|    HTTP_WKSIDX_GET = hdrtoken_wks_to_index(HTTP_METHOD_GET.c_str());
  164|      1|    HTTP_WKSIDX_METHODS_CNT++;
  165|      1|    HTTP_WKSIDX_HEAD = hdrtoken_wks_to_index(HTTP_METHOD_HEAD.c_str());
  166|      1|    HTTP_WKSIDX_METHODS_CNT++;
  167|      1|    HTTP_WKSIDX_OPTIONS = hdrtoken_wks_to_index(HTTP_METHOD_OPTIONS.c_str());
  168|      1|    HTTP_WKSIDX_METHODS_CNT++;
  169|      1|    HTTP_WKSIDX_POST = hdrtoken_wks_to_index(HTTP_METHOD_POST.c_str());
  170|      1|    HTTP_WKSIDX_METHODS_CNT++;
  171|      1|    HTTP_WKSIDX_PURGE = hdrtoken_wks_to_index(HTTP_METHOD_PURGE.c_str());
  172|      1|    HTTP_WKSIDX_METHODS_CNT++;
  173|      1|    HTTP_WKSIDX_PUT = hdrtoken_wks_to_index(HTTP_METHOD_PUT.c_str());
  174|      1|    HTTP_WKSIDX_METHODS_CNT++;
  175|      1|    HTTP_WKSIDX_TRACE = hdrtoken_wks_to_index(HTTP_METHOD_TRACE.c_str());
  176|      1|    HTTP_WKSIDX_METHODS_CNT++;
  177|      1|    HTTP_WKSIDX_PUSH = hdrtoken_wks_to_index(HTTP_METHOD_PUSH.c_str());
  178|      1|    HTTP_WKSIDX_METHODS_CNT++;
  179|       |
  180|      1|    HTTP_VALUE_BYTES                = hdrtoken_string_to_wks_sv("bytes");
  181|      1|    HTTP_VALUE_CHUNKED              = hdrtoken_string_to_wks_sv("chunked");
  182|      1|    HTTP_VALUE_CLOSE                = hdrtoken_string_to_wks_sv("close");
  183|      1|    HTTP_VALUE_COMPRESS             = hdrtoken_string_to_wks_sv("compress");
  184|      1|    HTTP_VALUE_DEFLATE              = hdrtoken_string_to_wks_sv("deflate");
  185|      1|    HTTP_VALUE_GZIP                 = hdrtoken_string_to_wks_sv("gzip");
  186|      1|    HTTP_VALUE_BROTLI               = hdrtoken_string_to_wks_sv("br");
  187|      1|    HTTP_VALUE_ZSTD                 = hdrtoken_string_to_wks_sv("zstd");
  188|      1|    HTTP_VALUE_IDENTITY             = hdrtoken_string_to_wks_sv("identity");
  189|      1|    HTTP_VALUE_KEEP_ALIVE           = hdrtoken_string_to_wks_sv("keep-alive");
  190|      1|    HTTP_VALUE_MAX_AGE              = hdrtoken_string_to_wks_sv("max-age");
  191|      1|    HTTP_VALUE_MAX_STALE            = hdrtoken_string_to_wks_sv("max-stale");
  192|      1|    HTTP_VALUE_MIN_FRESH            = hdrtoken_string_to_wks_sv("min-fresh");
  193|      1|    HTTP_VALUE_MUST_REVALIDATE      = hdrtoken_string_to_wks_sv("must-revalidate");
  194|      1|    HTTP_VALUE_NONE                 = hdrtoken_string_to_wks_sv("none");
  195|      1|    HTTP_VALUE_NO_CACHE             = hdrtoken_string_to_wks_sv("no-cache");
  196|      1|    HTTP_VALUE_NO_STORE             = hdrtoken_string_to_wks_sv("no-store");
  197|      1|    HTTP_VALUE_NO_TRANSFORM         = hdrtoken_string_to_wks_sv("no-transform");
  198|      1|    HTTP_VALUE_ONLY_IF_CACHED       = hdrtoken_string_to_wks_sv("only-if-cached");
  199|      1|    HTTP_VALUE_PRIVATE              = hdrtoken_string_to_wks_sv("private");
  200|      1|    HTTP_VALUE_PROXY_REVALIDATE     = hdrtoken_string_to_wks_sv("proxy-revalidate");
  201|      1|    HTTP_VALUE_PUBLIC               = hdrtoken_string_to_wks_sv("public");
  202|      1|    HTTP_VALUE_S_MAXAGE             = hdrtoken_string_to_wks_sv("s-maxage");
  203|      1|    HTTP_VALUE_NEED_REVALIDATE_ONCE = hdrtoken_string_to_wks_sv("need-revalidate-once");
  204|      1|    HTTP_VALUE_100_CONTINUE         = hdrtoken_string_to_wks_sv("100-continue");
  205|      1|  }
  206|  3.12k|}
_Z15http_hdr_createP7HdrHeap8HTTPType11HTTPVersion:
  213|  18.7k|{
  214|  18.7k|  HTTPHdrImpl *hh;
  215|       |
  216|  18.7k|  hh = (HTTPHdrImpl *)heap->allocate_obj(sizeof(HTTPHdrImpl), HdrHeapObjType::HTTP_HEADER);
  217|  18.7k|  http_hdr_init(heap, hh, polarity, version);
  218|  18.7k|  return (hh);
  219|  18.7k|}
_Z13http_hdr_initP7HdrHeapP11HTTPHdrImpl8HTTPType11HTTPVersion:
  226|  18.7k|{
  227|  18.7k|  memset(&(hh->u), 0, sizeof(hh->u));
  228|  18.7k|  hh->m_polarity    = polarity;
  229|  18.7k|  hh->m_version     = HTTP_1_0;
  230|  18.7k|  hh->m_fields_impl = mime_hdr_create(heap);
  231|  18.7k|  if (polarity == HTTPType::REQUEST) {
  ------------------
  |  Branch (231:7): [True: 9.36k, False: 9.36k]
  ------------------
  232|  9.36k|    hh->u.req.m_url_impl       = url_create(heap);
  233|  9.36k|    hh->u.req.m_method_wks_idx = -1;
  234|  9.36k|  }
  235|       |
  236|  18.7k|  if (version == HTTP_2_0 || version == HTTP_3_0) {
  ------------------
  |  Branch (236:7): [True: 6.24k, False: 12.4k]
  |  Branch (236:30): [True: 6.24k, False: 6.24k]
  ------------------
  237|  12.4k|    MIMEField *field;
  238|  12.4k|    switch (polarity) {
  239|  6.24k|    case HTTPType::REQUEST:
  ------------------
  |  Branch (239:5): [True: 6.24k, False: 6.24k]
  ------------------
  240|  6.24k|      field = mime_field_create_named(heap, hh->m_fields_impl, PSEUDO_HEADER_METHOD);
  241|  6.24k|      mime_hdr_field_attach(hh->m_fields_impl, field, false, nullptr);
  242|       |
  243|  6.24k|      field = mime_field_create_named(heap, hh->m_fields_impl, PSEUDO_HEADER_SCHEME);
  244|  6.24k|      mime_hdr_field_attach(hh->m_fields_impl, field, false, nullptr);
  245|       |
  246|  6.24k|      field = mime_field_create_named(heap, hh->m_fields_impl, PSEUDO_HEADER_AUTHORITY);
  247|  6.24k|      mime_hdr_field_attach(hh->m_fields_impl, field, false, nullptr);
  248|       |
  249|  6.24k|      field = mime_field_create_named(heap, hh->m_fields_impl, PSEUDO_HEADER_PATH);
  250|  6.24k|      mime_hdr_field_attach(hh->m_fields_impl, field, false, nullptr);
  251|  6.24k|      break;
  252|  6.24k|    case HTTPType::RESPONSE:
  ------------------
  |  Branch (252:5): [True: 6.24k, False: 6.24k]
  ------------------
  253|  6.24k|      field = mime_field_create_named(heap, hh->m_fields_impl, PSEUDO_HEADER_STATUS);
  254|  6.24k|      mime_hdr_field_attach(hh->m_fields_impl, field, false, nullptr);
  255|  6.24k|      break;
  256|      0|    default:
  ------------------
  |  Branch (256:5): [True: 0, False: 12.4k]
  ------------------
  257|      0|      ink_abort("HTTPType::UNKNOWN");
  258|  12.4k|    }
  259|  12.4k|  }
  260|  18.7k|}
_Z16is_http1_versionhh:
  611|  2.34k|{
  612|       |  // Return true if 1.1 or 1.0
  613|  2.34k|  return (major == 1) && (minor == 1 || minor == 0);
  ------------------
  |  Branch (613:10): [True: 1.03k, False: 1.30k]
  |  Branch (613:27): [True: 484, False: 555]
  |  Branch (613:41): [True: 483, False: 72]
  ------------------
  614|  2.34k|}
_Z20http_hdr_version_setP11HTTPHdrImplRK11HTTPVersion:
  624|  2.34k|{
  625|  2.34k|  hh->m_version = ver;
  626|  2.34k|  return is_http1_version(ver.get_major(), ver.get_minor());
  627|  2.34k|}
_Z19http_hdr_method_setP7HdrHeapP11HTTPHdrImplNSt3__117basic_string_viewIcNS3_11char_traitsIcEEEEsb:
  656|  1.97k|{
  657|  1.97k|  ink_assert(hh->m_polarity == HTTPType::REQUEST);
  ------------------
  |  |   45|  1.97k|#define ink_assert(EX) (void)(EX)
  ------------------
  658|       |
  659|  1.97k|  hh->u.req.m_method_wks_idx = method_wks_idx;
  660|  1.97k|  mime_str_u16_set(heap, method, &(hh->u.req.m_ptr_method), &(hh->u.req.m_len_method), must_copy);
  661|  1.97k|}
_Z19http_hdr_status_setP11HTTPHdrImpl10HTTPStatus:
  695|  1.37k|{
  696|  1.37k|  ink_assert(hh->m_polarity == HTTPType::RESPONSE);
  ------------------
  |  |   45|  1.37k|#define ink_assert(EX) (void)(EX)
  ------------------
  697|  1.37k|  hh->u.resp.m_status = static_cast<int16_t>(status);
  698|  1.37k|}
_Z19http_hdr_reason_setP7HdrHeapP11HTTPHdrImplNSt3__117basic_string_viewIcNS3_11char_traitsIcEEEEb:
  715|     36|{
  716|     36|  ink_assert(hh->m_polarity == HTTPType::RESPONSE);
  ------------------
  |  |   45|     36|#define ink_assert(EX) (void)(EX)
  ------------------
  717|     36|  mime_str_u16_set(heap, value, &(hh->u.resp.m_ptr_reason), &(hh->u.resp.m_len_reason), must_copy);
  718|     36|}
_Z16http_parser_initP10HTTPParser:
  815|  18.7k|{
  816|  18.7k|  parser->m_parsing_http = true;
  817|  18.7k|  mime_parser_init(&parser->m_mime_parser);
  818|  18.7k|}
_Z17http_parser_clearP10HTTPParser:
  822|  18.7k|{
  823|  18.7k|  parser->m_parsing_http = true;
  824|  18.7k|  mime_parser_clear(&parser->m_mime_parser);
  825|  18.7k|}
_Z21http_parser_parse_reqP10HTTPParserP7HdrHeapP11HTTPHdrImplPPKcS6_bbimm:
  852|  9.36k|{
  853|  9.36k|  if (parser->m_parsing_http) {
  ------------------
  |  Branch (853:7): [True: 9.36k, False: 0]
  ------------------
  854|  9.36k|    MIMEScanner *scanner = &parser->m_mime_parser.m_scanner;
  855|  9.36k|    URLImpl     *url;
  856|       |
  857|  9.36k|    ParseResult err;
  858|  9.36k|    bool        line_is_real;
  859|  9.36k|    const char *cur;
  860|  9.36k|    const char *line_start;
  861|  9.36k|    const char *real_end;
  862|  9.36k|    const char *method_start;
  863|  9.36k|    const char *method_end;
  864|  9.36k|    const char *url_start;
  865|  9.36k|    const char *url_end;
  866|  9.36k|    const char *version_start;
  867|  9.36k|    const char *version_end;
  868|       |
  869|  9.36k|    swoc::TextView text, parsed;
  870|       |
  871|  9.36k|    real_end = end;
  872|       |
  873|  9.36k|  start:
  874|  9.36k|    hh->m_polarity = HTTPType::REQUEST;
  875|       |
  876|       |    // Make sure the line is not longer than max_request_line_size
  877|  9.36k|    if (scanner->get_buffered_line_size() > max_request_line_size) {
  ------------------
  |  Branch (877:9): [True: 0, False: 9.36k]
  ------------------
  878|      0|      return ParseResult::ERROR;
  879|      0|    }
  880|       |
  881|  9.36k|    text.assign(*start, real_end);
  882|  9.36k|    err    = scanner->get(text, parsed, line_is_real, eof, MIMEScanner::ScanType::LINE);
  883|  9.36k|    *start = text.data();
  884|  9.36k|    if (static_cast<int>(err) < 0) {
  ------------------
  |  Branch (884:9): [True: 43, False: 9.32k]
  ------------------
  885|     43|      return err;
  886|     43|    }
  887|       |    // We have to get a request line.  If we get parse done here,
  888|       |    //   that meas we got an empty request
  889|  9.32k|    if (err == ParseResult::DONE) {
  ------------------
  |  Branch (889:9): [True: 6.86k, False: 2.45k]
  ------------------
  890|  6.86k|      return ParseResult::ERROR;
  891|  6.86k|    }
  892|  2.45k|    if (err == ParseResult::CONT) {
  ------------------
  |  Branch (892:9): [True: 0, False: 2.45k]
  ------------------
  893|      0|      return err;
  894|      0|    }
  895|       |
  896|  2.45k|    ink_assert(parsed.size() < UINT16_MAX);
  ------------------
  |  |   45|  2.45k|#define ink_assert(EX) (void)(EX)
  ------------------
  897|  2.45k|    line_start = cur = parsed.data();
  898|  2.45k|    end              = parsed.data_end();
  899|       |
  900|  2.45k|    if (static_cast<unsigned>(end - line_start) > max_request_line_size) {
  ------------------
  |  Branch (900:9): [True: 0, False: 2.45k]
  ------------------
  901|      0|      return ParseResult::ERROR;
  902|      0|    }
  903|       |
  904|  2.45k|    must_copy_strings = (must_copy_strings || (!line_is_real));
  ------------------
  |  Branch (904:26): [True: 2.45k, False: 0]
  |  Branch (904:47): [True: 0, False: 0]
  ------------------
  905|       |
  906|  2.45k|#if (ENABLE_PARSER_FAST_PATHS)
  907|       |    // first try fast path
  908|  2.45k|    if (end - cur >= 16) {
  ------------------
  |  Branch (908:9): [True: 608, False: 1.85k]
  ------------------
  909|    608|      if (((cur[0] ^ 'G') | (cur[1] ^ 'E') | (cur[2] ^ 'T')) != 0) {
  ------------------
  |  Branch (909:11): [True: 424, False: 184]
  ------------------
  910|    424|        goto slow_case;
  911|    424|      }
  912|    184|      if (((end[-10] ^ 'H') | (end[-9] ^ 'T') | (end[-8] ^ 'T') | (end[-7] ^ 'P') | (end[-6] ^ '/') | (end[-4] ^ '.') |
  ------------------
  |  Branch (912:11): [True: 45, False: 139]
  ------------------
  913|    184|           (end[-2] ^ '\r') | (end[-1] ^ '\n')) != 0) {
  914|     45|        goto slow_case;
  915|     45|      }
  916|    139|      if (!(isdigit(end[-5]) && isdigit(end[-3]))) {
  ------------------
  |  Branch (916:13): [True: 120, False: 19]
  |  Branch (916:33): [True: 103, False: 17]
  ------------------
  917|     36|        goto slow_case;
  918|     36|      }
  919|    103|      if (!(ParseRules::is_space(cur[3]) && (!ParseRules::is_space(cur[4])) && (!ParseRules::is_space(end[-12])) &&
  ------------------
  |  Branch (919:13): [True: 97, False: 6]
  |  Branch (919:45): [True: 91, False: 6]
  |  Branch (919:80): [True: 85, False: 6]
  ------------------
  920|     85|            ParseRules::is_space(end[-11]))) {
  ------------------
  |  Branch (920:13): [True: 78, False: 7]
  ------------------
  921|     25|        goto slow_case;
  922|     25|      }
  923|     78|      if (&(cur[4]) >= &(end[-11])) {
  ------------------
  |  Branch (923:11): [True: 0, False: 78]
  ------------------
  924|      0|        goto slow_case;
  925|      0|      }
  926|       |
  927|     78|      HTTPVersion version{static_cast<uint8_t>(end[-5] - '0'), static_cast<uint8_t>(end[-3] - '0')};
  928|       |
  929|     78|      http_hdr_method_set(heap, hh, {&(cur[0]), 3}, HTTP_WKSIDX_GET, must_copy_strings);
  930|     78|      ink_assert(hh->u.req.m_url_impl != nullptr);
  ------------------
  |  |   45|     78|#define ink_assert(EX) (void)(EX)
  ------------------
  931|     78|      url       = hh->u.req.m_url_impl;
  932|     78|      url_start = &(cur[4]);
  933|     78|      err       = ::url_parse(heap, url, &url_start, &(end[-11]), must_copy_strings, strict_uri_parsing);
  934|     78|      if (static_cast<int>(err) < 0) {
  ------------------
  |  Branch (934:11): [True: 6, False: 72]
  ------------------
  935|      6|        return err;
  936|      6|      }
  937|     72|      if (!http_hdr_version_set(hh, version)) {
  ------------------
  |  Branch (937:11): [True: 16, False: 56]
  ------------------
  938|     16|        return ParseResult::ERROR;
  939|     16|      }
  940|       |
  941|     56|      end                    = real_end;
  942|     56|      parser->m_parsing_http = false;
  943|       |
  944|     56|      ParseResult ret = mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof,
  945|     56|                                          false, max_hdr_field_size);
  946|       |      // If we're done with the main parse do some validation
  947|     56|      if (ret == ParseResult::DONE) {
  ------------------
  |  Branch (947:11): [True: 50, False: 6]
  ------------------
  948|     50|        ret = validate_hdr_request_target(HTTP_WKSIDX_GET, url);
  949|     50|      }
  950|     56|      if (ret == ParseResult::DONE) {
  ------------------
  |  Branch (950:11): [True: 36, False: 20]
  ------------------
  951|     36|        ret = validate_hdr_host(hh); // check HOST header
  952|     36|      }
  953|     56|      if (ret == ParseResult::DONE) {
  ------------------
  |  Branch (953:11): [True: 36, False: 20]
  ------------------
  954|     36|        ret = validate_hdr_content_length(heap, hh);
  955|     36|      }
  956|     56|      return ret;
  957|     72|    }
  958|  1.85k|#endif
  959|       |
  960|  2.38k|  slow_case:
  961|       |
  962|  2.38k|    method_start  = nullptr;
  963|  2.38k|    method_end    = nullptr;
  964|  2.38k|    url_start     = nullptr;
  965|  2.38k|    url_end       = nullptr;
  966|  2.38k|    version_start = nullptr;
  967|  2.38k|    version_end   = nullptr;
  968|  2.38k|    url           = nullptr;
  969|       |
  970|  2.38k|    if (ParseRules::is_cr(*cur))
  ------------------
  |  Branch (970:9): [True: 102, False: 2.27k]
  ------------------
  971|  2.38k|      GETNEXT(done);
  ------------------
  |  |  831|    102|  {                    \
  |  |  832|    102|    cur += 1;          \
  |  |  833|    102|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 102]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|    102|  }
  ------------------
  972|  2.38k|    if (ParseRules::is_lf(*cur)) {
  ------------------
  |  Branch (972:9): [True: 0, False: 2.38k]
  ------------------
  973|      0|      goto start;
  974|      0|    }
  975|       |
  976|  2.59k|  parse_method1:
  977|       |
  978|  2.59k|    if (ParseRules::is_ws(*cur)) {
  ------------------
  |  Branch (978:9): [True: 209, False: 2.38k]
  ------------------
  979|    209|      GETNEXT(done);
  ------------------
  |  |  831|    209|  {                    \
  |  |  832|    209|    cur += 1;          \
  |  |  833|    209|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 209]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|    209|  }
  ------------------
  980|    209|      goto parse_method1;
  981|    209|    }
  982|  2.38k|    if (!ParseRules::is_token(*cur)) {
  ------------------
  |  Branch (982:9): [True: 182, False: 2.19k]
  ------------------
  983|    182|      goto done;
  984|    182|    }
  985|  2.19k|    method_start = cur;
  986|  2.19k|    GETNEXT(done);
  ------------------
  |  |  831|  2.19k|  {                    \
  |  |  832|  2.19k|    cur += 1;          \
  |  |  833|  2.19k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 2.19k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  2.19k|  }
  ------------------
  987|  7.65k|  parse_method2:
  988|  7.65k|    if (ParseRules::is_ws(*cur)) {
  ------------------
  |  Branch (988:9): [True: 1.89k, False: 5.75k]
  ------------------
  989|  1.89k|      method_end = cur;
  990|  1.89k|      goto parse_version1;
  991|  1.89k|    }
  992|  5.75k|    if (!ParseRules::is_token(*cur)) {
  ------------------
  |  Branch (992:9): [True: 300, False: 5.45k]
  ------------------
  993|    300|      goto done;
  994|    300|    }
  995|  5.45k|    GETNEXT(done);
  ------------------
  |  |  831|  5.45k|  {                    \
  |  |  832|  5.45k|    cur += 1;          \
  |  |  833|  5.45k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 5.45k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  5.45k|  }
  ------------------
  996|  5.45k|    goto parse_method2;
  997|       |
  998|  1.89k|  parse_version1:
  999|  1.89k|    cur = end - 1;
 1000|  1.89k|    if (ParseRules::is_lf(*cur) && (cur >= line_start)) {
  ------------------
  |  Branch (1000:9): [True: 1.89k, False: 0]
  |  Branch (1000:36): [True: 1.89k, False: 0]
  ------------------
 1001|  1.89k|      cur -= 1;
 1002|  1.89k|    }
 1003|  1.89k|    if (ParseRules::is_cr(*cur) && (cur >= line_start)) {
  ------------------
  |  Branch (1003:9): [True: 47, False: 1.85k]
  |  Branch (1003:36): [True: 47, False: 0]
  ------------------
 1004|     47|      cur -= 1;
 1005|     47|    }
 1006|       |    // A client may add extra white spaces after the HTTP version.
 1007|       |    // So, skip white spaces.
 1008|  2.62k|    while (ParseRules::is_ws(*cur) && (cur >= line_start)) {
  ------------------
  |  Branch (1008:12): [True: 724, False: 1.89k]
  |  Branch (1008:39): [True: 724, False: 0]
  ------------------
 1009|    724|      cur -= 1;
 1010|    724|    }
 1011|  1.89k|    version_end = cur + 1;
 1012|  4.95k|  parse_version2:
 1013|  4.95k|    if (isdigit(*cur)) {
  ------------------
  |  Branch (1013:9): [True: 3.06k, False: 1.88k]
  ------------------
 1014|  3.06k|      GETPREV(parse_url);
  ------------------
  |  |  839|  3.06k|  {                         \
  |  |  840|  3.06k|    cur -= 1;               \
  |  |  841|  3.06k|    if (cur < line_start) { \
  |  |  ------------------
  |  |  |  Branch (841:9): [True: 10, False: 3.05k]
  |  |  ------------------
  |  |  842|     10|      goto label;           \
  |  |  843|     10|    }                       \
  |  |  844|  3.06k|  }
  ------------------
 1015|  3.05k|      goto parse_version2;
 1016|  3.06k|    }
 1017|  1.88k|    if (*cur == '.') {
  ------------------
  |  Branch (1017:9): [True: 1.02k, False: 864]
  ------------------
 1018|  1.02k|      GETPREV(parse_url);
  ------------------
  |  |  839|  1.02k|  {                         \
  |  |  840|  1.02k|    cur -= 1;               \
  |  |  841|  1.02k|    if (cur < line_start) { \
  |  |  ------------------
  |  |  |  Branch (841:9): [True: 10, False: 1.01k]
  |  |  ------------------
  |  |  842|     10|      goto label;           \
  |  |  843|     10|    }                       \
  |  |  844|  1.02k|  }
  ------------------
 1019|  1.01k|      goto parse_version3;
 1020|  1.02k|    }
 1021|    864|    goto parse_url;
 1022|  2.15k|  parse_version3:
 1023|  2.15k|    if (isdigit(*cur)) {
  ------------------
  |  Branch (1023:9): [True: 1.14k, False: 1.00k]
  ------------------
 1024|  1.14k|      GETPREV(parse_url);
  ------------------
  |  |  839|  1.14k|  {                         \
  |  |  840|  1.14k|    cur -= 1;               \
  |  |  841|  1.14k|    if (cur < line_start) { \
  |  |  ------------------
  |  |  |  Branch (841:9): [True: 6, False: 1.14k]
  |  |  ------------------
  |  |  842|      6|      goto label;           \
  |  |  843|      6|    }                       \
  |  |  844|  1.14k|  }
  ------------------
 1025|  1.14k|      goto parse_version3;
 1026|  1.14k|    }
 1027|  1.00k|    if (*cur == '/') {
  ------------------
  |  Branch (1027:9): [True: 956, False: 53]
  ------------------
 1028|    956|      GETPREV(parse_url);
  ------------------
  |  |  839|    956|  {                         \
  |  |  840|    956|    cur -= 1;               \
  |  |  841|    956|    if (cur < line_start) { \
  |  |  ------------------
  |  |  |  Branch (841:9): [True: 0, False: 956]
  |  |  ------------------
  |  |  842|      0|      goto label;           \
  |  |  843|      0|    }                       \
  |  |  844|    956|  }
  ------------------
 1029|    956|      goto parse_version4;
 1030|    956|    }
 1031|     53|    goto parse_url;
 1032|    956|  parse_version4:
 1033|    956|    if (*cur != 'P') {
  ------------------
  |  Branch (1033:9): [True: 21, False: 935]
  ------------------
 1034|     21|      goto parse_url;
 1035|     21|    }
 1036|    935|    GETPREV(parse_url);
  ------------------
  |  |  839|    935|  {                         \
  |  |  840|    935|    cur -= 1;               \
  |  |  841|    935|    if (cur < line_start) { \
  |  |  ------------------
  |  |  |  Branch (841:9): [True: 0, False: 935]
  |  |  ------------------
  |  |  842|      0|      goto label;           \
  |  |  843|      0|    }                       \
  |  |  844|    935|  }
  ------------------
 1037|    935|    if (*cur != 'T') {
  ------------------
  |  Branch (1037:9): [True: 9, False: 926]
  ------------------
 1038|      9|      goto parse_url;
 1039|      9|    }
 1040|    926|    GETPREV(parse_url);
  ------------------
  |  |  839|    926|  {                         \
  |  |  840|    926|    cur -= 1;               \
  |  |  841|    926|    if (cur < line_start) { \
  |  |  ------------------
  |  |  |  Branch (841:9): [True: 0, False: 926]
  |  |  ------------------
  |  |  842|      0|      goto label;           \
  |  |  843|      0|    }                       \
  |  |  844|    926|  }
  ------------------
 1041|    926|    if (*cur != 'T') {
  ------------------
  |  Branch (1041:9): [True: 9, False: 917]
  ------------------
 1042|      9|      goto parse_url;
 1043|      9|    }
 1044|    917|    GETPREV(parse_url);
  ------------------
  |  |  839|    917|  {                         \
  |  |  840|    917|    cur -= 1;               \
  |  |  841|    917|    if (cur < line_start) { \
  |  |  ------------------
  |  |  |  Branch (841:9): [True: 0, False: 917]
  |  |  ------------------
  |  |  842|      0|      goto label;           \
  |  |  843|      0|    }                       \
  |  |  844|    917|  }
  ------------------
 1045|    917|    if (*cur != 'H') {
  ------------------
  |  Branch (1045:9): [True: 6, False: 911]
  ------------------
 1046|      6|      goto parse_url;
 1047|      6|    }
 1048|    911|    version_start = cur;
 1049|       |
 1050|  1.89k|  parse_url:
 1051|  1.89k|    url_start = method_end + 1;
 1052|  1.89k|    if (version_start) {
  ------------------
  |  Branch (1052:9): [True: 911, False: 988]
  ------------------
 1053|    911|      url_end = version_start - 1;
 1054|    988|    } else {
 1055|    988|      url_end = end - 1;
 1056|    988|    }
 1057|  2.52k|    while ((url_start < end) && ParseRules::is_ws(*url_start)) {
  ------------------
  |  Branch (1057:12): [True: 2.52k, False: 0]
  |  Branch (1057:33): [True: 628, False: 1.89k]
  ------------------
 1058|    628|      url_start += 1;
 1059|    628|    }
 1060|  3.79k|    while ((url_end >= line_start) && ParseRules::is_wslfcr(*url_end)) {
  ------------------
  |  Branch (1060:12): [True: 3.79k, False: 0]
  |  Branch (1060:39): [True: 1.89k, False: 1.89k]
  ------------------
 1061|  1.89k|      url_end -= 1;
 1062|  1.89k|    }
 1063|  1.89k|    url_end += 1;
 1064|       |
 1065|  2.38k|  done:
 1066|  2.38k|    if (!method_start || !method_end) {
  ------------------
  |  Branch (1066:9): [True: 182, False: 2.19k]
  |  Branch (1066:26): [True: 300, False: 1.89k]
  ------------------
 1067|    482|      return ParseResult::ERROR;
 1068|    482|    }
 1069|       |
 1070|       |    // checking these with an if statement makes coverity flag as dead code because
 1071|       |    // url_start and url_end logically cannot be 0 at this time
 1072|  1.89k|    ink_assert(url_start);
  ------------------
  |  |   45|  1.89k|#define ink_assert(EX) (void)(EX)
  ------------------
 1073|  1.89k|    ink_assert(url_end);
  ------------------
  |  |   45|  1.89k|#define ink_assert(EX) (void)(EX)
  ------------------
 1074|       |
 1075|  1.89k|    int method_wks_idx = hdrtoken_method_tokenize(method_start, static_cast<int>(method_end - method_start));
 1076|  1.89k|    http_hdr_method_set(heap, hh, {method_start, static_cast<std::string_view::size_type>(method_end - method_start)},
 1077|  1.89k|                        method_wks_idx, must_copy_strings);
 1078|       |
 1079|  1.89k|    ink_assert(hh->u.req.m_url_impl != nullptr);
  ------------------
  |  |   45|  1.89k|#define ink_assert(EX) (void)(EX)
  ------------------
 1080|       |
 1081|  1.89k|    url = hh->u.req.m_url_impl;
 1082|  1.89k|    err = ::url_parse(heap, url, &url_start, url_end, must_copy_strings, strict_uri_parsing);
 1083|       |
 1084|  1.89k|    if (static_cast<int>(err) < 0) {
  ------------------
  |  Branch (1084:9): [True: 633, False: 1.26k]
  ------------------
 1085|    633|      return err;
 1086|    633|    }
 1087|       |
 1088|  1.26k|    HTTPVersion version;
 1089|  1.26k|    if (version_start && version_end) {
  ------------------
  |  Branch (1089:9): [True: 900, False: 366]
  |  Branch (1089:26): [True: 900, False: 0]
  ------------------
 1090|    900|      version = http_parse_version(version_start, version_end);
 1091|    900|    } else {
 1092|    366|      return ParseResult::ERROR;
 1093|    366|    }
 1094|       |
 1095|    900|    if (!http_hdr_version_set(hh, version)) {
  ------------------
  |  Branch (1095:9): [True: 34, False: 866]
  ------------------
 1096|     34|      return ParseResult::ERROR;
 1097|     34|    }
 1098|       |
 1099|    866|    end                    = real_end;
 1100|    866|    parser->m_parsing_http = false;
 1101|    866|  }
 1102|       |
 1103|    866|  ParseResult ret = mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, false,
 1104|    866|                                      max_hdr_field_size);
 1105|       |  // If we're done with the main parse do some validation
 1106|    866|  if (ret == ParseResult::DONE) {
  ------------------
  |  Branch (1106:7): [True: 840, False: 26]
  ------------------
 1107|    840|    ret = validate_hdr_request_target(hh->u.req.m_method_wks_idx, hh->u.req.m_url_impl);
 1108|    840|  }
 1109|    866|  if (ret == ParseResult::DONE) {
  ------------------
  |  Branch (1109:7): [True: 766, False: 100]
  ------------------
 1110|    766|    ret = validate_hdr_host(hh); // check HOST header
 1111|    766|  }
 1112|    866|  if (ret == ParseResult::DONE) {
  ------------------
  |  Branch (1112:7): [True: 493, False: 373]
  ------------------
 1113|    493|    ret = validate_hdr_content_length(heap, hh);
 1114|    493|  }
 1115|    866|  return ret;
 1116|  9.36k|}
_Z27validate_hdr_request_targetiP7URLImpl:
 1120|    890|{
 1121|    890|  ParseResult ret = ParseResult::DONE;
 1122|    890|  auto        host{url->get_host()};
 1123|    890|  auto        path{url->get_path()};
 1124|    890|  auto        scheme{url->get_scheme()};
 1125|       |
 1126|    890|  if (host.empty()) {
  ------------------
  |  Branch (1126:7): [True: 760, False: 130]
  ------------------
 1127|    760|    if (path == "*"sv) { // asterisk-form
  ------------------
  |  Branch (1127:9): [True: 0, False: 760]
  ------------------
 1128|       |      // Skip this check for now because URLImpl can't distinguish '*' and '/*'
 1129|       |      // if (method_wk_idx != HTTP_WKSIDX_OPTIONS) {
 1130|       |      //   ret = ParseResult::ERROR;
 1131|       |      // }
 1132|    760|    } else { // origin-form
 1133|       |      // Nothing to check here
 1134|    760|    }
 1135|    760|  } else if (scheme.empty() && !host.empty()) { // authority-form
  ------------------
  |  Branch (1135:14): [True: 94, False: 36]
  |  Branch (1135:32): [True: 94, False: 0]
  ------------------
 1136|     94|    if (method_wk_idx != HTTP_WKSIDX_CONNECT) {
  ------------------
  |  Branch (1136:9): [True: 88, False: 6]
  ------------------
 1137|     88|      ret = ParseResult::ERROR;
 1138|     88|    }
 1139|     94|  } else { // absolute-form
 1140|       |    // Nothing to check here
 1141|     36|  }
 1142|       |
 1143|    890|  return ret;
 1144|    890|}
_Z22http_parse_host_headerNSt3__117basic_string_viewIcNS_11char_traitsIcEEEERS3_RiRb:
 1148|    377|{
 1149|    377|  swoc::TextView text{value};
 1150|       |
 1151|    377|  host     = {};
 1152|    377|  port     = 0;
 1153|    377|  has_port = false;
 1154|       |
 1155|    377|  text.ltrim_if(&ParseRules::is_ws);
 1156|    377|  text.rtrim_if(&ParseRules::is_ws);
 1157|    377|  if (text.empty()) {
  ------------------
  |  Branch (1157:7): [True: 0, False: 377]
  ------------------
 1158|      0|    return false;
 1159|      0|  }
 1160|       |
 1161|    377|  if ('[' == *text) {
  ------------------
  |  Branch (1161:7): [True: 62, False: 315]
  ------------------
 1162|       |    // IPv6.
 1163|     62|    auto const close = text.find(']');
 1164|     62|    if (close == swoc::TextView::npos) {
  ------------------
  |  Branch (1164:9): [True: 19, False: 43]
  ------------------
 1165|       |      // No closing ']', invalid host.
 1166|     19|      return false;
 1167|     19|    }
 1168|       |
 1169|     43|    host = {text.data(), close + 1};
 1170|     43|    text.remove_prefix(close + 1);
 1171|     43|    if (!text.empty()) {
  ------------------
  |  Branch (1171:9): [True: 28, False: 15]
  ------------------
 1172|     28|      if (':' != text.front()) {
  ------------------
  |  Branch (1172:11): [True: 20, False: 8]
  ------------------
 1173|       |        // If there are more characters, the next one must be a colon for the port.
 1174|     20|        return false;
 1175|     20|      }
 1176|      8|      text.remove_prefix(1);
 1177|      8|      if (text.empty()) {
  ------------------
  |  Branch (1177:11): [True: 6, False: 2]
  ------------------
 1178|       |        // Port is indicated but not provided.
 1179|      6|        return false;
 1180|      6|      }
 1181|      2|      has_port = true;
 1182|      2|    }
 1183|    315|  } else {
 1184|       |    // IPv4 or hostname.
 1185|    315|    auto const first_colon = text.find(':');
 1186|    315|    if (first_colon == swoc::TextView::npos) {
  ------------------
  |  Branch (1186:9): [True: 107, False: 208]
  ------------------
 1187|    107|      host = text;
 1188|    208|    } else {
 1189|    208|      if (text.find(':', first_colon + 1) != swoc::TextView::npos || first_colon == 0) {
  ------------------
  |  Branch (1189:11): [True: 36, False: 172]
  |  Branch (1189:70): [True: 51, False: 121]
  ------------------
 1190|       |        // Only one colon is allowed, and it can't be the first character (empty host).
 1191|     87|        return false;
 1192|     87|      }
 1193|       |
 1194|    121|      host = {text.data(), first_colon};
 1195|    121|      text.remove_prefix(first_colon + 1);
 1196|    121|      if (text.empty()) {
  ------------------
  |  Branch (1196:11): [True: 14, False: 107]
  ------------------
 1197|     14|        return false;
 1198|     14|      }
 1199|    107|      has_port = true;
 1200|    107|    }
 1201|    315|  }
 1202|       |
 1203|    231|  if (!validate_host_name(host)) {
  ------------------
  |  Branch (1203:7): [True: 66, False: 165]
  ------------------
 1204|     66|    return false;
 1205|     66|  }
 1206|       |
 1207|    165|  if (has_port) {
  ------------------
  |  Branch (1207:7): [True: 82, False: 83]
  ------------------
 1208|     82|    if (text.size() > 5 || !std::all_of(text.begin(), text.end(), &ParseRules::is_digit)) {
  ------------------
  |  Branch (1208:9): [True: 32, False: 50]
  |  Branch (1208:28): [True: 6, False: 44]
  ------------------
 1209|       |      // Too many characters for a port, or non-digit characters in the port.
 1210|     38|      return false;
 1211|     38|    }
 1212|       |
 1213|     44|    port = ink_atoi(text.data(), static_cast<int>(text.size()));
 1214|     44|    if (port <= 0 || port > 65535) {
  ------------------
  |  Branch (1214:9): [True: 3, False: 41]
  |  Branch (1214:22): [True: 5, False: 36]
  ------------------
 1215|      8|      return false;
 1216|      8|    }
 1217|     44|  }
 1218|       |
 1219|    119|  return true;
 1220|    165|}
_Z17validate_hdr_hostP11HTTPHdrImpl:
 1224|    802|{
 1225|    802|  ParseResult ret        = ParseResult::DONE;
 1226|    802|  MIMEField  *host_field = mime_hdr_field_find(hh->m_fields_impl, static_cast<std::string_view>(MIME_FIELD_HOST));
 1227|    802|  if (host_field) {
  ------------------
  |  Branch (1227:7): [True: 392, False: 410]
  ------------------
 1228|    392|    if (host_field->has_dups()) {
  ------------------
  |  Branch (1228:9): [True: 7, False: 385]
  ------------------
 1229|      7|      ret = ParseResult::ERROR; // can't have more than 1 host field.
 1230|    385|    } else if (auto host{host_field->value_get()}; host.empty()) {
  ------------------
  |  Branch (1230:52): [True: 8, False: 377]
  ------------------
 1231|      8|      ret = ParseResult::ERROR;
 1232|    377|    } else {
 1233|    377|      std::string_view parsed_host;
 1234|    377|      int              port     = 0;
 1235|    377|      bool             has_port = false;
 1236|       |
 1237|    377|      if (!http_parse_host_header(host, parsed_host, port, has_port)) {
  ------------------
  |  Branch (1237:11): [True: 258, False: 119]
  ------------------
 1238|    258|        ret = ParseResult::ERROR;
 1239|    258|      }
 1240|    377|    }
 1241|    392|  }
 1242|    802|  return ret;
 1243|    802|}
_Z27validate_hdr_content_lengthP7HdrHeapP11HTTPHdrImpl:
 1247|  8.52k|{
 1248|  8.52k|  MIMEField *content_length_field =
 1249|  8.52k|    mime_hdr_field_find(hh->m_fields_impl, static_cast<std::string_view>(MIME_FIELD_CONTENT_LENGTH));
 1250|       |
 1251|  8.52k|  if (content_length_field) {
  ------------------
  |  Branch (1251:7): [True: 291, False: 8.23k]
  ------------------
 1252|       |    // RFC 7230 section 3.3.3:
 1253|       |    // If a message is received with both a Transfer-Encoding and a
 1254|       |    // Content-Length header field, the Transfer-Encoding overrides
 1255|       |    // the Content-Length
 1256|    291|    if (mime_hdr_field_find(hh->m_fields_impl, static_cast<std::string_view>(MIME_FIELD_TRANSFER_ENCODING)) != nullptr) {
  ------------------
  |  Branch (1256:9): [True: 106, False: 185]
  ------------------
 1257|       |      // Delete all Content-Length headers
 1258|    106|      Dbg(dbg_ctl_http, "Transfer-Encoding header and Content-Length headers the request, removing all Content-Length headers");
  ------------------
  |  |  173|    106|  do {                              \
  |  |  174|    106|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 106]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|    106|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 106]
  |  |  ------------------
  ------------------
 1259|    106|      mime_hdr_field_delete(heap, hh->m_fields_impl, content_length_field, true);
 1260|    106|      return ParseResult::DONE;
 1261|    106|    }
 1262|       |
 1263|       |    // RFC 7230 section 3.3.3:
 1264|       |    // If a message is received without Transfer-Encoding and with
 1265|       |    // either multiple Content-Length header fields having differing
 1266|       |    // field-values or a single Content-Length header field having an
 1267|       |    // invalid value, then the message framing is invalid and the
 1268|       |    // recipient MUST treat it as an unrecoverable error.  If this is a
 1269|       |    // request message, the server MUST respond with a 400 (Bad Request)
 1270|       |    // status code and then close the connection
 1271|    185|    std::string_view value = content_length_field->value_get();
 1272|       |
 1273|       |    // RFC 9110 section 8.6.
 1274|       |    // Content-Length = 1*DIGIT
 1275|       |    //
 1276|    185|    if (value.empty()) {
  ------------------
  |  Branch (1276:9): [True: 22, False: 163]
  ------------------
 1277|     22|      Dbg(dbg_ctl_http, "Content-Length headers don't match the ABNF, returning parse error");
  ------------------
  |  |  173|     22|  do {                              \
  |  |  174|     22|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 22]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|     22|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 22]
  |  |  ------------------
  ------------------
 1278|     22|      return ParseResult::ERROR;
 1279|     22|    }
 1280|       |
 1281|       |    // If the content-length value contains a non-numeric value, the header is invalid
 1282|    163|    if (std::find_if(value.cbegin(), value.cend(), [](std::string_view::value_type c) { return !std::isdigit(c); }) !=
  ------------------
  |  Branch (1282:9): [True: 42, False: 121]
  ------------------
 1283|    163|        value.cend()) {
 1284|     42|      Dbg(dbg_ctl_http, "Content-Length value contains non-digit, returning parse error");
  ------------------
  |  |  173|     42|  do {                              \
  |  |  174|     42|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 42]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|     42|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 42]
  |  |  ------------------
  ------------------
 1285|     42|      return ParseResult::ERROR;
 1286|     42|    }
 1287|       |
 1288|    243|    while (content_length_field->has_dups()) {
  ------------------
  |  Branch (1288:12): [True: 217, False: 26]
  ------------------
 1289|    217|      std::string_view value_dup = content_length_field->m_next_dup->value_get();
 1290|       |
 1291|    217|      if ((value.length() != value_dup.length()) || value.compare(value_dup) != 0) {
  ------------------
  |  Branch (1291:11): [True: 35, False: 182]
  |  Branch (1291:53): [True: 60, False: 122]
  ------------------
 1292|       |        // Values are different, parse error
 1293|     95|        Dbg(dbg_ctl_http, "Content-Length headers don't match, returning parse error");
  ------------------
  |  |  173|     95|  do {                              \
  |  |  174|     95|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 95]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|     95|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 95]
  |  |  ------------------
  ------------------
 1294|     95|        return ParseResult::ERROR;
 1295|    122|      } else {
 1296|       |        // Delete the duplicate since it has the same value
 1297|    122|        Dbg(dbg_ctl_http, "Deleting duplicate Content-Length header");
  ------------------
  |  |  173|    122|  do {                              \
  |  |  174|    122|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 122]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|    122|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 122]
  |  |  ------------------
  ------------------
 1298|    122|        mime_hdr_field_delete(heap, hh->m_fields_impl, content_length_field->m_next_dup, false);
 1299|    122|      }
 1300|    217|    }
 1301|    121|  }
 1302|       |
 1303|  8.25k|  return ParseResult::DONE;
 1304|  8.52k|}
_Z22http_parser_parse_respP10HTTPParserP7HdrHeapP11HTTPHdrImplPPKcS6_bb:
 1312|  9.36k|{
 1313|  9.36k|  if (parser->m_parsing_http) {
  ------------------
  |  Branch (1313:7): [True: 9.36k, False: 0]
  ------------------
 1314|  9.36k|    MIMEScanner *scanner = &parser->m_mime_parser.m_scanner;
 1315|       |
 1316|  9.36k|    ParseResult err;
 1317|  9.36k|    bool        line_is_real;
 1318|  9.36k|    const char *cur;
 1319|  9.36k|    const char *line_start;
 1320|  9.36k|    const char *real_end;
 1321|  9.36k|    const char *version_start;
 1322|  9.36k|    const char *version_end;
 1323|  9.36k|    const char *status_start;
 1324|  9.36k|    const char *status_end;
 1325|  9.36k|    const char *reason_start;
 1326|  9.36k|    const char *reason_end;
 1327|  9.36k|    const char *old_start;
 1328|       |
 1329|  9.36k|    real_end  = end;
 1330|  9.36k|    old_start = *start;
 1331|       |
 1332|  9.36k|    hh->m_polarity = HTTPType::RESPONSE;
 1333|       |
 1334|       |    // Make sure the line is not longer than 64K
 1335|  9.36k|    if (scanner->get_buffered_line_size() >= UINT16_MAX) {
  ------------------
  |  Branch (1335:9): [True: 0, False: 9.36k]
  ------------------
 1336|      0|      return ParseResult::ERROR;
 1337|      0|    }
 1338|       |
 1339|  9.36k|    swoc::TextView text{*start, real_end};
 1340|  9.36k|    swoc::TextView parsed;
 1341|  9.36k|    err    = scanner->get(text, parsed, line_is_real, eof, MIMEScanner::ScanType::LINE);
 1342|  9.36k|    *start = text.data();
 1343|  9.36k|    if (static_cast<int>(err) < 0) {
  ------------------
  |  Branch (1343:9): [True: 135, False: 9.22k]
  ------------------
 1344|    135|      return err;
 1345|    135|    }
 1346|       |    // Make sure the length headers are consistent
 1347|  9.22k|    if (err == ParseResult::DONE) {
  ------------------
  |  Branch (1347:9): [True: 6.77k, False: 2.45k]
  ------------------
 1348|  6.77k|      err = validate_hdr_content_length(heap, hh);
 1349|  6.77k|    }
 1350|  9.22k|    if ((err == ParseResult::DONE) || (err == ParseResult::CONT)) {
  ------------------
  |  Branch (1350:9): [True: 6.77k, False: 2.45k]
  |  Branch (1350:39): [True: 0, False: 2.45k]
  ------------------
 1351|  6.77k|      return err;
 1352|  6.77k|    }
 1353|       |
 1354|  2.45k|    ink_assert(parsed.size() < UINT16_MAX);
  ------------------
  |  |   45|  2.45k|#define ink_assert(EX) (void)(EX)
  ------------------
 1355|  2.45k|    line_start = cur = parsed.data();
 1356|  2.45k|    end              = parsed.data_end();
 1357|       |
 1358|  2.45k|    must_copy_strings = (must_copy_strings || (!line_is_real));
  ------------------
  |  Branch (1358:26): [True: 2.45k, False: 0]
  |  Branch (1358:47): [True: 0, False: 0]
  ------------------
 1359|       |
 1360|  2.45k|#if (ENABLE_PARSER_FAST_PATHS)
 1361|       |    // first try fast path
 1362|  2.45k|    if (end - cur >= 16) {
  ------------------
  |  Branch (1362:9): [True: 300, False: 2.15k]
  ------------------
 1363|    300|      int http_match =
 1364|    300|        ((cur[0] ^ 'H') | (cur[1] ^ 'T') | (cur[2] ^ 'T') | (cur[3] ^ 'P') | (cur[4] ^ '/') | (cur[6] ^ '.') | (cur[8] ^ ' '));
 1365|    300|      if ((http_match != 0) || (!(isdigit(cur[5]) && isdigit(cur[7]) && isdigit(cur[9]) && isdigit(cur[10]) && isdigit(cur[11]) &&
  ------------------
  |  Branch (1365:11): [True: 191, False: 109]
  |  Branch (1365:35): [True: 93, False: 16]
  |  Branch (1365:54): [True: 76, False: 17]
  |  Branch (1365:73): [True: 61, False: 15]
  |  Branch (1365:92): [True: 53, False: 8]
  |  Branch (1365:112): [True: 35, False: 18]
  ------------------
 1366|    272|                                  (!ParseRules::is_space(cur[13]))))) {
  ------------------
  |  Branch (1366:35): [True: 28, False: 7]
  ------------------
 1367|    272|        goto slow_case;
 1368|    272|      }
 1369|       |
 1370|     28|      reason_start = &(cur[13]);
 1371|     28|      reason_end   = end - 1;
 1372|    313|      while ((reason_end > reason_start + 1) && (ParseRules::is_space(reason_end[-1]))) {
  ------------------
  |  Branch (1372:14): [True: 295, False: 18]
  |  Branch (1372:49): [True: 285, False: 10]
  ------------------
 1373|    285|        --reason_end;
 1374|    285|      }
 1375|       |
 1376|     28|      HTTPVersion version(cur[5] - '0', cur[7] - '0');
 1377|     28|      HTTPStatus  status = static_cast<HTTPStatus>((cur[9] - '0') * 100 + (cur[10] - '0') * 10 + (cur[11] - '0'));
 1378|       |
 1379|     28|      http_hdr_version_set(hh, version);
 1380|     28|      http_hdr_status_set(hh, status);
 1381|     28|      http_hdr_reason_set(heap, hh, {reason_start, static_cast<std::string_view::size_type>(reason_end - reason_start)},
 1382|     28|                          must_copy_strings);
 1383|       |
 1384|     28|      end                    = real_end;
 1385|     28|      parser->m_parsing_http = false;
 1386|     28|      auto ret = mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, true);
 1387|       |      // Make sure the length headers are consistent
 1388|     28|      if (ret == ParseResult::DONE) {
  ------------------
  |  Branch (1388:11): [True: 22, False: 6]
  ------------------
 1389|     22|        ret = validate_hdr_content_length(heap, hh);
 1390|     22|      }
 1391|     28|      return ret;
 1392|    300|    }
 1393|  2.15k|#endif
 1394|       |
 1395|  2.42k|  slow_case:
 1396|  2.42k|    version_start = nullptr;
 1397|  2.42k|    version_end   = nullptr;
 1398|  2.42k|    status_start  = nullptr;
 1399|  2.42k|    status_end    = nullptr;
 1400|  2.42k|    reason_start  = nullptr;
 1401|  2.42k|    reason_end    = nullptr;
 1402|       |
 1403|  2.42k|    version_start = cur = line_start;
 1404|  2.42k|    if (*cur != 'H') {
  ------------------
  |  Branch (1404:9): [True: 779, False: 1.64k]
  ------------------
 1405|    779|      goto eoh;
 1406|    779|    }
 1407|  1.64k|    GETNEXT(eoh);
  ------------------
  |  |  831|  1.64k|  {                    \
  |  |  832|  1.64k|    cur += 1;          \
  |  |  833|  1.64k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 1.64k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  1.64k|  }
  ------------------
 1408|  1.64k|    if (*cur != 'T') {
  ------------------
  |  Branch (1408:9): [True: 59, False: 1.59k]
  ------------------
 1409|     59|      goto eoh;
 1410|     59|    }
 1411|  1.59k|    GETNEXT(eoh);
  ------------------
  |  |  831|  1.59k|  {                    \
  |  |  832|  1.59k|    cur += 1;          \
  |  |  833|  1.59k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 1.59k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  1.59k|  }
  ------------------
 1412|  1.59k|    if (*cur != 'T') {
  ------------------
  |  Branch (1412:9): [True: 17, False: 1.57k]
  ------------------
 1413|     17|      goto eoh;
 1414|     17|    }
 1415|  1.57k|    GETNEXT(eoh);
  ------------------
  |  |  831|  1.57k|  {                    \
  |  |  832|  1.57k|    cur += 1;          \
  |  |  833|  1.57k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 1.57k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  1.57k|  }
  ------------------
 1416|  1.57k|    if (*cur != 'P') {
  ------------------
  |  Branch (1416:9): [True: 21, False: 1.55k]
  ------------------
 1417|     21|      goto eoh;
 1418|     21|    }
 1419|  1.55k|    GETNEXT(eoh);
  ------------------
  |  |  831|  1.55k|  {                    \
  |  |  832|  1.55k|    cur += 1;          \
  |  |  833|  1.55k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 1.55k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  1.55k|  }
  ------------------
 1420|  1.55k|    if (*cur != '/') {
  ------------------
  |  Branch (1420:9): [True: 23, False: 1.52k]
  ------------------
 1421|     23|      goto eoh;
 1422|     23|    }
 1423|  1.52k|    GETNEXT(eoh);
  ------------------
  |  |  831|  1.52k|  {                    \
  |  |  832|  1.52k|    cur += 1;          \
  |  |  833|  1.52k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 1.52k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  1.52k|  }
  ------------------
 1424|  3.88k|  parse_version2:
 1425|  3.88k|    if (isdigit(*cur)) {
  ------------------
  |  Branch (1425:9): [True: 2.35k, False: 1.52k]
  ------------------
 1426|  2.35k|      GETNEXT(eoh);
  ------------------
  |  |  831|  2.35k|  {                    \
  |  |  832|  2.35k|    cur += 1;          \
  |  |  833|  2.35k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 2.35k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  2.35k|  }
  ------------------
 1427|  2.35k|      goto parse_version2;
 1428|  2.35k|    }
 1429|  1.52k|    if (*cur == '.') {
  ------------------
  |  Branch (1429:9): [True: 1.48k, False: 43]
  ------------------
 1430|  1.48k|      GETNEXT(eoh);
  ------------------
  |  |  831|  1.48k|  {                    \
  |  |  832|  1.48k|    cur += 1;          \
  |  |  833|  1.48k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 1.48k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  1.48k|  }
  ------------------
 1431|  1.48k|      goto parse_version3;
 1432|  1.48k|    }
 1433|     43|    goto eoh;
 1434|  3.24k|  parse_version3:
 1435|  3.24k|    if (isdigit(*cur)) {
  ------------------
  |  Branch (1435:9): [True: 1.75k, False: 1.48k]
  ------------------
 1436|  1.75k|      GETNEXT(eoh);
  ------------------
  |  |  831|  1.75k|  {                    \
  |  |  832|  1.75k|    cur += 1;          \
  |  |  833|  1.75k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 1.75k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  1.75k|  }
  ------------------
 1437|  1.75k|      goto parse_version3;
 1438|  1.75k|    }
 1439|  1.48k|    if (ParseRules::is_ws(*cur)) {
  ------------------
  |  Branch (1439:9): [True: 1.44k, False: 41]
  ------------------
 1440|  1.44k|      version_end = cur;
 1441|  1.44k|      GETNEXT(eoh);
  ------------------
  |  |  831|  1.44k|  {                    \
  |  |  832|  1.44k|    cur += 1;          \
  |  |  833|  1.44k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 1.44k]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|  1.44k|  }
  ------------------
 1442|  1.44k|      goto parse_status1;
 1443|  1.44k|    }
 1444|     41|    goto eoh;
 1445|       |
 1446|  1.64k|  parse_status1:
 1447|  1.64k|    if (ParseRules::is_ws(*cur)) {
  ------------------
  |  Branch (1447:9): [True: 196, False: 1.44k]
  ------------------
 1448|    196|      GETNEXT(done);
  ------------------
  |  |  831|    196|  {                    \
  |  |  832|    196|    cur += 1;          \
  |  |  833|    196|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 196]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|    196|  }
  ------------------
 1449|    196|      goto parse_status1;
 1450|    196|    }
 1451|  1.44k|    status_start = cur;
 1452|  1.95k|  parse_status2:
 1453|  1.95k|    status_end = cur;
 1454|  1.95k|    if (isdigit(*cur)) {
  ------------------
  |  Branch (1454:9): [True: 514, False: 1.44k]
  ------------------
 1455|    514|      GETNEXT(done);
  ------------------
  |  |  831|    514|  {                    \
  |  |  832|    514|    cur += 1;          \
  |  |  833|    514|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 514]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|    514|  }
  ------------------
 1456|    514|      goto parse_status2;
 1457|    514|    }
 1458|  1.44k|    if (ParseRules::is_ws(*cur)) {
  ------------------
  |  Branch (1458:9): [True: 50, False: 1.39k]
  ------------------
 1459|     50|      GETNEXT(done);
  ------------------
  |  |  831|     50|  {                    \
  |  |  832|     50|    cur += 1;          \
  |  |  833|     50|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 50]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|     50|  }
  ------------------
 1460|     50|      goto parse_reason1;
 1461|     50|    }
 1462|  1.39k|    goto done;
 1463|       |
 1464|  1.39k|  parse_reason1:
 1465|    249|    if (ParseRules::is_ws(*cur)) {
  ------------------
  |  Branch (1465:9): [True: 199, False: 50]
  ------------------
 1466|    199|      GETNEXT(done);
  ------------------
  |  |  831|    199|  {                    \
  |  |  832|    199|    cur += 1;          \
  |  |  833|    199|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (833:9): [True: 0, False: 199]
  |  |  ------------------
  |  |  834|      0|      goto label;      \
  |  |  835|      0|    }                  \
  |  |  836|    199|  }
  ------------------
 1467|    199|      goto parse_reason1;
 1468|    199|    }
 1469|     50|    reason_start = cur;
 1470|     50|    reason_end   = end - 1;
 1471|    475|    while ((reason_end >= line_start) && (ParseRules::is_cr(*reason_end) || ParseRules::is_lf(*reason_end))) {
  ------------------
  |  Branch (1471:12): [True: 475, False: 0]
  |  Branch (1471:43): [True: 375, False: 100]
  |  Branch (1471:77): [True: 50, False: 50]
  ------------------
 1472|    425|      reason_end -= 1;
 1473|    425|    }
 1474|     50|    reason_end += 1;
 1475|     50|    goto done;
 1476|       |
 1477|    983|  eoh:
 1478|    983|    *start = old_start;
 1479|    983|    return ParseResult::ERROR; // This used to return ParseResult::DONE by default before
 1480|       |
 1481|  1.44k|  done:
 1482|  1.44k|    if (!version_start || !version_end) {
  ------------------
  |  Branch (1482:9): [True: 0, False: 1.44k]
  |  Branch (1482:27): [True: 0, False: 1.44k]
  ------------------
 1483|      0|      return ParseResult::ERROR;
 1484|      0|    }
 1485|       |
 1486|  1.44k|    HTTPVersion version = http_parse_version(version_start, version_end);
 1487|       |
 1488|  1.44k|    if (version == HTTP_0_9) {
  ------------------
  |  Branch (1488:9): [True: 101, False: 1.34k]
  ------------------
 1489|    101|      return ParseResult::ERROR;
 1490|    101|    }
 1491|       |
 1492|  1.34k|    http_hdr_version_set(hh, version);
 1493|       |
 1494|  1.34k|    if (status_start && status_end) {
  ------------------
  |  Branch (1494:9): [True: 1.34k, False: 0]
  |  Branch (1494:25): [True: 1.34k, False: 0]
  ------------------
 1495|  1.34k|      http_hdr_status_set(hh, http_parse_status(status_start, status_end));
 1496|  1.34k|    }
 1497|       |
 1498|  1.34k|    if (reason_start && reason_end) {
  ------------------
  |  Branch (1498:9): [True: 8, False: 1.33k]
  |  Branch (1498:25): [True: 8, False: 0]
  ------------------
 1499|      8|      http_hdr_reason_set(heap, hh, {reason_start, static_cast<std::string_view::size_type>(reason_end - reason_start)},
 1500|      8|                          must_copy_strings);
 1501|      8|    }
 1502|       |
 1503|  1.34k|    end                    = real_end;
 1504|  1.34k|    parser->m_parsing_http = false;
 1505|  1.34k|  }
 1506|  1.34k|  auto ret = mime_parser_parse(&parser->m_mime_parser, heap, hh->m_fields_impl, start, end, must_copy_strings, eof, true);
 1507|       |  // Make sure the length headers are consistent
 1508|  1.34k|  if (ret == ParseResult::DONE) {
  ------------------
  |  Branch (1508:7): [True: 1.19k, False: 146]
  ------------------
 1509|  1.19k|    ret = validate_hdr_content_length(heap, hh);
 1510|  1.19k|  }
 1511|  1.34k|  return ret;
 1512|  9.36k|}
_Z17http_parse_statusPKcS0_:
 1519|  1.34k|{
 1520|  1.34k|  int status = 0;
 1521|       |
 1522|  1.34k|  while ((start != end) && ParseRules::is_space(*start)) {
  ------------------
  |  Branch (1522:10): [True: 45, False: 1.29k]
  |  Branch (1522:28): [True: 0, False: 45]
  ------------------
 1523|      0|    start += 1;
 1524|      0|  }
 1525|       |
 1526|  1.59k|  while ((start != end) && isdigit(*start)) {
  ------------------
  |  Branch (1526:10): [True: 249, False: 1.34k]
  |  Branch (1526:28): [True: 249, False: 0]
  ------------------
 1527|    249|    status = (status * 10) + (*start++ - '0');
 1528|    249|  }
 1529|       |
 1530|  1.34k|  return static_cast<HTTPStatus>(status);
 1531|  1.34k|}
_Z18http_parse_versionPKcS0_:
 1538|  2.34k|{
 1539|  2.34k|  int maj;
 1540|  2.34k|  int min;
 1541|       |
 1542|  2.34k|  if ((end - start) < 8) {
  ------------------
  |  Branch (1542:7): [True: 87, False: 2.25k]
  ------------------
 1543|     87|    return HTTP_0_9;
 1544|     87|  }
 1545|       |
 1546|  2.25k|  if ((start[0] == 'H') && (start[1] == 'T') && (start[2] == 'T') && (start[3] == 'P') && (start[4] == '/')) {
  ------------------
  |  Branch (1546:7): [True: 2.25k, False: 0]
  |  Branch (1546:28): [True: 2.25k, False: 0]
  |  Branch (1546:49): [True: 2.25k, False: 0]
  |  Branch (1546:70): [True: 2.25k, False: 0]
  |  Branch (1546:91): [True: 2.25k, False: 0]
  ------------------
 1547|  2.25k|    start += 5;
 1548|       |
 1549|  2.25k|    maj = 0;
 1550|  2.25k|    min = 0;
 1551|       |
 1552|  5.29k|    while ((start != end) && isdigit(*start)) {
  ------------------
  |  Branch (1552:12): [True: 5.29k, False: 0]
  |  Branch (1552:30): [True: 3.04k, False: 2.25k]
  ------------------
 1553|  3.04k|      maj    = (maj * 10) + (*start - '0');
 1554|  3.04k|      start += 1;
 1555|  3.04k|    }
 1556|       |
 1557|  2.25k|    if (*start == '.') {
  ------------------
  |  Branch (1557:9): [True: 2.25k, False: 0]
  ------------------
 1558|  2.25k|      start += 1;
 1559|  2.25k|    }
 1560|       |
 1561|  6.23k|    while ((start != end) && isdigit(*start)) {
  ------------------
  |  Branch (1561:12): [True: 3.98k, False: 2.25k]
  |  Branch (1561:30): [True: 3.98k, False: 0]
  ------------------
 1562|  3.98k|      min    = (min * 10) + (*start - '0');
 1563|  3.98k|      start += 1;
 1564|  3.98k|    }
 1565|       |
 1566|  2.25k|    return HTTPVersion(maj, min);
 1567|  2.25k|  }
 1568|       |
 1569|      0|  return HTTP_0_9;
 1570|  2.25k|}
HTTP.cc:_ZZ27validate_hdr_content_lengthP7HdrHeapP11HTTPHdrImplENK3$_0clEc:
 1282|  2.23k|    if (std::find_if(value.cbegin(), value.cend(), [](std::string_view::value_type c) { return !std::isdigit(c); }) !=

_Z11new_HdrHeapi:
  118|  18.8k|{
  119|  18.8k|  HdrHeap *h;
  120|  18.8k|  if (size <= HdrHeap::DEFAULT_SIZE) {
  ------------------
  |  Branch (120:7): [True: 18.7k, False: 153]
  ------------------
  121|  18.7k|    size = HdrHeap::DEFAULT_SIZE;
  122|  18.7k|    h    = static_cast<HdrHeap *>(THREAD_ALLOC(hdrHeapAllocator, this_ethread()));
  ------------------
  |  |   77|  18.7k|#define THREAD_ALLOC(_a, _t, ...)      thread_alloc(::_a, _t->_a, ##__VA_ARGS__)
  ------------------
  123|  18.7k|  } else {
  124|    153|    h = static_cast<HdrHeap *>(ats_malloc(size));
  125|    153|  }
  126|       |
  127|  18.8k|  h->m_size = size;
  128|  18.8k|  h->init();
  129|       |
  130|  18.8k|  return h;
  131|  18.8k|}
_ZN10HdrStrHeap5allocEi:
  135|  14.7k|{
  136|       |  // The callee is asking for a string heap to be created
  137|       |  //  that can allocate at least size bytes.  As such we,
  138|       |  //  need to include the size of the string heap header in
  139|       |  //  our calculations
  140|       |
  141|  14.7k|  int alloc_size = heap_size + sizeof(HdrStrHeap);
  142|       |
  143|  14.7k|  HdrStrHeap *sh;
  144|  14.7k|  if (alloc_size <= HdrStrHeap::DEFAULT_SIZE) {
  ------------------
  |  Branch (144:7): [True: 14.7k, False: 0]
  ------------------
  145|  14.7k|    alloc_size = HdrStrHeap::DEFAULT_SIZE;
  146|  14.7k|    sh         = static_cast<HdrStrHeap *>(THREAD_ALLOC(strHeapAllocator, this_ethread()));
  ------------------
  |  |   77|  14.7k|#define THREAD_ALLOC(_a, _t, ...)      thread_alloc(::_a, _t->_a, ##__VA_ARGS__)
  ------------------
  147|  14.7k|  } else {
  148|      0|    alloc_size = swoc::round_up<HdrStrHeap::DEFAULT_SIZE * 2>(alloc_size);
  149|      0|    sh         = static_cast<HdrStrHeap *>(ats_malloc(alloc_size));
  150|      0|  }
  151|       |
  152|       |  // Placement new the HdrStrHeap.
  153|  14.7k|  sh = new (sh) HdrStrHeap(alloc_size);
  154|       |
  155|  14.7k|  sh->_avail_size = alloc_size - sizeof(HdrStrHeap);
  156|       |
  157|  14.7k|  ink_assert(sh->refcount() == 0);
  ------------------
  |  |   45|  14.7k|#define ink_assert(EX) (void)(EX)
  ------------------
  158|       |
  159|  14.7k|  ink_assert(int(sh->total_size()) == alloc_size);
  ------------------
  |  |   45|  14.7k|#define ink_assert(EX) (void)(EX)
  ------------------
  160|       |
  161|  14.7k|  ink_assert(sh->_avail_size > 0);
  ------------------
  |  |   45|  14.7k|#define ink_assert(EX) (void)(EX)
  ------------------
  162|       |
  163|  14.7k|  return sh;
  164|  14.7k|}
_ZN7HdrHeap7destroyEv:
  168|  18.8k|{
  169|  18.8k|  if (m_next) {
  ------------------
  |  Branch (169:7): [True: 153, False: 18.7k]
  ------------------
  170|    153|    m_next->destroy();
  171|    153|  }
  172|       |
  173|  18.8k|  m_read_write_heap = nullptr;
  174|  56.6k|  for (auto &i : m_ronly_heap) {
  ------------------
  |  Branch (174:16): [True: 56.6k, False: 18.8k]
  ------------------
  175|  56.6k|    i.m_ref_count_ptr = nullptr;
  176|  56.6k|  }
  177|       |
  178|  18.8k|  if (m_size == HdrHeap::DEFAULT_SIZE) {
  ------------------
  |  Branch (178:7): [True: 18.7k, False: 153]
  ------------------
  179|  18.7k|    THREAD_FREE(this, hdrHeapAllocator, this_thread());
  ------------------
  |  |   97|  18.7k|  do {                                                                                             \
  |  |   98|  18.7k|    ::_a.destroy_if_enabled(_p);                                                                   \
  |  |   99|  18.7k|    Thread *_t = (_tin);                                                                           \
  |  |  100|  18.7k|    if (_t && !cmd_disable_pfreelist) {                                                            \
  |  |  ------------------
  |  |  |  Branch (100:9): [True: 0, False: 18.7k]
  |  |  |  Branch (100:15): [True: 0, False: 0]
  |  |  ------------------
  |  |  101|      0|      *(char **)_p    = (char *)_t->_a.freelist;                                                   \
  |  |  102|      0|      _t->_a.freelist = _p;                                                                        \
  |  |  103|      0|      _t->_a.allocated++;                                                                          \
  |  |  104|      0|      UPDATE_FREE_METRICS(::_a);                                                                   \
  |  |  105|      0|      if (thread_freelist_high_watermark > 0 && _t->_a.allocated > thread_freelist_high_watermark) \
  |  |  ------------------
  |  |  |  Branch (105:11): [True: 0, False: 0]
  |  |  |  Branch (105:49): [True: 0, False: 0]
  |  |  ------------------
  |  |  106|      0|        thread_freeup(::_a.raw(), _t->_a);                                                         \
  |  |  107|  18.7k|    } else {                                                                                       \
  |  |  108|  18.7k|      ::_a.raw().free_void(_p);                                                                    \
  |  |  109|  18.7k|    }                                                                                              \
  |  |  110|  18.7k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (110:12): [Folded, False: 18.7k]
  |  |  ------------------
  ------------------
  180|  18.7k|  } else {
  181|    153|    ats_free(this);
  182|    153|  }
  183|  18.8k|}
_ZN7HdrHeap12allocate_objEi14HdrHeapObjType:
  187|  47.7k|{
  188|  47.7k|  char           *new_space;
  189|  47.7k|  HdrHeapObjImpl *obj;
  190|       |
  191|  47.7k|  ink_assert(m_writeable);
  ------------------
  |  |   45|  47.7k|#define ink_assert(EX) (void)(EX)
  ------------------
  192|       |
  193|  47.7k|  nbytes = HdrHeapMarshalBlocks{swoc::round_up(nbytes)};
  194|       |
  195|  47.7k|  if (nbytes > static_cast<int>(HDR_MAX_ALLOC_SIZE)) {
  ------------------
  |  Branch (195:7): [True: 0, False: 47.7k]
  ------------------
  196|      0|    ink_assert(!"alloc too big");
  ------------------
  |  |   45|      0|#define ink_assert(EX) (void)(EX)
  ------------------
  197|      0|    return nullptr;
  198|      0|  }
  199|       |
  200|  47.7k|  HdrHeap *h = this;
  201|       |
  202|  48.4k|  while (true) {
  ------------------
  |  Branch (202:10): [True: 48.4k, Folded]
  ------------------
  203|  48.4k|    if (static_cast<unsigned>(nbytes) <= (h->m_free_size)) {
  ------------------
  |  Branch (203:9): [True: 47.7k, False: 672]
  ------------------
  204|  47.7k|      new_space        = h->m_free_start;
  205|  47.7k|      h->m_free_start += nbytes;
  206|  47.7k|      h->m_free_size  -= nbytes;
  207|       |
  208|  47.7k|      obj = reinterpret_cast<HdrHeapObjImpl *>(new_space);
  209|  47.7k|      obj_init_header(obj, type, nbytes, 0);
  210|  47.7k|      ink_assert(obj_is_aligned(obj));
  ------------------
  |  |   45|  47.7k|#define ink_assert(EX) (void)(EX)
  ------------------
  211|       |
  212|  47.7k|      return obj;
  213|  47.7k|    }
  214|       |
  215|    672|    if (h->m_next == nullptr) {
  ------------------
  |  Branch (215:9): [True: 153, False: 519]
  ------------------
  216|       |      // Allocate our next pointer heap
  217|       |      //   twice as large as this one so
  218|       |      //   number of pointer heaps is O(log n)
  219|       |      //   with regard to number of bytes allocated
  220|    153|      h->m_next = new_HdrHeap(h->m_size * 2);
  221|    153|    }
  222|       |
  223|    672|    h = h->m_next;
  224|    672|  }
  225|  47.7k|}
_ZN7HdrHeap14deallocate_objEP14HdrHeapObjImpl:
  229|     24|{
  230|     24|  ink_assert(m_writeable);
  ------------------
  |  |   45|     24|#define ink_assert(EX) (void)(EX)
  ------------------
  231|     24|  obj->m_type = static_cast<uint32_t>(HdrHeapObjType::EMPTY);
  232|     24|}
_ZN7HdrHeap12allocate_strEi:
  236|  54.4k|{
  237|  54.4k|  int last_size = 0;
  238|  54.4k|  int next_size = 0;
  239|  54.4k|  ink_assert(m_writeable);
  ------------------
  |  |   45|  54.4k|#define ink_assert(EX) (void)(EX)
  ------------------
  240|       |
  241|       |  // INKqa08287 - We could get infinite build up
  242|       |  //   of dead strings on header merge.  To prevent
  243|       |  //   this we keep track of the dead string space
  244|       |  //   and force a heap coalesce if it is too large.
  245|       |  //   Ideally this should be done on free_string()
  246|       |  //   but I already no that this code path is
  247|       |  //   safe for forcing a str coalesce so I'm doing
  248|       |  //   it here for sanity's sake
  249|  54.4k|  int coalesce = m_lost_string_space > static_cast<int>(MAX_LOST_STR_SPACE) ? 1 : 0;
  ------------------
  |  Branch (249:18): [True: 0, False: 54.4k]
  ------------------
  250|       |
  251|  54.4k|  for (;;) {
  252|  54.4k|    if (coalesce) {
  ------------------
  |  Branch (252:9): [True: 0, False: 54.4k]
  ------------------
  253|      0|      switch (coalesce) {
  254|      0|      case 2:
  ------------------
  |  Branch (254:7): [True: 0, False: 0]
  ------------------
  255|      0|        Warning("HdrHeap=%p coalescing twice", this);
  ------------------
  |  |   88|      0|#define Warning(...)   DiagsError(DL_Warning, __VA_ARGS__)   // Log concerning information
  |  |  ------------------
  |  |  |  |   80|      0|  do {                                                                  \
  |  |  |  |   81|      0|    static const SourceLocation DiagsError_loc = MakeSourceLocation();  \
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|      0|#define MakeSourceLocation() SourceLocation(__FILE__, __FUNCTION__, __LINE__)
  |  |  |  |  ------------------
  |  |  |  |   82|      0|    static LogMessage           DiagsError_log_message;                 \
  |  |  |  |   83|      0|    DiagsError_log_message.message(LEVEL, DiagsError_loc, __VA_ARGS__); \
  |  |  |  |   84|      0|  } while (false)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (84:12): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  256|      0|        break;
  257|      0|      case 3:
  ------------------
  |  Branch (257:7): [True: 0, False: 0]
  ------------------
  258|      0|        Warning("HdrHeap=%p coalescing three or more times", this);
  ------------------
  |  |   88|      0|#define Warning(...)   DiagsError(DL_Warning, __VA_ARGS__)   // Log concerning information
  |  |  ------------------
  |  |  |  |   80|      0|  do {                                                                  \
  |  |  |  |   81|      0|    static const SourceLocation DiagsError_loc = MakeSourceLocation();  \
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|      0|#define MakeSourceLocation() SourceLocation(__FILE__, __FUNCTION__, __LINE__)
  |  |  |  |  ------------------
  |  |  |  |   82|      0|    static LogMessage           DiagsError_log_message;                 \
  |  |  |  |   83|      0|    DiagsError_log_message.message(LEVEL, DiagsError_loc, __VA_ARGS__); \
  |  |  |  |   84|      0|  } while (false)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (84:12): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  259|      0|        break;
  260|      0|      default:
  ------------------
  |  Branch (260:7): [True: 0, False: 0]
  ------------------
  261|      0|        break;
  262|      0|      }
  263|       |
  264|      0|      coalesce_str_heaps();
  265|      0|    }
  266|  54.4k|    do {
  267|       |      // First check to see if we have a read/write
  268|       |      //   string heap
  269|  54.4k|      if (!m_read_write_heap) {
  ------------------
  |  Branch (269:11): [True: 14.7k, False: 39.6k]
  ------------------
  270|  14.7k|        if (next_size) {
  ------------------
  |  Branch (270:13): [True: 0, False: 14.7k]
  ------------------
  271|      0|          Warning("HdrHeap=%p new read/write string heap twice last_size=%d", this, last_size);
  ------------------
  |  |   88|      0|#define Warning(...)   DiagsError(DL_Warning, __VA_ARGS__)   // Log concerning information
  |  |  ------------------
  |  |  |  |   80|      0|  do {                                                                  \
  |  |  |  |   81|      0|    static const SourceLocation DiagsError_loc = MakeSourceLocation();  \
  |  |  |  |  ------------------
  |  |  |  |  |  |   32|      0|#define MakeSourceLocation() SourceLocation(__FILE__, __FUNCTION__, __LINE__)
  |  |  |  |  ------------------
  |  |  |  |   82|      0|    static LogMessage           DiagsError_log_message;                 \
  |  |  |  |   83|      0|    DiagsError_log_message.message(LEVEL, DiagsError_loc, __VA_ARGS__); \
  |  |  |  |   84|      0|  } while (false)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (84:12): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  272|      0|        }
  273|  14.7k|        next_size         = (last_size * 2) - int(sizeof(HdrStrHeap));
  274|  14.7k|        next_size         = next_size > nbytes ? next_size : nbytes;
  ------------------
  |  Branch (274:29): [True: 0, False: 14.7k]
  ------------------
  275|  14.7k|        m_read_write_heap = HdrStrHeap::alloc(next_size);
  276|  14.7k|      }
  277|       |      // Try to allocate of our read/write string heap
  278|  54.4k|      if (char *new_space = m_read_write_heap->allocate(nbytes); new_space) {
  ------------------
  |  Branch (278:66): [True: 54.4k, False: 0]
  ------------------
  279|  54.4k|        return new_space;
  280|  54.4k|      }
  281|       |
  282|      0|      last_size = m_read_write_heap->total_size();
  283|       |
  284|       |      // Our existing rw str heap doesn't have sufficient
  285|       |      //  capacity.  We need to move the current rw heap
  286|       |      //  out of the way and create a new one
  287|      0|    } while (demote_rw_str_heap() == 0);
  ------------------
  |  Branch (287:14): [True: 0, False: 0]
  ------------------
  288|       |
  289|       |    // We failed to demote.  We'll have to coalesce the heaps.
  290|      0|    ++coalesce;
  291|      0|    next_size = 0;
  292|      0|  }
  293|  54.4k|}
_ZN7HdrHeap13duplicate_strEPKci:
  320|  54.4k|{
  321|  54.4k|  HeapGuard guard(this, str); // Don't let the source get de-allocated.
  322|  54.4k|  char     *new_str = allocate_str(nbytes);
  323|       |
  324|  54.4k|  memcpy(new_str, str, nbytes);
  325|  54.4k|  return (new_str);
  326|  54.4k|}
_ZN10HdrStrHeap4freeEv:
 1171|  14.7k|{
 1172|  14.7k|  if (_total_size == HdrStrHeap::DEFAULT_SIZE) {
  ------------------
  |  Branch (1172:7): [True: 14.7k, False: 0]
  ------------------
 1173|  14.7k|    THREAD_FREE(this, strHeapAllocator, this_thread());
  ------------------
  |  |   97|  14.7k|  do {                                                                                             \
  |  |   98|  14.7k|    ::_a.destroy_if_enabled(_p);                                                                   \
  |  |   99|  14.7k|    Thread *_t = (_tin);                                                                           \
  |  |  100|  14.7k|    if (_t && !cmd_disable_pfreelist) {                                                            \
  |  |  ------------------
  |  |  |  Branch (100:9): [True: 0, False: 14.7k]
  |  |  |  Branch (100:15): [True: 0, False: 0]
  |  |  ------------------
  |  |  101|      0|      *(char **)_p    = (char *)_t->_a.freelist;                                                   \
  |  |  102|      0|      _t->_a.freelist = _p;                                                                        \
  |  |  103|      0|      _t->_a.allocated++;                                                                          \
  |  |  104|      0|      UPDATE_FREE_METRICS(::_a);                                                                   \
  |  |  105|      0|      if (thread_freelist_high_watermark > 0 && _t->_a.allocated > thread_freelist_high_watermark) \
  |  |  ------------------
  |  |  |  Branch (105:11): [True: 0, False: 0]
  |  |  |  Branch (105:49): [True: 0, False: 0]
  |  |  ------------------
  |  |  106|      0|        thread_freeup(::_a.raw(), _t->_a);                                                         \
  |  |  107|  14.7k|    } else {                                                                                       \
  |  |  108|  14.7k|      ::_a.raw().free_void(_p);                                                                    \
  |  |  109|  14.7k|    }                                                                                              \
  |  |  110|  14.7k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (110:12): [Folded, False: 14.7k]
  |  |  ------------------
  ------------------
 1174|  14.7k|  } else {
 1175|      0|    ats_free(this);
 1176|      0|  }
 1177|  14.7k|}
_ZN10HdrStrHeap8allocateEi:
 1186|  54.4k|{
 1187|  54.4k|  if (_avail_size >= static_cast<unsigned>(nbytes)) {
  ------------------
  |  Branch (1187:7): [True: 54.4k, False: 0]
  ------------------
 1188|  54.4k|    char *new_space  = reinterpret_cast<char *>(this) + _total_size - _avail_size;
 1189|  54.4k|    _avail_size     -= nbytes;
 1190|  54.4k|    return new_space;
 1191|  54.4k|  } else {
 1192|      0|    return nullptr;
 1193|      0|  }
 1194|  54.4k|}
_ZN7HdrHeap4initEv:
   92|  18.8k|{
   93|  18.8k|  m_data_start = m_free_start = (reinterpret_cast<char *>(this)) + HDR_HEAP_HDR_SIZE;
   94|  18.8k|  m_magic                     = HdrBufMagic::ALIVE;
   95|  18.8k|  m_writeable                 = true;
   96|       |
   97|  18.8k|  m_next      = nullptr;
   98|  18.8k|  m_free_size = m_size - HDR_HEAP_HDR_SIZE;
   99|       |
  100|       |  // We need to clear m_ptr directly since it's garbage and
  101|       |  //  using the operator functions will to free() what ever
  102|       |  //  garbage it is pointing to
  103|  18.8k|  m_read_write_heap.detach();
  104|       |
  105|  56.6k|  for (auto &i : m_ronly_heap) {
  ------------------
  |  Branch (105:16): [True: 56.6k, False: 18.8k]
  ------------------
  106|  56.6k|    i.m_heap_start = nullptr;
  107|  56.6k|    i.m_ref_count_ptr.detach();
  108|  56.6k|    i.m_locked   = false;
  109|  56.6k|    i.m_heap_len = 0;
  110|  56.6k|  }
  111|  18.8k|  m_lost_string_space = 0;
  112|       |
  113|  18.8k|  ink_assert(m_free_size > 0);
  ------------------
  |  |   45|  18.8k|#define ink_assert(EX) (void)(EX)
  ------------------
  114|  18.8k|}

_Z18hdrtoken_hash_initv:
  333|      1|{
  334|      1|  uint32_t i;
  335|      1|  int      num_collisions;
  336|       |
  337|      1|  memset(hdrtoken_hash_table, 0, sizeof(hdrtoken_hash_table));
  338|      1|  num_collisions = 0;
  339|       |
  340|    136|  for (i = 0; i < static_cast<int> SIZEOF(_hdrtoken_strs); i++) {
  ------------------
  |  |   43|    136|#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
  ------------------
  |  Branch (340:15): [True: 135, False: 1]
  ------------------
  341|       |    // convert the common string to the well-known token
  342|    135|    unsigned const char *wks;
  343|    135|    int                  wks_idx =
  344|    135|      hdrtoken_tokenize_dfa(_hdrtoken_strs[i], static_cast<int>(strlen(_hdrtoken_strs[i])), reinterpret_cast<const char **>(&wks));
  345|    135|    ink_release_assert(wks_idx >= 0);
  ------------------
  |  |   48|    135|#define ink_release_assert(EX) ((void)(__builtin_expect(!!(EX), 0) ? (void)0 : _ink_assert(#EX, __FILE__, __LINE__)))
  |  |  ------------------
  |  |  |  Branch (48:40): [True: 135, False: 0]
  |  |  ------------------
  ------------------
  346|       |
  347|    135|    uint32_t hash = hdrtoken_hash(wks, hdrtoken_str_lengths[wks_idx]);
  348|    135|    uint32_t slot = hash_to_slot(hash);
  349|       |
  350|    135|    if (hdrtoken_hash_table[slot].wks) {
  ------------------
  |  Branch (350:9): [True: 0, False: 135]
  ------------------
  351|      0|      printf("ERROR: hdrtoken_hash_table[%u] collision: '%s' replacing '%s'\n", slot, reinterpret_cast<const char *>(wks),
  352|      0|             hdrtoken_hash_table[slot].wks);
  353|      0|      ++num_collisions;
  354|      0|    }
  355|    135|    hdrtoken_hash_table[slot].wks  = reinterpret_cast<const char *>(wks);
  356|    135|    hdrtoken_hash_table[slot].hash = hash;
  357|    135|  }
  358|       |
  359|      1|  if (num_collisions > 0) {
  ------------------
  |  Branch (359:7): [True: 0, False: 1]
  ------------------
  360|      0|    abort();
  361|      0|  }
  362|      1|}
_Z13hdrtoken_initv:
  384|      2|{
  385|      2|  static int inited = 0;
  386|       |
  387|      2|  int i;
  388|       |
  389|      2|  if (!inited) {
  ------------------
  |  Branch (389:7): [True: 1, False: 1]
  ------------------
  390|      1|    inited = 1;
  391|       |
  392|      1|    hdrtoken_strs_dfa = new DFA;
  393|      1|    hdrtoken_strs_dfa->compile(_hdrtoken_strs, SIZEOF(_hdrtoken_strs), (RE_CASE_INSENSITIVE));
  ------------------
  |  |   43|      1|#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
  ------------------
  394|       |
  395|       |    // all the tokenized hdrtoken strings are placed in a special heap,
  396|       |    // and each string is prepended with a HdrTokenHeapPrefix ---
  397|       |    // this makes it easy to tell that a string is a tokenized
  398|       |    // string (because its address is within the heap), and
  399|       |    // makes it easy to find the length, index, flags, mask, and
  400|       |    // other info from the prefix.
  401|       |
  402|      1|    int heap_size = 0;
  403|    136|    for (i = 0; i < static_cast<int> SIZEOF(_hdrtoken_strs); i++) {
  ------------------
  |  |   43|    136|#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
  ------------------
  |  Branch (403:17): [True: 135, False: 1]
  ------------------
  404|    135|      hdrtoken_str_lengths[i]    = static_cast<int>(strlen(_hdrtoken_strs[i]));
  405|    135|      int sstr_len               = snap_up_to_multiple(hdrtoken_str_lengths[i] + 1, sizeof(HdrTokenHeapPrefix));
  406|    135|      int packed_prefix_str_len  = sizeof(HdrTokenHeapPrefix) + sstr_len;
  407|    135|      heap_size                 += packed_prefix_str_len;
  408|    135|    }
  409|       |
  410|      1|    _hdrtoken_strs_heap_f = static_cast<const char *>(ats_calloc(1, heap_size));
  411|      1|    _hdrtoken_strs_heap_l = _hdrtoken_strs_heap_f + heap_size - 1;
  412|       |
  413|      1|    char *heap_ptr = const_cast<char *>(_hdrtoken_strs_heap_f);
  414|       |
  415|    136|    for (i = 0; i < static_cast<int> SIZEOF(_hdrtoken_strs); i++) {
  ------------------
  |  |   43|    136|#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
  ------------------
  |  Branch (415:17): [True: 135, False: 1]
  ------------------
  416|    135|      HdrTokenHeapPrefix prefix;
  417|       |
  418|    135|      memset(&prefix, 0, sizeof(HdrTokenHeapPrefix));
  419|       |
  420|    135|      prefix.wks_idx         = i;
  421|    135|      prefix.wks_length      = hdrtoken_str_lengths[i];
  422|    135|      prefix.wks_token_type  = HdrTokenType::OTHER;         // default, can override later
  423|    135|      prefix.wks_info.name   = nullptr;                     // default, can override later
  424|    135|      prefix.wks_info.slotid = MIME_SLOTID_NONE;            // default, can override later
  ------------------
  |  |  295|    135|#define MIME_SLOTID_NONE -1
  ------------------
  425|    135|      prefix.wks_info.mask   = TOK_64_CONST(0);             // default, can override later
  ------------------
  |  |  311|    135|#define TOK_64_CONST(x) x##LL
  ------------------
  426|    135|      prefix.wks_info.flags  = HdrTokenInfoFlags::MULTVALS; // default, can override later
  427|       |
  428|    135|      int sstr_len = snap_up_to_multiple(hdrtoken_str_lengths[i] + 1, sizeof(HdrTokenHeapPrefix));
  429|       |
  430|    135|      *reinterpret_cast<HdrTokenHeapPrefix *>(heap_ptr)  = prefix;                     // set string prefix
  431|    135|      heap_ptr                                          += sizeof(HdrTokenHeapPrefix); // advance heap ptr past index
  432|    135|      hdrtoken_strs[i]                                   = heap_ptr;                   // record string pointer
  433|       |      // coverity[secure_coding]
  434|    135|      ink_strlcpy(const_cast<char *>(hdrtoken_strs[i]), _hdrtoken_strs[i],
  ------------------
  |  |   62|    135|#define ink_strlcpy strlcpy
  ------------------
  435|    135|                  heap_size - sizeof(HdrTokenHeapPrefix)); // copy string into heap
  436|    135|      heap_ptr  += sstr_len;                               // advance heap ptr past string
  437|    135|      heap_size -= sstr_len;
  438|    135|    }
  439|       |
  440|       |    // Set the token types for certain tokens
  441|     44|    for (i = 0; _hdrtoken_strs_type_initializers[i].name != nullptr; i++) {
  ------------------
  |  Branch (441:17): [True: 43, False: 1]
  ------------------
  442|     43|      int                 wks_idx;
  443|     43|      HdrTokenHeapPrefix *prefix;
  444|       |
  445|     43|      wks_idx = hdrtoken_tokenize_dfa(_hdrtoken_strs_type_initializers[i].name,
  446|     43|                                      static_cast<int>(strlen(_hdrtoken_strs_type_initializers[i].name)));
  447|       |
  448|     43|      ink_assert((wks_idx >= 0) && (wks_idx < (int)SIZEOF(hdrtoken_strs)));
  ------------------
  |  |   45|     86|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 43, False: 0]
  |  |  |  Branch (45:31): [True: 43, False: 0]
  |  |  ------------------
  ------------------
  449|       |      // coverity[negative_returns]
  450|     43|      prefix                 = hdrtoken_index_to_prefix(wks_idx);
  451|     43|      prefix->wks_token_type = _hdrtoken_strs_type_initializers[i].type;
  452|     43|    }
  453|       |
  454|       |    // Set special data for field names
  455|     77|    for (i = 0; _hdrtoken_strs_field_initializers[i].name != nullptr; i++) {
  ------------------
  |  Branch (455:17): [True: 76, False: 1]
  ------------------
  456|     76|      int                 wks_idx;
  457|     76|      HdrTokenHeapPrefix *prefix;
  458|       |
  459|     76|      wks_idx = hdrtoken_tokenize_dfa(_hdrtoken_strs_field_initializers[i].name,
  460|     76|                                      static_cast<int>(strlen(_hdrtoken_strs_field_initializers[i].name)));
  461|       |
  462|     76|      ink_assert((wks_idx >= 0) && (wks_idx < (int)SIZEOF(hdrtoken_strs)));
  ------------------
  |  |   45|    152|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 76, False: 0]
  |  |  |  Branch (45:31): [True: 76, False: 0]
  |  |  ------------------
  ------------------
  463|     76|      prefix                  = hdrtoken_index_to_prefix(wks_idx);
  464|     76|      prefix->wks_info.slotid = _hdrtoken_strs_field_initializers[i].slotid;
  465|     76|      prefix->wks_info.flags  = _hdrtoken_strs_field_initializers[i].flags;
  466|     76|      prefix->wks_info.mask   = _hdrtoken_strs_field_initializers[i].mask;
  467|     76|    }
  468|       |
  469|    136|    for (i = 0; i < static_cast<int> SIZEOF(_hdrtoken_strs); i++) {
  ------------------
  |  |   43|    136|#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
  ------------------
  |  Branch (469:17): [True: 135, False: 1]
  ------------------
  470|    135|      HdrTokenHeapPrefix *prefix  = hdrtoken_index_to_prefix(i);
  471|    135|      prefix->wks_info.name       = hdrtoken_strs[i];
  472|    135|      hdrtoken_str_token_types[i] = prefix->wks_token_type;  // parallel array for speed
  473|    135|      hdrtoken_str_slotids[i]     = prefix->wks_info.slotid; // parallel array for speed
  474|    135|      hdrtoken_str_masks[i]       = prefix->wks_info.mask;   // parallel array for speed
  475|    135|      hdrtoken_str_flags[i]       = prefix->wks_info.flags;  // parallel array for speed
  476|    135|    }
  477|       |
  478|      1|    hdrtoken_hash_init();
  479|      1|  }
  480|      2|}
_Z21hdrtoken_tokenize_dfaPKciPS0_:
  487|    254|{
  488|    254|  int wks_idx;
  489|       |
  490|    254|  wks_idx = hdrtoken_strs_dfa->match({string, static_cast<size_t>(string_len)});
  491|       |
  492|    254|  if (wks_idx < 0) {
  ------------------
  |  Branch (492:7): [True: 0, False: 254]
  ------------------
  493|      0|    wks_idx = -1;
  494|      0|  }
  495|    254|  if (wks_string_out) {
  ------------------
  |  Branch (495:7): [True: 135, False: 119]
  ------------------
  496|    135|    if (wks_idx >= 0) {
  ------------------
  |  Branch (496:9): [True: 135, False: 0]
  ------------------
  497|    135|      *wks_string_out = hdrtoken_index_to_wks(wks_idx);
  498|    135|    } else {
  499|      0|      *wks_string_out = nullptr;
  500|      0|    }
  501|    135|  }
  502|       |  // printf("hdrtoken_tokenize_dfa(%d,*s) - return %d\n",string_len,string,wks_idx);
  503|       |
  504|    254|  return wks_idx;
  505|    254|}
_Z24hdrtoken_method_tokenizePKci:
  514|  1.89k|{
  515|  1.89k|  const char *string_out;
  516|  1.89k|  int         retval = -1;
  517|  1.89k|  if (hdrtoken_is_wks(string)) {
  ------------------
  |  Branch (517:7): [True: 0, False: 1.89k]
  ------------------
  518|      0|    retval = hdrtoken_wks_to_index(string);
  519|      0|    return retval;
  520|      0|  }
  521|  1.89k|  retval = hdrtoken_tokenize(string, string_len, &string_out);
  522|  1.89k|  if (retval >= 0) {
  ------------------
  |  Branch (522:7): [True: 83, False: 1.81k]
  ------------------
  523|     83|    if (strncmp(string, string_out, string_len) != 0) {
  ------------------
  |  Branch (523:9): [True: 32, False: 51]
  ------------------
  524|       |      // Not a case match
  525|     32|      retval = -1;
  526|     32|    }
  527|     83|  }
  528|  1.89k|  return retval;
  529|  1.89k|}
_Z17hdrtoken_tokenizePKciPS0_:
  536|  58.8k|{
  537|  58.8k|  int                 wks_idx;
  538|  58.8k|  HdrTokenHashBucket *bucket;
  539|       |
  540|  58.8k|  ink_assert(string != nullptr);
  ------------------
  |  |   45|  58.8k|#define ink_assert(EX) (void)(EX)
  ------------------
  541|       |
  542|  58.8k|  if (hdrtoken_is_wks(string)) {
  ------------------
  |  Branch (542:7): [True: 0, False: 58.8k]
  ------------------
  543|      0|    wks_idx = hdrtoken_wks_to_index(string);
  544|      0|    if (wks_string_out) {
  ------------------
  |  Branch (544:9): [True: 0, False: 0]
  ------------------
  545|      0|      *wks_string_out = string;
  546|      0|    }
  547|      0|    return wks_idx;
  548|      0|  }
  549|       |
  550|  58.8k|  uint32_t hash = hdrtoken_hash(reinterpret_cast<const unsigned char *>(string), static_cast<unsigned int>(string_len));
  551|  58.8k|  uint32_t slot = hash_to_slot(hash);
  552|       |
  553|  58.8k|  bucket = &(hdrtoken_hash_table[slot]);
  554|  58.8k|  if ((bucket->wks != nullptr) && (bucket->hash == hash) && (hdrtoken_wks_to_length(bucket->wks) == string_len)) {
  ------------------
  |  Branch (554:7): [True: 5.55k, False: 53.2k]
  |  Branch (554:35): [True: 5.29k, False: 253]
  |  Branch (554:61): [True: 5.08k, False: 211]
  ------------------
  555|  5.08k|    wks_idx = hdrtoken_wks_to_index(bucket->wks);
  556|  5.08k|    if (wks_string_out) {
  ------------------
  |  Branch (556:9): [True: 962, False: 4.12k]
  ------------------
  557|    962|      *wks_string_out = bucket->wks;
  558|    962|    }
  559|  5.08k|    return wks_idx;
  560|  5.08k|  }
  561|       |
  562|  53.7k|  Dbg(dbg_ctl_hdr_token, "Did not find a WKS for '%.*s'", string_len, string);
  ------------------
  |  |  173|  53.7k|  do {                              \
  |  |  174|  53.7k|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 53.7k]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|  53.7k|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 53.7k]
  |  |  ------------------
  ------------------
  563|  53.7k|  return -1;
  564|  58.8k|}
_Z22hdrtoken_string_to_wksPKc:
  571|     13|{
  572|     13|  const char *wks = nullptr;
  573|     13|  hdrtoken_tokenize(string, static_cast<int>(strlen(string)), &wks);
  574|     13|  return wks;
  575|     13|}
_Z25hdrtoken_string_to_wks_svPKc:
  593|    160|{
  594|    160|  const char *wks = nullptr;
  595|    160|  auto        length{strlen(string)};
  596|    160|  hdrtoken_tokenize(string, static_cast<int>(length), &wks);
  597|    160|  return c_str_view{wks, length};
  598|    160|}
_Z13hdrtoken_hashPKhj:
  321|  58.9k|{
  322|  58.9k|  ATSHash32FNV1a fnv;
  323|  58.9k|  fnv.update(string, length, ATSHash::nocase());
  324|  58.9k|  fnv.final();
  325|  58.9k|  return fnv.get();
  326|  58.9k|}
_Z12hash_to_slotj:
  315|  58.9k|{
  316|  58.9k|  return ((hash >> 15) ^ hash) & TINY_MASK(15);
  ------------------
  |  |  311|  58.9k|#define TINY_MASK(x) (((uint32_t)1 << (x)) - 1)
  ------------------
  317|  58.9k|}
HdrToken.cc:_ZL19snap_up_to_multiplejj:
  376|    270|{
  377|    270|  return ((n + (unit - 1)) / unit) * unit;
  378|    270|}

_ZN10HdrCsvIter8find_csvEv:
   36|  6.67k|{
   37|  6.67k|  char sep_list[3] = {'"', m_separator, 0};
   38|       |
   39|  6.67k|  m_csv.clear();
   40|       |
   41|  18.3k|  while (m_cur_field) {
  ------------------
  |  Branch (41:10): [True: 16.6k, False: 1.63k]
  ------------------
   42|  18.1k|    while (m_value) {
  ------------------
  |  Branch (42:12): [True: 6.49k, False: 11.6k]
  ------------------
   43|  6.49k|      bool in_quote_p = false;
   44|       |      // Index of next interesting character.
   45|  6.49k|      TextView::size_type idx = 0;
   46|       |      // Characters of interest in a null terminated string.
   47|  9.68k|      while (idx < m_value.size()) {
  ------------------
  |  Branch (47:14): [True: 8.89k, False: 793]
  ------------------
   48|       |        // Next character of interest.
   49|  8.89k|        idx = m_value.find_first_of(sep_list, idx);
   50|  8.89k|        if (TextView::npos == idx) {
  ------------------
  |  Branch (50:13): [True: 1.38k, False: 7.50k]
  ------------------
   51|       |          // no more, consume all of @a src.
   52|  1.38k|          break;
   53|  7.50k|        } else if ('"' == m_value[idx]) {
  ------------------
  |  Branch (53:20): [True: 2.87k, False: 4.62k]
  ------------------
   54|  2.87k|          if (in_quote_p) {
  ------------------
  |  Branch (54:15): [True: 1.12k, False: 1.75k]
  ------------------
   55|       |            // quoted-pair only allowed inside a quoted-string.
   56|       |            // Can always back up because if @a in_quote_p there's a least a preceding quote.
   57|  1.12k|            if (m_value[idx - 1] != '\\') {
  ------------------
  |  Branch (57:17): [True: 924, False: 198]
  ------------------
   58|    924|              in_quote_p = false;
   59|    924|            }
   60|  1.75k|          } else {
   61|  1.75k|            in_quote_p = true;
   62|  1.75k|          }
   63|  2.87k|          ++idx;
   64|  4.62k|        } else if (m_separator == m_value[idx]) { // separator.
  ------------------
  |  Branch (64:20): [True: 4.62k, False: 0]
  ------------------
   65|  4.62k|          if (in_quote_p) {
  ------------------
  |  Branch (65:15): [True: 316, False: 4.31k]
  ------------------
   66|       |            // quoted separator, skip and continue.
   67|    316|            ++idx;
   68|  4.31k|          } else {
   69|       |            // found token, finish up.
   70|  4.31k|            break;
   71|  4.31k|          }
   72|  4.62k|        }
   73|  8.89k|      }
   74|       |
   75|       |      // Trim and then see if there's anything left.
   76|  6.49k|      m_csv = m_value.take_prefix(idx).trim_if(&ParseRules::is_ws);
   77|  6.49k|      if (m_csv && '"' == m_csv[0]) {
  ------------------
  |  Branch (77:11): [True: 6.05k, False: 439]
  |  Branch (77:20): [True: 1.23k, False: 4.82k]
  ------------------
   78|  1.23k|        m_csv.remove_prefix(1);
   79|  1.23k|      }
   80|  6.49k|      if (m_csv && '"' == m_csv[m_csv.size() - 1]) {
  ------------------
  |  Branch (80:11): [True: 5.39k, False: 1.09k]
  |  Branch (80:20): [True: 470, False: 4.92k]
  ------------------
   81|    470|        m_csv.remove_suffix(1);
   82|    470|      }
   83|       |      // If there's any value after that, we're done.
   84|  6.49k|      if (m_csv) {
  ------------------
  |  Branch (84:11): [True: 5.03k, False: 1.45k]
  ------------------
   85|  5.03k|        return;
   86|  5.03k|      }
   87|  6.49k|    }
   88|       |    // Current field is exhausted, try the next if following dupes.
   89|  11.6k|    if (m_follow_dups && m_cur_field->m_next_dup) {
  ------------------
  |  Branch (89:9): [True: 11.6k, False: 0]
  |  Branch (89:26): [True: 10.2k, False: 1.41k]
  ------------------
   90|  10.2k|      this->field_init(m_cur_field->m_next_dup);
   91|  10.2k|    } else {
   92|  1.41k|      m_cur_field = nullptr;
   93|  1.41k|    }
   94|  11.6k|  }
   95|  6.67k|}

_Z24mime_field_presence_maskPKc:
  358|  2.67k|{
  359|  2.67k|  return hdrtoken_wks_to_mask(well_known_str);
  360|  2.67k|}
_Z21mime_hdr_presence_setP11MIMEHdrImplPKc:
  384|  2.56k|{
  385|  2.56k|  uint64_t mask = mime_field_presence_mask(well_known_str);
  386|  2.56k|  if (mask != 0) {
  ------------------
  |  Branch (386:7): [True: 2.44k, False: 122]
  ------------------
  387|  2.44k|    h->m_presence_bits |= mask;
  388|  2.44k|  }
  389|  2.56k|}
_Z21mime_hdr_presence_setP11MIMEHdrImpli:
  393|  2.56k|{
  394|  2.56k|  const char *wks = hdrtoken_index_to_wks(well_known_str_index);
  395|  2.56k|  mime_hdr_presence_set(h, wks);
  396|  2.56k|}
_Z23mime_hdr_presence_unsetP11MIMEHdrImplPKc:
  400|    106|{
  401|    106|  uint64_t mask = mime_field_presence_mask(well_known_str);
  402|    106|  if (mask != 0) {
  ------------------
  |  Branch (402:7): [True: 106, False: 0]
  ------------------
  403|    106|    h->m_presence_bits &= (~mask);
  404|    106|  }
  405|    106|}
_Z23mime_hdr_presence_unsetP11MIMEHdrImpli:
  409|    106|{
  410|    106|  const char *wks = hdrtoken_index_to_wks(well_known_str_index);
  411|    106|  mime_hdr_presence_unset(h, wks);
  412|    106|}
_Z9mime_initv:
  640|      1|{
  641|      1|  static int init = 1;
  642|       |
  643|      1|  if (init) {
  ------------------
  |  Branch (643:7): [True: 1, False: 0]
  ------------------
  644|      1|    init = 0;
  645|       |
  646|      1|    hdrtoken_init();
  647|       |
  648|      1|    MIME_FIELD_ACCEPT                    = hdrtoken_string_to_wks_sv("Accept");
  649|      1|    MIME_FIELD_ACCEPT_CHARSET            = hdrtoken_string_to_wks_sv("Accept-Charset");
  650|      1|    MIME_FIELD_ACCEPT_ENCODING           = hdrtoken_string_to_wks_sv("Accept-Encoding");
  651|      1|    MIME_FIELD_ACCEPT_LANGUAGE           = hdrtoken_string_to_wks_sv("Accept-Language");
  652|      1|    MIME_FIELD_ACCEPT_RANGES             = hdrtoken_string_to_wks_sv("Accept-Ranges");
  653|      1|    MIME_FIELD_AGE                       = hdrtoken_string_to_wks_sv("Age");
  654|      1|    MIME_FIELD_ALLOW                     = hdrtoken_string_to_wks_sv("Allow");
  655|      1|    MIME_FIELD_APPROVED                  = hdrtoken_string_to_wks_sv("Approved");
  656|      1|    MIME_FIELD_AUTHORIZATION             = hdrtoken_string_to_wks_sv("Authorization");
  657|      1|    MIME_FIELD_BYTES                     = hdrtoken_string_to_wks_sv("Bytes");
  658|      1|    MIME_FIELD_CACHE_CONTROL             = hdrtoken_string_to_wks_sv("Cache-Control");
  659|      1|    MIME_FIELD_CLIENT_IP                 = hdrtoken_string_to_wks_sv("Client-ip");
  660|      1|    MIME_FIELD_CONNECTION                = hdrtoken_string_to_wks_sv("Connection");
  661|      1|    MIME_FIELD_CONTENT_BASE              = hdrtoken_string_to_wks_sv("Content-Base");
  662|      1|    MIME_FIELD_CONTENT_ENCODING          = hdrtoken_string_to_wks_sv("Content-Encoding");
  663|      1|    MIME_FIELD_CONTENT_LANGUAGE          = hdrtoken_string_to_wks_sv("Content-Language");
  664|      1|    MIME_FIELD_CONTENT_LENGTH            = hdrtoken_string_to_wks_sv("Content-Length");
  665|      1|    MIME_FIELD_CONTENT_LOCATION          = hdrtoken_string_to_wks_sv("Content-Location");
  666|      1|    MIME_FIELD_CONTENT_MD5               = hdrtoken_string_to_wks_sv("Content-MD5");
  667|      1|    MIME_FIELD_CONTENT_RANGE             = hdrtoken_string_to_wks_sv("Content-Range");
  668|      1|    MIME_FIELD_CONTENT_TYPE              = hdrtoken_string_to_wks_sv("Content-Type");
  669|      1|    MIME_FIELD_CONTROL                   = hdrtoken_string_to_wks_sv("Control");
  670|      1|    MIME_FIELD_COOKIE                    = hdrtoken_string_to_wks_sv("Cookie");
  671|      1|    MIME_FIELD_DATE                      = hdrtoken_string_to_wks_sv("Date");
  672|      1|    MIME_FIELD_DISTRIBUTION              = hdrtoken_string_to_wks_sv("Distribution");
  673|      1|    MIME_FIELD_ETAG                      = hdrtoken_string_to_wks_sv("Etag");
  674|      1|    MIME_FIELD_EXPECT                    = hdrtoken_string_to_wks_sv("Expect");
  675|      1|    MIME_FIELD_EXPIRES                   = hdrtoken_string_to_wks_sv("Expires");
  676|      1|    MIME_FIELD_FOLLOWUP_TO               = hdrtoken_string_to_wks_sv("Followup-To");
  677|      1|    MIME_FIELD_FROM                      = hdrtoken_string_to_wks_sv("From");
  678|      1|    MIME_FIELD_HOST                      = hdrtoken_string_to_wks_sv("Host");
  679|      1|    MIME_FIELD_IF_MATCH                  = hdrtoken_string_to_wks_sv("If-Match");
  680|      1|    MIME_FIELD_IF_MODIFIED_SINCE         = hdrtoken_string_to_wks_sv("If-Modified-Since");
  681|      1|    MIME_FIELD_IF_NONE_MATCH             = hdrtoken_string_to_wks_sv("If-None-Match");
  682|      1|    MIME_FIELD_IF_RANGE                  = hdrtoken_string_to_wks_sv("If-Range");
  683|      1|    MIME_FIELD_IF_UNMODIFIED_SINCE       = hdrtoken_string_to_wks_sv("If-Unmodified-Since");
  684|      1|    MIME_FIELD_KEEP_ALIVE                = hdrtoken_string_to_wks_sv("Keep-Alive");
  685|      1|    MIME_FIELD_KEYWORDS                  = hdrtoken_string_to_wks_sv("Keywords");
  686|      1|    MIME_FIELD_LAST_MODIFIED             = hdrtoken_string_to_wks_sv("Last-Modified");
  687|      1|    MIME_FIELD_LINES                     = hdrtoken_string_to_wks_sv("Lines");
  688|      1|    MIME_FIELD_LOCATION                  = hdrtoken_string_to_wks_sv("Location");
  689|      1|    MIME_FIELD_MAX_FORWARDS              = hdrtoken_string_to_wks_sv("Max-Forwards");
  690|      1|    MIME_FIELD_MESSAGE_ID                = hdrtoken_string_to_wks_sv("Message-ID");
  691|      1|    MIME_FIELD_NEWSGROUPS                = hdrtoken_string_to_wks_sv("Newsgroups");
  692|      1|    MIME_FIELD_ORGANIZATION              = hdrtoken_string_to_wks_sv("Organization");
  693|      1|    MIME_FIELD_PATH                      = hdrtoken_string_to_wks_sv("Path");
  694|      1|    MIME_FIELD_PRAGMA                    = hdrtoken_string_to_wks_sv("Pragma");
  695|      1|    MIME_FIELD_PROXY_AUTHENTICATE        = hdrtoken_string_to_wks_sv("Proxy-Authenticate");
  696|      1|    MIME_FIELD_PROXY_AUTHORIZATION       = hdrtoken_string_to_wks_sv("Proxy-Authorization");
  697|      1|    MIME_FIELD_PROXY_CONNECTION          = hdrtoken_string_to_wks_sv("Proxy-Connection");
  698|      1|    MIME_FIELD_PUBLIC                    = hdrtoken_string_to_wks_sv("Public");
  699|      1|    MIME_FIELD_RANGE                     = hdrtoken_string_to_wks_sv("Range");
  700|      1|    MIME_FIELD_REFERENCES                = hdrtoken_string_to_wks_sv("References");
  701|      1|    MIME_FIELD_REFERER                   = hdrtoken_string_to_wks_sv("Referer");
  702|      1|    MIME_FIELD_REPLY_TO                  = hdrtoken_string_to_wks_sv("Reply-To");
  703|      1|    MIME_FIELD_RETRY_AFTER               = hdrtoken_string_to_wks_sv("Retry-After");
  704|      1|    MIME_FIELD_SENDER                    = hdrtoken_string_to_wks_sv("Sender");
  705|      1|    MIME_FIELD_SERVER                    = hdrtoken_string_to_wks_sv("Server");
  706|      1|    MIME_FIELD_SET_COOKIE                = hdrtoken_string_to_wks_sv("Set-Cookie");
  707|      1|    MIME_FIELD_STRICT_TRANSPORT_SECURITY = hdrtoken_string_to_wks_sv("Strict-Transport-Security");
  708|      1|    MIME_FIELD_SUBJECT                   = hdrtoken_string_to_wks_sv("Subject");
  709|      1|    MIME_FIELD_SUMMARY                   = hdrtoken_string_to_wks_sv("Summary");
  710|      1|    MIME_FIELD_TE                        = hdrtoken_string_to_wks_sv("TE");
  711|      1|    MIME_FIELD_TRANSFER_ENCODING         = hdrtoken_string_to_wks_sv("Transfer-Encoding");
  712|      1|    MIME_FIELD_UPGRADE                   = hdrtoken_string_to_wks_sv("Upgrade");
  713|      1|    MIME_FIELD_USER_AGENT                = hdrtoken_string_to_wks_sv("User-Agent");
  714|      1|    MIME_FIELD_VARY                      = hdrtoken_string_to_wks_sv("Vary");
  715|      1|    MIME_FIELD_VIA                       = hdrtoken_string_to_wks_sv("Via");
  716|      1|    MIME_FIELD_WARNING                   = hdrtoken_string_to_wks_sv("Warning");
  717|      1|    MIME_FIELD_WWW_AUTHENTICATE          = hdrtoken_string_to_wks_sv("Www-Authenticate");
  718|      1|    MIME_FIELD_XREF                      = hdrtoken_string_to_wks_sv("Xref");
  719|      1|    MIME_FIELD_ATS_INTERNAL              = hdrtoken_string_to_wks_sv("@Ats-Internal");
  720|      1|    MIME_FIELD_X_ID                      = hdrtoken_string_to_wks_sv("X-ID");
  721|      1|    MIME_FIELD_X_FORWARDED_FOR           = hdrtoken_string_to_wks_sv("X-Forwarded-For");
  722|      1|    MIME_FIELD_FORWARDED                 = hdrtoken_string_to_wks_sv("Forwarded");
  723|      1|    MIME_FIELD_SEC_WEBSOCKET_KEY         = hdrtoken_string_to_wks_sv("Sec-WebSocket-Key");
  724|      1|    MIME_FIELD_SEC_WEBSOCKET_VERSION     = hdrtoken_string_to_wks_sv("Sec-WebSocket-Version");
  725|      1|    MIME_FIELD_HTTP2_SETTINGS            = hdrtoken_string_to_wks_sv("HTTP2-Settings");
  726|      1|    MIME_FIELD_EARLY_DATA                = hdrtoken_string_to_wks_sv("Early-Data");
  727|       |
  728|      1|    MIME_WKSIDX_ACCEPT                    = hdrtoken_wks_to_index(MIME_FIELD_ACCEPT.c_str());
  729|      1|    MIME_WKSIDX_ACCEPT_CHARSET            = hdrtoken_wks_to_index(MIME_FIELD_ACCEPT_CHARSET.c_str());
  730|      1|    MIME_WKSIDX_ACCEPT_ENCODING           = hdrtoken_wks_to_index(MIME_FIELD_ACCEPT_ENCODING.c_str());
  731|      1|    MIME_WKSIDX_ACCEPT_LANGUAGE           = hdrtoken_wks_to_index(MIME_FIELD_ACCEPT_LANGUAGE.c_str());
  732|      1|    MIME_WKSIDX_ACCEPT_RANGES             = hdrtoken_wks_to_index(MIME_FIELD_ACCEPT_RANGES.c_str());
  733|      1|    MIME_WKSIDX_AGE                       = hdrtoken_wks_to_index(MIME_FIELD_AGE.c_str());
  734|      1|    MIME_WKSIDX_ALLOW                     = hdrtoken_wks_to_index(MIME_FIELD_ALLOW.c_str());
  735|      1|    MIME_WKSIDX_APPROVED                  = hdrtoken_wks_to_index(MIME_FIELD_APPROVED.c_str());
  736|      1|    MIME_WKSIDX_AUTHORIZATION             = hdrtoken_wks_to_index(MIME_FIELD_AUTHORIZATION.c_str());
  737|      1|    MIME_WKSIDX_BYTES                     = hdrtoken_wks_to_index(MIME_FIELD_BYTES.c_str());
  738|      1|    MIME_WKSIDX_CACHE_CONTROL             = hdrtoken_wks_to_index(MIME_FIELD_CACHE_CONTROL.c_str());
  739|      1|    MIME_WKSIDX_CLIENT_IP                 = hdrtoken_wks_to_index(MIME_FIELD_CLIENT_IP.c_str());
  740|      1|    MIME_WKSIDX_CONNECTION                = hdrtoken_wks_to_index(MIME_FIELD_CONNECTION.c_str());
  741|      1|    MIME_WKSIDX_CONTENT_BASE              = hdrtoken_wks_to_index(MIME_FIELD_CONTENT_BASE.c_str());
  742|      1|    MIME_WKSIDX_CONTENT_ENCODING          = hdrtoken_wks_to_index(MIME_FIELD_CONTENT_ENCODING.c_str());
  743|      1|    MIME_WKSIDX_CONTENT_LANGUAGE          = hdrtoken_wks_to_index(MIME_FIELD_CONTENT_LANGUAGE.c_str());
  744|      1|    MIME_WKSIDX_CONTENT_LENGTH            = hdrtoken_wks_to_index(MIME_FIELD_CONTENT_LENGTH.c_str());
  745|      1|    MIME_WKSIDX_CONTENT_LOCATION          = hdrtoken_wks_to_index(MIME_FIELD_CONTENT_LOCATION.c_str());
  746|      1|    MIME_WKSIDX_CONTENT_MD5               = hdrtoken_wks_to_index(MIME_FIELD_CONTENT_MD5.c_str());
  747|      1|    MIME_WKSIDX_CONTENT_RANGE             = hdrtoken_wks_to_index(MIME_FIELD_CONTENT_RANGE.c_str());
  748|      1|    MIME_WKSIDX_CONTENT_TYPE              = hdrtoken_wks_to_index(MIME_FIELD_CONTENT_TYPE.c_str());
  749|      1|    MIME_WKSIDX_CONTROL                   = hdrtoken_wks_to_index(MIME_FIELD_CONTROL.c_str());
  750|      1|    MIME_WKSIDX_COOKIE                    = hdrtoken_wks_to_index(MIME_FIELD_COOKIE.c_str());
  751|      1|    MIME_WKSIDX_DATE                      = hdrtoken_wks_to_index(MIME_FIELD_DATE.c_str());
  752|      1|    MIME_WKSIDX_DISTRIBUTION              = hdrtoken_wks_to_index(MIME_FIELD_DISTRIBUTION.c_str());
  753|      1|    MIME_WKSIDX_ETAG                      = hdrtoken_wks_to_index(MIME_FIELD_ETAG.c_str());
  754|      1|    MIME_WKSIDX_EXPECT                    = hdrtoken_wks_to_index(MIME_FIELD_EXPECT.c_str());
  755|      1|    MIME_WKSIDX_EXPIRES                   = hdrtoken_wks_to_index(MIME_FIELD_EXPIRES.c_str());
  756|      1|    MIME_WKSIDX_FOLLOWUP_TO               = hdrtoken_wks_to_index(MIME_FIELD_FOLLOWUP_TO.c_str());
  757|      1|    MIME_WKSIDX_FROM                      = hdrtoken_wks_to_index(MIME_FIELD_FROM.c_str());
  758|      1|    MIME_WKSIDX_HOST                      = hdrtoken_wks_to_index(MIME_FIELD_HOST.c_str());
  759|      1|    MIME_WKSIDX_IF_MATCH                  = hdrtoken_wks_to_index(MIME_FIELD_IF_MATCH.c_str());
  760|      1|    MIME_WKSIDX_IF_MODIFIED_SINCE         = hdrtoken_wks_to_index(MIME_FIELD_IF_MODIFIED_SINCE.c_str());
  761|      1|    MIME_WKSIDX_IF_NONE_MATCH             = hdrtoken_wks_to_index(MIME_FIELD_IF_NONE_MATCH.c_str());
  762|      1|    MIME_WKSIDX_IF_RANGE                  = hdrtoken_wks_to_index(MIME_FIELD_IF_RANGE.c_str());
  763|      1|    MIME_WKSIDX_IF_UNMODIFIED_SINCE       = hdrtoken_wks_to_index(MIME_FIELD_IF_UNMODIFIED_SINCE.c_str());
  764|      1|    MIME_WKSIDX_KEEP_ALIVE                = hdrtoken_wks_to_index(MIME_FIELD_KEEP_ALIVE.c_str());
  765|      1|    MIME_WKSIDX_KEYWORDS                  = hdrtoken_wks_to_index(MIME_FIELD_KEYWORDS.c_str());
  766|      1|    MIME_WKSIDX_LAST_MODIFIED             = hdrtoken_wks_to_index(MIME_FIELD_LAST_MODIFIED.c_str());
  767|      1|    MIME_WKSIDX_LINES                     = hdrtoken_wks_to_index(MIME_FIELD_LINES.c_str());
  768|      1|    MIME_WKSIDX_LOCATION                  = hdrtoken_wks_to_index(MIME_FIELD_LOCATION.c_str());
  769|      1|    MIME_WKSIDX_MAX_FORWARDS              = hdrtoken_wks_to_index(MIME_FIELD_MAX_FORWARDS.c_str());
  770|      1|    MIME_WKSIDX_MESSAGE_ID                = hdrtoken_wks_to_index(MIME_FIELD_MESSAGE_ID.c_str());
  771|      1|    MIME_WKSIDX_NEWSGROUPS                = hdrtoken_wks_to_index(MIME_FIELD_NEWSGROUPS.c_str());
  772|      1|    MIME_WKSIDX_ORGANIZATION              = hdrtoken_wks_to_index(MIME_FIELD_ORGANIZATION.c_str());
  773|      1|    MIME_WKSIDX_PATH                      = hdrtoken_wks_to_index(MIME_FIELD_PATH.c_str());
  774|      1|    MIME_WKSIDX_PRAGMA                    = hdrtoken_wks_to_index(MIME_FIELD_PRAGMA.c_str());
  775|      1|    MIME_WKSIDX_PROXY_AUTHENTICATE        = hdrtoken_wks_to_index(MIME_FIELD_PROXY_AUTHENTICATE.c_str());
  776|      1|    MIME_WKSIDX_PROXY_AUTHORIZATION       = hdrtoken_wks_to_index(MIME_FIELD_PROXY_AUTHORIZATION.c_str());
  777|      1|    MIME_WKSIDX_PROXY_CONNECTION          = hdrtoken_wks_to_index(MIME_FIELD_PROXY_CONNECTION.c_str());
  778|      1|    MIME_WKSIDX_PUBLIC                    = hdrtoken_wks_to_index(MIME_FIELD_PUBLIC.c_str());
  779|      1|    MIME_WKSIDX_RANGE                     = hdrtoken_wks_to_index(MIME_FIELD_RANGE.c_str());
  780|      1|    MIME_WKSIDX_REFERENCES                = hdrtoken_wks_to_index(MIME_FIELD_REFERENCES.c_str());
  781|      1|    MIME_WKSIDX_REFERER                   = hdrtoken_wks_to_index(MIME_FIELD_REFERER.c_str());
  782|      1|    MIME_WKSIDX_REPLY_TO                  = hdrtoken_wks_to_index(MIME_FIELD_REPLY_TO.c_str());
  783|      1|    MIME_WKSIDX_RETRY_AFTER               = hdrtoken_wks_to_index(MIME_FIELD_RETRY_AFTER.c_str());
  784|      1|    MIME_WKSIDX_SENDER                    = hdrtoken_wks_to_index(MIME_FIELD_SENDER.c_str());
  785|      1|    MIME_WKSIDX_SERVER                    = hdrtoken_wks_to_index(MIME_FIELD_SERVER.c_str());
  786|      1|    MIME_WKSIDX_SET_COOKIE                = hdrtoken_wks_to_index(MIME_FIELD_SET_COOKIE.c_str());
  787|      1|    MIME_WKSIDX_STRICT_TRANSPORT_SECURITY = hdrtoken_wks_to_index(MIME_FIELD_STRICT_TRANSPORT_SECURITY.c_str());
  788|      1|    MIME_WKSIDX_SUBJECT                   = hdrtoken_wks_to_index(MIME_FIELD_SUBJECT.c_str());
  789|      1|    MIME_WKSIDX_SUMMARY                   = hdrtoken_wks_to_index(MIME_FIELD_SUMMARY.c_str());
  790|      1|    MIME_WKSIDX_TE                        = hdrtoken_wks_to_index(MIME_FIELD_TE.c_str());
  791|      1|    MIME_WKSIDX_TRANSFER_ENCODING         = hdrtoken_wks_to_index(MIME_FIELD_TRANSFER_ENCODING.c_str());
  792|      1|    MIME_WKSIDX_UPGRADE                   = hdrtoken_wks_to_index(MIME_FIELD_UPGRADE.c_str());
  793|      1|    MIME_WKSIDX_USER_AGENT                = hdrtoken_wks_to_index(MIME_FIELD_USER_AGENT.c_str());
  794|      1|    MIME_WKSIDX_VARY                      = hdrtoken_wks_to_index(MIME_FIELD_VARY.c_str());
  795|      1|    MIME_WKSIDX_VIA                       = hdrtoken_wks_to_index(MIME_FIELD_VIA.c_str());
  796|      1|    MIME_WKSIDX_WARNING                   = hdrtoken_wks_to_index(MIME_FIELD_WARNING.c_str());
  797|      1|    MIME_WKSIDX_WWW_AUTHENTICATE          = hdrtoken_wks_to_index(MIME_FIELD_WWW_AUTHENTICATE.c_str());
  798|      1|    MIME_WKSIDX_XREF                      = hdrtoken_wks_to_index(MIME_FIELD_XREF.c_str());
  799|      1|    MIME_WKSIDX_X_ID                      = hdrtoken_wks_to_index(MIME_FIELD_X_ID.c_str());
  800|      1|    MIME_WKSIDX_X_FORWARDED_FOR           = hdrtoken_wks_to_index(MIME_FIELD_X_FORWARDED_FOR.c_str());
  801|      1|    MIME_WKSIDX_FORWARDED                 = hdrtoken_wks_to_index(MIME_FIELD_FORWARDED.c_str());
  802|      1|    MIME_WKSIDX_SEC_WEBSOCKET_KEY         = hdrtoken_wks_to_index(MIME_FIELD_SEC_WEBSOCKET_KEY.c_str());
  803|      1|    MIME_WKSIDX_SEC_WEBSOCKET_VERSION     = hdrtoken_wks_to_index(MIME_FIELD_SEC_WEBSOCKET_VERSION.c_str());
  804|      1|    MIME_WKSIDX_HTTP2_SETTINGS            = hdrtoken_wks_to_index(MIME_FIELD_HTTP2_SETTINGS.c_str());
  805|      1|    MIME_WKSIDX_EARLY_DATA                = hdrtoken_wks_to_index(MIME_FIELD_EARLY_DATA.c_str());
  806|       |
  807|      1|    MIME_VALUE_BYTES                = hdrtoken_string_to_wks_sv("bytes");
  808|      1|    MIME_VALUE_CHUNKED              = hdrtoken_string_to_wks_sv("chunked");
  809|      1|    MIME_VALUE_CLOSE                = hdrtoken_string_to_wks_sv("close");
  810|      1|    MIME_VALUE_COMPRESS             = hdrtoken_string_to_wks_sv("compress");
  811|      1|    MIME_VALUE_DEFLATE              = hdrtoken_string_to_wks_sv("deflate");
  812|      1|    MIME_VALUE_GZIP                 = hdrtoken_string_to_wks_sv("gzip");
  813|      1|    MIME_VALUE_BROTLI               = hdrtoken_string_to_wks_sv("br");
  814|      1|    MIME_VALUE_ZSTD                 = hdrtoken_string_to_wks_sv("zstd");
  815|      1|    MIME_VALUE_IDENTITY             = hdrtoken_string_to_wks_sv("identity");
  816|      1|    MIME_VALUE_KEEP_ALIVE           = hdrtoken_string_to_wks_sv("keep-alive");
  817|      1|    MIME_VALUE_MAX_AGE              = hdrtoken_string_to_wks_sv("max-age");
  818|      1|    MIME_VALUE_MAX_STALE            = hdrtoken_string_to_wks_sv("max-stale");
  819|      1|    MIME_VALUE_MIN_FRESH            = hdrtoken_string_to_wks_sv("min-fresh");
  820|      1|    MIME_VALUE_MUST_REVALIDATE      = hdrtoken_string_to_wks_sv("must-revalidate");
  821|      1|    MIME_VALUE_NONE                 = hdrtoken_string_to_wks_sv("none");
  822|      1|    MIME_VALUE_NO_CACHE             = hdrtoken_string_to_wks_sv("no-cache");
  823|      1|    MIME_VALUE_NO_STORE             = hdrtoken_string_to_wks_sv("no-store");
  824|      1|    MIME_VALUE_NO_TRANSFORM         = hdrtoken_string_to_wks_sv("no-transform");
  825|      1|    MIME_VALUE_ONLY_IF_CACHED       = hdrtoken_string_to_wks_sv("only-if-cached");
  826|      1|    MIME_VALUE_PRIVATE              = hdrtoken_string_to_wks_sv("private");
  827|      1|    MIME_VALUE_PROXY_REVALIDATE     = hdrtoken_string_to_wks_sv("proxy-revalidate");
  828|      1|    MIME_VALUE_PUBLIC               = hdrtoken_string_to_wks_sv("public");
  829|      1|    MIME_VALUE_S_MAXAGE             = hdrtoken_string_to_wks_sv("s-maxage");
  830|      1|    MIME_VALUE_NEED_REVALIDATE_ONCE = hdrtoken_string_to_wks_sv("need-revalidate-once");
  831|      1|    MIME_VALUE_WEBSOCKET            = hdrtoken_string_to_wks_sv("websocket");
  832|      1|    MIME_VALUE_H2C                  = hdrtoken_string_to_wks_sv(MIME_UPGRADE_H2C_TOKEN);
  ------------------
  |  |  387|      1|#define MIME_UPGRADE_H2C_TOKEN "h2c"
  ------------------
  833|       |
  834|      1|    mime_init_date_format_table();
  835|      1|    mime_init_cache_control_cooking_masks();
  836|      1|  }
  837|      1|}
_Z37mime_init_cache_control_cooking_masksv:
  841|      1|{
  842|      1|  static struct {
  843|      1|    const char *name;
  844|      1|    uint32_t    mask;
  845|      1|  } cc_mask_table[] = {
  846|      1|    {"max-age",              MIME_COOKED_MASK_CC_MAX_AGE             },
  847|      1|    {"no-cache",             MIME_COOKED_MASK_CC_NO_CACHE            },
  848|      1|    {"no-store",             MIME_COOKED_MASK_CC_NO_STORE            },
  849|      1|    {"no-transform",         MIME_COOKED_MASK_CC_NO_TRANSFORM        },
  850|      1|    {"max-stale",            MIME_COOKED_MASK_CC_MAX_STALE           },
  851|      1|    {"min-fresh",            MIME_COOKED_MASK_CC_MIN_FRESH           },
  852|      1|    {"only-if-cached",       MIME_COOKED_MASK_CC_ONLY_IF_CACHED      },
  853|      1|    {"public",               MIME_COOKED_MASK_CC_PUBLIC              },
  854|      1|    {"private",              MIME_COOKED_MASK_CC_PRIVATE             },
  855|      1|    {"must-revalidate",      MIME_COOKED_MASK_CC_MUST_REVALIDATE     },
  856|      1|    {"proxy-revalidate",     MIME_COOKED_MASK_CC_PROXY_REVALIDATE    },
  857|      1|    {"s-maxage",             MIME_COOKED_MASK_CC_S_MAXAGE            },
  858|      1|    {"need-revalidate-once", MIME_COOKED_MASK_CC_NEED_REVALIDATE_ONCE},
  859|      1|    {nullptr,                0                                       }
  860|      1|  };
  861|       |
  862|     14|  for (int i = 0; cc_mask_table[i].name != nullptr; i++) {
  ------------------
  |  Branch (862:19): [True: 13, False: 1]
  ------------------
  863|     13|    const char         *wks                      = hdrtoken_string_to_wks(cc_mask_table[i].name);
  864|     13|    HdrTokenHeapPrefix *p                        = hdrtoken_wks_to_prefix(wks);
  865|     13|    p->wks_type_specific.u.cache_control.cc_mask = cc_mask_table[i].mask;
  866|     13|  }
  867|      1|}
_Z27mime_init_date_format_tablev:
  871|      1|{
  872|       |  ////////////////////////////////////////////////////////////////
  873|       |  // to speed up the days_since_epoch to m/d/y conversion, we   //
  874|       |  // use a pre-computed lookup table to support the common case //
  875|       |  // of dates that are +/- one year from today --- this code    //
  876|       |  // builds the lookup table during the first call.             //
  877|       |  ////////////////////////////////////////////////////////////////
  878|       |
  879|      1|  time_t now_secs;
  880|      1|  time_t i, now_days, first_days, last_days, num_days;
  881|      1|  int    m = 0, d = 0, y = 0;
  882|       |
  883|      1|  time(&now_secs);
  884|      1|  now_days   = static_cast<time_t>(now_secs / (60 * 60 * 24));
  885|      1|  first_days = now_days - 366;
  886|      1|  last_days  = now_days + 366;
  887|      1|  num_days   = last_days - first_days + 1;
  888|       |
  889|      1|  _days_to_mdy_fast_lookup_table           = static_cast<MDY *>(ats_malloc(num_days * sizeof(MDY)));
  890|      1|  _days_to_mdy_fast_lookup_table_first_day = first_days;
  891|      1|  _days_to_mdy_fast_lookup_table_last_day  = last_days;
  892|       |
  893|    734|  for (i = 0; i < num_days; i++) {
  ------------------
  |  Branch (893:15): [True: 733, False: 1]
  ------------------
  894|    733|    mime_days_since_epoch_to_mdy_slowcase(first_days + i, &m, &d, &y);
  895|    733|    _days_to_mdy_fast_lookup_table[i].m = m;
  896|    733|    _days_to_mdy_fast_lookup_table[i].d = d;
  897|    733|    _days_to_mdy_fast_lookup_table[i].y = y;
  898|    733|  }
  899|      1|}
_Z15mime_hdr_createP7HdrHeap:
  903|  18.7k|{
  904|  18.7k|  MIMEHdrImpl *mh;
  905|       |
  906|  18.7k|  mh = (MIMEHdrImpl *)heap->allocate_obj(sizeof(MIMEHdrImpl), HdrHeapObjType::MIME_HEADER);
  907|  18.7k|  mime_hdr_init(mh);
  908|  18.7k|  return mh;
  909|  18.7k|}
_Z26_mime_hdr_field_block_initP18MIMEFieldBlockImpl:
  913|  19.6k|{
  914|  19.6k|  fblock->m_freetop = 0;
  915|  19.6k|  fblock->m_next    = nullptr;
  916|       |
  917|       |#ifdef BLOCK_INIT_PARANOIA
  918|       |  int i;
  919|       |
  920|       |  // FIX: Could eliminate this initialization loop if we assumed
  921|       |  //      every slot above the freetop of the block was garbage;
  922|       |  //      but to be safe, and help debugging, for now we are eating
  923|       |  //      the cost of initializing all slots in a block.
  924|       |
  925|       |  for (i = 0; i < MIME_FIELD_BLOCK_SLOTS; i++) {
  926|       |    MIMEField *field   = &(fblock->m_field_slots[i]);
  927|       |    field->m_readiness = MIME_FIELD_SLOT_READINESS_EMPTY;
  928|       |  }
  929|       |#endif
  930|  19.6k|}
_Z26mime_hdr_cooked_stuff_initP11MIMEHdrImplP9MIMEField:
  934|  20.1k|{
  935|       |  // to be safe, reinitialize unless you know this call is for other cooked field
  936|  20.1k|  if ((changing_field_or_null == nullptr) || (changing_field_or_null->m_wks_idx != MIME_WKSIDX_PRAGMA)) {
  ------------------
  |  Branch (936:7): [True: 18.7k, False: 1.45k]
  |  Branch (936:46): [True: 394, False: 1.06k]
  ------------------
  937|  19.1k|    mh->m_cooked_stuff.m_cache_control.m_mask           = 0;
  938|  19.1k|    mh->m_cooked_stuff.m_cache_control.m_secs_max_age   = 0;
  939|  19.1k|    mh->m_cooked_stuff.m_cache_control.m_secs_s_maxage  = 0;
  940|  19.1k|    mh->m_cooked_stuff.m_cache_control.m_secs_max_stale = 0;
  941|  19.1k|    mh->m_cooked_stuff.m_cache_control.m_secs_min_fresh = 0;
  942|  19.1k|  }
  943|  20.1k|  if ((changing_field_or_null == nullptr) || (changing_field_or_null->m_wks_idx != MIME_WKSIDX_CACHE_CONTROL)) {
  ------------------
  |  Branch (943:7): [True: 18.7k, False: 1.45k]
  |  Branch (943:46): [True: 1.06k, False: 394]
  ------------------
  944|  19.7k|    mh->m_cooked_stuff.m_pragma.m_no_cache = false;
  945|  19.7k|  }
  946|  20.1k|}
_Z13mime_hdr_initP11MIMEHdrImpl:
  950|  18.7k|{
  951|  18.7k|  mime_hdr_init_accelerators_and_presence_bits(mh);
  952|       |
  953|  18.7k|  mime_hdr_cooked_stuff_init(mh, nullptr);
  954|       |
  955|       |  // first header is inline: fake an object header for uniformity
  956|  18.7k|  obj_init_header((HdrHeapObjImpl *)&(mh->m_first_fblock), HdrHeapObjType::FIELD_BLOCK, sizeof(MIMEFieldBlockImpl), 0);
  957|       |
  958|  18.7k|  _mime_hdr_field_block_init(&(mh->m_first_fblock));
  959|  18.7k|  mh->m_fblock_list_tail = &(mh->m_first_fblock);
  960|       |
  961|  18.7k|  MIME_HDR_SANITY_CHECK(mh);
  ------------------
  |  |   75|  18.7k|#define MIME_HDR_SANITY_CHECK (void)
  ------------------
  962|  18.7k|}
_Z25_mime_field_block_destroyP7HdrHeapP18MIMEFieldBlockImpl:
  976|     24|{
  977|     24|  heap->deallocate_obj(fblock);
  978|     24|}
_Z34_mime_hdr_field_list_search_by_wksP11MIMEHdrImpli:
 1133|  1.72k|{
 1134|  1.72k|  MIMEFieldBlockImpl *fblock;
 1135|  1.72k|  MIMEField          *field, *too_far_field;
 1136|       |
 1137|  1.72k|  ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
  ------------------
  |  |   45|  1.72k|#define ink_assert(EX) (void)(EX)
  ------------------
 1138|       |
 1139|  2.98k|  for (fblock = &(mh->m_first_fblock); fblock != nullptr; fblock = fblock->m_next) {
  ------------------
  |  Branch (1139:40): [True: 2.86k, False: 122]
  ------------------
 1140|  2.86k|    field = &(fblock->m_field_slots[0]);
 1141|       |
 1142|  2.86k|    too_far_field = &(fblock->m_field_slots[fblock->m_freetop]);
 1143|  28.6k|    while (field < too_far_field) {
  ------------------
  |  Branch (1143:12): [True: 27.3k, False: 1.25k]
  ------------------
 1144|  27.3k|      if (field->is_live() && (field->m_wks_idx == wks_idx)) {
  ------------------
  |  Branch (1144:11): [True: 27.2k, False: 122]
  |  Branch (1144:31): [True: 1.60k, False: 25.6k]
  ------------------
 1145|  1.60k|        return field;
 1146|  1.60k|      }
 1147|  25.7k|      ++field;
 1148|  25.7k|    }
 1149|  2.86k|  }
 1150|       |
 1151|    122|  return nullptr;
 1152|  1.72k|}
_Z37_mime_hdr_field_list_search_by_stringP11MIMEHdrImplNSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
 1156|  15.7k|{
 1157|  15.7k|  MIMEFieldBlockImpl *fblock;
 1158|  15.7k|  MIMEField          *field, *too_far_field;
 1159|       |
 1160|  15.7k|  ink_assert(mh);
  ------------------
  |  |   45|  15.7k|#define ink_assert(EX) (void)(EX)
  ------------------
 1161|  26.8k|  for (fblock = &(mh->m_first_fblock); fblock != nullptr; fblock = fblock->m_next) {
  ------------------
  |  Branch (1161:40): [True: 24.0k, False: 2.84k]
  ------------------
 1162|  24.0k|    field = &(fblock->m_field_slots[0]);
 1163|       |
 1164|  24.0k|    too_far_field = &(fblock->m_field_slots[fblock->m_freetop]);
 1165|   244k|    while (field < too_far_field) {
  ------------------
  |  Branch (1165:12): [True: 233k, False: 11.0k]
  ------------------
 1166|   233k|      if (field->is_live() &&
  ------------------
  |  Branch (1166:11): [True: 230k, False: 2.84k]
  ------------------
 1167|   230k|          ts::iequals(std::string_view{field->m_ptr_name, static_cast<std::string_view::size_type>(field->m_len_name)},
  ------------------
  |  Branch (1167:11): [True: 12.9k, False: 217k]
  ------------------
 1168|   230k|                      field_name)) {
 1169|  12.9k|        return field;
 1170|  12.9k|      }
 1171|   220k|      ++field;
 1172|   220k|    }
 1173|  24.0k|  }
 1174|       |
 1175|  2.84k|  return nullptr;
 1176|  15.7k|}
_Z38_mime_hdr_field_list_search_by_slotnumP11MIMEHdrImpli:
 1180|  3.18k|{
 1181|  3.18k|  unsigned int        block_num, block_index;
 1182|  3.18k|  MIMEFieldBlockImpl *fblock;
 1183|       |
 1184|  3.18k|  if (slotnum < MIME_FIELD_BLOCK_SLOTS) {
  ------------------
  |  |   86|  3.18k|#define MIME_FIELD_BLOCK_SLOTS 16
  ------------------
  |  Branch (1184:7): [True: 3.18k, False: 0]
  ------------------
 1185|  3.18k|    fblock      = &(mh->m_first_fblock);
 1186|  3.18k|    block_index = slotnum;
 1187|  3.18k|    if (block_index >= fblock->m_freetop) {
  ------------------
  |  Branch (1187:9): [True: 0, False: 3.18k]
  ------------------
 1188|      0|      return nullptr;
 1189|  3.18k|    } else {
 1190|  3.18k|      return &(fblock->m_field_slots[block_index]);
 1191|  3.18k|    }
 1192|  3.18k|  } else {
 1193|      0|    block_num   = slotnum / MIME_FIELD_BLOCK_SLOTS;
  ------------------
  |  |   86|      0|#define MIME_FIELD_BLOCK_SLOTS 16
  ------------------
 1194|      0|    block_index = slotnum % MIME_FIELD_BLOCK_SLOTS;
  ------------------
  |  |   86|      0|#define MIME_FIELD_BLOCK_SLOTS 16
  ------------------
 1195|       |
 1196|      0|    fblock = &(mh->m_first_fblock);
 1197|      0|    while (block_num-- && fblock) {
  ------------------
  |  Branch (1197:12): [True: 0, False: 0]
  |  Branch (1197:27): [True: 0, False: 0]
  ------------------
 1198|      0|      fblock = fblock->m_next;
 1199|      0|    }
 1200|      0|    if ((fblock == nullptr) || (block_index >= fblock->m_freetop)) {
  ------------------
  |  Branch (1200:9): [True: 0, False: 0]
  |  Branch (1200:32): [True: 0, False: 0]
  ------------------
 1201|      0|      return nullptr;
 1202|      0|    } else {
 1203|      0|      return &(fblock->m_field_slots[block_index]);
 1204|      0|    }
 1205|      0|  }
 1206|  3.18k|}
_Z19mime_hdr_field_findP11MIMEHdrImplNSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
 1210|  31.1k|{
 1211|  31.1k|  HdrTokenHeapPrefix *token_info;
 1212|  31.1k|  const bool          is_wks = hdrtoken_is_wks(field_name.data());
 1213|       |
 1214|  31.1k|  ink_assert(!field_name.empty());
  ------------------
  |  |   45|  31.1k|#define ink_assert(EX) (void)(EX)
  ------------------
 1215|       |
 1216|       |  ////////////////////////////////////////////
 1217|       |  // do presence check and slot accelerator //
 1218|       |  ////////////////////////////////////////////
 1219|       |
 1220|       |#if TRACK_FIELD_FIND_CALLS
 1221|       |  Dbg(dbg_ctl_http, "mime_hdr_field_find(hdr 0x%X, field %.*s): is_wks = %d", mh, static_cast<int>(field_name.length()),
 1222|       |      field_name.data(), is_wks);
 1223|       |#endif
 1224|       |
 1225|  31.1k|  if (is_wks) {
  ------------------
  |  Branch (1225:7): [True: 15.3k, False: 15.7k]
  ------------------
 1226|  15.3k|    token_info = hdrtoken_wks_to_prefix(field_name.data());
 1227|  15.3k|    if ((token_info->wks_info.mask) && ((mh->m_presence_bits & token_info->wks_info.mask) == 0)) {
  ------------------
  |  Branch (1227:9): [True: 14.8k, False: 434]
  |  Branch (1227:40): [True: 10.4k, False: 4.48k]
  ------------------
 1228|       |#if TRACK_FIELD_FIND_CALLS
 1229|       |      Dbg(dbg_ctl_http, "mime_hdr_field_find(hdr 0x%X, field %.*s): MISS (due to presence bits)", mh, field_name_len,
 1230|       |          field_name_str);
 1231|       |#endif
 1232|  10.4k|      return nullptr;
 1233|  10.4k|    }
 1234|       |
 1235|  4.91k|    int32_t slot_id = token_info->wks_info.slotid;
 1236|       |
 1237|  4.91k|    if (slot_id != MIME_SLOTID_NONE) {
  ------------------
  |  |  295|  4.91k|#define MIME_SLOTID_NONE -1
  ------------------
  |  Branch (1237:9): [True: 4.08k, False: 834]
  ------------------
 1238|  4.08k|      uint32_t slotnum = mime_hdr_get_accelerator_slotnum(mh, slot_id);
 1239|       |
 1240|  4.08k|      if (slotnum != MIME_FIELD_SLOTNUM_UNKNOWN) {
  ------------------
  |  |   91|  4.08k|#define MIME_FIELD_SLOTNUM_UNKNOWN MIME_FIELD_SLOTNUM_MAX
  |  |  ------------------
  |  |  |  |   90|  4.08k|#define MIME_FIELD_SLOTNUM_MAX     (MIME_FIELD_SLOTNUM_MASK - 1)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|  4.08k|#define MIME_FIELD_SLOTNUM_MASK    ((1 << MIME_FIELD_SLOTNUM_BITS) - 1)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   88|  4.08k|#define MIME_FIELD_SLOTNUM_BITS    4
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (1240:11): [True: 3.18k, False: 895]
  ------------------
 1241|  3.18k|        MIMEField *f = _mime_hdr_field_list_search_by_slotnum(mh, slotnum);
 1242|  3.18k|        ink_assert((f == nullptr) || f->is_live());
  ------------------
  |  |   45|  6.37k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 3.18k]
  |  |  |  Branch (45:31): [True: 3.18k, False: 0]
  |  |  ------------------
  ------------------
 1243|       |#if TRACK_FIELD_FIND_CALLS
 1244|       |        Dbg(dbg_ctl_http, "mime_hdr_field_find(hdr 0x%X, field %.*s): %s (due to slot accelerators)", mh,
 1245|       |            static_cast<int>(field_name.length()), field_name.data(), (f ? "HIT" : "MISS"));
 1246|       |#endif
 1247|  3.18k|        return f;
 1248|  3.18k|      } else {
 1249|       |#if TRACK_FIELD_FIND_CALLS
 1250|       |        Dbg(dbg_ctl_http, "mime_hdr_field_find(hdr 0x%X, field %.*s): UNKNOWN (slot too big)", mh,
 1251|       |            static_cast<int>(field_name.length()), field_name.data());
 1252|       |#endif
 1253|    895|      }
 1254|  4.08k|    }
 1255|       |
 1256|       |    ///////////////////////////////////////////////////////////////////////////
 1257|       |    // search by well-known string index or by case-insensitive string match //
 1258|       |    ///////////////////////////////////////////////////////////////////////////
 1259|       |
 1260|  1.72k|    MIMEField *f = _mime_hdr_field_list_search_by_wks(mh, token_info->wks_idx);
 1261|  1.72k|    ink_assert((f == nullptr) || f->is_live());
  ------------------
  |  |   45|  3.33k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 122, False: 1.60k]
  |  |  |  Branch (45:31): [True: 1.60k, False: 0]
  |  |  ------------------
  ------------------
 1262|       |#if TRACK_FIELD_FIND_CALLS
 1263|       |    Dbg(dbg_ctl_http, "mime_hdr_field_find(hdr 0x%X, field %.*s): %s (due to WKS list walk)", mh,
 1264|       |        static_cast<int>(field_name.length()), field_name.data(), (f ? "HIT" : "MISS"));
 1265|       |#endif
 1266|  1.72k|    return f;
 1267|  15.7k|  } else {
 1268|  15.7k|    MIMEField *f = _mime_hdr_field_list_search_by_string(mh, field_name);
 1269|       |
 1270|  15.7k|    ink_assert((f == nullptr) || f->is_live());
  ------------------
  |  |   45|  28.7k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 2.84k, False: 12.9k]
  |  |  |  Branch (45:31): [True: 12.9k, False: 0]
  |  |  ------------------
  ------------------
 1271|       |#if TRACK_FIELD_FIND_CALLS
 1272|       |    Dbg(dbg_ctl_http, "mime_hdr_field_find(hdr 0x%X, field %.*s): %s (due to strcmp list walk)", mh,
 1273|       |        static_cast<int>(field_name.length()), field_name.data(), (f ? "HIT" : "MISS"));
 1274|       |#endif
 1275|  15.7k|    return f;
 1276|  15.7k|  }
 1277|  31.1k|}
_Z15mime_field_initP9MIMEField:
 1334|  51.1k|{
 1335|  51.1k|  memset(field, 0, sizeof(MIMEField));
 1336|  51.1k|  field->m_readiness = MIME_FIELD_SLOT_READINESS_DETACHED;
  ------------------
  |  |   79|  51.1k|#define MIME_FIELD_SLOT_READINESS_DETACHED 1
  ------------------
 1337|  51.1k|  field->m_wks_idx   = -1;
 1338|  51.1k|}
_Z17mime_field_createP7HdrHeapP11MIMEHdrImpl:
 1342|  51.1k|{
 1343|  51.1k|  MIMEField          *field;
 1344|  51.1k|  MIMEFieldBlockImpl *tail_fblock, *new_fblock;
 1345|       |
 1346|  51.1k|  tail_fblock = mh->m_fblock_list_tail;
 1347|  51.1k|  if (tail_fblock->m_freetop >= MIME_FIELD_BLOCK_SLOTS) {
  ------------------
  |  |   86|  51.1k|#define MIME_FIELD_BLOCK_SLOTS 16
  ------------------
  |  Branch (1347:7): [True: 969, False: 50.1k]
  ------------------
 1348|    969|    new_fblock = (MIMEFieldBlockImpl *)heap->allocate_obj(sizeof(MIMEFieldBlockImpl), HdrHeapObjType::FIELD_BLOCK);
 1349|    969|    _mime_hdr_field_block_init(new_fblock);
 1350|    969|    tail_fblock->m_next    = new_fblock;
 1351|    969|    tail_fblock            = new_fblock;
 1352|    969|    mh->m_fblock_list_tail = new_fblock;
 1353|    969|  }
 1354|       |
 1355|  51.1k|  field = &(tail_fblock->m_field_slots[tail_fblock->m_freetop]);
 1356|  51.1k|  ++tail_fblock->m_freetop;
 1357|       |
 1358|  51.1k|  mime_field_init(field);
 1359|       |
 1360|  51.1k|  return field;
 1361|  51.1k|}
_Z23mime_field_create_namedP7HdrHeapP11MIMEHdrImplNSt3__117basic_string_viewIcNS3_11char_traitsIcEEEE:
 1365|  31.2k|{
 1366|  31.2k|  MIMEField *field              = mime_field_create(heap, mh);
 1367|  31.2k|  int        field_name_wks_idx = hdrtoken_tokenize(name.data(), static_cast<int>(name.length()));
 1368|  31.2k|  mime_field_name_set(heap, mh, field, field_name_wks_idx, name, true);
 1369|  31.2k|  return field;
 1370|  31.2k|}
_Z21mime_hdr_field_attachP11MIMEHdrImplP9MIMEFieldiS2_:
 1374|  51.1k|{
 1375|  51.1k|  MIME_HDR_SANITY_CHECK(mh);
  ------------------
  |  |   75|  51.1k|#define MIME_HDR_SANITY_CHECK (void)
  ------------------
 1376|       |
 1377|  51.1k|  if (!field->is_detached()) {
  ------------------
  |  Branch (1377:7): [True: 0, False: 51.1k]
  ------------------
 1378|      0|    return;
 1379|      0|  }
 1380|       |
 1381|  51.1k|  ink_assert(field->m_ptr_name != nullptr);
  ------------------
  |  |   45|  51.1k|#define ink_assert(EX) (void)(EX)
  ------------------
 1382|       |
 1383|       |  //////////////////////////////////////////////////
 1384|       |  // if we don't know the head dup, or are given  //
 1385|       |  // a non-head dup, then search for the head dup //
 1386|       |  //////////////////////////////////////////////////
 1387|       |
 1388|  51.1k|  if (check_for_dups || (prev_dup && (!prev_dup->is_dup_head()))) {
  ------------------
  |  Branch (1388:7): [True: 19.9k, False: 31.2k]
  |  Branch (1388:26): [True: 0, False: 31.2k]
  |  Branch (1388:38): [True: 0, False: 0]
  ------------------
 1389|  19.9k|    std::string_view name{field->name_get()};
 1390|  19.9k|    prev_dup = mime_hdr_field_find(mh, name);
 1391|  19.9k|    ink_assert((prev_dup == nullptr) || (prev_dup->is_dup_head()));
  ------------------
  |  |   45|  35.2k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 4.54k, False: 15.3k]
  |  |  |  Branch (45:31): [True: 15.3k, False: 0]
  |  |  ------------------
  ------------------
 1392|  19.9k|  }
 1393|       |
 1394|  51.1k|  field->m_readiness = MIME_FIELD_SLOT_READINESS_LIVE;
  ------------------
  |  |   80|  51.1k|#define MIME_FIELD_SLOT_READINESS_LIVE     2
  ------------------
 1395|       |
 1396|       |  ////////////////////////////////////////////////////////////////////
 1397|       |  // now, attach the new field --- if there are dups, make sure the //
 1398|       |  // field is patched into the dup list in increasing slot order to //
 1399|       |  // maintain the invariant that dups are chained in slot order     //
 1400|       |  ////////////////////////////////////////////////////////////////////
 1401|       |
 1402|  51.1k|  if (prev_dup) {
  ------------------
  |  Branch (1402:7): [True: 15.3k, False: 35.7k]
  ------------------
 1403|  15.3k|    MIMEField *next_dup;
 1404|  15.3k|    int        field_slotnum, prev_slotnum, next_slotnum;
 1405|       |
 1406|       |    /////////////////////////////////////////////////////////////////
 1407|       |    // walk down dup list looking for the last dup in slot-order   //
 1408|       |    // before this field object --- meaning a dup before the field //
 1409|       |    // in slot order who either has no next dup, or whose next dup //
 1410|       |    // is numerically after the field in slot order.               //
 1411|       |    /////////////////////////////////////////////////////////////////
 1412|       |
 1413|  15.3k|    field_slotnum = mime_hdr_field_slotnum(mh, field);
 1414|  15.3k|    prev_slotnum  = mime_hdr_field_slotnum(mh, prev_dup);
 1415|  15.3k|    next_dup      = prev_dup->m_next_dup;
 1416|  15.3k|    next_slotnum  = (next_dup ? mime_hdr_field_slotnum(mh, next_dup) : -1);
  ------------------
  |  Branch (1416:22): [True: 13.8k, False: 1.56k]
  ------------------
 1417|       |
 1418|  15.3k|    ink_assert(field_slotnum != prev_slotnum);
  ------------------
  |  |   45|  15.3k|#define ink_assert(EX) (void)(EX)
  ------------------
 1419|       |
 1420|   600k|    while (prev_slotnum < field_slotnum) // break if prev after field
  ------------------
  |  Branch (1420:12): [True: 600k, False: 0]
  ------------------
 1421|   600k|    {
 1422|   600k|      if (next_dup == nullptr) {
  ------------------
  |  Branch (1422:11): [True: 15.3k, False: 585k]
  ------------------
 1423|  15.3k|        break; // no next dup, we're done
 1424|  15.3k|      }
 1425|   585k|      if (next_slotnum > field_slotnum) {
  ------------------
  |  Branch (1425:11): [True: 0, False: 585k]
  ------------------
 1426|      0|        break; // next dup is after us, we're done
 1427|      0|      }
 1428|   585k|      prev_dup     = next_dup;
 1429|   585k|      prev_slotnum = next_slotnum;
 1430|   585k|      next_dup     = prev_dup->m_next_dup;
 1431|   585k|    }
 1432|       |
 1433|       |    /////////////////////////////////////////////////////
 1434|       |    // we get here if the prev_slotnum > field_slotnum //
 1435|       |    // (meaning we're now the first dup in the list),  //
 1436|       |    // or when we've found the correct prev and next   //
 1437|       |    /////////////////////////////////////////////////////
 1438|       |
 1439|  15.3k|    if (prev_slotnum > field_slotnum) // we are now the head
  ------------------
  |  Branch (1439:9): [True: 0, False: 15.3k]
  ------------------
 1440|      0|    {
 1441|       |      /////////////////////////////////////////////////////////////
 1442|       |      // here, it turns out that "prev_dup" is actually after    //
 1443|       |      // "field" in the list of fields --- so, prev_dup is a bit //
 1444|       |      // of a misnomer, it is actually, the NEXT field!          //
 1445|       |      /////////////////////////////////////////////////////////////
 1446|       |
 1447|      0|      field->m_flags    = (field->m_flags | MIME_FIELD_SLOT_FLAGS_DUP_HEAD);
  ------------------
  |  |   83|      0|#define MIME_FIELD_SLOT_FLAGS_DUP_HEAD (1 << 0)
  ------------------
 1448|      0|      field->m_next_dup = prev_dup;
 1449|      0|      prev_dup->m_flags = (prev_dup->m_flags & ~MIME_FIELD_SLOT_FLAGS_DUP_HEAD);
  ------------------
  |  |   83|      0|#define MIME_FIELD_SLOT_FLAGS_DUP_HEAD (1 << 0)
  ------------------
 1450|      0|      mime_hdr_set_accelerators_and_presence_bits(mh, field);
 1451|      0|    } else // patch us after prev, and before next
 1452|  15.3k|    {
 1453|  15.3k|      ink_assert(prev_slotnum < field_slotnum);
  ------------------
  |  |   45|  15.3k|#define ink_assert(EX) (void)(EX)
  ------------------
 1454|  15.3k|      ink_assert((next_dup == nullptr) || (next_slotnum > field_slotnum));
  ------------------
  |  |   45|  15.3k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 15.3k, False: 0]
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1455|  15.3k|      field->m_flags = (field->m_flags & ~MIME_FIELD_SLOT_FLAGS_DUP_HEAD);
  ------------------
  |  |   83|  15.3k|#define MIME_FIELD_SLOT_FLAGS_DUP_HEAD (1 << 0)
  ------------------
 1456|  15.3k|      ink_assert((next_dup == nullptr) || next_dup->is_live());
  ------------------
  |  |   45|  15.3k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 15.3k, False: 0]
  |  |  |  Branch (45:31): [True: 0, False: 0]
  |  |  ------------------
  ------------------
 1457|  15.3k|      prev_dup->m_next_dup = field;
 1458|  15.3k|      field->m_next_dup    = next_dup;
 1459|  15.3k|    }
 1460|  35.7k|  } else {
 1461|  35.7k|    field->m_flags = (field->m_flags | MIME_FIELD_SLOT_FLAGS_DUP_HEAD);
  ------------------
  |  |   83|  35.7k|#define MIME_FIELD_SLOT_FLAGS_DUP_HEAD (1 << 0)
  ------------------
 1462|  35.7k|    mime_hdr_set_accelerators_and_presence_bits(mh, field);
 1463|  35.7k|  }
 1464|       |
 1465|       |  // Now keep the cooked cache consistent
 1466|  51.1k|  ink_assert(field->is_live());
  ------------------
  |  |   45|  51.1k|#define ink_assert(EX) (void)(EX)
  ------------------
 1467|  51.1k|  if (field->m_ptr_value && field->is_cooked()) {
  ------------------
  |  Branch (1467:7): [True: 19.9k, False: 31.2k]
  |  Branch (1467:29): [True: 1.45k, False: 18.4k]
  ------------------
 1468|  1.45k|    mh->recompute_cooked_stuff(field);
 1469|  1.45k|  }
 1470|       |
 1471|  51.1k|  MIME_HDR_SANITY_CHECK(mh);
  ------------------
  |  |   75|  51.1k|#define MIME_HDR_SANITY_CHECK (void)
  ------------------
 1472|  51.1k|}
_Z21mime_hdr_field_detachP11MIMEHdrImplP9MIMEFieldb:
 1476|  1.09k|{
 1477|  1.09k|  ink_assert(mh);
  ------------------
  |  |   45|  1.09k|#define ink_assert(EX) (void)(EX)
  ------------------
 1478|  1.09k|  MIMEField *next_dup = field->m_next_dup;
 1479|       |
 1480|       |  // If this field is already detached, there's nothing to do. There must
 1481|       |  // not be a dup list if we detached correctly.
 1482|  1.09k|  if (field->is_detached()) {
  ------------------
  |  Branch (1482:7): [True: 0, False: 1.09k]
  ------------------
 1483|      0|    ink_assert(next_dup == nullptr);
  ------------------
  |  |   45|      0|#define ink_assert(EX) (void)(EX)
  ------------------
 1484|      0|    return;
 1485|      0|  }
 1486|       |
 1487|  1.09k|  ink_assert(field->is_live());
  ------------------
  |  |   45|  1.09k|#define ink_assert(EX) (void)(EX)
  ------------------
 1488|  1.09k|  MIME_HDR_SANITY_CHECK(mh);
  ------------------
  |  |   75|  1.09k|#define MIME_HDR_SANITY_CHECK (void)
  ------------------
 1489|       |
 1490|       |  // Normally, this function is called with the current dup list head,
 1491|       |  // so, we need to update the accelerators after the patch out.  But, if
 1492|       |  // this function is ever called in the middle of a dup list, we need
 1493|       |  // to walk the list to find the previous dup in the list to patch out
 1494|       |  // the dup being detached.
 1495|       |
 1496|  1.09k|  if (field->m_flags & MIME_FIELD_SLOT_FLAGS_DUP_HEAD) // head of list?
  ------------------
  |  |   83|  1.09k|#define MIME_FIELD_SLOT_FLAGS_DUP_HEAD (1 << 0)
  ------------------
  |  Branch (1496:7): [True: 974, False: 122]
  ------------------
 1497|    974|  {
 1498|    974|    if (!next_dup) // only child
  ------------------
  |  Branch (1498:9): [True: 106, False: 868]
  ------------------
 1499|    106|    {
 1500|    106|      mime_hdr_unset_accelerators_and_presence_bits(mh, field);
 1501|    106|    } else // next guy is dup head
 1502|    868|    {
 1503|    868|      next_dup->m_flags |= MIME_FIELD_SLOT_FLAGS_DUP_HEAD;
  ------------------
  |  |   83|    868|#define MIME_FIELD_SLOT_FLAGS_DUP_HEAD (1 << 0)
  ------------------
 1504|    868|      mime_hdr_set_accelerators_and_presence_bits(mh, next_dup);
 1505|    868|    }
 1506|    974|  } else // need to walk list to find and patch out from predecessor
 1507|    122|  {
 1508|    122|    std::string_view name{field->name_get()};
 1509|    122|    MIMEField       *prev = mime_hdr_field_find(mh, name);
 1510|       |
 1511|    122|    while (prev && (prev->m_next_dup != field)) {
  ------------------
  |  Branch (1511:12): [True: 122, False: 0]
  |  Branch (1511:20): [True: 0, False: 122]
  ------------------
 1512|      0|      prev = prev->m_next_dup;
 1513|      0|    }
 1514|    122|    ink_assert(prev != nullptr);
  ------------------
  |  |   45|    122|#define ink_assert(EX) (void)(EX)
  ------------------
 1515|       |
 1516|    122|    if (prev->m_next_dup == field) {
  ------------------
  |  Branch (1516:9): [True: 122, False: 0]
  ------------------
 1517|    122|      prev->m_next_dup = next_dup;
 1518|    122|    }
 1519|    122|  }
 1520|       |
 1521|       |  // Field is now detached and alone
 1522|  1.09k|  field->m_readiness = MIME_FIELD_SLOT_READINESS_DETACHED;
  ------------------
  |  |   79|  1.09k|#define MIME_FIELD_SLOT_READINESS_DETACHED 1
  ------------------
 1523|  1.09k|  field->m_next_dup  = nullptr;
 1524|       |
 1525|       |  // Because we changed the values through detaching,update the cooked cache
 1526|  1.09k|  if (field->is_cooked()) {
  ------------------
  |  Branch (1526:7): [True: 0, False: 1.09k]
  ------------------
 1527|      0|    mh->recompute_cooked_stuff(field);
 1528|      0|  }
 1529|       |
 1530|  1.09k|  MIME_HDR_SANITY_CHECK(mh);
  ------------------
  |  |   75|  1.09k|#define MIME_HDR_SANITY_CHECK (void)
  ------------------
 1531|       |
 1532|       |  // At this point, the list should be back to a valid state, either the
 1533|       |  // next dup detached and the accelerators set to the next dup (if any),
 1534|       |  // or an interior dup detached and patched around.  If we are requested
 1535|       |  // to delete the whole dup list, we tail-recurse to delete it.
 1536|       |
 1537|  1.09k|  if (detach_all_dups && next_dup) {
  ------------------
  |  Branch (1537:7): [True: 0, False: 1.09k]
  |  Branch (1537:26): [True: 0, False: 0]
  ------------------
 1538|      0|    mime_hdr_field_detach(mh, next_dup, detach_all_dups);
 1539|      0|  }
 1540|  1.09k|}
_Z21mime_hdr_field_deleteP7HdrHeapP11MIMEHdrImplP9MIMEFieldb:
 1544|  1.20k|{
 1545|  1.20k|  if (delete_all_dups) {
  ------------------
  |  Branch (1545:7): [True: 106, False: 1.09k]
  ------------------
 1546|  1.08k|    while (field) {
  ------------------
  |  Branch (1546:12): [True: 974, False: 106]
  ------------------
 1547|    974|      MIMEField *next = field->m_next_dup;
 1548|    974|      mime_hdr_field_delete(heap, mh, field, false);
 1549|    974|      field = next;
 1550|    974|    }
 1551|  1.09k|  } else {
 1552|  1.09k|    heap->free_string(field->m_ptr_name, field->m_len_name);
 1553|  1.09k|    heap->free_string(field->m_ptr_value, field->m_len_value);
 1554|       |
 1555|  1.09k|    MIME_HDR_SANITY_CHECK(mh);
  ------------------
  |  |   75|  1.09k|#define MIME_HDR_SANITY_CHECK (void)
  ------------------
 1556|  1.09k|    mime_hdr_field_detach(mh, field, false);
 1557|       |
 1558|  1.09k|    MIME_HDR_SANITY_CHECK(mh);
  ------------------
  |  |   75|  1.09k|#define MIME_HDR_SANITY_CHECK (void)
  ------------------
 1559|  1.09k|    mime_field_destroy(mh, field);
 1560|       |
 1561|  1.09k|    MIMEFieldBlockImpl *prev_block        = nullptr;
 1562|  1.09k|    bool                can_destroy_block = true;
 1563|  3.46k|    for (auto fblock = &(mh->m_first_fblock); fblock != nullptr; fblock = fblock->m_next) {
  ------------------
  |  Branch (1563:47): [True: 2.95k, False: 504]
  ------------------
 1564|  2.95k|      if (prev_block != nullptr) {
  ------------------
  |  Branch (1564:11): [True: 1.86k, False: 1.09k]
  ------------------
 1565|  1.86k|        if (fblock->m_freetop == MIME_FIELD_BLOCK_SLOTS && fblock->contains(field)) {
  ------------------
  |  |   86|  3.72k|#define MIME_FIELD_BLOCK_SLOTS 16
  ------------------
  |  Branch (1565:13): [True: 1.61k, False: 248]
  |  Branch (1565:60): [True: 592, False: 1.02k]
  ------------------
 1566|       |          // Check if fields in all slots are deleted
 1567|  4.59k|          for (auto &m_field_slot : fblock->m_field_slots) {
  ------------------
  |  Branch (1567:35): [True: 4.59k, False: 24]
  ------------------
 1568|  4.59k|            if (m_field_slot.m_readiness != MIME_FIELD_SLOT_READINESS_DELETED) {
  ------------------
  |  |   81|  4.59k|#define MIME_FIELD_SLOT_READINESS_DELETED  3
  ------------------
  |  Branch (1568:17): [True: 568, False: 4.02k]
  ------------------
 1569|    568|              can_destroy_block = false;
 1570|    568|              break;
 1571|    568|            }
 1572|  4.59k|          }
 1573|       |          // Destroy a block and maintain the chain
 1574|    592|          if (can_destroy_block) {
  ------------------
  |  Branch (1574:15): [True: 24, False: 568]
  ------------------
 1575|     24|            prev_block->m_next = fblock->m_next;
 1576|     24|            _mime_field_block_destroy(heap, fblock);
 1577|     24|            if (prev_block->m_next == nullptr) {
  ------------------
  |  Branch (1577:17): [True: 10, False: 14]
  ------------------
 1578|     10|              mh->m_fblock_list_tail = prev_block;
 1579|     10|            }
 1580|     24|          }
 1581|    592|          break;
 1582|    592|        }
 1583|  1.86k|      }
 1584|  2.36k|      prev_block = fblock;
 1585|  2.36k|    }
 1586|  1.09k|  }
 1587|       |
 1588|  1.20k|  MIME_HDR_SANITY_CHECK(mh);
  ------------------
  |  |   75|  1.20k|#define MIME_HDR_SANITY_CHECK (void)
  ------------------
 1589|  1.20k|}
_Z22mime_hdr_field_slotnumP11MIMEHdrImplP9MIMEField:
 1606|  44.5k|{
 1607|  44.5k|  int                 slots_so_far;
 1608|  44.5k|  MIMEFieldBlockImpl *fblock;
 1609|       |
 1610|  44.5k|  slots_so_far = 0;
 1611|   119k|  for (fblock = &(mh->m_first_fblock); fblock != nullptr; fblock = fblock->m_next) {
  ------------------
  |  Branch (1611:40): [True: 119k, False: 0]
  ------------------
 1612|   119k|    if (fblock->contains(field)) {
  ------------------
  |  Branch (1612:9): [True: 44.5k, False: 74.4k]
  ------------------
 1613|  44.5k|      MIMEField *first      = &(fblock->m_field_slots[0]);
 1614|  44.5k|      ptrdiff_t  block_slot = field - first; // in units of MIMEField
 1615|  44.5k|      return slots_so_far + block_slot;
 1616|  44.5k|    }
 1617|  74.4k|    slots_so_far += MIME_FIELD_BLOCK_SLOTS;
  ------------------
  |  |   86|  74.4k|#define MIME_FIELD_BLOCK_SLOTS 16
  ------------------
 1618|  74.4k|  }
 1619|      0|  return -1;
 1620|  44.5k|}
_Z18mime_field_destroyP11MIMEHdrImplP9MIMEField:
 1660|  1.09k|{
 1661|  1.09k|  ink_assert(field->m_readiness == MIME_FIELD_SLOT_READINESS_DETACHED);
  ------------------
  |  |   45|  1.09k|#define ink_assert(EX) (void)(EX)
  ------------------
 1662|  1.09k|  field->m_readiness = MIME_FIELD_SLOT_READINESS_DELETED;
  ------------------
  |  |   81|  1.09k|#define MIME_FIELD_SLOT_READINESS_DELETED  3
  ------------------
 1663|  1.09k|}
_ZNK9MIMEField8name_getEv:
 1667|  20.0k|{
 1668|  20.0k|  if (m_wks_idx >= 0) {
  ------------------
  |  Branch (1668:7): [True: 4.24k, False: 15.7k]
  ------------------
 1669|  4.24k|    return {hdrtoken_index_to_wks(m_wks_idx), m_len_name};
 1670|  4.24k|  }
 1671|  15.7k|  return {m_ptr_name, m_len_name};
 1672|  20.0k|}
_Z19mime_field_name_setP7HdrHeapP11MIMEHdrImplP9MIMEFieldsNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEEb:
 1677|  31.2k|{
 1678|  31.2k|  ink_assert(field->m_readiness == MIME_FIELD_SLOT_READINESS_DETACHED);
  ------------------
  |  |   45|  31.2k|#define ink_assert(EX) (void)(EX)
  ------------------
 1679|       |
 1680|  31.2k|  field->m_wks_idx = name_wks_idx_or_neg1;
 1681|  31.2k|  mime_str_u16_set(heap, name, &(field->m_ptr_name), &(field->m_len_name), must_copy_string);
 1682|       |
 1683|  31.2k|  if ((name_wks_idx_or_neg1 == MIME_WKSIDX_CACHE_CONTROL) || (name_wks_idx_or_neg1 == MIME_WKSIDX_PRAGMA)) {
  ------------------
  |  Branch (1683:7): [True: 0, False: 31.2k]
  |  Branch (1683:62): [True: 0, False: 31.2k]
  ------------------
 1684|      0|    field->m_flags |= MIME_FIELD_SLOT_FLAGS_COOKED;
  ------------------
  |  |   84|      0|#define MIME_FIELD_SLOT_FLAGS_COOKED   (1 << 1)
  ------------------
 1685|      0|  }
 1686|  31.2k|}
_ZNK9MIMEField9value_getEv:
 1721|  1.32k|{
 1722|  1.32k|  return {m_ptr_value, m_len_value};
 1723|  1.32k|}
_Z25mime_field_name_value_setP7HdrHeapP11MIMEHdrImplP9MIMEFieldsNSt3__117basic_string_viewIcNS5_11char_traitsIcEEEES9_iib:
 2103|  19.9k|{
 2104|  19.9k|  auto         name_length{static_cast<int>(name.length())};
 2105|  19.9k|  auto         value_length{static_cast<int>(value.length())};
 2106|  19.9k|  unsigned int n_v_raw_pad = n_v_raw_length - (name_length + value_length);
 2107|       |
 2108|  19.9k|  ink_assert(field->m_readiness == MIME_FIELD_SLOT_READINESS_DETACHED);
  ------------------
  |  |   45|  19.9k|#define ink_assert(EX) (void)(EX)
  ------------------
 2109|       |
 2110|  19.9k|  if (must_copy_strings) {
  ------------------
  |  Branch (2110:7): [True: 0, False: 19.9k]
  ------------------
 2111|      0|    mime_field_name_set(heap, mh, field, name_wks_idx_or_neg1, name, true);
 2112|      0|    mime_field_value_set(heap, mh, field, value, true);
 2113|  19.9k|  } else {
 2114|  19.9k|    field->m_wks_idx   = name_wks_idx_or_neg1;
 2115|  19.9k|    field->m_ptr_name  = name.data();
 2116|  19.9k|    field->m_ptr_value = value.data();
 2117|  19.9k|    field->m_len_name  = name_length;
 2118|  19.9k|    field->m_len_value = value_length;
 2119|  19.9k|    if (n_v_raw_printable && (n_v_raw_pad <= 7)) {
  ------------------
  |  Branch (2119:9): [True: 308, False: 19.6k]
  |  Branch (2119:30): [True: 231, False: 77]
  ------------------
 2120|    231|      field->m_n_v_raw_printable     = n_v_raw_printable;
 2121|    231|      field->m_n_v_raw_printable_pad = n_v_raw_pad;
 2122|  19.6k|    } else {
 2123|  19.6k|      field->m_n_v_raw_printable = 0;
 2124|  19.6k|    }
 2125|       |
 2126|       |    // Now keep the cooked cache consistent
 2127|  19.9k|    if ((name_wks_idx_or_neg1 == MIME_WKSIDX_CACHE_CONTROL) || (name_wks_idx_or_neg1 == MIME_WKSIDX_PRAGMA)) {
  ------------------
  |  Branch (2127:9): [True: 394, False: 19.5k]
  |  Branch (2127:64): [True: 1.06k, False: 18.4k]
  ------------------
 2128|  1.45k|      field->m_flags |= MIME_FIELD_SLOT_FLAGS_COOKED;
  ------------------
  |  |   84|  1.45k|#define MIME_FIELD_SLOT_FLAGS_COOKED   (1 << 1)
  ------------------
 2129|  1.45k|    }
 2130|  19.9k|    if (field->is_live() && field->is_cooked()) {
  ------------------
  |  Branch (2130:9): [True: 0, False: 19.9k]
  |  Branch (2130:29): [True: 0, False: 0]
  ------------------
 2131|      0|      mh->recompute_cooked_stuff(field);
 2132|      0|    }
 2133|  19.9k|  }
 2134|  19.9k|}
_ZN11MIMEScanner4initEv:
 2210|  18.7k|{
 2211|  18.7k|  m_state = INITIAL_PARSE_STATE;
 2212|       |  // Ugly, but required because of how proxy allocation works - that leaves the instance in a
 2213|       |  // random state, so even assigning to it can crash. Because this method substitutes for a real
 2214|       |  // constructor in the proxy allocation system, call the CTOR here. Any memory that gets allocated
 2215|       |  // is supposed to be cleaned up by calling @c clear on this object.
 2216|  18.7k|  new (&m_line) std::string;
 2217|  18.7k|}
_ZN11MIMEScanner6appendEN4swoc7_1_5_158TextViewE:
 2221|  2.03k|{
 2222|  2.03k|  m_line += text;
 2223|  2.03k|  return *this;
 2224|  2.03k|}
_ZN11MIMEScanner3getERN4swoc7_1_5_158TextViewES3_RbbNS_8ScanTypeE:
 2228|  44.7k|{
 2229|  44.7k|  ParseResult zret = ParseResult::CONT;
 2230|       |  // Need this for handling dangling CR.
 2231|  44.7k|  static const char RAW_CR{ParseRules::CHAR_CR};
 2232|       |
 2233|  44.7k|  auto text = input;
 2234|   128k|  while (ParseResult::CONT == zret && !text.empty()) {
  ------------------
  |  Branch (2234:10): [True: 99.6k, False: 29.2k]
  |  Branch (2234:39): [True: 84.1k, False: 15.4k]
  ------------------
 2235|  84.1k|    switch (m_state) {
  ------------------
  |  Branch (2235:13): [True: 84.1k, False: 0]
  ------------------
 2236|  31.0k|    case MimeParseState::BEFORE: // waiting to find a field.
  ------------------
  |  Branch (2236:5): [True: 31.0k, False: 53.1k]
  ------------------
 2237|  31.0k|      m_line.resize(0);          // any caller should already be done with the buffer
 2238|  31.0k|      if (ParseRules::is_cr(*text)) {
  ------------------
  |  Branch (2238:11): [True: 1.05k, False: 30.0k]
  ------------------
 2239|  1.05k|        ++text;
 2240|  1.05k|        if (!text.empty() && ParseRules::is_lf(*text)) {
  ------------------
  |  Branch (2240:13): [True: 1.04k, False: 8]
  |  Branch (2240:30): [True: 24, False: 1.01k]
  ------------------
 2241|       |          // optimize a bit - this happens >99% of the time after a CR.
 2242|     24|          ++text;
 2243|     24|          zret = ParseResult::DONE;
 2244|  1.02k|        } else {
 2245|  1.02k|          m_state = MimeParseState::FOUND_CR;
 2246|  1.02k|        }
 2247|  30.0k|      } else if (ParseRules::is_lf(*text)) {
  ------------------
  |  Branch (2247:18): [True: 2.10k, False: 27.9k]
  ------------------
 2248|  2.10k|        ++text;
 2249|  2.10k|        zret = ParseResult::DONE; // Required by regression test.
 2250|  27.9k|      } else {
 2251|       |        // consume this character in the next state.
 2252|  27.9k|        m_state = MimeParseState::INSIDE;
 2253|  27.9k|      }
 2254|  31.0k|      break;
 2255|  1.01k|    case MimeParseState::FOUND_CR:
  ------------------
  |  Branch (2255:5): [True: 1.01k, False: 83.1k]
  ------------------
 2256|       |      // Looking for a field and found a CR, which should mean terminating the header.
 2257|  1.01k|      if (ParseRules::is_lf(*text)) {
  ------------------
  |  Branch (2257:11): [True: 0, False: 1.01k]
  ------------------
 2258|      0|        ++text;
 2259|      0|        zret = ParseResult::DONE;
 2260|  1.01k|      } else {
 2261|       |        // This really should be an error (spec doesn't permit lone CR) but the regression tests
 2262|       |        // require it.
 2263|  1.01k|        this->append(TextView(&RAW_CR, 1)); // This is to fix a core dump of the icc 19.1 compiler when {&RAW_CR, 1} is used
 2264|  1.01k|        m_state = MimeParseState::INSIDE;
 2265|  1.01k|      }
 2266|  1.01k|      break;
 2267|  29.4k|    case MimeParseState::INSIDE: {
  ------------------
  |  Branch (2267:5): [True: 29.4k, False: 54.7k]
  ------------------
 2268|  29.4k|      auto lf_off = text.find(ParseRules::CHAR_LF);
 2269|  29.4k|      if (lf_off != TextView::npos) {
  ------------------
  |  Branch (2269:11): [True: 29.2k, False: 211]
  ------------------
 2270|  29.2k|        text.remove_prefix(lf_off + 1); // drop up to and including LF
 2271|  29.2k|        if (ScanType::LINE == scan_type) {
  ------------------
  |  Branch (2271:13): [True: 4.95k, False: 24.2k]
  ------------------
 2272|  4.95k|          zret    = ParseResult::OK;
 2273|  4.95k|          m_state = MimeParseState::BEFORE;
 2274|  24.2k|        } else {
 2275|  24.2k|          m_state = MimeParseState::AFTER; // looking for line folding.
 2276|  24.2k|        }
 2277|  29.2k|      } else { // no EOL, consume all text without changing state.
 2278|    211|        text.remove_prefix(text.size());
 2279|    211|      }
 2280|  29.4k|    } break;
 2281|  22.6k|    case MimeParseState::AFTER:
  ------------------
  |  Branch (2281:5): [True: 22.6k, False: 61.5k]
  ------------------
 2282|       |      // After a LF, the next line might be a continuation / folded line. That's indicated by a
 2283|       |      // starting whitespace. If that's the case, back up over the preceding CR/LF with space and
 2284|       |      // pretend it's the same line.
 2285|  22.6k|      if (ParseRules::is_ws(*text)) { // folded line.
  ------------------
  |  Branch (2285:11): [True: 511, False: 22.1k]
  ------------------
 2286|    511|        char *unfold = const_cast<char *>(text.data() - 1);
 2287|    511|        *unfold--    = ' ';
 2288|    511|        if (ParseRules::is_cr(*unfold)) {
  ------------------
  |  Branch (2288:13): [True: 237, False: 274]
  ------------------
 2289|    237|          *unfold = ' ';
 2290|    237|        }
 2291|    511|        m_state = MimeParseState::INSIDE; // back inside the field.
 2292|  22.1k|      } else {
 2293|  22.1k|        m_state = MimeParseState::BEFORE; // field terminated.
 2294|  22.1k|        zret    = ParseResult::OK;
 2295|  22.1k|      }
 2296|  22.6k|      break;
 2297|  84.1k|    }
 2298|  84.1k|  }
 2299|       |
 2300|  44.7k|  TextView parsed_text{input.data(), text.data()};
 2301|  44.7k|  bool     save_parsed_text_p = !parsed_text.empty();
 2302|       |
 2303|  44.7k|  if (ParseResult::CONT == zret) {
  ------------------
  |  Branch (2303:7): [True: 15.4k, False: 29.2k]
  ------------------
 2304|       |    // data ran out before we got a clear final result. There a number of things we need to check
 2305|       |    // and possibly adjust that result. It's less complex to do this cleanup than handle all of
 2306|       |    // these checks in the parser state machine.
 2307|  15.4k|    if (eof_p) {
  ------------------
  |  Branch (2307:9): [True: 15.4k, False: 0]
  ------------------
 2308|       |      // Should never return PARSE_CONT if we've hit EOF.
 2309|  15.4k|      if (parsed_text.empty()) {
  ------------------
  |  Branch (2309:11): [True: 13.6k, False: 1.87k]
  ------------------
 2310|       |        // all input previously consumed. If we're between fields, that's cool.
 2311|  13.6k|        if (MimeParseState::INSIDE != m_state) {
  ------------------
  |  Branch (2311:13): [True: 13.6k, False: 0]
  ------------------
 2312|  13.6k|          m_state = MimeParseState::BEFORE; // probably not needed...
 2313|  13.6k|          zret    = ParseResult::DONE;
 2314|  13.6k|        } else {
 2315|      0|          zret = ParseResult::ERROR; // unterminated field.
 2316|      0|        }
 2317|  13.6k|      } else if (MimeParseState::AFTER == m_state) {
  ------------------
  |  Branch (2317:18): [True: 1.65k, False: 219]
  ------------------
 2318|       |        // Special case it seems - need to accept the final field even if there's no header
 2319|       |        // terminating CR LF. This is only reasonable after absolute end of input (EOF) because
 2320|       |        // otherwise this might be a multiline field where we haven't seen the next leading space.
 2321|  1.65k|        m_state = MimeParseState::BEFORE;
 2322|  1.65k|        zret    = ParseResult::OK;
 2323|  1.65k|      } else {
 2324|       |        // Partial input, no field / line CR LF
 2325|    219|        zret = ParseResult::ERROR; // Unterminated field.
 2326|    219|      }
 2327|  15.4k|    } else if (!parsed_text.empty()) {
  ------------------
  |  Branch (2327:16): [True: 0, False: 0]
  ------------------
 2328|      0|      if (MimeParseState::INSIDE == m_state) {
  ------------------
  |  Branch (2328:11): [True: 0, False: 0]
  ------------------
 2329|       |        // Inside a field but more data is expected. Save what we've got.
 2330|      0|        this->append(parsed_text);  // Do this here to force appending.
 2331|      0|        save_parsed_text_p = false; // don't double append.
 2332|      0|      } else if (MimeParseState::AFTER == m_state) {
  ------------------
  |  Branch (2332:18): [True: 0, False: 0]
  ------------------
 2333|       |        // After a field but we still have data. Need to parse it too.
 2334|      0|        m_state = MimeParseState::BEFORE;
 2335|      0|        zret    = ParseResult::OK;
 2336|      0|      }
 2337|      0|    }
 2338|  15.4k|  }
 2339|       |
 2340|  44.7k|  if (save_parsed_text_p && !m_line.empty()) {
  ------------------
  |  Branch (2340:7): [True: 31.0k, False: 13.6k]
  |  Branch (2340:29): [True: 1.01k, False: 30.0k]
  ------------------
 2341|       |    // If we're already accumulating, continue to do so if we have data.
 2342|  1.01k|    this->append(parsed_text);
 2343|  1.01k|  }
 2344|       |
 2345|       |  // adjust out arguments.
 2346|  44.7k|  output_shares_input = true;
 2347|  44.7k|  if (ParseResult::CONT != zret) {
  ------------------
  |  Branch (2347:7): [True: 44.7k, False: 0]
  ------------------
 2348|  44.7k|    if (!m_line.empty()) {
  ------------------
  |  Branch (2348:9): [True: 1.03k, False: 43.6k]
  ------------------
 2349|  1.03k|      output              = m_line; // cleared when called with state MimeParseState::BEFORE
 2350|  1.03k|      output_shares_input = false;
 2351|  43.6k|    } else {
 2352|  43.6k|      output = parsed_text;
 2353|  43.6k|    }
 2354|  44.7k|  }
 2355|       |
 2356|       |  // Make sure there are no null characters in the input scanned so far
 2357|  44.7k|  if (zret != ParseResult::ERROR && TextView::npos != parsed_text.find('\0')) {
  ------------------
  |  Branch (2357:7): [True: 44.4k, False: 219]
  |  Branch (2357:37): [True: 54, False: 44.4k]
  ------------------
 2358|     54|    zret = ParseResult::ERROR;
 2359|     54|  }
 2360|       |
 2361|  44.7k|  input.remove_prefix(parsed_text.size());
 2362|  44.7k|  return zret;
 2363|  44.7k|}
_Z17_mime_parser_initP10MIMEParser:
 2367|  37.4k|{
 2368|  37.4k|  parser->m_field       = 0;
 2369|  37.4k|  parser->m_field_flags = 0;
 2370|  37.4k|  parser->m_value       = -1;
 2371|  37.4k|}
_Z16mime_parser_initP10MIMEParser:
 2378|  18.7k|{
 2379|  18.7k|  parser->m_scanner.init();
 2380|  18.7k|  _mime_parser_init(parser);
 2381|  18.7k|}
_Z17mime_parser_clearP10MIMEParser:
 2385|  18.7k|{
 2386|  18.7k|  parser->m_scanner.clear();
 2387|  18.7k|  _mime_parser_init(parser);
 2388|  18.7k|}
_Z17mime_parser_parseP10MIMEParserP7HdrHeapP11MIMEHdrImplPPKcS6_bbbm:
 2393|  2.29k|{
 2394|  2.29k|  ParseResult err;
 2395|  2.29k|  bool        line_is_real;
 2396|       |
 2397|  2.29k|  MIMEScanner *scanner = &parser->m_scanner;
 2398|       |
 2399|  25.9k|  while (true) {
  ------------------
  |  Branch (2399:10): [True: 25.9k, Folded]
  ------------------
 2400|       |    ////////////////////////////////////////////////////////////////////////////
 2401|       |    // get a name:value line, with all continuation lines glued into one line //
 2402|       |    ////////////////////////////////////////////////////////////////////////////
 2403|       |
 2404|  25.9k|    TextView text{*real_s, real_e};
 2405|  25.9k|    TextView parsed;
 2406|  25.9k|    err     = scanner->get(text, parsed, line_is_real, eof, MIMEScanner::ScanType::FIELD);
 2407|  25.9k|    *real_s = text.data();
 2408|  25.9k|    if (err != ParseResult::OK) {
  ------------------
  |  Branch (2408:9): [True: 2.20k, False: 23.7k]
  ------------------
 2409|  2.20k|      return err;
 2410|  2.20k|    }
 2411|       |
 2412|       |    //////////////////////////////////////////////////
 2413|       |    // if got a LF or CR on its own, end the header //
 2414|       |    //////////////////////////////////////////////////
 2415|       |
 2416|  23.7k|    if ((parsed.size() >= 2) && (parsed[0] == ParseRules::CHAR_CR) && (parsed[1] == ParseRules::CHAR_LF)) {
  ------------------
  |  Branch (2416:9): [True: 23.7k, False: 0]
  |  Branch (2416:33): [True: 816, False: 22.9k]
  |  Branch (2416:71): [True: 0, False: 816]
  ------------------
 2417|      0|      return ParseResult::DONE;
 2418|      0|    }
 2419|       |
 2420|  23.7k|    if ((parsed.size() >= 1) && (parsed[0] == ParseRules::CHAR_LF)) {
  ------------------
  |  Branch (2420:9): [True: 23.7k, False: 0]
  |  Branch (2420:33): [True: 0, False: 23.7k]
  ------------------
 2421|      0|      return ParseResult::DONE;
 2422|      0|    }
 2423|       |
 2424|       |    /////////////////////////////////////////////
 2425|       |    // find pointers into the name:value field //
 2426|       |    /////////////////////////////////////////////
 2427|       |
 2428|       |    /**
 2429|       |     * Fix for INKqa09141. The is_token function fails for '@' character.
 2430|       |     * Header names starting with '@' signs are valid headers. Hence we
 2431|       |     * have to add one more check to see if the first parameter is '@'
 2432|       |     * character then, the header name is valid.
 2433|       |     **/
 2434|  23.7k|    if ((!ParseRules::is_token(*parsed)) && (*parsed != '@')) {
  ------------------
  |  Branch (2434:9): [True: 4.14k, False: 19.6k]
  |  Branch (2434:45): [True: 1.50k, False: 2.63k]
  ------------------
 2435|  1.50k|      continue; // toss away garbage line
 2436|  1.50k|    }
 2437|       |
 2438|       |    // find name last
 2439|  22.2k|    auto field_value = parsed; // need parsed as is later on.
 2440|  22.2k|    auto field_name  = field_value.split_prefix_at(':');
 2441|  22.2k|    if (field_name.empty()) {
  ------------------
  |  Branch (2441:9): [True: 2.25k, False: 20.0k]
  ------------------
 2442|  2.25k|      continue; // toss away garbage line
 2443|  2.25k|    }
 2444|       |
 2445|       |    // RFC7230 section 3.2.4:
 2446|       |    // No whitespace is allowed between the header field-name and colon.  In
 2447|       |    // the past, differences in the handling of such whitespace have led to
 2448|       |    // security vulnerabilities in request routing and response handling.  A
 2449|       |    // server MUST reject any received request message that contains
 2450|       |    // whitespace between a header field-name and colon with a response code
 2451|       |    // of 400 (Bad Request).
 2452|       |    // A proxy MUST remove any such whitespace from a response message before
 2453|       |    // forwarding the message downstream.
 2454|  20.0k|    bool raw_print_field = true;
 2455|  20.0k|    if (is_ws(field_name.back())) {
  ------------------
  |  Branch (2455:9): [True: 235, False: 19.7k]
  ------------------
 2456|    235|      if (!remove_ws_from_field_name) {
  ------------------
  |  Branch (2456:11): [True: 6, False: 229]
  ------------------
 2457|      6|        return ParseResult::ERROR;
 2458|      6|      }
 2459|    229|      field_name.rtrim_if(&ParseRules::is_ws);
 2460|    229|      raw_print_field = false;
 2461|  19.7k|    } else if (parsed.suffix(2) != "\r\n") {
  ------------------
  |  Branch (2461:16): [True: 19.4k, False: 308]
  ------------------
 2462|  19.4k|      raw_print_field = false;
 2463|  19.4k|    }
 2464|       |
 2465|       |    // find value first
 2466|  20.0k|    field_value.ltrim_if(&ParseRules::is_ws);
 2467|  20.0k|    field_value.rtrim_if(&ParseRules::is_wslfcr);
 2468|       |
 2469|       |    // Make sure the name + value is not longer than configured max_hdr_field_size
 2470|  20.0k|    if (field_name.size() + field_value.size() > max_hdr_field_size) {
  ------------------
  |  Branch (2470:9): [True: 0, False: 20.0k]
  ------------------
 2471|      0|      return ParseResult::ERROR;
 2472|      0|    }
 2473|       |
 2474|       |    //    int total_line_length = (int)(field_line_last - field_line_first + 1);
 2475|       |
 2476|       |    //////////////////////////////////////////////////////////////////////
 2477|       |    // if we can't leave the name & value in the real buffer, copy them //
 2478|       |    //////////////////////////////////////////////////////////////////////
 2479|       |
 2480|  20.0k|    if (must_copy_strings || (!line_is_real)) {
  ------------------
  |  Branch (2480:9): [True: 20.0k, False: 0]
  |  Branch (2480:30): [True: 0, False: 0]
  ------------------
 2481|  20.0k|      char     *dup   = heap->duplicate_str(parsed.data(), parsed.size());
 2482|  20.0k|      ptrdiff_t delta = dup - parsed.data();
 2483|  20.0k|      field_name.assign(field_name.data() + delta, field_name.size());
 2484|  20.0k|      field_value.assign(field_value.data() + delta, field_value.size());
 2485|  20.0k|    }
 2486|       |    ///////////////////////
 2487|       |    // tokenize the name //
 2488|       |    ///////////////////////
 2489|       |
 2490|  20.0k|    int field_name_wks_idx = hdrtoken_tokenize(field_name.data(), field_name.size());
 2491|       |
 2492|  20.0k|    if (field_name_wks_idx < 0) {
  ------------------
  |  Branch (2492:9): [True: 15.8k, False: 4.12k]
  ------------------
 2493|  22.0k|      for (auto i : field_name) {
  ------------------
  |  Branch (2493:19): [True: 22.0k, False: 15.8k]
  ------------------
 2494|  22.0k|        if (!ParseRules::is_http_field_name(i)) {
  ------------------
  |  Branch (2494:13): [True: 57, False: 22.0k]
  ------------------
 2495|     57|          return ParseResult::ERROR;
 2496|     57|        }
 2497|  22.0k|      }
 2498|  15.8k|    }
 2499|       |
 2500|       |    // RFC 9110 Section 5.5. Field Values
 2501|  46.2k|    for (char i : field_value) {
  ------------------
  |  Branch (2501:17): [True: 46.2k, False: 19.9k]
  ------------------
 2502|       |      // FIXME: ParseRules::is_http_field_value() should be used but the implementation looks wrong
 2503|  46.2k|      if (ParseRules::is_control(i)) {
  ------------------
  |  Branch (2503:11): [True: 26, False: 46.2k]
  ------------------
 2504|     26|        return ParseResult::ERROR;
 2505|     26|      }
 2506|  46.2k|    }
 2507|       |
 2508|       |    ///////////////////////////////////////////
 2509|       |    // build and insert the new field object //
 2510|       |    ///////////////////////////////////////////
 2511|       |
 2512|  19.9k|    MIMEField *field = mime_field_create(heap, mh);
 2513|  19.9k|    mime_field_name_value_set(heap, mh, field, field_name_wks_idx, field_name, field_value, raw_print_field, parsed.size(), false);
 2514|  19.9k|    mime_hdr_field_attach(mh, field, 1, nullptr);
 2515|  19.9k|  }
 2516|  2.29k|}
_Z16mime_str_u16_setP7HdrHeapNSt3__117basic_string_viewIcNS1_11char_traitsIcEEEEPPKcPtb:
 2754|  35.1k|{
 2755|  35.1k|  auto s_len{static_cast<int>(src.length())};
 2756|  35.1k|  ink_assert(s_len >= 0 && s_len < UINT16_MAX);
  ------------------
  |  |   45|  70.2k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 35.1k, False: 0]
  |  |  |  Branch (45:31): [True: 35.1k, False: 0]
  |  |  ------------------
  ------------------
 2757|       |  // INKqa08287 - keep track of free string space.
 2758|       |  //  INVARIANT: passed in result pointers must be to
 2759|       |  //    either NULL or be valid ptr for a string already
 2760|       |  //    the string heaps
 2761|  35.1k|  heap->free_string(*d_str, *d_len);
 2762|       |
 2763|  35.1k|  auto s_str{src.data()};
 2764|  35.1k|  if (must_copy && s_str) {
  ------------------
  |  Branch (2764:7): [True: 35.1k, False: 0]
  |  Branch (2764:20): [True: 34.4k, False: 699]
  ------------------
 2765|  34.4k|    s_str = heap->duplicate_str(s_str, s_len);
 2766|  34.4k|  }
 2767|  35.1k|  *d_str = s_str;
 2768|  35.1k|  *d_len = s_len;
 2769|  35.1k|  return s_str;
 2770|  35.1k|}
_Z37mime_days_since_epoch_to_mdy_slowcaselPiS_S_:
 2802|    733|{
 2803|    733|  static constexpr int DAYS_OFFSET = 25508;
 2804|       |
 2805|    733|  static const char months[] = {
 2806|    733|    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
 2807|    733|    2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
 2808|    733|    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
 2809|    733|    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,
 2810|    733|    6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  7,
 2811|    733|    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  8,
 2812|    733|    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  9,  9,
 2813|    733|    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  10, 10,
 2814|    733|    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
 2815|    733|    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 0,  0,  0,
 2816|    733|    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,
 2817|    733|    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1};
 2818|       |
 2819|    733|  static constexpr int days[12] = {305, 336, -1, 30, 60, 91, 121, 152, 183, 213, 244, 274};
 2820|       |
 2821|    733|  time_t mday, year, month, d, dp;
 2822|       |
 2823|    733|  mday = days_since_jan_1_1970;
 2824|       |
 2825|       |  /* guess the year and refine the guess */
 2826|    733|  year = mday / 365 + 69;
 2827|    733|  d = dp = (year * 365) + (year / 4) - (year / 100) + (year / 100 + 3) / 4 - DAYS_OFFSET - 1;
 2828|       |
 2829|  2.05k|  while (dp < mday) {
  ------------------
  |  Branch (2829:10): [True: 1.32k, False: 733]
  ------------------
 2830|  1.32k|    d     = dp;
 2831|  1.32k|    year += 1;
 2832|  1.32k|    dp    = (year * 365) + (year / 4) - (year / 100) + (year / 100 + 3) / 4 - DAYS_OFFSET - 1;
 2833|  1.32k|  }
 2834|       |
 2835|       |  /* convert the days */
 2836|    733|  d = mday - d;
 2837|    733|  if ((d < 0) || (d > 366)) {
  ------------------
  |  Branch (2837:7): [True: 0, False: 733]
  |  Branch (2837:18): [True: 0, False: 733]
  ------------------
 2838|      0|    ink_assert(!"bad date");
  ------------------
  |  |   45|      0|#define ink_assert(EX) (void)(EX)
  ------------------
 2839|    733|  } else {
 2840|    733|    month = months[d];
 2841|    733|    if (month > 1) {
  ------------------
  |  Branch (2841:9): [True: 615, False: 118]
  ------------------
 2842|    615|      year -= 1;
 2843|    615|    }
 2844|       |
 2845|    733|    mday  = d - days[month] - 1;
 2846|    733|    year += 1900;
 2847|       |
 2848|       |    // coverity[Y2K38_SAFETY:FALSE]
 2849|    733|    *m_return = month;
 2850|       |    // coverity[Y2K38_SAFETY:FALSE]
 2851|    733|    *d_return = mday;
 2852|       |    // coverity[Y2K38_SAFETY:FALSE]
 2853|    733|    *y_return = year;
 2854|    733|  }
 2855|    733|}
_ZN18MIMEFieldBlockImpl8containsEPK9MIMEField:
 3645|   122k|{
 3646|   122k|  MIMEField *first = &(m_field_slots[0]);
 3647|   122k|  MIMEField *last  = &(m_field_slots[MIME_FIELD_BLOCK_SLOTS - 1]);
  ------------------
  |  |   86|   122k|#define MIME_FIELD_BLOCK_SLOTS 16
  ------------------
 3648|   122k|  return (field >= first) && (field <= last);
  ------------------
  |  Branch (3648:10): [True: 91.7k, False: 30.8k]
  |  Branch (3648:30): [True: 46.4k, False: 45.3k]
  ------------------
 3649|   122k|}
_ZN11MIMEHdrImpl22recompute_cooked_stuffEP9MIMEFieldPKNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEm:
 3721|  1.45k|{
 3722|  1.45k|  int         len, tlen;
 3723|  1.45k|  const char *s;
 3724|  1.45k|  const char *c;
 3725|  1.45k|  const char *e;
 3726|  1.45k|  const char *token_wks;
 3727|  1.45k|  MIMEField  *field;
 3728|  1.45k|  uint32_t    mask = 0;
 3729|       |
 3730|  1.45k|  mime_hdr_cooked_stuff_init(this, changing_field_or_null);
 3731|       |
 3732|       |  /////////////////////////////////////////////////////////////////////////////
 3733|       |  // (1) cook the Cache-Control header (or targeted variant) if present     //
 3734|       |  /////////////////////////////////////////////////////////////////////////////
 3735|       |
 3736|       |  // to be safe, recompute unless you know this call is for other cooked field
 3737|  1.45k|  if ((changing_field_or_null == nullptr) || (changing_field_or_null->m_wks_idx != MIME_WKSIDX_PRAGMA)) {
  ------------------
  |  Branch (3737:7): [True: 0, False: 1.45k]
  |  Branch (3737:46): [True: 394, False: 1.06k]
  ------------------
 3738|    394|    ink_assert(targeted_headers != nullptr || targeted_headers_count == 0);
  ------------------
  |  |   45|    788|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 0, False: 394]
  |  |  |  Branch (45:31): [True: 394, False: 0]
  |  |  ------------------
  ------------------
 3739|    394|    field = nullptr;
 3740|       |
 3741|       |    // Check for targeted cache control headers first (in priority order).
 3742|    394|    for (size_t i = 0; i < targeted_headers_count; ++i) {
  ------------------
  |  Branch (3742:24): [True: 0, False: 394]
  ------------------
 3743|      0|      field = mime_hdr_field_find(this, targeted_headers[i]);
 3744|      0|      if (field) {
  ------------------
  |  Branch (3744:11): [True: 0, False: 0]
  ------------------
 3745|      0|        break;
 3746|      0|      }
 3747|      0|    }
 3748|       |
 3749|       |    // If no targeted header was found, fall back to standard Cache-Control.
 3750|    394|    if (!field) {
  ------------------
  |  Branch (3750:9): [True: 394, False: 0]
  ------------------
 3751|    394|      field = mime_hdr_field_find(this, static_cast<std::string_view>(MIME_FIELD_CACHE_CONTROL));
 3752|    394|    }
 3753|       |
 3754|    394|    if (field) {
  ------------------
  |  Branch (3754:9): [True: 394, False: 0]
  ------------------
 3755|       |      // try pathpaths first -- unlike most other fastpaths, this one
 3756|       |      // is probably more useful for polygraph than for the real world
 3757|    394|      if (!field->has_dups()) {
  ------------------
  |  Branch (3757:11): [True: 187, False: 207]
  ------------------
 3758|    187|        auto val{field->value_get()};
 3759|    187|        if (ptr_len_casecmp(val.data(), val.length(), "public", 6) == 0) {
  ------------------
  |  Branch (3759:13): [True: 17, False: 170]
  ------------------
 3760|     17|          mask                                   = MIME_COOKED_MASK_CC_PUBLIC;
 3761|     17|          m_cooked_stuff.m_cache_control.m_mask |= mask;
 3762|    170|        } else if (ptr_len_casecmp(val.data(), val.length(), "private,no-cache", 16) == 0) {
  ------------------
  |  Branch (3762:20): [True: 10, False: 160]
  ------------------
 3763|     10|          mask                                   = MIME_COOKED_MASK_CC_PRIVATE | MIME_COOKED_MASK_CC_NO_CACHE;
 3764|     10|          m_cooked_stuff.m_cache_control.m_mask |= mask;
 3765|     10|        }
 3766|    187|      }
 3767|       |
 3768|    394|      if (mask == 0) {
  ------------------
  |  Branch (3768:11): [True: 367, False: 27]
  ------------------
 3769|    367|        HdrCsvIter csv_iter;
 3770|       |
 3771|  1.30k|        for (s = csv_iter.get_first(field, &len); s != nullptr; s = csv_iter.get_next(&len)) {
  ------------------
  |  Branch (3771:51): [True: 941, False: 367]
  ------------------
 3772|    941|          e = s + len;
 3773|       |          // Store set mask bits from this CSV value so we can clear them if needed.
 3774|    941|          uint32_t csv_value_mask = 0;
 3775|       |
 3776|  2.70k|          for (c = s; (c < e) && (ParseRules::is_token(*c)); c++) {
  ------------------
  |  Branch (3776:23): [True: 2.00k, False: 694]
  |  Branch (3776:34): [True: 1.76k, False: 247]
  ------------------
 3777|  1.76k|            ;
 3778|  1.76k|          }
 3779|    941|          tlen = c - s;
 3780|       |
 3781|       |          // If >= 0 then this is a well known token
 3782|    941|          if (hdrtoken_tokenize(s, tlen, &token_wks) >= 0) {
  ------------------
  |  Branch (3782:15): [True: 256, False: 685]
  ------------------
 3783|       |#if TRACK_COOKING
 3784|       |            Dbg(dbg_ctl_http, "recompute_cooked_stuff: got field '%s'", token_wks);
 3785|       |#endif
 3786|       |
 3787|    256|            HdrTokenHeapPrefix *p                  = hdrtoken_wks_to_prefix(token_wks);
 3788|    256|            mask                                   = p->wks_type_specific.u.cache_control.cc_mask;
 3789|    256|            m_cooked_stuff.m_cache_control.m_mask |= mask;
 3790|    256|            csv_value_mask                        |= mask;
 3791|       |
 3792|       |#if TRACK_COOKING
 3793|       |            Dbg(dbg_ctl_http, "                        set mask 0x%0X", mask);
 3794|       |#endif
 3795|       |
 3796|    256|            if (mask & (MIME_COOKED_MASK_CC_MAX_AGE | MIME_COOKED_MASK_CC_S_MAXAGE | MIME_COOKED_MASK_CC_MAX_STALE |
  ------------------
  |  Branch (3796:17): [True: 0, False: 256]
  ------------------
 3797|    256|                        MIME_COOKED_MASK_CC_MIN_FRESH)) {
 3798|      0|              int value;
 3799|       |              // Per RFC 7230 Section 3.2.3, there should be no whitespace around '='.
 3800|      0|              const char *value_start = c;
 3801|       |
 3802|       |              // Check if the next character is '=' (no space allowed before '=').
 3803|      0|              if (c < e && *c == '=') {
  ------------------
  |  Branch (3803:19): [True: 0, False: 0]
  |  Branch (3803:28): [True: 0, False: 0]
  ------------------
 3804|      0|                ++c; // Move past the '='
 3805|       |
 3806|       |                // Again: no whitespace after the '=' either. Keep in mind that values can be negative.
 3807|      0|                bool valid_syntax = (c < e) && (is_digit(*c) || *c == '-');
  ------------------
  |  Branch (3807:37): [True: 0, False: 0]
  |  Branch (3807:49): [True: 0, False: 0]
  |  Branch (3807:65): [True: 0, False: 0]
  ------------------
 3808|       |
 3809|      0|                if (valid_syntax) {
  ------------------
  |  Branch (3809:21): [True: 0, False: 0]
  ------------------
 3810|       |                  // Reset to value_start to let mime_parse_integer do its work.
 3811|      0|                  c = value_start;
 3812|      0|                  if (mime_parse_integer(c, e, &value)) {
  ------------------
  |  Branch (3812:23): [True: 0, False: 0]
  ------------------
 3813|       |#if TRACK_COOKING
 3814|       |                    Dbg(dbg_ctl_http, "                        set integer value %d", value);
 3815|       |#endif
 3816|      0|                    if (token_wks == MIME_VALUE_MAX_AGE.c_str()) {
  ------------------
  |  Branch (3816:25): [True: 0, False: 0]
  ------------------
 3817|      0|                      m_cooked_stuff.m_cache_control.m_secs_max_age = value;
 3818|      0|                    } else if (token_wks == MIME_VALUE_MIN_FRESH.c_str()) {
  ------------------
  |  Branch (3818:32): [True: 0, False: 0]
  ------------------
 3819|      0|                      m_cooked_stuff.m_cache_control.m_secs_min_fresh = value;
 3820|      0|                    } else if (token_wks == MIME_VALUE_MAX_STALE.c_str()) {
  ------------------
  |  Branch (3820:32): [True: 0, False: 0]
  ------------------
 3821|      0|                      m_cooked_stuff.m_cache_control.m_secs_max_stale = value;
 3822|      0|                    } else if (token_wks == MIME_VALUE_S_MAXAGE.c_str()) {
  ------------------
  |  Branch (3822:32): [True: 0, False: 0]
  ------------------
 3823|      0|                      m_cooked_stuff.m_cache_control.m_secs_s_maxage = value;
 3824|      0|                    }
 3825|      0|                  } else {
 3826|       |#if TRACK_COOKING
 3827|       |                    Dbg(dbg_ctl_http, "                        set integer value %d", INT_MAX);
 3828|       |#endif
 3829|      0|                    if (token_wks == MIME_VALUE_MAX_STALE.c_str()) {
  ------------------
  |  Branch (3829:25): [True: 0, False: 0]
  ------------------
 3830|      0|                      m_cooked_stuff.m_cache_control.m_secs_max_stale = INT_MAX;
 3831|      0|                    }
 3832|      0|                  }
 3833|      0|                } else {
 3834|       |                  // Syntax is malformed (e.g., whitespace after '=', quotes around value, or no value).
 3835|       |                  // Treat this as unrecognized and clear the mask.
 3836|      0|                  csv_value_mask                         = 0;
 3837|      0|                  m_cooked_stuff.m_cache_control.m_mask &= ~mask;
 3838|      0|                }
 3839|      0|              } else {
 3840|       |                // No '=' found, or whitespace before '='. This is malformed.
 3841|       |                // For directives that require values, this is an error.
 3842|       |                // Clear the mask for this directive.
 3843|      0|                csv_value_mask                         = 0;
 3844|      0|                m_cooked_stuff.m_cache_control.m_mask &= ~mask;
 3845|      0|              }
 3846|      0|            }
 3847|       |
 3848|       |            // Detect whether there is any more non-whitespace content after the
 3849|       |            // directive. This indicates an unrecognized or malformed directive.
 3850|       |            // This can happen, for instance, if the host uses semicolons
 3851|       |            // instead of commas as separators which is against RFC 7234 (see
 3852|       |            // issue #12029). Regardless of the cause, this means we need to
 3853|       |            // ignore the directive and clear any mask bits we set from it.
 3854|    258|            while (c < e && ParseRules::is_ws(*c)) {
  ------------------
  |  Branch (3854:20): [True: 7, False: 251]
  |  Branch (3854:29): [True: 2, False: 5]
  ------------------
 3855|      2|              ++c;
 3856|      2|            }
 3857|    256|            if (c < e) {
  ------------------
  |  Branch (3857:17): [True: 5, False: 251]
  ------------------
 3858|       |              // There's non-whitespace content that wasn't parsed. This means
 3859|       |              // that we cannot really understand what this directive is.
 3860|       |              // Per RFC 7234 Section 5.2: "A cache MUST ignore unrecognized cache
 3861|       |              // directives."
 3862|      5|              if (csv_value_mask != 0) {
  ------------------
  |  Branch (3862:19): [True: 0, False: 5]
  ------------------
 3863|       |                // Reverse the mask that we set above.
 3864|      0|                m_cooked_stuff.m_cache_control.m_mask &= ~csv_value_mask;
 3865|      0|              }
 3866|      5|            }
 3867|    256|          }
 3868|    941|        }
 3869|    367|      }
 3870|    394|    }
 3871|    394|  }
 3872|       |  ///////////////////////////////////////////
 3873|       |  // (2) cook the Pragma header if present //
 3874|       |  ///////////////////////////////////////////
 3875|       |
 3876|  1.45k|  if ((changing_field_or_null == nullptr) || (changing_field_or_null->m_wks_idx != MIME_WKSIDX_CACHE_CONTROL)) {
  ------------------
  |  Branch (3876:7): [True: 0, False: 1.45k]
  |  Branch (3876:46): [True: 1.06k, False: 394]
  ------------------
 3877|  1.06k|    field = mime_hdr_field_find(this, static_cast<std::string_view>(MIME_FIELD_PRAGMA));
 3878|  1.06k|    if (field) {
  ------------------
  |  Branch (3878:9): [True: 1.06k, False: 0]
  ------------------
 3879|  1.06k|      if (!field->has_dups()) { // try fastpath first
  ------------------
  |  Branch (3879:11): [True: 349, False: 711]
  ------------------
 3880|    349|        auto val{field->value_get()};
 3881|    349|        if (ptr_len_casecmp(val.data(), val.length(), "no-cache", 8) == 0) {
  ------------------
  |  Branch (3881:13): [True: 10, False: 339]
  ------------------
 3882|     10|          m_cooked_stuff.m_pragma.m_no_cache = true;
 3883|     10|          return;
 3884|     10|        }
 3885|    349|      }
 3886|       |
 3887|  1.05k|      {
 3888|  1.05k|        HdrCsvIter csv_iter;
 3889|       |
 3890|  5.36k|        for (s = csv_iter.get_first(field, &len); s != nullptr; s = csv_iter.get_next(&len)) {
  ------------------
  |  Branch (3890:51): [True: 4.31k, False: 1.05k]
  ------------------
 3891|  4.31k|          e = s + len;
 3892|  12.1k|          for (c = s; (c < e) && (ParseRules::is_token(*c)); c++) {
  ------------------
  |  Branch (3892:23): [True: 8.85k, False: 3.30k]
  |  Branch (3892:34): [True: 7.84k, False: 1.01k]
  ------------------
 3893|  7.84k|            ;
 3894|  7.84k|          }
 3895|  4.31k|          tlen = c - s;
 3896|       |
 3897|  4.31k|          if (hdrtoken_tokenize(s, tlen, &token_wks) >= 0) {
  ------------------
  |  Branch (3897:15): [True: 398, False: 3.91k]
  ------------------
 3898|    398|            if (token_wks == MIME_VALUE_NO_CACHE.c_str()) {
  ------------------
  |  Branch (3898:17): [True: 197, False: 201]
  ------------------
 3899|    197|              m_cooked_stuff.m_pragma.m_no_cache = true;
 3900|    197|            }
 3901|    398|          }
 3902|  4.31k|        }
 3903|  1.05k|      }
 3904|  1.05k|    }
 3905|  1.06k|  }
 3906|  1.45k|}
_Z44mime_hdr_init_accelerators_and_presence_bitsP11MIMEHdrImpl:
  421|  18.7k|{
  422|  18.7k|  mh->m_presence_bits        = 0;
  423|  18.7k|  mh->m_slot_accelerators[0] = 0xFFFFFFFF;
  424|  18.7k|  mh->m_slot_accelerators[1] = 0xFFFFFFFF;
  425|  18.7k|  mh->m_slot_accelerators[2] = 0xFFFFFFFF;
  426|  18.7k|  mh->m_slot_accelerators[3] = 0xFFFFFFFF;
  427|  18.7k|}
_Z32mime_hdr_get_accelerator_slotnumP11MIMEHdrImpli:
  431|  4.08k|{
  432|  4.08k|  ink_assert((slot_id != MIME_SLOTID_NONE) && (slot_id < 32));
  ------------------
  |  |   45|  8.16k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 4.08k, False: 0]
  |  |  |  Branch (45:31): [True: 4.08k, False: 0]
  |  |  ------------------
  ------------------
  433|       |
  434|  4.08k|  uint32_t word_index = slot_id / 8;                         // 4 words of 8 slots
  435|  4.08k|  uint32_t word       = mh->m_slot_accelerators[word_index]; // 8 slots of 4 bits each
  436|  4.08k|  uint32_t nybble     = slot_id % 8;                         // which of the 8 nybbles?
  437|  4.08k|  uint32_t slot       = ((word >> (nybble * 4)) & 15);       // grab the 4 bit slotnum
  438|  4.08k|  return slot;
  439|  4.08k|}
_Z43mime_hdr_set_accelerators_and_presence_bitsP11MIMEHdrImplP9MIMEField:
  460|  36.6k|{
  461|  36.6k|  int       slot_id;
  462|  36.6k|  ptrdiff_t slot_num;
  463|  36.6k|  if (field->m_wks_idx < 0) {
  ------------------
  |  Branch (463:7): [True: 34.0k, False: 2.56k]
  ------------------
  464|  34.0k|    return;
  465|  34.0k|  }
  466|       |
  467|  2.56k|  ink_assert(mh);
  ------------------
  |  |   45|  2.56k|#define ink_assert(EX) (void)(EX)
  ------------------
  468|       |
  469|  2.56k|  mime_hdr_presence_set(mh, field->m_wks_idx);
  470|       |
  471|  2.56k|  slot_id = hdrtoken_index_to_slotid(field->m_wks_idx);
  472|  2.56k|  if (slot_id != MIME_SLOTID_NONE) {
  ------------------
  |  |  295|  2.56k|#define MIME_SLOTID_NONE -1
  ------------------
  |  Branch (472:7): [True: 2.04k, False: 521]
  ------------------
  473|  2.04k|    if (mh->m_first_fblock.contains(field)) {
  ------------------
  |  Branch (473:9): [True: 1.25k, False: 788]
  ------------------
  474|  1.25k|      slot_num = (field - &(mh->m_first_fblock.m_field_slots[0]));
  475|       |      // contains() assure that the field is in the block, and the calculated
  476|       |      // slot_num will be between 0 and 15, which seem valid.
  477|       |      // However, strangely, this function regards slot number 14 and 15 as
  478|       |      // unknown for some reason that is not clear. It might be a bug.
  479|       |      // The block below is left to keep the original behavior. See also TS-4316.
  480|  1.25k|      if (slot_num >= MIME_FIELD_SLOTNUM_UNKNOWN) {
  ------------------
  |  |   91|  1.25k|#define MIME_FIELD_SLOTNUM_UNKNOWN MIME_FIELD_SLOTNUM_MAX
  |  |  ------------------
  |  |  |  |   90|  1.25k|#define MIME_FIELD_SLOTNUM_MAX     (MIME_FIELD_SLOTNUM_MASK - 1)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|  1.25k|#define MIME_FIELD_SLOTNUM_MASK    ((1 << MIME_FIELD_SLOTNUM_BITS) - 1)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   88|  1.25k|#define MIME_FIELD_SLOTNUM_BITS    4
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  |  Branch (480:11): [True: 82, False: 1.17k]
  ------------------
  481|     82|        slot_num = MIME_FIELD_SLOTNUM_UNKNOWN;
  ------------------
  |  |   91|     82|#define MIME_FIELD_SLOTNUM_UNKNOWN MIME_FIELD_SLOTNUM_MAX
  |  |  ------------------
  |  |  |  |   90|     82|#define MIME_FIELD_SLOTNUM_MAX     (MIME_FIELD_SLOTNUM_MASK - 1)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|     82|#define MIME_FIELD_SLOTNUM_MASK    ((1 << MIME_FIELD_SLOTNUM_BITS) - 1)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   88|     82|#define MIME_FIELD_SLOTNUM_BITS    4
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  482|     82|      }
  483|  1.25k|    } else {
  484|    788|      slot_num = MIME_FIELD_SLOTNUM_UNKNOWN;
  ------------------
  |  |   91|    788|#define MIME_FIELD_SLOTNUM_UNKNOWN MIME_FIELD_SLOTNUM_MAX
  |  |  ------------------
  |  |  |  |   90|    788|#define MIME_FIELD_SLOTNUM_MAX     (MIME_FIELD_SLOTNUM_MASK - 1)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|    788|#define MIME_FIELD_SLOTNUM_MASK    ((1 << MIME_FIELD_SLOTNUM_BITS) - 1)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   88|    788|#define MIME_FIELD_SLOTNUM_BITS    4
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  485|    788|    }
  486|  2.04k|    mime_hdr_set_accelerator_slotnum(mh, slot_id, slot_num);
  487|  2.04k|  }
  488|  2.56k|}
_Z32mime_hdr_set_accelerator_slotnumP11MIMEHdrImplij:
  443|  2.15k|{
  444|  2.15k|  ink_assert((slot_id != MIME_SLOTID_NONE) && (slot_id < 32));
  ------------------
  |  |   45|  4.30k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 2.15k, False: 0]
  |  |  |  Branch (45:31): [True: 2.15k, False: 0]
  |  |  ------------------
  ------------------
  445|  2.15k|  ink_assert(slot_num < 16);
  ------------------
  |  |   45|  2.15k|#define ink_assert(EX) (void)(EX)
  ------------------
  446|       |
  447|  2.15k|  uint32_t word_index = slot_id / 8;                         // 4 words of 8 slots
  448|  2.15k|  uint32_t word       = mh->m_slot_accelerators[word_index]; // 8 slots of 4 bits each
  449|  2.15k|  uint32_t nybble     = slot_id % 8;                         // which of the 8 nybbles?
  450|  2.15k|  uint32_t shift      = nybble * 4;                          // shift in chunks of 4 bits
  451|  2.15k|  uint32_t mask       = ~(MIME_FIELD_SLOTNUM_MASK << shift); // mask to zero out old slot
  ------------------
  |  |   89|  2.15k|#define MIME_FIELD_SLOTNUM_MASK    ((1 << MIME_FIELD_SLOTNUM_BITS) - 1)
  |  |  ------------------
  |  |  |  |   88|  2.15k|#define MIME_FIELD_SLOTNUM_BITS    4
  |  |  ------------------
  ------------------
  452|  2.15k|  uint32_t graft      = (slot_num << shift);                 // plug to insert into slot
  453|  2.15k|  uint32_t new_word   = (word & mask) | graft;               // new value
  454|       |
  455|  2.15k|  mh->m_slot_accelerators[word_index] = new_word;
  456|  2.15k|}
_Z45mime_hdr_unset_accelerators_and_presence_bitsP11MIMEHdrImplP9MIMEField:
  492|    106|{
  493|    106|  int slot_id;
  494|    106|  if (field->m_wks_idx < 0) {
  ------------------
  |  Branch (494:7): [True: 0, False: 106]
  ------------------
  495|      0|    return;
  496|      0|  }
  497|       |
  498|    106|  mime_hdr_presence_unset(mh, field->m_wks_idx);
  499|       |
  500|    106|  slot_id = hdrtoken_index_to_slotid(field->m_wks_idx);
  501|    106|  if (slot_id != MIME_SLOTID_NONE) {
  ------------------
  |  |  295|    106|#define MIME_SLOTID_NONE -1
  ------------------
  |  Branch (501:7): [True: 106, False: 0]
  ------------------
  502|    106|    mime_hdr_set_accelerator_slotnum(mh, slot_id, MIME_FIELD_SLOTNUM_MAX);
  ------------------
  |  |   90|    106|#define MIME_FIELD_SLOTNUM_MAX     (MIME_FIELD_SLOTNUM_MASK - 1)
  |  |  ------------------
  |  |  |  |   89|    106|#define MIME_FIELD_SLOTNUM_MASK    ((1 << MIME_FIELD_SLOTNUM_BITS) - 1)
  |  |  |  |  ------------------
  |  |  |  |  |  |   88|    106|#define MIME_FIELD_SLOTNUM_BITS    4
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  503|    106|  }
  504|    106|}
MIME.cc:_ZL5is_wsc:
  347|  20.0k|{
  348|  20.0k|  return ((c == ParseRules::CHAR_SP) || (c == ParseRules::CHAR_HT));
  ------------------
  |  Branch (348:11): [True: 227, False: 19.7k]
  |  Branch (348:41): [True: 8, False: 19.7k]
  ------------------
  349|  20.0k|}

_Z18validate_host_nameNSt3__117basic_string_viewIcNS_11char_traitsIcEEEE:
  103|    765|{
  104|    765|  return std::all_of(addr.begin(), addr.end(), &is_host_char);
  105|    765|}
_Z15validate_schemeNSt3__117basic_string_viewIcNS_11char_traitsIcEEEE:
  117|    260|{
  118|    260|  if (scheme.empty()) {
  ------------------
  |  Branch (118:7): [True: 6, False: 254]
  ------------------
  119|      6|    return false;
  120|      6|  }
  121|       |
  122|    254|  if (!ParseRules::is_alpha(scheme[0])) {
  ------------------
  |  Branch (122:7): [True: 9, False: 245]
  ------------------
  123|      9|    return false;
  124|      9|  }
  125|       |
  126|  12.4k|  for (size_t i = 0; i < scheme.size(); ++i) {
  ------------------
  |  Branch (126:22): [True: 12.2k, False: 218]
  ------------------
  127|  12.2k|    const char &c = scheme[i];
  128|       |
  129|  12.2k|    if (!(ParseRules::is_alnum(c) != 0 || c == '+' || c == '-' || c == '.')) {
  ------------------
  |  Branch (129:11): [True: 9.94k, False: 2.30k]
  |  Branch (129:43): [True: 647, False: 1.65k]
  |  Branch (129:55): [True: 304, False: 1.35k]
  |  Branch (129:67): [True: 1.32k, False: 27]
  ------------------
  130|     27|      return false;
  131|     27|    }
  132|  12.2k|  }
  133|       |
  134|    218|  return true;
  135|    245|}
_Z8url_initv:
  142|      1|{
  143|      1|  static int init = 1;
  144|       |
  145|      1|  if (init) {
  ------------------
  |  Branch (145:7): [True: 1, False: 0]
  ------------------
  146|      1|    init = 0;
  147|       |
  148|      1|    hdrtoken_init();
  149|       |
  150|      1|    URL_SCHEME_FILE      = hdrtoken_string_to_wks_sv("file");
  151|      1|    URL_SCHEME_FTP       = hdrtoken_string_to_wks_sv("ftp");
  152|      1|    URL_SCHEME_GOPHER    = hdrtoken_string_to_wks_sv("gopher");
  153|      1|    URL_SCHEME_HTTP      = hdrtoken_string_to_wks_sv("http");
  154|      1|    URL_SCHEME_HTTP_UDS  = c_str_view("http+unix", 9);
  155|      1|    URL_SCHEME_HTTPS     = hdrtoken_string_to_wks_sv("https");
  156|      1|    URL_SCHEME_HTTPS_UDS = c_str_view("https+unix", 10);
  157|      1|    URL_SCHEME_WSS       = hdrtoken_string_to_wks_sv("wss");
  158|      1|    URL_SCHEME_WS        = hdrtoken_string_to_wks_sv("ws");
  159|      1|    URL_SCHEME_MAILTO    = hdrtoken_string_to_wks_sv("mailto");
  160|      1|    URL_SCHEME_NEWS      = hdrtoken_string_to_wks_sv("news");
  161|      1|    URL_SCHEME_NNTP      = hdrtoken_string_to_wks_sv("nntp");
  162|      1|    URL_SCHEME_PROSPERO  = hdrtoken_string_to_wks_sv("prospero");
  163|      1|    URL_SCHEME_TELNET    = hdrtoken_string_to_wks_sv("telnet");
  164|      1|    URL_SCHEME_TUNNEL    = hdrtoken_string_to_wks_sv("tunnel");
  165|      1|    URL_SCHEME_WAIS      = hdrtoken_string_to_wks_sv("wais");
  166|      1|    URL_SCHEME_PNM       = hdrtoken_string_to_wks_sv("pnm");
  167|      1|    URL_SCHEME_RTSP      = hdrtoken_string_to_wks_sv("rtsp");
  168|      1|    URL_SCHEME_RTSPU     = hdrtoken_string_to_wks_sv("rtspu");
  169|      1|    URL_SCHEME_MMS       = hdrtoken_string_to_wks_sv("mms");
  170|      1|    URL_SCHEME_MMSU      = hdrtoken_string_to_wks_sv("mmsu");
  171|      1|    URL_SCHEME_MMST      = hdrtoken_string_to_wks_sv("mmst");
  172|       |
  173|      1|    ink_assert(URL_SCHEME_FILE.c_str() && URL_SCHEME_FTP.c_str() && URL_SCHEME_GOPHER.c_str() && URL_SCHEME_HTTP.c_str() &&
  ------------------
  |  |   45|     42|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  |  Branch (45:31): [True: 1, False: 0]
  |  |  ------------------
  ------------------
  174|      1|               URL_SCHEME_HTTP_UDS.c_str() && URL_SCHEME_HTTPS.c_str() && URL_SCHEME_HTTPS_UDS.c_str() && URL_SCHEME_WS.c_str() &&
  175|      1|               URL_SCHEME_WSS.c_str() && URL_SCHEME_MAILTO.c_str() && URL_SCHEME_NEWS.c_str() && URL_SCHEME_NNTP.c_str() &&
  176|      1|               URL_SCHEME_PROSPERO.c_str() && URL_SCHEME_TELNET.c_str() && URL_SCHEME_TUNNEL.c_str() && URL_SCHEME_WAIS.c_str() &&
  177|      1|               URL_SCHEME_PNM.c_str() && URL_SCHEME_RTSP.c_str() && URL_SCHEME_RTSPU.c_str() && URL_SCHEME_MMS.c_str() &&
  178|      1|               URL_SCHEME_MMSU.c_str() && URL_SCHEME_MMST.c_str());
  179|       |
  180|      1|    URL_WKSIDX_FILE     = hdrtoken_wks_to_index(URL_SCHEME_FILE.c_str());
  181|      1|    URL_WKSIDX_FTP      = hdrtoken_wks_to_index(URL_SCHEME_FTP.c_str());
  182|      1|    URL_WKSIDX_GOPHER   = hdrtoken_wks_to_index(URL_SCHEME_GOPHER.c_str());
  183|      1|    URL_WKSIDX_HTTP     = hdrtoken_wks_to_index(URL_SCHEME_HTTP.c_str());
  184|      1|    URL_WKSIDX_HTTPS    = hdrtoken_wks_to_index(URL_SCHEME_HTTPS.c_str());
  185|      1|    URL_WKSIDX_WS       = hdrtoken_wks_to_index(URL_SCHEME_WS.c_str());
  186|      1|    URL_WKSIDX_WSS      = hdrtoken_wks_to_index(URL_SCHEME_WSS.c_str());
  187|      1|    URL_WKSIDX_MAILTO   = hdrtoken_wks_to_index(URL_SCHEME_MAILTO.c_str());
  188|      1|    URL_WKSIDX_NEWS     = hdrtoken_wks_to_index(URL_SCHEME_NEWS.c_str());
  189|      1|    URL_WKSIDX_NNTP     = hdrtoken_wks_to_index(URL_SCHEME_NNTP.c_str());
  190|      1|    URL_WKSIDX_PROSPERO = hdrtoken_wks_to_index(URL_SCHEME_PROSPERO.c_str());
  191|      1|    URL_WKSIDX_TELNET   = hdrtoken_wks_to_index(URL_SCHEME_TELNET.c_str());
  192|      1|    URL_WKSIDX_TUNNEL   = hdrtoken_wks_to_index(URL_SCHEME_TUNNEL.c_str());
  193|      1|    URL_WKSIDX_WAIS     = hdrtoken_wks_to_index(URL_SCHEME_WAIS.c_str());
  194|      1|    URL_WKSIDX_PNM      = hdrtoken_wks_to_index(URL_SCHEME_PNM.c_str());
  195|      1|    URL_WKSIDX_RTSP     = hdrtoken_wks_to_index(URL_SCHEME_RTSP.c_str());
  196|      1|    URL_WKSIDX_RTSPU    = hdrtoken_wks_to_index(URL_SCHEME_RTSPU.c_str());
  197|      1|    URL_WKSIDX_MMS      = hdrtoken_wks_to_index(URL_SCHEME_MMS.c_str());
  198|      1|    URL_WKSIDX_MMSU     = hdrtoken_wks_to_index(URL_SCHEME_MMSU.c_str());
  199|      1|    URL_WKSIDX_MMST     = hdrtoken_wks_to_index(URL_SCHEME_MMST.c_str());
  200|      1|  }
  201|      1|}
_Z10url_createP7HdrHeap:
  214|  9.36k|{
  215|  9.36k|  URLImpl *url;
  216|       |
  217|  9.36k|  url = (URLImpl *)heap->allocate_obj(sizeof(URLImpl), HdrHeapObjType::URL);
  218|  9.36k|  obj_clear_data((HdrHeapObjImpl *)url);
  219|  9.36k|  url->m_url_type       = URLType::NONE;
  220|  9.36k|  url->m_scheme_wks_idx = -1;
  221|  9.36k|  url_clear_string_ref(url);
  222|  9.36k|  return url;
  223|  9.36k|}
_ZN7URLImpl10set_schemeEP7HdrHeapNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEib:
  393|    247|{
  394|    247|  const char *scheme_wks;
  395|    247|  url_called_set(this);
  396|    247|  if (value.empty()) {
  ------------------
  |  Branch (396:7): [True: 0, False: 247]
  ------------------
  397|      0|    value = {nullptr, 0};
  398|      0|  }
  399|       |
  400|    247|  mime_str_u16_set(heap, value, &(this->m_ptr_scheme), &(this->m_len_scheme), copy_string);
  401|       |
  402|    247|  this->m_scheme_wks_idx = scheme_wks_idx;
  403|    247|  if (scheme_wks_idx >= 0) {
  ------------------
  |  Branch (403:7): [True: 52, False: 195]
  ------------------
  404|     52|    scheme_wks = hdrtoken_index_to_wks(scheme_wks_idx);
  405|    195|  } else {
  406|    195|    scheme_wks = nullptr;
  407|    195|  }
  408|       |
  409|    247|  if (scheme_wks == nullptr) {
  ------------------
  |  Branch (409:7): [True: 195, False: 52]
  ------------------
  410|    195|    if (value == static_cast<std::string_view>(URL_SCHEME_HTTP_UDS)) {
  ------------------
  |  Branch (410:9): [True: 6, False: 189]
  ------------------
  411|      6|      this->m_url_type = URLType::HTTP;
  412|    189|    } else if (value == static_cast<std::string_view>(URL_SCHEME_HTTPS_UDS)) {
  ------------------
  |  Branch (412:16): [True: 6, False: 183]
  ------------------
  413|      6|      this->m_url_type = URLType::HTTPS;
  414|    183|    } else {
  415|    183|      this->m_url_type = URLType::HTTP;
  416|    183|    }
  417|    195|  } else if (scheme_wks == URL_SCHEME_HTTP.c_str() || scheme_wks == URL_SCHEME_WS.c_str()) {
  ------------------
  |  Branch (417:14): [True: 6, False: 46]
  |  Branch (417:55): [True: 7, False: 39]
  ------------------
  418|     13|    this->m_url_type = URLType::HTTP;
  419|     39|  } else if (scheme_wks == URL_SCHEME_HTTPS.c_str() || scheme_wks == URL_SCHEME_WSS.c_str()) {
  ------------------
  |  Branch (419:14): [True: 6, False: 33]
  |  Branch (419:56): [True: 6, False: 27]
  ------------------
  420|     12|    this->m_url_type = URLType::HTTPS;
  421|     27|  } else {
  422|     27|    this->m_url_type = URLType::HTTP;
  423|     27|  }
  424|       |
  425|    247|  return scheme_wks; // tokenized string or NULL if not well known
  426|    247|}
_ZN7URLImpl8set_userEP7HdrHeapNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEb:
  433|     63|{
  434|     63|  url_called_set(this);
  435|     63|  if (value.empty()) {
  ------------------
  |  Branch (435:7): [True: 0, False: 63]
  ------------------
  436|      0|    value = {nullptr, 0};
  437|      0|  }
  438|     63|  mime_str_u16_set(heap, value, &(this->m_ptr_user), &(this->m_len_user), copy_string);
  439|     63|}
_ZN7URLImpl12set_passwordEP7HdrHeapNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEb:
  446|     17|{
  447|     17|  url_called_set(this);
  448|     17|  if (value.empty()) {
  ------------------
  |  Branch (448:7): [True: 0, False: 17]
  ------------------
  449|      0|    value = {nullptr, 0};
  450|      0|  }
  451|     17|  mime_str_u16_set(heap, value, &(this->m_ptr_password), &(this->m_len_password), copy_string);
  452|     17|}
_ZN7URLImpl8set_hostEP7HdrHeapNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEb:
  459|    384|{
  460|    384|  url_called_set(this);
  461|    384|  if (value.empty()) {
  ------------------
  |  Branch (461:7): [True: 0, False: 384]
  ------------------
  462|      0|    value = {nullptr, 0};
  463|      0|  }
  464|    384|  mime_str_u16_set(heap, value, &(this->m_ptr_host), &(this->m_len_host), copy_string);
  465|    384|}
_ZN7URLImpl8set_portEP7HdrHeapNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEb:
  472|     85|{
  473|     85|  url_called_set(this);
  474|     85|  if (value.empty()) {
  ------------------
  |  Branch (474:7): [True: 0, False: 85]
  ------------------
  475|      0|    value = {nullptr, 0};
  476|      0|  }
  477|     85|  mime_str_u16_set(heap, value, &(this->m_ptr_port), &(this->m_len_port), copy_string);
  478|       |
  479|     85|  this->m_port = 0;
  480|    463|  for (auto digit : value) {
  ------------------
  |  Branch (480:19): [True: 463, False: 14]
  ------------------
  481|    463|    if (!ParseRules::is_digit(digit)) {
  ------------------
  |  Branch (481:9): [True: 71, False: 392]
  ------------------
  482|     71|      break;
  483|     71|    }
  484|    392|    this->m_port = this->m_port * 10 + (digit - '0');
  485|    392|  }
  486|     85|}
_ZN7URLImpl8set_pathEP7HdrHeapNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEb:
  513|    854|{
  514|    854|  url_called_set(this);
  515|    854|  if (value.empty()) {
  ------------------
  |  Branch (515:7): [True: 699, False: 155]
  ------------------
  516|    699|    value = {nullptr, 0};
  517|    699|  }
  518|    854|  mime_str_u16_set(heap, value, &(this->m_ptr_path), &(this->m_len_path), copy_string);
  519|    854|}
_ZN7URLImpl9set_queryEP7HdrHeapNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEb:
  529|    153|{
  530|    153|  url_called_set(this);
  531|    153|  mime_str_u16_set(heap, value, &(this->m_ptr_query), &(this->m_len_query), copy_string);
  532|    153|}
_ZN7URLImpl12set_fragmentEP7HdrHeapNSt3__117basic_string_viewIcNS2_11char_traitsIcEEEEb:
  539|    119|{
  540|    119|  url_called_set(this);
  541|    119|  mime_str_u16_set(heap, value, &(this->m_ptr_fragment), &(this->m_len_fragment), copy_string);
  542|    119|}
_Z14url_called_setP7URLImpl:
  578|  1.92k|{
  579|  1.92k|  url->m_clean = !url->m_ptr_printed_string;
  580|  1.92k|}
_Z20url_clear_string_refP7URLImpl:
  584|  9.36k|{
  585|  9.36k|  if (url->m_ptr_printed_string) {
  ------------------
  |  Branch (585:7): [True: 0, False: 9.36k]
  ------------------
  586|      0|    url->m_len_printed_string = 0;
  587|      0|    url->m_ptr_printed_string = nullptr;
  588|      0|    url->m_clean              = true;
  589|      0|  }
  590|  9.36k|  return;
  591|  9.36k|}
_ZNK7URLImpl10get_schemeEv:
  688|    890|{
  689|    890|  if (this->m_scheme_wks_idx >= 0) {
  ------------------
  |  Branch (689:7): [True: 13, False: 877]
  ------------------
  690|     13|    return {hdrtoken_index_to_wks(this->m_scheme_wks_idx),
  691|     13|            static_cast<std::string_view::size_type>(hdrtoken_index_to_length(this->m_scheme_wks_idx))};
  692|    877|  } else {
  693|    877|    return {this->m_ptr_scheme, static_cast<std::string_view::size_type>(this->m_len_scheme)};
  694|    877|  }
  695|    890|}
_ZNK7URLImpl8get_hostEv:
  720|    890|{
  721|    890|  return {this->m_ptr_host, static_cast<std::string_view::size_type>(this->m_len_host)};
  722|    890|}
_ZNK7URLImpl8get_pathEv:
  738|    890|{
  739|    890|  return {this->m_ptr_path, static_cast<std::string_view::size_type>(this->m_len_path)};
  740|    890|}
_Z16url_parse_schemeP7HdrHeapP7URLImplPPKcS4_b:
 1107|  1.97k|{
 1108|  1.97k|  const char *cur = *start;
 1109|  1.97k|  const char *scheme_wks;
 1110|  1.97k|  const char *scheme_start = nullptr;
 1111|  1.97k|  const char *scheme_end   = nullptr;
 1112|  1.97k|  int         scheme_wks_idx;
 1113|       |
 1114|       |  // Skip over spaces
 1115|  1.97k|  while (' ' == *cur && ++cur < end) {}
  ------------------
  |  Branch (1115:10): [True: 0, False: 1.97k]
  |  Branch (1115:25): [True: 0, False: 0]
  ------------------
 1116|       |
 1117|  1.97k|  if (cur < end) {
  ------------------
  |  Branch (1117:7): [True: 1.84k, False: 130]
  ------------------
 1118|  1.84k|    scheme_start = scheme_end = cur;
 1119|       |
 1120|       |    // If the URL is more complex then a path, parse to see if there is a scheme
 1121|  1.84k|    if ('/' != *cur) {
  ------------------
  |  Branch (1121:9): [True: 1.08k, False: 759]
  ------------------
 1122|       |      // Search for a : it could be part of a scheme or a username:password
 1123|  24.2k|      while (':' != *cur && ++cur < end) {}
  ------------------
  |  Branch (1123:14): [True: 23.7k, False: 542]
  |  Branch (1123:29): [True: 23.2k, False: 546]
  ------------------
 1124|       |
 1125|       |      // If there is a :// then there is a scheme
 1126|  1.08k|      if (cur + 2 < end && cur[1] == '/' && cur[2] == '/') { // found "://"
  ------------------
  |  Branch (1126:11): [True: 481, False: 607]
  |  Branch (1126:28): [True: 310, False: 171]
  |  Branch (1126:45): [True: 289, False: 21]
  ------------------
 1127|    289|        scheme_end     = cur;
 1128|    289|        scheme_wks_idx = hdrtoken_tokenize(scheme_start, scheme_end - scheme_start, &scheme_wks);
 1129|       |
 1130|    289|        if (!(scheme_wks_idx > 0 && hdrtoken_wks_to_token_type(scheme_wks) == HdrTokenType::SCHEME)) {
  ------------------
  |  Branch (1130:15): [True: 50, False: 239]
  |  Branch (1130:37): [True: 29, False: 21]
  ------------------
 1131|       |          // Unknown scheme, validate the scheme
 1132|    260|          if (!validate_scheme({scheme_start, static_cast<size_t>(scheme_end - scheme_start)})) {
  ------------------
  |  Branch (1132:15): [True: 42, False: 218]
  ------------------
 1133|     42|            return ParseResult::ERROR;
 1134|     42|          }
 1135|    260|        }
 1136|    247|        url->set_scheme(heap, std::string_view{scheme_start, static_cast<std::string_view::size_type>(scheme_end - scheme_start)},
 1137|    247|                        scheme_wks_idx, copy_strings_p);
 1138|    247|      }
 1139|  1.08k|    }
 1140|  1.80k|    *start = scheme_end;
 1141|  1.80k|    return ParseResult::CONT;
 1142|  1.84k|  }
 1143|    130|  return ParseResult::ERROR; // no non-whitespace found
 1144|  1.97k|}
_Z9url_parseP7HdrHeapP7URLImplPPKcS4_bib:
 1194|  1.97k|{
 1195|  1.97k|  if (strict_uri_parsing == 1 && !url_is_strictly_compliant(*start, end)) {
  ------------------
  |  Branch (1195:7): [True: 0, False: 1.97k]
  |  Branch (1195:34): [True: 0, False: 0]
  ------------------
 1196|      0|    return ParseResult::ERROR;
 1197|      0|  }
 1198|  1.97k|  if (strict_uri_parsing == 2 && !url_is_mostly_compliant(*start, end)) {
  ------------------
  |  Branch (1198:7): [True: 0, False: 1.97k]
  |  Branch (1198:34): [True: 0, False: 0]
  ------------------
 1199|      0|    return ParseResult::ERROR;
 1200|      0|  }
 1201|       |
 1202|  1.97k|  ParseResult zret = url_parse_scheme(heap, url, start, end, copy_strings_p);
 1203|  1.97k|  return ParseResult::CONT == zret ? url_parse_http(heap, url, start, end, copy_strings_p, verify_host_characters) : zret;
  ------------------
  |  Branch (1203:10): [True: 1.80k, False: 172]
  ------------------
 1204|  1.97k|}
_Z18url_parse_internetP7HdrHeapP7URLImplPPKcS4_bb:
 1235|  1.80k|{
 1236|  1.80k|  const char         *cur = *start;
 1237|  1.80k|  const char         *base;              // Base for host/port field.
 1238|  1.80k|  const char         *bracket = nullptr; // marker for open bracket, if any.
 1239|  1.80k|  swoc::TextView      user, passw, host, port;
 1240|  1.80k|  static size_t const MAX_COLON  = 8; // max # of valid colons.
 1241|  1.80k|  size_t              n_colon    = 0;
 1242|  1.80k|  const char         *last_colon = nullptr; // pointer to last colon seen.
 1243|       |
 1244|       |  // Do a quick check for "://"
 1245|  1.80k|  if (end - cur > 3 && (((':' ^ *cur) | ('/' ^ cur[1]) | ('/' ^ cur[2])) == 0)) {
  ------------------
  |  Branch (1245:7): [True: 483, False: 1.32k]
  |  Branch (1245:24): [True: 55, False: 428]
  ------------------
 1246|     55|    cur += 3;
 1247|  1.75k|  } else if (':' == *cur && (++cur >= end || ('/' == *cur && (++cur >= end || ('/' == *cur && ++cur >= end))))) {
  ------------------
  |  Branch (1247:14): [True: 264, False: 1.48k]
  |  Branch (1247:30): [True: 9, False: 255]
  |  Branch (1247:47): [True: 217, False: 38]
  |  Branch (1247:63): [True: 7, False: 210]
  |  Branch (1247:80): [True: 192, False: 18]
  |  Branch (1247:95): [True: 192, False: 0]
  ------------------
 1248|    208|    return ParseResult::ERROR;
 1249|    208|  }
 1250|       |
 1251|  1.59k|  base = cur;
 1252|       |  // skipped leading stuff, start real parsing.
 1253|  16.5k|  while (cur < end) {
  ------------------
  |  Branch (1253:10): [True: 15.0k, False: 1.51k]
  ------------------
 1254|       |    // Note: Each case is responsible for incrementing @a cur if
 1255|       |    // appropriate!
 1256|  15.0k|    switch (*cur) {
 1257|     77|    case ']': // address close
  ------------------
  |  Branch (1257:5): [True: 77, False: 14.9k]
  ------------------
 1258|     77|      if (nullptr == bracket || n_colon >= MAX_COLON) {
  ------------------
  |  Branch (1258:11): [True: 8, False: 69]
  |  Branch (1258:33): [True: 6, False: 63]
  ------------------
 1259|     14|        return ParseResult::ERROR;
 1260|     14|      }
 1261|     63|      ++cur;
 1262|       |      /* We keep the brackets because there are too many other places
 1263|       |         that depend on them and it's too painful to keep track if
 1264|       |         they should be used. I thought about being clever with
 1265|       |         stripping brackets from non-IPv6 content but that gets ugly
 1266|       |         as well. Just not worth it.
 1267|       |       */
 1268|     63|      host.assign(bracket, cur);
 1269|       |      // Spec requires This constitute the entire host so the next
 1270|       |      // character must be missing (EOS), slash, or colon.
 1271|     63|      if (cur >= end || '/' == *cur) { // done which is OK
  ------------------
  |  Branch (1271:11): [True: 18, False: 45]
  |  Branch (1271:25): [True: 6, False: 39]
  ------------------
 1272|     24|        last_colon = nullptr;
 1273|     24|        break;
 1274|     39|      } else if (':' != *cur) { // otherwise it must be a colon
  ------------------
  |  Branch (1274:18): [True: 20, False: 19]
  ------------------
 1275|     20|        return ParseResult::ERROR;
 1276|     20|      }
 1277|       |      /* We want to prevent more than 1 colon following so we set @a
 1278|       |         n_colon appropriately.
 1279|       |      */
 1280|     19|      n_colon = MAX_COLON - 1;
 1281|       |    // FALL THROUGH
 1282|    820|    case ':': // track colons, fail if too many.
  ------------------
  |  Branch (1282:5): [True: 801, False: 14.2k]
  ------------------
 1283|    820|      if (++n_colon > MAX_COLON) {
  ------------------
  |  Branch (1283:11): [True: 12, False: 808]
  ------------------
 1284|     12|        return ParseResult::ERROR;
 1285|     12|      }
 1286|    808|      last_colon = cur;
 1287|    808|      ++cur;
 1288|    808|      break;
 1289|    977|    case '@': // user/password marker.
  ------------------
  |  Branch (1289:5): [True: 977, False: 14.0k]
  ------------------
 1290|    977|      if (user || n_colon > 1) {
  ------------------
  |  Branch (1290:11): [True: 16, False: 961]
  |  Branch (1290:19): [True: 8, False: 953]
  ------------------
 1291|     24|        return ParseResult::ERROR; // we already got one, or too many colons.
 1292|     24|      }
 1293|    953|      if (n_colon) {
  ------------------
  |  Branch (1293:11): [True: 434, False: 519]
  ------------------
 1294|    434|        user.assign(base, last_colon);
 1295|    434|        passw.assign(last_colon + 1, cur);
 1296|    434|        n_colon    = 0;
 1297|    434|        last_colon = nullptr;
 1298|    519|      } else {
 1299|    519|        user.assign(base, cur);
 1300|    519|      }
 1301|    953|      ++cur;
 1302|    953|      base = cur;
 1303|    953|      break;
 1304|     91|    case '[':                       // address open
  ------------------
  |  Branch (1304:5): [True: 91, False: 14.9k]
  ------------------
 1305|     91|      if (bracket || base != cur) { // must be first char in field
  ------------------
  |  Branch (1305:11): [True: 6, False: 85]
  |  Branch (1305:22): [True: 7, False: 78]
  ------------------
 1306|     13|        return ParseResult::ERROR;
 1307|     13|      }
 1308|     78|      bracket = cur; // location and flag.
 1309|     78|      ++cur;
 1310|     78|      break;
 1311|       |    // RFC 3986, section 3.2:
 1312|       |    // The authority component is ...  terminated by the next slash ("/"),
 1313|       |    // question mark ("?"), or number sign ("#") character, or by the end of
 1314|       |    // the URI.
 1315|    884|    case '/':
  ------------------
  |  Branch (1315:5): [True: 884, False: 14.1k]
  ------------------
 1316|    990|    case '?':
  ------------------
  |  Branch (1316:5): [True: 106, False: 14.8k]
  ------------------
 1317|  1.03k|    case '#':
  ------------------
  |  Branch (1317:5): [True: 42, False: 14.9k]
  ------------------
 1318|  1.03k|      end = cur; // We're done parsing authority, cause loop exit.
 1319|  1.03k|      break;
 1320|  12.0k|    default:
  ------------------
  |  Branch (1320:5): [True: 12.0k, False: 2.97k]
  ------------------
 1321|  12.0k|      ++cur;
 1322|  12.0k|      break;
 1323|  15.0k|    };
 1324|  14.9k|  }
 1325|       |  // Time to pick up the pieces. At this pointer cur._ptr is the first
 1326|       |  // character past the parse area.
 1327|       |
 1328|  1.51k|  if (user) {
  ------------------
  |  Branch (1328:7): [True: 63, False: 1.45k]
  ------------------
 1329|     63|    url->set_user(heap, user, copy_strings_p);
 1330|     63|    if (passw) {
  ------------------
  |  Branch (1330:9): [True: 17, False: 46]
  ------------------
 1331|     17|      url->set_password(heap, passw, copy_strings_p);
 1332|     17|    }
 1333|     63|  }
 1334|       |
 1335|       |  // @a host not set means no brackets to mark explicit host.
 1336|  1.51k|  if (!host) {
  ------------------
  |  Branch (1336:7): [True: 1.48k, False: 31]
  ------------------
 1337|  1.48k|    if (1 == n_colon || MAX_COLON == n_colon) { // presume port.
  ------------------
  |  Branch (1337:9): [True: 103, False: 1.38k]
  |  Branch (1337:25): [True: 12, False: 1.36k]
  ------------------
 1338|    115|      host.assign(base, last_colon);
 1339|  1.36k|    } else { // it's all host.
 1340|  1.36k|      host.assign(base, cur);
 1341|  1.36k|      last_colon = nullptr; // prevent port setting.
 1342|  1.36k|    }
 1343|  1.48k|  }
 1344|  1.51k|  if (!host.empty()) {
  ------------------
  |  Branch (1344:7): [True: 534, False: 980]
  ------------------
 1345|    534|    if (!verify_host_characters || validate_host_name(host)) {
  ------------------
  |  Branch (1345:9): [True: 0, False: 534]
  |  Branch (1345:36): [True: 384, False: 150]
  ------------------
 1346|    384|      url->set_host(heap, host, copy_strings_p);
 1347|    384|    } else {
 1348|    150|      return ParseResult::ERROR;
 1349|    150|    }
 1350|    534|  }
 1351|       |
 1352|  1.36k|  if (last_colon) {
  ------------------
  |  Branch (1352:7): [True: 111, False: 1.25k]
  ------------------
 1353|    111|    ink_assert(n_colon);
  ------------------
  |  |   45|    111|#define ink_assert(EX) (void)(EX)
  ------------------
 1354|    111|    port.assign(last_colon + 1, cur);
 1355|    111|    if (port.empty()) {
  ------------------
  |  Branch (1355:9): [True: 26, False: 85]
  ------------------
 1356|     26|      return ParseResult::ERROR; // colon w/o port value.
 1357|     26|    }
 1358|     85|    url->set_port(heap, port, copy_strings_p);
 1359|     85|  }
 1360|  1.33k|  *start = cur;
 1361|  1.33k|  return ParseResult::DONE;
 1362|  1.36k|}
_Z14url_parse_httpP7HdrHeapP7URLImplPPKcS4_bb:
 1371|  1.80k|{
 1372|  1.80k|  ParseResult err;
 1373|  1.80k|  const char *cur;
 1374|  1.80k|  const char *path_start     = nullptr;
 1375|  1.80k|  const char *path_end       = nullptr;
 1376|  1.80k|  const char *query_start    = nullptr;
 1377|  1.80k|  const char *query_end      = nullptr;
 1378|  1.80k|  const char *fragment_start = nullptr;
 1379|  1.80k|  const char *fragment_end   = nullptr;
 1380|  1.80k|  char        mask;
 1381|       |
 1382|  1.80k|  err = url_parse_internet(heap, url, start, end, copy_strings, verify_host_characters);
 1383|  1.80k|  if (static_cast<int>(err) < 0) {
  ------------------
  |  Branch (1383:7): [True: 467, False: 1.33k]
  ------------------
 1384|    467|    return err;
 1385|    467|  }
 1386|       |
 1387|  1.33k|  cur                     = *start;
 1388|  1.33k|  bool nothing_after_host = false;
 1389|  1.33k|  if (*start == end) {
  ------------------
  |  Branch (1389:7): [True: 340, False: 998]
  ------------------
 1390|    340|    nothing_after_host = true;
 1391|    340|    goto done;
 1392|    340|  }
 1393|       |
 1394|    998|  if (*cur == '/') {
  ------------------
  |  Branch (1394:7): [True: 854, False: 144]
  ------------------
 1395|    854|    path_start = cur;
 1396|    854|  }
 1397|    998|  mask = '?' & '#';
 1398|  6.67k|parse_path2:
 1399|  6.67k|  if ((*cur & mask) == mask) {
  ------------------
  |  Branch (1399:7): [True: 2.60k, False: 4.06k]
  ------------------
 1400|  2.60k|    if (*cur == '?') {
  ------------------
  |  Branch (1400:9): [True: 153, False: 2.45k]
  ------------------
 1401|    153|      path_end = cur;
 1402|    153|      goto parse_query1;
 1403|    153|    }
 1404|  2.45k|    if (*cur == '#') {
  ------------------
  |  Branch (1404:9): [True: 47, False: 2.40k]
  ------------------
 1405|     47|      path_end = cur;
 1406|     47|      goto parse_fragment1;
 1407|     47|    }
 1408|  4.06k|  } else {
 1409|  4.06k|    ink_assert((*cur != '?') && (*cur != '#'));
  ------------------
  |  |   45|  8.13k|#define ink_assert(EX) (void)(EX)
  |  |  ------------------
  |  |  |  Branch (45:31): [True: 4.06k, False: 0]
  |  |  |  Branch (45:31): [True: 4.06k, False: 0]
  |  |  ------------------
  ------------------
 1410|  4.06k|  }
 1411|  6.47k|  GETNEXT(done);
  ------------------
  |  | 1098|  6.47k|  {                    \
  |  | 1099|  6.47k|    cur += 1;          \
  |  | 1100|  6.47k|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (1100:9): [True: 798, False: 5.67k]
  |  |  ------------------
  |  | 1101|    798|      goto label;      \
  |  | 1102|    798|    }                  \
  |  | 1103|  6.47k|  }
  ------------------
 1412|  5.67k|  goto parse_path2;
 1413|       |
 1414|    153|parse_query1:
 1415|    153|  query_start = cur + 1;
 1416|    153|  GETNEXT(done);
  ------------------
  |  | 1098|    153|  {                    \
  |  | 1099|    153|    cur += 1;          \
  |  | 1100|    153|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (1100:9): [True: 62, False: 91]
  |  |  ------------------
  |  | 1101|     62|      goto label;      \
  |  | 1102|     62|    }                  \
  |  | 1103|    153|  }
  ------------------
 1417|    309|parse_query2:
 1418|    309|  if (*cur == '#') {
  ------------------
  |  Branch (1418:7): [True: 72, False: 237]
  ------------------
 1419|     72|    query_end = cur;
 1420|     72|    goto parse_fragment1;
 1421|     72|  }
 1422|    237|  GETNEXT(done);
  ------------------
  |  | 1098|    237|  {                    \
  |  | 1099|    237|    cur += 1;          \
  |  | 1100|    237|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (1100:9): [True: 19, False: 218]
  |  |  ------------------
  |  | 1101|     19|      goto label;      \
  |  | 1102|     19|    }                  \
  |  | 1103|    237|  }
  ------------------
 1423|    218|  goto parse_query2;
 1424|       |
 1425|    119|parse_fragment1:
 1426|    119|  fragment_start = cur + 1;
 1427|    119|  GETNEXT(done);
  ------------------
  |  | 1098|    119|  {                    \
  |  | 1099|    119|    cur += 1;          \
  |  | 1100|    119|    if (cur >= end) {  \
  |  |  ------------------
  |  |  |  Branch (1100:9): [True: 108, False: 11]
  |  |  ------------------
  |  | 1101|    108|      goto label;      \
  |  | 1102|    108|    }                  \
  |  | 1103|    119|  }
  ------------------
 1428|     11|  fragment_end = end;
 1429|       |
 1430|  1.33k|done:
 1431|  1.33k|  if (path_start) {
  ------------------
  |  Branch (1431:7): [True: 854, False: 484]
  ------------------
 1432|       |    // There was an explicit path set with '/'.
 1433|    854|    if (!path_end) {
  ------------------
  |  Branch (1433:9): [True: 798, False: 56]
  ------------------
 1434|    798|      path_end = cur;
 1435|    798|    }
 1436|    854|    if (path_start == path_end) {
  ------------------
  |  Branch (1436:9): [True: 0, False: 854]
  ------------------
 1437|      0|      url->m_path_is_empty = true;
 1438|    854|    } else {
 1439|    854|      url->m_path_is_empty = false;
 1440|       |      // Per RFC 3986 section 3, the query string does not contain the initial
 1441|       |      // '?' nor does the fragment contain the initial '#'. The path however
 1442|       |      // does contain the initial '/' and a path can be empty, containing no
 1443|       |      // characters at all, not even the initial '/'. Our path_get interface,
 1444|       |      // however, has long not behaved accordingly, returning only the
 1445|       |      // characters after the first '/'. This does not allow users to tell
 1446|       |      // whether the path was absolutely empty. Further, callers have to
 1447|       |      // account for the missing first '/' character themselves, either in URL
 1448|       |      // length calculations or when piecing together their own URL. There are
 1449|       |      // various examples of this in core and in the plugins shipped with Traffic
 1450|       |      // Server.
 1451|       |      //
 1452|       |      // Correcting this behavior by having path_get return the entire path,
 1453|       |      // (inclusive of any first '/') and an empty string if there were no
 1454|       |      // characters specified in the path would break existing functionality,
 1455|       |      // including various plugins that expect this behavior. Rather than
 1456|       |      // correcting this behavior, therefore, we maintain the current
 1457|       |      // functionality but add state to determine whether the path was
 1458|       |      // absolutely empty so we can reconstruct such URLs.
 1459|       |      //
 1460|       |      // Remove all preceding slashes
 1461|  1.91k|      while (path_start < path_end && *path_start == '/') {
  ------------------
  |  Branch (1461:14): [True: 1.21k, False: 699]
  |  Branch (1461:39): [True: 1.05k, False: 155]
  ------------------
 1462|  1.05k|        ++path_start;
 1463|  1.05k|      }
 1464|    854|    }
 1465|       |
 1466|    854|    url->set_path(heap, {path_start, static_cast<std::string_view::size_type>(path_end - path_start)}, copy_strings);
 1467|    854|  } else if (!nothing_after_host) {
  ------------------
  |  Branch (1467:14): [True: 144, False: 340]
  ------------------
 1468|       |    // There was no path set via '/': it is absolutely empty. However, if there
 1469|       |    // is no path, query, or fragment after the host, we by convention add a
 1470|       |    // slash after the authority.  Users of URL expect this behavior. Thus the
 1471|       |    // nothing_after_host check.
 1472|    144|    url->m_path_is_empty = true;
 1473|    144|  }
 1474|  1.33k|  if (query_start) {
  ------------------
  |  Branch (1474:7): [True: 153, False: 1.18k]
  ------------------
 1475|       |    // There was a query string marked by '?'.
 1476|    153|    if (!query_end) {
  ------------------
  |  Branch (1476:9): [True: 81, False: 72]
  ------------------
 1477|     81|      query_end = cur;
 1478|     81|    }
 1479|    153|    url->set_query(heap, {query_start, static_cast<std::string_view::size_type>(query_end - query_start)}, copy_strings);
 1480|    153|  }
 1481|  1.33k|  if (fragment_start) {
  ------------------
  |  Branch (1481:7): [True: 119, False: 1.21k]
  ------------------
 1482|       |    // There was a fragment string marked by '#'.
 1483|    119|    if (!fragment_end) {
  ------------------
  |  Branch (1483:9): [True: 108, False: 11]
  ------------------
 1484|    108|      fragment_end = cur;
 1485|    108|    }
 1486|    119|    url->set_fragment(heap, {fragment_start, static_cast<std::string_view::size_type>(fragment_end - fragment_start)},
 1487|    119|                      copy_strings);
 1488|    119|  }
 1489|       |
 1490|  1.33k|  *start = cur;
 1491|  1.33k|  return ParseResult::DONE;
 1492|     11|}
URL.cc:_ZL12is_host_charc:
   95|  7.21k|{
   96|  7.21k|  return (ParseRules::is_alnum(c) || (c == '-') || (c == '.') || (c == '[') || (c == ']') || (c == '_') || (c == ':') ||
  ------------------
  |  Branch (96:11): [True: 3.62k, False: 3.59k]
  |  Branch (96:38): [True: 427, False: 3.16k]
  |  Branch (96:52): [True: 621, False: 2.54k]
  |  Branch (96:66): [True: 205, False: 2.33k]
  |  Branch (96:80): [True: 231, False: 2.10k]
  |  Branch (96:94): [True: 536, False: 1.57k]
  |  Branch (96:108): [True: 148, False: 1.42k]
  ------------------
   97|  1.42k|          (c == '~') || (c == '%'));
  ------------------
  |  Branch (97:11): [True: 666, False: 757]
  |  Branch (97:25): [True: 541, False: 216]
  ------------------
   98|  7.21k|}

_ZN11BaseLogFileC2EPKc:
   31|  6.24k|BaseLogFile::BaseLogFile(const char *name) : m_name(ats_strdup(name))
  ------------------
  |  |  134|  6.24k|#define ats_strdup(p) _xstrdup((p), -1, nullptr)
  ------------------
   32|  6.24k|{
   33|  6.24k|  log_log_trace("exiting BaseLogFile constructor, m_name=%s, this=%p\n", m_name.get(), this);
  ------------------
  |  |   59|  6.24k|  do {                                             \
  |  |   60|  6.24k|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|  6.24k|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 6.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|  6.24k|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|  6.24k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 6.24k]
  |  |  ------------------
  ------------------
   34|  6.24k|}
_ZN11BaseLogFileD2Ev:
   67|  6.24k|{
   68|  6.24k|  log_log_trace("entering BaseLogFile destructor, m_name=%s, this=%p\n", m_name.get(), this);
  ------------------
  |  |   59|  6.24k|  do {                                             \
  |  |   60|  6.24k|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|  6.24k|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 6.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|  6.24k|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|  6.24k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 6.24k]
  |  |  ------------------
  ------------------
   69|       |
   70|  6.24k|  if (m_is_regfile) {
  ------------------
  |  Branch (70:7): [True: 0, False: 6.24k]
  ------------------
   71|      0|    close_file();
   72|  6.24k|  } else {
   73|  6.24k|    log_log_trace("not a regular file, not closing, m_name=%s, this=%p\n", m_name.get(), this);
  ------------------
  |  |   59|  6.24k|  do {                                             \
  |  |   60|  6.24k|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|  6.24k|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 6.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|  6.24k|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|  6.24k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 6.24k]
  |  |  ------------------
  ------------------
   74|  6.24k|  }
   75|       |
   76|  6.24k|  log_log_trace("exiting BaseLogFile destructor, this=%p\n", this);
  ------------------
  |  |   59|  6.24k|  do {                                             \
  |  |   60|  6.24k|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|  6.24k|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 6.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|  6.24k|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|  6.24k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 6.24k]
  |  |  ------------------
  ------------------
   77|  6.24k|}
_ZN11BaseLogFile9open_fileEi:
  267|  6.24k|{
  268|  6.24k|  log_log_trace("BaseLogFile: entered open_file()\n");
  ------------------
  |  |   59|  6.24k|  do {                                             \
  |  |   60|  6.24k|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|  6.24k|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 6.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|  6.24k|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|  6.24k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 6.24k]
  |  |  ------------------
  ------------------
  269|  6.24k|  if (is_open()) {
  ------------------
  |  Branch (269:7): [True: 0, False: 6.24k]
  ------------------
  270|      0|    return LOG_FILE_NO_ERROR;
  271|      0|  }
  272|       |
  273|  6.24k|  if (!m_name.get()) {
  ------------------
  |  Branch (273:7): [True: 0, False: 6.24k]
  ------------------
  274|      0|    log_log_error("BaseLogFile: m_name is nullptr, aborting open_file()\n");
  ------------------
  |  |   65|      0|  do {                                             \
  |  |   66|      0|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|      0|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   67|      0|      BaseLogFile::log_log(LL_Error, __VA_ARGS__); \
  |  |   68|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (68:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
  275|      0|    return LOG_FILE_COULD_NOT_OPEN_FILE;
  276|  6.24k|  } else if (!strcmp(m_name.get(), "stdout")) {
  ------------------
  |  Branch (276:14): [True: 3.12k, False: 3.12k]
  ------------------
  277|  3.12k|    log_log_trace("BaseLogFile: stdout opened\n");
  ------------------
  |  |   59|  3.12k|  do {                                             \
  |  |   60|  3.12k|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|  3.12k|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 3.12k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|  3.12k|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|  3.12k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 3.12k]
  |  |  ------------------
  ------------------
  278|  3.12k|    m_fp      = stdout;
  279|  3.12k|    m_is_init = true;
  280|  3.12k|    return LOG_FILE_NO_ERROR;
  281|  3.12k|  } else if (!strcmp(m_name.get(), "stderr")) {
  ------------------
  |  Branch (281:14): [True: 3.12k, False: 0]
  ------------------
  282|  3.12k|    log_log_trace("BaseLogFile: stderr opened\n");
  ------------------
  |  |   59|  3.12k|  do {                                             \
  |  |   60|  3.12k|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|  3.12k|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 3.12k]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|  3.12k|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|  3.12k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 3.12k]
  |  |  ------------------
  ------------------
  283|  3.12k|    m_fp      = stderr;
  284|  3.12k|    m_is_init = true;
  285|  3.12k|    return LOG_FILE_NO_ERROR;
  286|  3.12k|  }
  287|       |
  288|       |  // means this object is representing a real file on disk
  289|      0|  m_is_regfile = true;
  290|       |
  291|       |  // Check to see if the file exists BEFORE we try to open it, since
  292|       |  // opening it will also create it.
  293|      0|  bool file_exists = BaseLogFile::exists(m_name.get());
  294|       |
  295|      0|  if (file_exists) {
  ------------------
  |  Branch (295:7): [True: 0, False: 0]
  ------------------
  296|      0|    if (!m_meta_info) {
  ------------------
  |  Branch (296:9): [True: 0, False: 0]
  ------------------
  297|       |      // This object must be fresh since it has not built its MetaInfo
  298|       |      // so we create a new MetaInfo object that will read right away
  299|       |      // (in the constructor) the corresponding metafile
  300|      0|      m_meta_info = std::make_unique<BaseMetaInfo>(m_name.get());
  301|      0|    }
  302|      0|  } else {
  303|       |    // The log file does not exist, so we create a new MetaInfo object
  304|       |    //  which will save itself to disk right away (in the constructor)
  305|      0|    if (m_has_signature) {
  ------------------
  |  Branch (305:9): [True: 0, False: 0]
  ------------------
  306|      0|      m_meta_info = std::make_unique<BaseMetaInfo>(m_name.get(), static_cast<long>(time(nullptr)), m_signature);
  307|      0|    } else {
  308|      0|      m_meta_info = std::make_unique<BaseMetaInfo>(m_name.get(), static_cast<long>(time(nullptr)));
  309|      0|    }
  310|      0|  }
  311|       |
  312|       |  // open actual log file (not metainfo)
  313|      0|  log_log_trace("BaseLogFile: attempting to open %s\n", m_name.get());
  ------------------
  |  |   59|      0|  do {                                             \
  |  |   60|      0|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|      0|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|      0|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
  314|       |
  315|      0|  m_fp = elevating_fopen(m_name.get(), "a+");
  316|       |
  317|       |  // error check
  318|      0|  if (m_fp) {
  ------------------
  |  Branch (318:7): [True: 0, False: 0]
  ------------------
  319|      0|    setlinebuf(m_fp);
  320|      0|  } else {
  321|      0|    log_log_error("Error opening log file %s: %s\n", m_name.get(), strerror(errno));
  ------------------
  |  |   65|      0|  do {                                             \
  |  |   66|      0|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|      0|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   67|      0|      BaseLogFile::log_log(LL_Error, __VA_ARGS__); \
  |  |   68|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (68:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
  322|      0|    log_log_error("Actual error: %s\n", (errno == EINVAL ? "einval" : "something else"));
  ------------------
  |  |   65|      0|  do {                                             \
  |  |   66|      0|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|      0|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   67|      0|      BaseLogFile::log_log(LL_Error, __VA_ARGS__); \
  |  |  ------------------
  |  |  |  Branch (67:38): [True: 0, False: 0]
  |  |  ------------------
  |  |   68|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (68:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
  323|      0|    return LOG_FILE_COULD_NOT_OPEN_FILE;
  324|      0|  }
  325|       |
  326|       |  // set permissions if necessary
  327|      0|  if (perm != -1) {
  ------------------
  |  Branch (327:7): [True: 0, False: 0]
  ------------------
  328|       |    // means LogFile passed in some permissions we need to set
  329|      0|    log_log_trace("BaseLogFile attempting to change %s's permissions to %o\n", m_name.get(), perm);
  ------------------
  |  |   59|      0|  do {                                             \
  |  |   60|      0|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|      0|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|      0|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
  330|      0|    if (elevating_chmod(m_name.get(), perm) != 0) {
  ------------------
  |  Branch (330:9): [True: 0, False: 0]
  ------------------
  331|      0|      log_log_error("Error changing logfile=%s permissions: %s\n", m_name.get(), strerror(errno));
  ------------------
  |  |   65|      0|  do {                                             \
  |  |   66|      0|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|      0|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   67|      0|      BaseLogFile::log_log(LL_Error, __VA_ARGS__); \
  |  |   68|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (68:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
  332|      0|    }
  333|      0|  }
  334|       |
  335|       |  // set m_bytes_written to force the rolling based on file size.
  336|      0|  fseek(m_fp, 0, SEEK_END);
  337|      0|  m_bytes_written = ftell(m_fp);
  338|       |
  339|      0|  log_log_trace("BaseLogFile %s is now open (fd=%d)\n", m_name.get(), fileno(m_fp));
  ------------------
  |  |   59|      0|  do {                                             \
  |  |   60|      0|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|      0|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   61|      0|      BaseLogFile::log_log(LL_Debug, __VA_ARGS__); \
  |  |   62|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (62:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
  340|      0|  m_is_init = true;
  341|      0|  return LOG_FILE_NO_ERROR;
  342|      0|}

_Z14get_cont_flagsv:
   42|      6|{
   43|      6|  return local_flags;
   44|      6|}

_ZN16DiagsConfigState7enabledE12DiagsTagTypei:
   59|  6.24k|{
   60|  6.24k|  if (_enabled[dtt] == new_value) {
  ------------------
  |  Branch (60:7): [True: 6.24k, False: 0]
  ------------------
   61|  6.24k|    return;
   62|  6.24k|  }
   63|      0|  _enabled[dtt] = new_value;
   64|       |
   65|      0|  if (DiagsTagType_Debug == dtt) {
  ------------------
  |  Branch (65:7): [True: 0, False: 0]
  ------------------
   66|      0|    DbgCtl::_config_mode.store(new_value, std::memory_order_relaxed);
   67|      0|  }
   68|      0|}
_ZN8DiagsPtr3setEP5Diags:
   75|  3.12k|{
   76|  3.12k|  _diags_ptr = new_ptr;
   77|       |
   78|  3.12k|  DebugInterface::set_instance(new_ptr);
   79|  3.12k|}
_ZN5DiagsC2ENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEEPKcS6_P11BaseLogFileii:
  108|  3.12k|  : diags_log(nullptr),
  109|  3.12k|    stdout_log(nullptr),
  110|  3.12k|    stderr_log(nullptr),
  111|  3.12k|    magic(DIAGS_MAGIC),
  ------------------
  |  |   48|  3.12k|#define DIAGS_MAGIC 0x12345678
  ------------------
  112|  3.12k|    show_location(SHOW_LOCATION_NONE),
  113|  3.12k|    base_debug_tags(nullptr),
  114|  3.12k|    base_action_tags(nullptr),
  115|  3.12k|    prefix_str(prefix_string)
  116|  3.12k|{
  117|  3.12k|  ink_release_assert(!prefix_str.empty());
  ------------------
  |  |   48|  3.12k|#define ink_release_assert(EX) ((void)(__builtin_expect(!!(EX), 0) ? (void)0 : _ink_assert(#EX, __FILE__, __LINE__)))
  |  |  ------------------
  |  |  |  Branch (48:40): [True: 3.12k, False: 0]
  |  |  ------------------
  ------------------
  118|  3.12k|  int i;
  119|       |
  120|  3.12k|  cleanup_func = nullptr;
  121|  3.12k|  ink_mutex_init(&tag_table_lock);
  122|       |
  123|       |  ////////////////////////////////////////////////////////
  124|       |  // initialize the default, base debugging/action tags //
  125|       |  ////////////////////////////////////////////////////////
  126|       |
  127|  3.12k|  if (bdt && *bdt) {
  ------------------
  |  Branch (127:7): [True: 3.12k, False: 0]
  |  Branch (127:14): [True: 0, False: 3.12k]
  ------------------
  128|      0|    base_debug_tags = ats_strdup(bdt);
  ------------------
  |  |  134|      0|#define ats_strdup(p) _xstrdup((p), -1, nullptr)
  ------------------
  129|      0|  }
  130|  3.12k|  if (bat && *bat) {
  ------------------
  |  Branch (130:7): [True: 3.12k, False: 0]
  |  Branch (130:14): [True: 0, False: 3.12k]
  ------------------
  131|      0|    base_action_tags = ats_strdup(bat);
  ------------------
  |  |  134|      0|#define ats_strdup(p) _xstrdup((p), -1, nullptr)
  ------------------
  132|      0|  }
  133|       |
  134|  3.12k|  config.enabled(DiagsTagType_Debug, base_debug_tags != nullptr ? 1 : 0);
  ------------------
  |  Branch (134:38): [True: 0, False: 3.12k]
  ------------------
  135|  3.12k|  config.enabled(DiagsTagType_Action, base_action_tags != nullptr ? 1 : 0);
  ------------------
  |  Branch (135:39): [True: 0, False: 3.12k]
  ------------------
  136|       |
  137|       |  // The caller must always provide a non-empty prefix.
  138|       |
  139|  31.2k|  for (i = 0; i < DiagsLevel_Count; i++) {
  ------------------
  |  |   67|  31.2k|#define DiagsLevel_Count DL_Undefined
  ------------------
  |  Branch (139:15): [True: 28.0k, False: 3.12k]
  ------------------
  140|  28.0k|    config.outputs[i].to_stdout   = false;
  141|  28.0k|    config.outputs[i].to_stderr   = false;
  142|  28.0k|    config.outputs[i].to_syslog   = false;
  143|  28.0k|    config.outputs[i].to_diagslog = true;
  144|  28.0k|  }
  145|       |
  146|       |  // create default stdout and stderr BaseLogFile objects
  147|       |  // (in case the user of this class doesn't specify in the future)
  148|  3.12k|  stdout_log = new BaseLogFile("stdout");
  149|  3.12k|  stderr_log = new BaseLogFile("stderr");
  150|  3.12k|  stdout_log->open_file(); // should never fail
  151|  3.12k|  stderr_log->open_file(); // should never fail
  152|       |
  153|       |  //////////////////////////////////////////////////////////////////
  154|       |  // start off with empty tag tables, will build in reconfigure() //
  155|       |  //////////////////////////////////////////////////////////////////
  156|       |
  157|  3.12k|  activated_tags[DiagsTagType_Debug]  = nullptr;
  158|  3.12k|  activated_tags[DiagsTagType_Action] = nullptr;
  159|       |
  160|  3.12k|  outputlog_rolling_enabled  = RollingEnabledValues::NO_ROLLING;
  161|  3.12k|  outputlog_rolling_interval = -1;
  162|  3.12k|  outputlog_rolling_size     = -1;
  163|  3.12k|  diagslog_rolling_enabled   = RollingEnabledValues::NO_ROLLING;
  164|  3.12k|  diagslog_rolling_interval  = -1;
  165|  3.12k|  diagslog_rolling_size      = -1;
  166|       |
  167|  3.12k|  outputlog_time_last_roll = time(nullptr);
  168|  3.12k|  diagslog_time_last_roll  = time(nullptr);
  169|       |
  170|  3.12k|  diags_logfile_perm  = dl_perm;
  171|  3.12k|  output_logfile_perm = ol_perm;
  172|       |
  173|  3.12k|  if (setup_diagslog(_diags_log)) {
  ------------------
  |  Branch (173:7): [True: 3.12k, False: 0]
  ------------------
  174|  3.12k|    diags_log = _diags_log;
  175|  3.12k|  }
  176|  3.12k|}
_ZN5DiagsD2Ev:
  179|  3.12k|{
  180|  3.12k|  if (diags_log) {
  ------------------
  |  Branch (180:7): [True: 0, False: 3.12k]
  ------------------
  181|      0|    delete diags_log;
  182|      0|    diags_log = nullptr;
  183|      0|  }
  184|       |
  185|  3.12k|  if (stdout_log) {
  ------------------
  |  Branch (185:7): [True: 3.12k, False: 0]
  ------------------
  186|  3.12k|    delete stdout_log;
  187|  3.12k|    stdout_log = nullptr;
  188|  3.12k|  }
  189|       |
  190|  3.12k|  if (stderr_log) {
  ------------------
  |  Branch (190:7): [True: 3.12k, False: 0]
  ------------------
  191|  3.12k|    delete stderr_log;
  192|  3.12k|    stderr_log = nullptr;
  193|  3.12k|  }
  194|       |
  195|  3.12k|  ats_free((void *)base_debug_tags);
  196|  3.12k|  ats_free((void *)base_action_tags);
  197|       |
  198|  3.12k|  deactivate_all(DiagsTagType_Debug);
  199|  3.12k|  deactivate_all(DiagsTagType_Action);
  200|  3.12k|}
_ZNK5Diags13tag_activatedEPKc12DiagsTagType:
  330|  81.1k|{
  331|  81.1k|  if (tag == nullptr) {
  ------------------
  |  Branch (331:7): [True: 0, False: 81.1k]
  ------------------
  332|      0|    return true;
  333|      0|  }
  334|       |
  335|       |  // Snapshot the regex under the lock, then release the lock before running
  336|       |  // Regex::exec().  exec() can lazily construct a thread_local RegexContext
  337|       |  // whose destructor registration via __cxa_thread_atexit_impl takes the
  338|       |  // dynamic loader lock.  Holding tag_table_lock across exec() therefore
  339|       |  // creates a lock-order inversion with dlopen() callers that construct a
  340|       |  // DbgCtl during a plugin's static initialization (which takes
  341|       |  // tag_table_lock while already holding the dl loader lock).  See the
  342|       |  // analogous fix in DbgCtl::_new_reference.
  343|  81.1k|  std::shared_ptr<Regex> regex;
  344|  81.1k|  {
  345|  81.1k|    lock();
  346|  81.1k|    regex = activated_tags[mode];
  347|  81.1k|    unlock();
  348|  81.1k|  }
  349|       |
  350|  81.1k|  return regex ? regex->exec(tag, RE_ANCHORED) : false;
  ------------------
  |  Branch (350:10): [True: 0, False: 81.1k]
  ------------------
  351|  81.1k|}
_ZN5Diags14deactivate_allE12DiagsTagType:
  395|  6.24k|{
  396|  6.24k|  lock();
  397|  6.24k|  activated_tags[mode].reset();
  398|  6.24k|  unlock();
  399|  6.24k|  if ((DiagsTagType_Debug == mode) && (this == diags())) {
  ------------------
  |  Branch (399:7): [True: 3.12k, False: 3.12k]
  |  Branch (399:39): [True: 3.12k, False: 0]
  ------------------
  400|  3.12k|    DbgCtl::update([&](const char *tag) -> bool { return tag_activated(tag, DiagsTagType_Debug); });
  401|  3.12k|  }
  402|  6.24k|}
_ZN5Diags14setup_diagslogEP11BaseLogFile:
  458|  3.12k|{
  459|  3.12k|  if (blf != nullptr) {
  ------------------
  |  Branch (459:7): [True: 0, False: 3.12k]
  ------------------
  460|      0|    if (blf->open_file(diags_logfile_perm) != BaseLogFile::LOG_FILE_NO_ERROR) {
  ------------------
  |  Branch (460:9): [True: 0, False: 0]
  ------------------
  461|      0|      log_log_error("Could not open diags log file: %s\n", strerror(errno));
  ------------------
  |  |   65|      0|  do {                                             \
  |  |   66|      0|    if (BASELOGFILE_DEBUG_MODE)                    \
  |  |  ------------------
  |  |  |  |   47|      0|  0 // change this to 1 to enable debug messages
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (47:3): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   67|      0|      BaseLogFile::log_log(LL_Error, __VA_ARGS__); \
  |  |   68|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (68:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
  462|      0|      delete blf;
  463|      0|      return false;
  464|      0|    }
  465|      0|  }
  466|       |
  467|  3.12k|  return true;
  468|  3.12k|}
Diags.cc:_ZZN5Diags14deactivate_allE12DiagsTagTypeENK3$_0clEPKc:
  400|  40.5k|    DbgCtl::update([&](const char *tag) -> bool { return tag_activated(tag, DiagsTagType_Debug); });

_ZN11ATSHashBaseD2Ev:
   25|  58.9k|ATSHashBase::~ATSHashBase() {}

_ZN14ATSHash32FNV1aC2Ev:
   13|  58.9k|ATSHash32FNV1a::ATSHash32FNV1a() = default;
_ZN14ATSHash32FNV1a5finalEv:
   17|  58.9k|{
   18|  58.9k|}
_ZNK14ATSHash32FNV1a3getEv:
   22|  58.9k|{
   23|  58.9k|  return hval;
   24|  58.9k|}

_ZN12je_mi_malloc25globalJeMiNodumpAllocatorEv:
  173|      2|{
  174|      2|  static auto instance = new JeMiNodumpAllocator();
  175|      2|  return *instance;
  176|      2|}

_Z10ink_atoi64PKci:
  144|     44|{
  145|     44|  int64_t num      = 0;
  146|     44|  int     negative = 0;
  147|       |
  148|     44|  while (len > 0 && *str && ParseRules::is_wslfcr(*str)) {
  ------------------
  |  Branch (148:10): [True: 44, False: 0]
  |  Branch (148:21): [True: 44, False: 0]
  |  Branch (148:29): [True: 0, False: 44]
  ------------------
  149|      0|    str += 1;
  150|      0|    len--;
  151|      0|  }
  152|       |
  153|     44|  if (len < 1) {
  ------------------
  |  Branch (153:7): [True: 0, False: 44]
  ------------------
  154|      0|    return 0;
  155|      0|  }
  156|       |
  157|     44|  if (unlikely(str[0] == '0' && len > 1 && str[1] == 'x')) {
  ------------------
  |  |   80|    106|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (80:21): [True: 0, False: 44]
  |  |  |  Branch (80:41): [True: 10, False: 34]
  |  |  |  Branch (80:41): [True: 8, False: 2]
  |  |  |  Branch (80:41): [True: 0, False: 8]
  |  |  ------------------
  ------------------
  158|      0|    str += 2;
  159|      0|    while (len > 0 && *str && ParseRules::is_hex(*str)) {
  ------------------
  |  Branch (159:12): [True: 0, False: 0]
  |  Branch (159:23): [True: 0, False: 0]
  |  Branch (159:31): [True: 0, False: 0]
  ------------------
  160|      0|      num = (num << 4) + ink_get_hex(*str++);
  161|      0|      len--;
  162|      0|    }
  163|     44|  } else {
  164|     44|    if (unlikely(*str == '-')) {
  ------------------
  |  |   80|     44|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (80:21): [True: 0, False: 44]
  |  |  ------------------
  ------------------
  165|      0|      negative  = 1;
  166|      0|      str      += 1;
  167|      0|    }
  168|       |
  169|       |    /*
  170|       |      NOTE: we first compute the value as negative then correct the
  171|       |      sign back to positive. This enables us to correctly parse MININT.
  172|       |    */
  173|    182|    while (len > 0 && *str && ParseRules::is_digit(*str)) {
  ------------------
  |  Branch (173:12): [True: 138, False: 44]
  |  Branch (173:23): [True: 138, False: 0]
  |  Branch (173:31): [True: 138, False: 0]
  ------------------
  174|    138|      num = (num * 10) - (*str++ - '0');
  175|    138|      len--;
  176|    138|    }
  177|     44|#if USE_SI_MULTIPLIERS
  178|     44|    if (len > 0 && *str) {
  ------------------
  |  Branch (178:9): [True: 0, False: 44]
  |  Branch (178:20): [True: 0, False: 0]
  ------------------
  179|      0|      if (*str == 'K') {
  ------------------
  |  Branch (179:11): [True: 0, False: 0]
  ------------------
  180|      0|        num = num * (1 << 10);
  181|      0|      } else if (*str == 'M') {
  ------------------
  |  Branch (181:18): [True: 0, False: 0]
  ------------------
  182|      0|        num = num * (1 << 20);
  183|      0|      } else if (*str == 'G') {
  ------------------
  |  Branch (183:18): [True: 0, False: 0]
  ------------------
  184|      0|        num = num * (1 << 30);
  185|      0|      }
  186|      0|    }
  187|     44|#endif
  188|       |
  189|     44|    if (!negative) {
  ------------------
  |  Branch (189:9): [True: 44, False: 0]
  ------------------
  190|     44|      num = -num;
  191|     44|    }
  192|     44|  }
  193|     44|  return num;
  194|     44|}

_Z20ats_hugepage_enabledv:
   61|     12|{
   62|     12|#ifdef MAP_HUGETLB
   63|     12|  return hugepage_enabled;
   64|       |#else
   65|       |  return false;
   66|       |#endif
   67|     12|}

_Z10ats_mallocm:
   52|  6.41k|{
   53|  6.41k|  void *ptr = nullptr;
   54|       |
   55|       |  /*
   56|       |   * There's some nasty code in libts that expects
   57|       |   * a MALLOC of a zero-sized item to work properly. Rather
   58|       |   * than allocate any space, we simply return a nullptr to make
   59|       |   * certain they die quickly & don't trash things.
   60|       |   */
   61|       |
   62|       |  // Useful for tracing bad mallocs
   63|       |  // ink_stack_trace_dump();
   64|  6.41k|  if (likely(size > 0)) {
  ------------------
  |  |   28|  6.41k|#define likely(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (28:19): [True: 6.41k, False: 0]
  |  |  ------------------
  ------------------
   65|  6.41k|    if (unlikely((ptr = malloc(size)) == nullptr)) {
  ------------------
  |  |   31|  6.41k|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (31:21): [True: 0, False: 6.41k]
  |  |  ------------------
  ------------------
   66|      0|      ink_abort("couldn't allocate %zu bytes", size);
   67|      0|    }
   68|  6.41k|  }
   69|  6.41k|  return ptr;
   70|  6.41k|} /* End ats_malloc */
_Z10ats_callocmm:
   74|      1|{
   75|      1|  void *ptr = calloc(nelem, elsize);
   76|      1|  if (unlikely(ptr == nullptr)) {
  ------------------
  |  |   31|      1|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (31:21): [True: 0, False: 1]
  |  |  ------------------
  ------------------
   77|      0|    ink_abort("couldn't allocate %zu %zu byte elements", nelem, elsize);
   78|      0|  }
   79|      1|  return ptr;
   80|      1|} /* End ats_calloc */
_Z12ats_memalignmm:
   96|     14|{
   97|     14|  void *ptr;
   98|       |
   99|     14|  if (alignment <= 8) {
  ------------------
  |  Branch (99:7): [True: 6, False: 8]
  ------------------
  100|      6|    return ats_malloc(size);
  101|      6|  }
  102|       |
  103|       |#if defined(openbsd)
  104|       |  if (alignment > PAGE_SIZE)
  105|       |    alignment = PAGE_SIZE;
  106|       |#endif
  107|       |
  108|      8|  int retcode = posix_memalign(&ptr, alignment, size);
  109|       |
  110|      8|  if (unlikely(retcode)) {
  ------------------
  |  |   31|      8|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (31:21): [True: 0, False: 8]
  |  |  ------------------
  ------------------
  111|      0|    if (retcode == EINVAL) {
  ------------------
  |  Branch (111:9): [True: 0, False: 0]
  ------------------
  112|      0|      ink_abort("couldn't allocate %zu bytes at alignment %zu - invalid alignment parameter", size, alignment);
  113|      0|    } else if (retcode == ENOMEM) {
  ------------------
  |  Branch (113:16): [True: 0, False: 0]
  ------------------
  114|      0|      ink_abort("couldn't allocate %zu bytes at alignment %zu - insufficient memory", size, alignment);
  115|      0|    } else {
  116|      0|      ink_abort("couldn't allocate %zu bytes at alignment %zu - unknown error %d", size, alignment, retcode);
  117|      0|    }
  118|      0|  }
  119|       |
  120|      8|  return ptr;
  121|      8|} /* End ats_memalign */
_Z8ats_freePv:
  125|  12.6k|{
  126|  12.6k|  if (likely(ptr != nullptr)) {
  ------------------
  |  |   28|  12.6k|#define likely(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (28:19): [True: 6.39k, False: 6.24k]
  |  |  ------------------
  ------------------
  127|  6.39k|    free(ptr);
  128|  6.39k|  }
  129|  12.6k|} /* End ats_free */
_Z8_xstrdupPKciS0_:
  242|  6.24k|{
  243|  6.24k|  char *newstr;
  244|       |
  245|  6.24k|  if (likely(str)) {
  ------------------
  |  |   28|  6.24k|#define likely(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (28:19): [True: 6.24k, False: 0]
  |  |  ------------------
  ------------------
  246|  6.24k|    if (length < 0) {
  ------------------
  |  Branch (246:9): [True: 6.24k, False: 0]
  ------------------
  247|  6.24k|      length = strlen(str);
  248|  6.24k|    }
  249|       |
  250|  6.24k|    newstr = static_cast<char *>(ats_malloc(length + 1));
  251|       |    // If this is a zero length string just null terminate and return.
  252|  6.24k|    if (unlikely(length == 0)) {
  ------------------
  |  |   31|  6.24k|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (31:21): [True: 0, False: 6.24k]
  |  |  ------------------
  ------------------
  253|      0|      *newstr = '\0';
  254|  6.24k|    } else {
  255|  6.24k|      strncpy(newstr, str, length); // we cannot do length + 1 because the string isn't
  256|  6.24k|      newstr[length] = '\0';        // guaranteed to be null terminated!
  257|  6.24k|    }
  258|  6.24k|    return newstr;
  259|  6.24k|  }
  260|      0|  return nullptr;
  261|  6.24k|}

_Z14ink_mutex_initP15pthread_mutex_t:
   50|  3.12k|{
   51|  3.12k|  int                          error;
   52|  3.12k|  static x_pthread_mutexattr_t attr;
   53|       |
   54|  3.12k|  error = pthread_mutex_init(m, &attr.attr);
   55|  3.12k|  if (unlikely(error != 0)) {
  ------------------
  |  |   31|  3.12k|#define unlikely(x) __builtin_expect(!!(x), 0)
  |  |  ------------------
  |  |  |  Branch (31:21): [True: 0, False: 3.12k]
  |  |  ------------------
  ------------------
   56|      0|    ink_abort("pthread_mutex_init(%p) failed: %s (%d)", m, strerror(error), error);
   57|      0|  }
   58|  3.12k|}
_ZN21x_pthread_mutexattr_tC2Ev:
   36|      2|  {
   37|      2|    pthread_mutexattr_init(&attr);
   38|       |#if DEBUG
   39|       |    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
   40|       |#endif
   41|      2|  }

_Z17ink_freelist_initPP12_InkFreeListPKcjjjb:
  139|     12|{
  140|     12|  InkFreeList       *f;
  141|     12|  ink_freelist_list *fll;
  142|       |
  143|       |  /* its safe to add to this global list because ink_freelist_init()
  144|       |     is only called from single-threaded initialization code. */
  145|     12|  f = static_cast<InkFreeList *>(ats_memalign(alignment, sizeof(InkFreeList)));
  146|     12|  ink_zero(*f);
  147|       |
  148|     12|  fll       = static_cast<ink_freelist_list *>(ats_malloc(sizeof(ink_freelist_list)));
  149|     12|  fll->fl   = f;
  150|     12|  fll->next = freelists;
  151|     12|  freelists = fll;
  152|       |
  153|     12|  f->name = name;
  154|       |  /* quick test for power of 2 */
  155|     12|  ink_assert(!(alignment & (alignment - 1)));
  ------------------
  |  |   45|     12|#define ink_assert(EX) (void)(EX)
  ------------------
  156|       |  // It is never useful to have alignment requirement looser than a page size
  157|       |  // so clip it. This makes the item alignment checks in the actual allocator simpler.
  158|     12|  f->alignment         = alignment;
  159|     12|  f->use_hugepages     = ats_hugepage_enabled() && use_hugepages;
  ------------------
  |  Branch (159:26): [True: 0, False: 12]
  |  Branch (159:52): [True: 0, False: 0]
  ------------------
  160|     12|  f->hugepages_failure = 0;
  161|     12|  if (f->use_hugepages) {
  ------------------
  |  Branch (161:7): [True: 0, False: 12]
  ------------------
  162|       |    // for hugepages, always make the allocation alignment on a hugepage boundary
  163|      0|    f->alignment = ats_hugepage_size();
  164|      0|    f->type_size = type_size;
  165|     12|  } else {
  166|     12|    if (f->alignment > ats_pagesize()) {
  ------------------
  |  Branch (166:9): [True: 0, False: 12]
  ------------------
  167|      0|      f->alignment = ats_pagesize();
  168|      0|    }
  169|       |    // Make sure we align *all* the objects in the allocation, not just the first one
  170|     12|    f->type_size = INK_ALIGN(type_size, f->alignment);
  ------------------
  |  |   50|     12|#define INK_ALIGN(size, boundary) (((size) + ((boundary) - 1)) & ~((boundary) - 1))
  ------------------
  171|     12|  }
  172|     12|  Dbg(dbg_ctl_freelist_init, "<%s> Alignment request/actual (%" PRIu32 "/%" PRIu32 ")", name, alignment, f->alignment);
  ------------------
  |  |  173|     12|  do {                              \
  |  |  174|     12|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 12]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|     12|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 12]
  |  |  ------------------
  ------------------
  173|     12|  Dbg(dbg_ctl_freelist_init, "<%s> Type Size request/actual (%" PRIu32 "/%" PRIu32 ")", name, type_size, f->type_size);
  ------------------
  |  |  173|     12|  do {                              \
  |  |  174|     12|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 12]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|     12|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 12]
  |  |  ------------------
  ------------------
  174|     12|  ink_assert(f->type_size != 0);
  ------------------
  |  |   45|     12|#define ink_assert(EX) (void)(EX)
  ------------------
  175|     12|  if (f->use_hugepages) {
  ------------------
  |  Branch (175:7): [True: 0, False: 12]
  ------------------
  176|      0|    f->chunk_size = INK_ALIGN(chunk_size * f->type_size, ats_hugepage_size()) / f->type_size;
  ------------------
  |  |   50|      0|#define INK_ALIGN(size, boundary) (((size) + ((boundary) - 1)) & ~((boundary) - 1))
  ------------------
  177|     12|  } else {
  178|     12|    f->chunk_size = INK_ALIGN(chunk_size * f->type_size, ats_pagesize()) / f->type_size;
  ------------------
  |  |   50|     12|#define INK_ALIGN(size, boundary) (((size) + ((boundary) - 1)) & ~((boundary) - 1))
  ------------------
  179|     12|  }
  180|     12|  Dbg(dbg_ctl_freelist_init, "<%s> Chunk Size request/actual (%" PRIu32 "/%" PRIu32 ")", name, chunk_size, f->chunk_size);
  ------------------
  |  |  173|     12|  do {                              \
  |  |  174|     12|    if ((CTL).on()) {               \
  |  |  ------------------
  |  |  |  Branch (174:9): [True: 0, False: 12]
  |  |  ------------------
  |  |  175|      0|      DbgPrint((CTL), __VA_ARGS__); \
  |  |  ------------------
  |  |  |  |  170|      0|#define DbgPrint(CTL, ...) (DbgCtl::print((CTL).tag(), __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__))
  |  |  ------------------
  |  |  176|      0|    }                               \
  |  |  177|     12|  } while (false)
  |  |  ------------------
  |  |  |  Branch (177:12): [Folded, False: 12]
  |  |  ------------------
  ------------------
  181|     12|  SET_FREELIST_POINTER_VERSION(f->head, FROM_PTR(0), 0);
  ------------------
  |  |  131|     12|  (_x).s.pointer = _p;                           \
  |  |  132|     12|  (_x).s.version = _v
  ------------------
  182|       |
  183|     12|  *fl = f;
  184|     12|}
_Z16ink_freelist_newP12_InkFreeList:
  207|  33.4k|{
  208|  33.4k|  void *ptr;
  209|       |
  210|  33.4k|  if (likely(ptr = freelist_global_ops->fl_new(f))) {
  ------------------
  |  |   77|  33.4k|#define likely(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (77:19): [True: 33.4k, False: 0]
  |  |  ------------------
  ------------------
  211|  33.4k|    ink_atomic_increment(reinterpret_cast<int *>(&f->used), 1);
  212|  33.4k|  }
  213|       |
  214|  33.4k|  return ptr;
  215|  33.4k|}
_Z17ink_freelist_freeP12_InkFreeListPv:
  309|  33.4k|{
  310|  33.4k|  if (likely(item != nullptr)) {
  ------------------
  |  |   77|  33.4k|#define likely(x) __builtin_expect(!!(x), 1)
  |  |  ------------------
  |  |  |  Branch (77:19): [True: 33.4k, False: 0]
  |  |  ------------------
  ------------------
  311|  33.4k|    ink_assert(f->used != 0);
  ------------------
  |  |   45|  33.4k|#define ink_assert(EX) (void)(EX)
  ------------------
  312|  33.4k|    freelist_global_ops->fl_free(f, item);
  313|  33.4k|    ink_atomic_decrement(reinterpret_cast<int *>(&f->used), 1);
  314|  33.4k|  }
  315|  33.4k|}
ink_queue.cc:_ZN12_GLOBAL__N_112freelist_newEP12_InkFreeList:
  222|  33.4k|{
  223|  33.4k|  head_p item;
  224|  33.4k|  head_p next;
  225|  33.4k|  int    result = 0;
  226|       |
  227|  33.4k|  do {
  228|  33.4k|    INK_QUEUE_LD(item, f->head);
  ------------------
  |  |   63|  33.4k|  do {                                                                                             \
  |  |   64|  33.4k|    const volatile __int128_t iqld0 = 0;                                                           \
  |  |   65|  33.4k|    *(__int128_t *)&(dst)           = __sync_val_compare_and_swap((__int128_t *)&(src), 0, iqld0); \
  |  |   66|  33.4k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (66:12): [Folded, False: 33.4k]
  |  |  ------------------
  ------------------
  229|  33.4k|    if (TO_PTR(FREELIST_POINTER(item)) == nullptr) {
  ------------------
  |  |  118|  33.4k|#define TO_PTR(_x)   ((void *)(_x))
  ------------------
  |  Branch (229:9): [True: 2, False: 33.4k]
  ------------------
  230|      2|      uint32_t i;
  231|      2|      void    *newp       = nullptr;
  232|      2|      size_t   alloc_size = static_cast<size_t>(f->chunk_size) * f->type_size;
  233|      2|      size_t   alignment  = 0;
  234|       |
  235|      2|      if (f->use_hugepages) {
  ------------------
  |  Branch (235:11): [True: 0, False: 2]
  ------------------
  236|      0|        alignment = ats_hugepage_size();
  237|      0|        newp      = ats_alloc_hugepage(alloc_size);
  238|      0|        if (newp == nullptr) {
  ------------------
  |  Branch (238:13): [True: 0, False: 0]
  ------------------
  239|      0|          f->hugepages_failure++;
  240|      0|        }
  241|      0|      }
  242|       |
  243|      2|      if (newp == nullptr) {
  ------------------
  |  Branch (243:11): [True: 2, False: 0]
  ------------------
  244|      2|        alignment = ats_pagesize();
  245|      2|        newp      = ats_memalign(alignment, INK_ALIGN(alloc_size, alignment));
  ------------------
  |  |   50|      2|#define INK_ALIGN(size, boundary) (((size) + ((boundary) - 1)) & ~((boundary) - 1))
  ------------------
  246|      2|      }
  247|       |
  248|      2|      if (f->advice) {
  ------------------
  |  Branch (248:11): [True: 0, False: 2]
  ------------------
  249|      0|        ats_madvise(static_cast<caddr_t>(newp), INK_ALIGN(alloc_size, alignment), f->advice);
  ------------------
  |  |   50|      0|#define INK_ALIGN(size, boundary) (((size) + ((boundary) - 1)) & ~((boundary) - 1))
  ------------------
  250|      0|      }
  251|      2|      SET_FREELIST_POINTER_VERSION(item, newp, 0);
  ------------------
  |  |  131|      2|  (_x).s.pointer = _p;                           \
  |  |  132|      2|  (_x).s.version = _v
  ------------------
  252|       |
  253|      2|      ink_atomic_increment(reinterpret_cast<int *>(&f->allocated), f->chunk_size);
  254|       |
  255|       |      /* free each of the new elements */
  256|    258|      for (i = 0; i < f->chunk_size; i++) {
  ------------------
  |  Branch (256:19): [True: 256, False: 2]
  ------------------
  257|    256|        char *a = (static_cast<char *>(FREELIST_POINTER(item))) + i * f->type_size;
  ------------------
  |  |  128|    256|#define FREELIST_POINTER(_x) (_x).s.pointer
  ------------------
  258|       |#ifdef DEADBEEF
  259|       |        const char str[4] = {static_cast<char>(0xde), static_cast<char>(0xad), static_cast<char>(0xbe), static_cast<char>(0xef)};
  260|       |        for (int j = 0; j < static_cast<int>(f->type_size); j++) {
  261|       |          a[j] = str[j % 4];
  262|       |        }
  263|       |#endif
  264|    256|        freelist_free(f, a);
  265|    256|      }
  266|       |
  267|  33.4k|    } else {
  268|  33.4k|      SET_FREELIST_POINTER_VERSION(next, *ADDRESS_OF_NEXT(TO_PTR(FREELIST_POINTER(item)), 0), FREELIST_VERSION(item) + 1);
  ------------------
  |  |  131|  33.4k|  (_x).s.pointer = _p;                           \
  |  |  132|  33.4k|  (_x).s.version = _v
  ------------------
  269|  33.4k|      result = ink_atomic_cas(&f->head.data, item.data, next.data);
  270|       |
  271|       |#ifdef SANITY
  272|       |      if (result) {
  273|       |        if (FREELIST_POINTER(item) == TO_PTR(FREELIST_POINTER(next))) {
  274|       |          ink_abort("ink_freelist_new: loop detected");
  275|       |        }
  276|       |        if (((uintptr_t)(TO_PTR(FREELIST_POINTER(next)))) & 3) {
  277|       |          ink_abort("ink_freelist_new: bad list");
  278|       |        }
  279|       |        if (TO_PTR(FREELIST_POINTER(next))) {
  280|       |          dummy_forced_read(TO_PTR(FREELIST_POINTER(next)));
  281|       |        }
  282|       |      }
  283|       |#endif /* SANITY */
  284|  33.4k|    }
  285|  33.4k|  } while (result == 0);
  ------------------
  |  Branch (285:12): [True: 2, False: 33.4k]
  ------------------
  286|  33.4k|  ink_assert(!((uintptr_t)TO_PTR(FREELIST_POINTER(item)) & (((uintptr_t)f->alignment) - 1)));
  ------------------
  |  |   45|  33.4k|#define ink_assert(EX) (void)(EX)
  ------------------
  287|       |
  288|  33.4k|  return TO_PTR(FREELIST_POINTER(item));
  ------------------
  |  |  118|  33.4k|#define TO_PTR(_x)   ((void *)(_x))
  ------------------
  289|  33.4k|}
ink_queue.cc:_ZN12_GLOBAL__N_113freelist_freeEP12_InkFreeListPv:
  322|  33.7k|{
  323|  33.7k|  void **adr_of_next = ADDRESS_OF_NEXT(item, 0);
  ------------------
  |  |  203|  33.7k|#define ADDRESS_OF_NEXT(x, offset) ((void **)((char *)x + offset))
  ------------------
  324|  33.7k|  head_p h;
  325|  33.7k|  head_p item_pair;
  326|  33.7k|  int    result = 0;
  327|       |
  328|       |  // ink_assert(!((long)item&(f->alignment-1))); XXX - why is this no longer working? -bcall
  329|       |
  330|       |#ifdef DEADBEEF
  331|       |  {
  332|       |    static const char str[4] = {static_cast<char>(0xde), static_cast<char>(0xad), static_cast<char>(0xbe), static_cast<char>(0xef)};
  333|       |
  334|       |    // set the entire item to DEADBEEF
  335|       |    for (int j = 0; j < static_cast<int>(f->type_size); j++) {
  336|       |      (static_cast<char *>(item))[j] = str[j % 4];
  337|       |    }
  338|       |  }
  339|       |#endif /* DEADBEEF */
  340|       |
  341|  67.4k|  while (!result) {
  ------------------
  |  Branch (341:10): [True: 33.7k, False: 33.7k]
  ------------------
  342|  33.7k|    INK_QUEUE_LD(h, f->head);
  ------------------
  |  |   63|  33.7k|  do {                                                                                             \
  |  |   64|  33.7k|    const volatile __int128_t iqld0 = 0;                                                           \
  |  |   65|  33.7k|    *(__int128_t *)&(dst)           = __sync_val_compare_and_swap((__int128_t *)&(src), 0, iqld0); \
  |  |   66|  33.7k|  } while (0)
  |  |  ------------------
  |  |  |  Branch (66:12): [Folded, False: 33.7k]
  |  |  ------------------
  ------------------
  343|       |#ifdef SANITY
  344|       |    if (TO_PTR(FREELIST_POINTER(h)) == item) {
  345|       |      ink_abort("ink_freelist_free: trying to free item twice");
  346|       |    }
  347|       |    if (((uintptr_t)(TO_PTR(FREELIST_POINTER(h)))) & 3) {
  348|       |      ink_abort("ink_freelist_free: bad list");
  349|       |    }
  350|       |    if (TO_PTR(FREELIST_POINTER(h))) {
  351|       |      dummy_forced_read(TO_PTR(FREELIST_POINTER(h)));
  352|       |    }
  353|       |#endif /* SANITY */
  354|  33.7k|    *adr_of_next = FREELIST_POINTER(h);
  ------------------
  |  |  128|  33.7k|#define FREELIST_POINTER(_x) (_x).s.pointer
  ------------------
  355|  33.7k|    SET_FREELIST_POINTER_VERSION(item_pair, FROM_PTR(item), FREELIST_VERSION(h));
  ------------------
  |  |  131|  33.7k|  (_x).s.pointer = _p;                           \
  |  |  132|  33.7k|  (_x).s.version = _v
  ------------------
  356|  33.7k|    INK_MEMORY_BARRIER;
  357|  33.7k|    result = ink_atomic_cas(&f->head.data, h.data, item_pair.data);
  358|  33.7k|  }
  359|  33.7k|}

_ZN6DbgCtl14_new_referenceEPKc:
  125|     34|{
  126|     34|  DebugInterface *p = DebugInterface::get_instance();
  127|     34|  debug_assert(tag != nullptr);
  ------------------
  |  |   45|     34|#define debug_assert(EX)              (void)(EX)
  ------------------
  128|       |
  129|     34|  _TagData *new_tag_data{nullptr};
  130|       |
  131|     34|  {
  132|     34|    _RegistryAccessor ra;
  133|       |
  134|     34|    auto &d{ra.data()};
  135|       |
  136|     34|    if (auto it = d.map.find(tag); it != d.map.end()) {
  ------------------
  |  Branch (136:36): [True: 8, False: 26]
  ------------------
  137|      8|      return &*it;
  138|      8|    }
  139|       |
  140|     26|    auto sz = std::strlen(tag);
  141|       |
  142|     26|    debug_assert(sz > 0);
  ------------------
  |  |   45|     26|#define debug_assert(EX)              (void)(EX)
  ------------------
  143|       |
  144|     26|    char *t = new char[sz + 1]; // Never deleted (leaky singleton) - reclaimed by OS at process exit.
  145|     26|    std::memcpy(t, tag, sz + 1);
  146|     26|    _TagData new_elem{t, false};
  147|       |
  148|     26|    auto res = d.map.insert(new_elem);
  149|       |
  150|     26|    debug_assert(res.second);
  ------------------
  |  |   45|     26|#define debug_assert(EX)              (void)(EX)
  ------------------
  151|       |
  152|     26|    new_tag_data = &*res.first;
  153|     26|  }
  154|     26|  new_tag_data->second = p && p->debug_tag_activated(tag);
  ------------------
  |  Branch (154:26): [True: 0, False: 26]
  |  Branch (154:31): [True: 0, False: 0]
  ------------------
  155|       |
  156|       |  // It is important that debug_tag_activated() is NOT called while the ra object exists, and the registry mutex is
  157|       |  // locked.  There is a mutex in the C/C++ runtime that both dlopen() and _cxa_thread_atexit() lock while running.
  158|       |  // Creating a _RegistryAccessor instance locks the registry mutex.  If the subsequent code in this function triggers
  159|       |  // the construction of a thread_local variable (with a non-trivial destructor), with the registry mutex locked, the
  160|       |  // following deadlock scenario is possible:
  161|       |  // 1.  Thread 1 calls a DbgCtl constructor, which locks the registry mutex, but then is suspended.
  162|       |  // 2.  Thread 2 calls dlopen() for a plugin, locking the runtime mutex.  It then executes the constructor for a
  163|       |  //     statically allocated DbgCtl object, which blocks on locking the registry mutex.
  164|       |  // 3.  Thread 1 resumes, and calls a function that causes the the construction of a thread_local variable with a
  165|       |  //     non-trivial destructor.  This causes a call to _cxa_thread_atexit(), to set up a call of the variable's
  166|       |  //     destructor at thread exit.  The call to _cxa_thread_atexit() will block on the runtime mutex (held by Thread 2).
  167|       |  //     So Thread 1 holds the registry mutex and is blocked waiting for the runtime mutex.  And Thread 2 holds the
  168|       |  //     runtime mutex and is blocked waiting for the registry mutex.  Deadlock.
  169|       |
  170|     26|  return new_tag_data;
  171|     34|}
_ZN6DbgCtl6updateERKNSt3__18functionIFbPKcEEE:
  183|  6.24k|{
  184|  6.24k|  _RegistryAccessor ra;
  185|  6.24k|  auto             &d{ra.data()};
  186|       |
  187|  81.1k|  for (auto &i : d.map) {
  ------------------
  |  Branch (187:16): [True: 81.1k, False: 6.24k]
  ------------------
  188|  81.1k|    i.second = f(i.first);
  189|  81.1k|  }
  190|  6.24k|}
_ZN14DebugInterface12get_instanceEv:
  259|     34|{
  260|     34|  return di_inst;
  261|     34|}
_ZN14DebugInterface12set_instanceEPS_:
  265|  3.12k|{
  266|  3.12k|  di_inst = i;
  267|  3.12k|  DbgCtl::update([&](const char *t) { return i->debug_tag_activated(t); });
  268|  3.12k|}
_ZN6DbgCtl17_RegistryAccessorC2Ev:
   88|  6.27k|  {
   89|  6.27k|    if (!_registry_instance) {
  ------------------
  |  Branch (89:9): [True: 2, False: 6.27k]
  ------------------
   90|      2|      Registry *expected{nullptr};
   91|      2|      Registry *r{new Registry};
   92|      2|      if (!_registry_instance.compare_exchange_strong(expected, r)) {
  ------------------
  |  Branch (92:11): [True: 0, False: 2]
  ------------------
   93|      0|        r->_mtx.lock();
   94|      0|        delete r;
   95|      0|      }
   96|      2|    }
   97|  6.27k|    _registry_instance.load()->_mtx.lock();
   98|  6.27k|    _mtx_is_locked = true;
   99|  6.27k|  }
_ZN6DbgCtl17_RegistryAccessor8RegistryC2Ev:
   77|      2|    Registry() = default;
_ZN6DbgCtl17_RegistryAccessor4dataEv:
  113|  6.27k|  {
  114|  6.27k|    return *_registry_instance;
  115|  6.27k|  }
_ZN6DbgCtl17_RegistryAccessorD2Ev:
  102|  6.27k|  {
  103|  6.27k|    if (_mtx_is_locked) {
  ------------------
  |  Branch (103:9): [True: 6.27k, False: 0]
  ------------------
  104|  6.27k|      _registry_instance.load()->_mtx.unlock();
  105|  6.27k|    }
  106|  6.27k|  }
_ZNK6DbgCtl17_RegistryAccessor6TagCmpclEPKcS3_:
   63|    216|    {
   64|    216|      return std::strcmp(a, b) < 0;
   65|    216|    }
DbgCtl.cc:_ZZN14DebugInterface12set_instanceEPS_ENK3$_0clEPKc:
  267|  40.5k|  DbgCtl::update([&](const char *t) { return i->debug_tag_activated(t); });

_ZN12RegexMatchesC2Ej:
  133|  16.9k|{
  134|  16.9k|  pcre2_general_context *ctx = pcre2_general_context_create(&RegexMatches::malloc, &RegexMatches::free, static_cast<void *>(this));
  135|       |
  136|  16.9k|  pcre2_match_data *match_data = pcre2_match_data_create(size, ctx);
  137|  16.9k|  debug_assert_message(match_data, "Failed to allocate pcre2 match data from custom context");
  ------------------
  |  |   46|  16.9k|#define debug_assert_message(EX, MSG) (void)(EX)
  ------------------
  138|       |
  139|  16.9k|  _MatchData::set(_match_data, match_data);
  140|  16.9k|}
_ZN12RegexMatches6mallocEmPv:
  145|  33.8k|{
  146|  33.8k|  auto *matches = static_cast<RegexMatches *>(caller);
  147|       |
  148|       |  // allocate from the buffer if possible
  149|  33.8k|  if (size <= sizeof(matches->_buffer) - matches->_buffer_bytes_used) {
  ------------------
  |  Branch (149:7): [True: 33.8k, False: 0]
  ------------------
  150|  33.8k|    void *ptr                    = matches->_buffer + matches->_buffer_bytes_used;
  151|  33.8k|    matches->_buffer_bytes_used += size;
  152|  33.8k|    return ptr;
  153|  33.8k|  }
  154|       |
  155|      0|  return ::malloc(size);
  156|  33.8k|}
_ZN12RegexMatches4freeEPvS0_:
  161|  16.9k|{
  162|  16.9k|  auto *matches = static_cast<RegexMatches *>(caller);
  163|       |
  164|       |  // Call free for any p outside _buffer
  165|       |  // If the pcre2 context requests more data than fits in our builtin buffer, we will call malloc
  166|       |  // to fulfil that request.
  167|       |  // !his checks for any pointers outside of our buffer in order to free that memory up.
  168|       |  //
  169|       |  // nullptr is outside of our buffer, but its ok to call ::free with nullptr.
  170|  16.9k|  if (!(p >= matches->_buffer && p < matches->_buffer + sizeof(matches->_buffer))) {
  ------------------
  |  Branch (170:9): [True: 16.9k, False: 0]
  |  Branch (170:34): [True: 16.9k, False: 0]
  ------------------
  171|      0|    ::free(p);
  172|      0|  }
  173|  16.9k|}
_ZN12RegexMatchesD2Ev:
  177|  16.9k|{
  178|  16.9k|  auto ptr = _MatchData::get(_match_data);
  179|  16.9k|  if (ptr != nullptr) {
  ------------------
  |  Branch (179:7): [True: 16.9k, False: 0]
  ------------------
  180|       |    pcre2_match_data_free(ptr);
  181|  16.9k|  }
  182|  16.9k|}
_ZN5RegexC2EOS_:
  322|    135|{
  323|    135|  _code = that._code;
  324|    135|  _Code::set(that._code, nullptr);
  325|    135|}
_ZN5RegexD2Ev:
  344|    135|{
  345|    135|  auto ptr = _Code::get(_code);
  346|    135|  if (ptr != nullptr) {
  ------------------
  |  Branch (346:7): [True: 0, False: 135]
  ------------------
  347|       |    pcre2_code_free(ptr);
  348|      0|  }
  349|    135|}
_ZN5Regex7compileENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEEj:
  354|    135|{
  355|    135|  std::string error;
  356|    135|  int         erroroffset;
  357|       |
  358|    135|  return this->compile(pattern, error, erroroffset, flags);
  359|    135|}
_ZN5Regex7compileENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEERNS0_12basic_stringIcS3_NS0_9allocatorIcEEEERij:
  364|    135|{
  365|       |  // free the existing compiled regex if there is one
  366|    135|  if (auto ptr = _Code::get(_code); ptr != nullptr) {
  ------------------
  |  Branch (366:37): [True: 0, False: 135]
  ------------------
  367|      0|    pcre2_code_free(ptr);
  368|      0|  }
  369|       |
  370|       |  // get the RegexContext instance - should only be null when shutting down
  371|    135|  RegexContext *regex_context = RegexContext::get_instance();
  372|    135|  if (regex_context == nullptr) {
  ------------------
  |  Branch (372:7): [True: 0, False: 135]
  ------------------
  373|      0|    return false;
  374|      0|  }
  375|       |
  376|    135|  PCRE2_SIZE error_offset;
  377|    135|  int        error_code;
  378|    135|  auto       code = pcre2_compile(reinterpret_cast<PCRE2_SPTR>(pattern.data()), pattern.size(), flags, &error_code, &error_offset,
  379|    135|                                  regex_context->get_compile_context());
  380|    135|  if (!code) {
  ------------------
  |  Branch (380:7): [True: 0, False: 135]
  ------------------
  381|      0|    erroroffset = error_offset;
  382|       |
  383|       |    // get pcre2 error message
  384|      0|    PCRE2_UCHAR buffer[256];
  385|      0|    pcre2_get_error_message(error_code, buffer, sizeof(buffer));
  386|      0|    error.assign((char const *)buffer);
  387|      0|    return false;
  388|      0|  }
  389|       |
  390|       |  // support for JIT
  391|    135|  pcre2_jit_compile(code, PCRE2_JIT_COMPLETE);
  392|       |
  393|    135|  _Code::set(_code, code);
  394|       |
  395|    135|  return true;
  396|    135|}
_ZNK5Regex4execENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEE:
  401|  16.9k|{
  402|  16.9k|  return this->exec(subject, 0);
  403|  16.9k|}
_ZNK5Regex4execENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEEj:
  408|  16.9k|{
  409|  16.9k|  if (_Code::get(_code) == nullptr) {
  ------------------
  |  Branch (409:7): [True: 0, False: 16.9k]
  ------------------
  410|      0|    return false;
  411|      0|  }
  412|  16.9k|  RegexMatches matches;
  413|       |
  414|  16.9k|  int count = this->exec(subject, matches, flags);
  415|  16.9k|  return count >= 0;
  416|  16.9k|}
_ZNK5Regex4execENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEER12RegexMatchesjPK17RegexMatchContext:
  428|  16.9k|{
  429|  16.9k|  auto code = _Code::get(_code);
  430|       |
  431|       |  // check if there is a compiled regex
  432|  16.9k|  if (code == nullptr) {
  ------------------
  |  Branch (432:7): [True: 0, False: 16.9k]
  ------------------
  433|      0|    return PCRE2_ERROR_NULL;
  434|      0|  }
  435|       |
  436|       |  // Use the provided or the thread global context?
  437|  16.9k|  pcre2_match_context *match_context;
  438|  16.9k|  if (nullptr == matchContext) {
  ------------------
  |  Branch (438:7): [True: 16.9k, False: 0]
  ------------------
  439|  16.9k|    match_context = RegexContext::get_instance()->get_match_context();
  440|  16.9k|  } else {
  441|      0|    match_context = RegexMatchContext::_MatchContext::get(matchContext->_match_context);
  442|      0|  }
  443|       |
  444|  16.9k|  int const rc = pcre2_match(code, reinterpret_cast<PCRE2_SPTR>(subject.data()), subject.size(), 0, flags,
  445|  16.9k|                             RegexMatches::_MatchData::get(matches._match_data), match_context);
  446|       |
  447|  16.9k|  matches._size = rc;
  448|       |
  449|       |  // match was successful
  450|  16.9k|  if (rc >= 0) {
  ------------------
  |  Branch (450:7): [True: 254, False: 16.6k]
  ------------------
  451|    254|    matches._subject = subject;
  452|       |
  453|       |    // match but the output vector was too small, adjust the size of the matches
  454|    254|    if (rc == 0) {
  ------------------
  |  Branch (454:9): [True: 0, False: 254]
  ------------------
  455|      0|      matches._size = pcre2_get_ovector_count(RegexMatches::_MatchData::get(matches._match_data));
  456|      0|    }
  457|    254|  }
  458|       |
  459|  16.9k|  return rc;
  460|  16.9k|}
_ZN3DFA5buildENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEEj:
  513|    135|{
  514|    135|  Regex       rxp;
  515|    135|  std::string string{pattern};
  516|       |
  517|    135|  if (!(flags & RE_UNANCHORED)) {
  ------------------
  |  Branch (517:7): [True: 135, False: 0]
  ------------------
  518|    135|    flags |= RE_ANCHORED;
  519|    135|  }
  520|       |
  521|    135|  if (!rxp.compile(pattern, flags)) {
  ------------------
  |  Branch (521:7): [True: 0, False: 135]
  ------------------
  522|      0|    return false;
  523|      0|  }
  524|    135|  _patterns.emplace_back(std::move(rxp), std::move(string));
  525|    135|  return true;
  526|    135|}
_ZN3DFA7compileEPKPKcij:
  551|      1|{
  552|      1|  _patterns.reserve(npatterns); // try to pre-allocate.
  553|    136|  for (int i = 0; i < npatterns; ++i) {
  ------------------
  |  Branch (553:19): [True: 135, False: 1]
  ------------------
  554|    135|    this->build(patterns[i], flags);
  555|    135|  }
  556|      1|  return _patterns.size();
  557|      1|}
_ZNK3DFA5matchENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEE:
  562|    254|{
  563|  16.9k|  for (auto spot = _patterns.begin(), limit = _patterns.end(); spot != limit; ++spot) {
  ------------------
  |  Branch (563:64): [True: 16.9k, False: 0]
  ------------------
  564|  16.9k|    if (spot->_re.exec(str)) {
  ------------------
  |  Branch (564:9): [True: 254, False: 16.6k]
  ------------------
  565|    254|      return spot - _patterns.begin();
  566|    254|    }
  567|  16.9k|  }
  568|       |
  569|      0|  return -1;
  570|    254|}
_ZN12RegexMatches10_MatchData3setERNS_13_MatchDataPtrEP23pcre2_real_match_data_8:
  126|  16.9k|  {
  127|  16.9k|    p._ptr = ptr;
  128|  16.9k|  }
_ZN12RegexMatches10_MatchData3getERKNS_13_MatchDataPtrE:
  121|  33.8k|  {
  122|  33.8k|    return static_cast<pcre2_match_data *>(p._ptr);
  123|  33.8k|  }
_ZN5Regex5_Code3getERKNS_8_CodePtrE:
  284|  34.0k|  {
  285|  34.0k|    return static_cast<pcre2_code *>(p._ptr);
  286|  34.0k|  }
_ZN5Regex5_Code3setERNS_8_CodePtrEP17pcre2_real_code_8:
  289|    270|  {
  290|    270|    p._ptr = ptr;
  291|    270|  }
Regex.cc:_ZN12_GLOBAL__N_112RegexContext12get_instanceEv:
   65|  17.0k|  {
   66|  17.0k|    thread_local RegexContext ctx;
   67|  17.0k|    return &ctx;
   68|  17.0k|  }
Regex.cc:_ZN12_GLOBAL__N_112RegexContextC2Ev:
  102|      1|  {
  103|      1|    _general_context = pcre2_general_context_create(my_malloc, my_free, nullptr);
  104|      1|    _compile_context = pcre2_compile_context_create(_general_context);
  105|      1|    _match_context   = pcre2_match_context_create(_general_context);
  106|      1|    _jit_stack       = pcre2_jit_stack_create(4096, 1024 * 1024, nullptr); // 1 page min and 1MB max
  107|       |    pcre2_jit_stack_assign(_match_context, nullptr, _jit_stack);
  108|      1|  }
Regex.cc:_ZN12_GLOBAL__N_19my_mallocEmPv:
   48|    948|{
   49|    948|  void *ptr = malloc(size);
   50|    948|  return ptr;
   51|    948|}
Regex.cc:_ZN12_GLOBAL__N_17my_freeEPvS0_:
   55|    678|{
   56|    678|  free(ptr);
   57|    678|}
Regex.cc:_ZN12_GLOBAL__N_112RegexContextD2Ev:
   70|      1|  {
   71|      1|    if (_general_context != nullptr) {
  ------------------
  |  Branch (71:9): [True: 1, False: 0]
  ------------------
   72|      1|      pcre2_general_context_free(_general_context);
   73|      1|    }
   74|      1|    if (_compile_context != nullptr) {
  ------------------
  |  Branch (74:9): [True: 1, False: 0]
  ------------------
   75|      1|      pcre2_compile_context_free(_compile_context);
   76|      1|    }
   77|      1|    if (_match_context != nullptr) {
  ------------------
  |  Branch (77:9): [True: 1, False: 0]
  ------------------
   78|      1|      pcre2_match_context_free(_match_context);
   79|      1|    }
   80|      1|    if (_jit_stack != nullptr) {
  ------------------
  |  Branch (80:9): [True: 1, False: 0]
  ------------------
   81|       |      pcre2_jit_stack_free(_jit_stack);
   82|      1|    }
   83|      1|  }
Regex.cc:_ZN12_GLOBAL__N_112RegexContext19get_compile_contextEv:
   91|    135|  {
   92|    135|    return _compile_context;
   93|    135|  }
Regex.cc:_ZN12_GLOBAL__N_112RegexContext17get_match_contextEv:
   96|  16.9k|  {
   97|  16.9k|    return _match_context;
   98|  16.9k|  }

LLVMFuzzerTestOneInput:
   35|  3.14k|{
   36|  3.14k|  if (size_data < kMinInputLength || size_data > kMaxInputLength) {
  ------------------
  |  |   28|  6.29k|#define kMinInputLength 10
  ------------------
                if (size_data < kMinInputLength || size_data > kMaxInputLength) {
  ------------------
  |  |   29|  3.14k|#define kMaxInputLength 1024
  ------------------
  |  Branch (36:7): [True: 6, False: 3.14k]
  |  Branch (36:38): [True: 22, False: 3.12k]
  ------------------
   37|     28|    return 0;
   38|     28|  }
   39|       |
   40|  3.12k|  std::string input(reinterpret_cast<const char *>(input_data), size_data);
   41|  3.12k|  char const *start = input.c_str();
   42|  3.12k|  char const *end   = input.c_str() + input.size();
   43|       |
   44|  3.12k|  cmd_disable_pfreelist = true;
   45|  3.12k|  DiagsPtr::set(new Diags("fuzzing", "", "", nullptr));
   46|       |
   47|  3.12k|  http_init();
   48|       |
   49|  3.12k|  HTTPParser parser;
   50|  3.12k|  HTTPHdr    req_hdr, rsp_hdr, req_hdr_2, rsp_hdr_2, req_hdr_3, rsp_hdr_3;
   51|       |
   52|  3.12k|  req_hdr.create(HTTPType::REQUEST);
   53|  3.12k|  rsp_hdr.create(HTTPType::RESPONSE);
   54|  3.12k|  req_hdr_2.create(HTTPType::REQUEST, HTTP_2_0);
   55|  3.12k|  rsp_hdr_2.create(HTTPType::RESPONSE, HTTP_2_0);
   56|  3.12k|  req_hdr_3.create(HTTPType::REQUEST, HTTP_3_0);
   57|  3.12k|  rsp_hdr_3.create(HTTPType::RESPONSE, HTTP_3_0);
   58|       |
   59|  3.12k|  {
   60|  3.12k|    http_parser_init(&parser);
   61|  3.12k|    ParseResult result = req_hdr.parse_req(&parser, &start, end, true);
   62|  3.12k|    http_parser_clear(&parser);
   63|  3.12k|  }
   64|  3.12k|  {
   65|  3.12k|    http_parser_init(&parser);
   66|  3.12k|    ParseResult result = rsp_hdr.parse_resp(&parser, &start, end, true);
   67|  3.12k|    http_parser_clear(&parser);
   68|  3.12k|  }
   69|  3.12k|  {
   70|  3.12k|    http_parser_init(&parser);
   71|  3.12k|    ParseResult result = req_hdr_2.parse_req(&parser, &start, end, true);
   72|  3.12k|    http_parser_clear(&parser);
   73|  3.12k|  }
   74|  3.12k|  {
   75|  3.12k|    http_parser_init(&parser);
   76|  3.12k|    ParseResult result = rsp_hdr_2.parse_resp(&parser, &start, end, true);
   77|  3.12k|    http_parser_clear(&parser);
   78|  3.12k|  }
   79|  3.12k|  {
   80|  3.12k|    http_parser_init(&parser);
   81|  3.12k|    ParseResult result = req_hdr_3.parse_req(&parser, &start, end, true);
   82|  3.12k|    http_parser_clear(&parser);
   83|  3.12k|  }
   84|  3.12k|  {
   85|  3.12k|    http_parser_init(&parser);
   86|  3.12k|    ParseResult result = rsp_hdr_3.parse_resp(&parser, &start, end, true);
   87|  3.12k|    http_parser_clear(&parser);
   88|  3.12k|  }
   89|       |
   90|  3.12k|  req_hdr.destroy();
   91|  3.12k|  rsp_hdr.destroy();
   92|  3.12k|  req_hdr_2.destroy();
   93|  3.12k|  rsp_hdr_2.destroy();
   94|  3.12k|  req_hdr_3.destroy();
   95|  3.12k|  rsp_hdr_3.destroy();
   96|       |
   97|  3.12k|  delete diags();
   98|       |
   99|  3.12k|  return 0;
  100|  3.14k|}

