_ZN11addressbook6Person25internal_default_instanceEv:
  322|      2|  static inline const Person* internal_default_instance() {
  323|      2|    return reinterpret_cast<const Person*>(
  324|      2|               &_Person_default_instance_);
  325|      2|  }
_ZN11addressbook6Person16default_instanceEv:
  319|      2|  static const Person& default_instance() {
  320|      2|    return *internal_default_instance();
  321|      2|  }

_ZN4brpc21NonreflectableMessageINS_12RedisRequestEEC2Ev:
   43|      2|    inline NonreflectableMessage() = default;
_ZN4brpc21NonreflectableMessageINS_13RedisResponseEEC2Ev:
   43|      2|    inline NonreflectableMessage() = default;

_ZN4brpc12RedisRequestC2Ev:
   33|      2|    : NonreflectableMessage<RedisRequest>() {
   34|      2|    SharedCtor();
   35|      2|}
_ZN4brpc12RedisRequest10SharedCtorEv:
   43|      2|void RedisRequest::SharedCtor() {
   44|      2|    _ncommand = 0;
   45|      2|    _has_error = false;
   46|      2|    _cached_size_ = 0;
   47|      2|}
_ZN4brpc13RedisResponseC2Ev:
  198|      2|    : NonreflectableMessage<RedisResponse>()
  199|      2|    , _first_reply(&_arena) {
  200|      2|    SharedCtor();
  201|      2|}
_ZN4brpc13RedisResponse10SharedCtorEv:
  209|      2|void RedisResponse::SharedCtor() {
  210|       |    _other_replies = NULL;
  211|      2|    _cached_size_ = 0;
  212|      2|    _nreply = 0;
  213|      2|}

_ZN4brpc18RedisCommandParserC2Ev:
  386|     84|    : _parsing_array(false)
  387|     84|    , _length(0)
  388|     84|    , _index(0) {}
_ZN4brpc18RedisCommandParser7ConsumeERN5butil5IOBufEPSt6vectorINS1_16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESaISC_EEPNS1_5ArenaE:
  396|     84|                                       butil::Arena* arena) {
  397|     84|    ParseError err = PARSE_OK;
  398|  1.15k|    do {
  399|  1.15k|        RedisCommandConsumeState state = ConsumeImpl(buf, arena, &err);
  400|  1.15k|        if (state == CONSUME_STATE_CONTINUE) {
  ------------------
  |  Branch (400:13): [True: 1.07k, False: 84]
  ------------------
  401|  1.07k|            continue;
  402|  1.07k|        } else if (state == CONSUME_STATE_DONE) {
  ------------------
  |  Branch (402:20): [True: 36, False: 48]
  ------------------
  403|     36|            break;
  404|     48|        } else {
  405|     48|            return err;
  406|     48|        }
  407|  1.15k|    } while (true);
  ------------------
  |  Branch (407:14): [True: 1.07k, Folded]
  ------------------
  408|       |    
  409|     36|    args->swap(_args);
  410|     36|    Reset();
  411|     36|    return PARSE_OK;
  412|     84|}
_ZN4brpc18RedisCommandParser11ConsumeImplERN5butil5IOBufEPNS1_5ArenaEPNS_10ParseErrorE:
  416|  1.15k|                                                         ParseError* err) {
  417|  1.15k|    const auto pfc = static_cast<const char *>(buf.fetch1());
  418|  1.15k|    if (pfc == NULL) {
  ------------------
  |  Branch (418:9): [True: 4, False: 1.15k]
  ------------------
  419|      4|        *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  420|      4|        return CONSUME_STATE_ERROR;
  421|      4|    }
  422|       |    // '*' stands for array "*<size>\r\n<sub-reply1><sub-reply2>..."
  423|  1.15k|    if (!_parsing_array && *pfc != '*') {
  ------------------
  |  Branch (423:9): [True: 84, False: 1.07k]
  |  Branch (423:28): [True: 55, False: 29]
  ------------------
  424|     55|        if (!std::isalpha(static_cast<unsigned char>(*pfc))) {
  ------------------
  |  Branch (424:13): [True: 16, False: 39]
  ------------------
  425|     16|            *err = PARSE_ERROR_TRY_OTHERS;
  426|     16|            return CONSUME_STATE_ERROR;
  427|     16|        }
  428|       |        // The HTTP/2 connection preface ("PRI * HTTP/2.0\r\n...") is alpha-leading
  429|       |        // and would otherwise be consumed as an inline redis command (first token
  430|       |        // "PRI"), preventing protocol auto-detection from falling through to
  431|       |        // HTTP/2 (e.g. gRPC clients). Defer to other protocols when the input
  432|       |        // matches the preface, either fully or as a not-yet-complete prefix. No
  433|       |        // valid redis command begins with these bytes, so this is unambiguous.
  434|       |        // See issue #3109.
  435|     39|        static const char h2_preface[] = "PRI * HTTP/2.0\r\n";
  436|     39|        const size_t h2_preface_len = sizeof(h2_preface) - 1;
  437|     39|        if (*pfc == h2_preface[0]) {
  ------------------
  |  Branch (437:13): [True: 4, False: 35]
  ------------------
  438|      4|            char head[h2_preface_len];
  439|      4|            const size_t n = buf.copy_to(head, h2_preface_len);
  440|      4|            if (memcmp(head, h2_preface, n) == 0) {
  ------------------
  |  Branch (440:17): [True: 0, False: 4]
  ------------------
  441|      0|                *err = PARSE_ERROR_TRY_OTHERS;
  442|      0|                return CONSUME_STATE_ERROR;
  443|      0|            }
  444|      4|        }
  445|     39|        const size_t max_inline_size =
  446|     39|            FLAGS_redis_max_allocation_size > 0 ?
  ------------------
  |  Branch (446:13): [True: 39, False: 0]
  ------------------
  447|     39|            static_cast<size_t>(FLAGS_redis_max_allocation_size) : 0;
  448|     39|        const size_t crlf_pos = FindCRLF(buf, max_inline_size + 2);
  449|     39|        if (crlf_pos == CRLF_NOT_FOUND) {
  ------------------
  |  Branch (449:13): [True: 4, False: 35]
  ------------------
  450|      4|            if (buf.size() <= max_inline_size) {
  ------------------
  |  Branch (450:17): [True: 4, False: 0]
  ------------------
  451|      4|                *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  452|      4|                return CONSUME_STATE_ERROR;
  453|      4|            }
  454|      0|            if (buf.size() == max_inline_size + 1) {
  ------------------
  |  Branch (454:17): [True: 0, False: 0]
  ------------------
  455|      0|                char last_char = '\0';
  456|      0|                buf.copy_to(&last_char, 1, max_inline_size);
  457|      0|                if (last_char == '\r') {
  ------------------
  |  Branch (457:21): [True: 0, False: 0]
  ------------------
  458|      0|                    *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  459|      0|                    return CONSUME_STATE_ERROR;
  460|      0|                }
  461|      0|            }
  462|      0|            LOG(ERROR) << "inline command exceeds max allocation size! max="
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  463|      0|                       << FLAGS_redis_max_allocation_size << ", actually=" << buf.size();
  464|      0|            *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  465|      0|            return CONSUME_STATE_ERROR;
  466|      0|        }
  467|     35|        if (crlf_pos > max_inline_size) {
  ------------------
  |  Branch (467:13): [True: 0, False: 35]
  ------------------
  468|      0|            LOG(ERROR) << "inline command exceeds max allocation size! max="
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  469|      0|                       << FLAGS_redis_max_allocation_size << ", actually=" << crlf_pos;
  470|      0|            *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  471|      0|            return CONSUME_STATE_ERROR;
  472|      0|        }
  473|     35|        const size_t buf_size = crlf_pos;
  474|     35|        const auto copy_str = static_cast<char *>(arena->allocate(buf_size + 1));
  475|       |        // arena->allocate() may return NULL on allocation failure
  476|     35|        if (copy_str == NULL) {
  ------------------
  |  Branch (476:13): [True: 0, False: 35]
  ------------------
  477|      0|            LOG(FATAL) << "Arena failed allocation";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  478|      0|            *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  479|      0|            return CONSUME_STATE_ERROR;
  480|      0|        }
  481|     35|        buf.copy_to(copy_str, buf_size);
  482|     35|        if (*copy_str == ' ') {
  ------------------
  |  Branch (482:13): [True: 0, False: 35]
  ------------------
  483|      0|            *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  484|      0|            return CONSUME_STATE_ERROR;
  485|      0|        }
  486|     35|        copy_str[buf_size] = '\0';
  487|     35|        size_t offset = 0;
  488|  2.24k|        while (offset < crlf_pos && copy_str[offset] != ' ') {
  ------------------
  |  Branch (488:16): [True: 2.23k, False: 13]
  |  Branch (488:37): [True: 2.21k, False: 22]
  ------------------
  489|  2.21k|            ++offset;
  490|  2.21k|        }
  491|     35|        const auto first_arg = static_cast<char*>(arena->allocate(offset));
  492|     35|        memcpy(first_arg, copy_str, offset);
  493|  2.24k|        for (size_t i = 0; i < offset; ++i) {
  ------------------
  |  Branch (493:28): [True: 2.21k, False: 35]
  ------------------
  494|  2.21k|            first_arg[i] = tolower(static_cast<unsigned char>(first_arg[i]));
  495|  2.21k|        }
  496|     35|        _args.push_back(butil::StringPiece(first_arg, offset));
  497|     35|        if (offset == crlf_pos) {
  ------------------
  |  Branch (497:13): [True: 13, False: 22]
  ------------------
  498|       |            // only one argument, directly return
  499|     13|            buf.pop_front(crlf_pos + 2);
  500|     13|            return CONSUME_STATE_DONE;
  501|     13|        }
  502|     22|        size_t arg_start_pos = ++offset;
  503|       |
  504|  8.85k|        for (; offset < crlf_pos; ++offset) {
  ------------------
  |  Branch (504:16): [True: 8.83k, False: 22]
  ------------------
  505|  8.83k|            if (copy_str[offset] != ' ') {
  ------------------
  |  Branch (505:17): [True: 7.72k, False: 1.10k]
  ------------------
  506|  7.72k|                continue;
  507|  7.72k|            }
  508|  1.10k|            const auto arg_length = offset - arg_start_pos;
  509|  1.10k|            const auto arg = static_cast<char *>(arena->allocate(arg_length));
  510|  1.10k|            memcpy(arg, copy_str + arg_start_pos, arg_length);
  511|  1.10k|            _args.push_back(butil::StringPiece(arg, arg_length));
  512|  1.10k|            arg_start_pos = ++offset;
  513|  1.10k|        }
  514|       |
  515|     22|        if (arg_start_pos < crlf_pos) {
  ------------------
  |  Branch (515:13): [True: 12, False: 10]
  ------------------
  516|       |            // process the last argument
  517|     12|            const auto arg_length = crlf_pos - arg_start_pos;
  518|     12|            const auto arg = static_cast<char *>(arena->allocate(arg_length));
  519|     12|            memcpy(arg, copy_str + arg_start_pos, arg_length);
  520|     12|            _args.push_back(butil::StringPiece(arg, arg_length));
  521|     12|        }
  522|       |
  523|     22|        buf.pop_front(crlf_pos + 2);
  524|     22|        return CONSUME_STATE_DONE;
  525|     35|    }
  526|       |    // '$' stands for bulk string "$<length>\r\n<string>\r\n"
  527|  1.09k|    if (_parsing_array && *pfc != '$') {
  ------------------
  |  Branch (527:9): [True: 1.07k, False: 29]
  |  Branch (527:27): [True: 9, False: 1.06k]
  ------------------
  528|      9|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  529|      9|        return CONSUME_STATE_ERROR;
  530|      9|    }
  531|  1.09k|    char intbuf[32];  // enough for fc + 64-bit decimal + \r\n
  532|  1.09k|    const size_t ncopied = buf.copy_to(intbuf, sizeof(intbuf) - 1);
  533|  1.09k|    intbuf[ncopied] = '\0';
  534|  1.09k|    const size_t crlf_pos = butil::StringPiece(intbuf, ncopied).find("\r\n");
  535|  1.09k|    if (crlf_pos == butil::StringPiece::npos) {  // not enough data
  ------------------
  |  Branch (535:9): [True: 1, False: 1.08k]
  ------------------
  536|      1|        *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  537|      1|        return CONSUME_STATE_ERROR;
  538|      1|    }
  539|  1.08k|    char* endptr = NULL;
  540|  1.08k|    int64_t value = strtoll(intbuf + 1/*skip fc*/, &endptr, 10);
  541|  1.08k|    if (endptr != intbuf + crlf_pos) {
  ------------------
  |  Branch (541:9): [True: 0, False: 1.08k]
  ------------------
  542|      0|        LOG(ERROR) << '`' << intbuf + 1 << "' is not a valid 64-bit decimal";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  543|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  544|      0|        return CONSUME_STATE_ERROR;
  545|      0|    }
  546|  1.08k|    if (value < 0) {
  ------------------
  |  Branch (546:9): [True: 0, False: 1.08k]
  ------------------
  547|      0|        LOG(ERROR) << "Invalid len=" << value << " in redis command";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  548|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  549|      0|        return CONSUME_STATE_ERROR;
  550|      0|    }
  551|  1.08k|    if (!_parsing_array) {
  ------------------
  |  Branch (551:9): [True: 29, False: 1.06k]
  ------------------
  552|     29|        if (value > (int64_t)(FLAGS_redis_max_allocation_size / sizeof(butil::StringPiece))) {
  ------------------
  |  Branch (552:13): [True: 0, False: 29]
  ------------------
  553|      0|            LOG(ERROR) << "command array size exceeds limit! max="
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  554|      0|                       << (FLAGS_redis_max_allocation_size / sizeof(butil::StringPiece))
  555|      0|                       << ", actually=" << value;
  556|      0|            *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  557|      0|            return CONSUME_STATE_ERROR;
  558|      0|        }
  559|     29|        buf.pop_front(crlf_pos + 2/*CRLF*/);
  560|     29|        if (value == 0) {
  ------------------
  |  Branch (560:13): [True: 8, False: 21]
  ------------------
  561|      8|            LOG(ERROR) << "Empty redis command array";
  ------------------
  |  |  485|      8|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      8|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 8]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  562|      8|            *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  563|      8|            return CONSUME_STATE_ERROR;
  564|      8|        }
  565|     21|        _parsing_array = true;
  566|     21|        _length = value;
  567|     21|        _index = 0;
  568|     21|        _args.resize(value);
  569|     21|        return CONSUME_STATE_CONTINUE;
  570|     29|    }
  571|  1.06k|    if (_index >= _length) {
  ------------------
  |  Branch (571:9): [True: 0, False: 1.06k]
  ------------------
  572|      0|        LOG(ERROR) << "Too many bulk strings in redis command";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  573|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  574|      0|        return CONSUME_STATE_ERROR;
  575|      0|    }
  576|  1.06k|    const int64_t len = value;  // `value' is length of the string
  577|  1.06k|    if (len < 0) {
  ------------------
  |  Branch (577:9): [True: 0, False: 1.06k]
  ------------------
  578|      0|        LOG(ERROR) << "string in command is nil!";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  579|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  580|      0|        return CONSUME_STATE_ERROR;
  581|      0|    }
  582|  1.06k|    if (len > FLAGS_redis_max_allocation_size) {
  ------------------
  |  Branch (582:9): [True: 0, False: 1.06k]
  ------------------
  583|      0|        LOG(ERROR) << "command string exceeds max allocation size! max="
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  584|      0|                   << FLAGS_redis_max_allocation_size << ", actually=" << len;
  585|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  586|      0|        return CONSUME_STATE_ERROR;
  587|      0|    }
  588|  1.06k|    if (buf.size() < crlf_pos + 2 + (size_t)len + 2/*CRLF*/) {
  ------------------
  |  Branch (588:9): [True: 0, False: 1.06k]
  ------------------
  589|      0|        *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  590|      0|        return CONSUME_STATE_ERROR;
  591|      0|    }
  592|  1.06k|    buf.pop_front(crlf_pos + 2/*CRLF*/);
  593|  1.06k|    char* d = (char*)arena->allocate((len/8 + 1) * 8);
  594|       |    // Guard against allocation failure
  595|  1.06k|    if (d == NULL) {
  ------------------
  |  Branch (595:9): [True: 0, False: 1.06k]
  ------------------
  596|      0|        LOG(FATAL) << "Arena failed allocation";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  597|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  598|      0|        return CONSUME_STATE_ERROR;
  599|      0|    }
  600|  1.06k|    buf.cutn(d, len);
  601|  1.06k|    d[len] = '\0';
  602|  1.06k|    _args[_index].set(d, len);
  603|  1.06k|    if (_index == 0) {
  ------------------
  |  Branch (603:9): [True: 13, False: 1.04k]
  ------------------
  604|       |        // convert it to lowercase when it is command name
  605|    527|        for (int i = 0; i < len; ++i) {
  ------------------
  |  Branch (605:25): [True: 514, False: 13]
  ------------------
  606|    514|            d[i] = ::tolower(static_cast<unsigned char>(d[i]));
  607|    514|        }
  608|     13|    }
  609|  1.06k|    char crlf[2];
  610|  1.06k|    buf.cutn(crlf, sizeof(crlf));
  611|  1.06k|    if (crlf[0] != '\r' || crlf[1] != '\n') {
  ------------------
  |  Branch (611:9): [True: 3, False: 1.05k]
  |  Branch (611:28): [True: 3, False: 1.05k]
  ------------------
  612|      6|        LOG(ERROR) << "string in command is not ended with CRLF";
  ------------------
  |  |  485|      6|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      6|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 6]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  613|      6|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  614|      6|        return CONSUME_STATE_ERROR;
  615|      6|    }
  616|  1.05k|    if (++_index == _length) {
  ------------------
  |  Branch (616:9): [True: 1, False: 1.05k]
  ------------------
  617|      1|        return CONSUME_STATE_DONE;
  618|      1|    }
  619|  1.05k|    return CONSUME_STATE_CONTINUE;
  620|  1.05k|}
_ZN4brpc18RedisCommandParser5ResetEv:
  622|     36|void RedisCommandParser::Reset() {
  623|     36|    _parsing_array = false;
  624|     36|    _length = 0;
  625|     36|    _index = 0;
  626|     36|    _args.clear();
  627|     36|}
redis_command.cpp:_ZN12_GLOBAL__N_18FindCRLFERKN5butil5IOBufEm:
   31|     39|size_t FindCRLF(const butil::IOBuf& buf, size_t max_scan_size) {
   32|     39|    butil::IOBufBytesIterator it(buf);
   33|     39|    bool prev_cr = false;
   34|     39|    size_t pos = 0;
   35|  15.3k|    while (it && pos < max_scan_size) {
  ------------------
  |  Branch (35:12): [True: 15.3k, False: 4]
  |  Branch (35:18): [True: 15.3k, False: 0]
  ------------------
   36|  15.3k|        const char c = static_cast<char>(*it);
   37|  15.3k|        if (prev_cr && c == '\n') {
  ------------------
  |  Branch (37:13): [True: 597, False: 14.7k]
  |  Branch (37:24): [True: 35, False: 562]
  ------------------
   38|     35|            return pos - 1;
   39|     35|        }
   40|  15.2k|        prev_cr = (c == '\r');
   41|  15.2k|        ++it;
   42|  15.2k|        ++pos;
   43|  15.2k|    }
   44|      4|    return CRLF_NOT_FOUND;
   45|     39|}

_ZN4brpc10RedisReply19ConsumePartialIOBufERN5butil5IOBufE:
   98|     84|ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf) {
   99|     84|    return ConsumePartialIOBuf(buf, 0);
  100|     84|}
_ZN4brpc10RedisReply19ConsumePartialIOBufERN5butil5IOBufEi:
  102|  2.84k|ParseError RedisReply::ConsumePartialIOBuf(butil::IOBuf& buf, int depth) {
  103|  2.84k|    if (depth > FLAGS_redis_max_reply_depth) {
  ------------------
  |  Branch (103:9): [True: 1, False: 2.84k]
  ------------------
  104|      1|        LOG(ERROR) << "redis reply exceeds max depth! max="
  ------------------
  |  |  485|      1|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      1|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 1]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  105|      1|                   << FLAGS_redis_max_reply_depth << ", actually=" << depth;
  106|      1|        return PARSE_ERROR_ABSOLUTELY_WRONG;
  107|      1|    }
  108|  2.84k|    if (_type == REDIS_REPLY_ARRAY && _data.array.last_index >= 0) {
  ------------------
  |  Branch (108:9): [True: 0, False: 2.84k]
  |  Branch (108:39): [True: 0, False: 0]
  ------------------
  109|       |        // The parsing was suspended while parsing sub replies,
  110|       |        // continue the parsing.
  111|      0|        RedisReply* subs = (RedisReply*)_data.array.replies;
  112|      0|        for (int i = _data.array.last_index; i < _length; ++i) {
  ------------------
  |  Branch (112:46): [True: 0, False: 0]
  ------------------
  113|      0|            ParseError err = subs[i].ConsumePartialIOBuf(buf, depth + 1);
  114|      0|            if (err != PARSE_OK) {
  ------------------
  |  Branch (114:17): [True: 0, False: 0]
  ------------------
  115|      0|                return err;
  116|      0|            }
  117|      0|            ++_data.array.last_index;
  118|      0|        }
  119|       |        // We've got an intact reply. reset the index.
  120|      0|        _data.array.last_index = -1;
  121|      0|        return PARSE_OK;
  122|      0|    }
  123|       |
  124|       |    // Notice that all branches returning PARSE_ERROR_NOT_ENOUGH_DATA must not change `buf'.
  125|  2.84k|    const char* pfc = (const char*)buf.fetch1();
  126|  2.84k|    if (pfc == NULL) {
  ------------------
  |  Branch (126:9): [True: 29, False: 2.81k]
  ------------------
  127|     29|        return PARSE_ERROR_NOT_ENOUGH_DATA;
  128|     29|    }
  129|  2.81k|    const char fc = *pfc;  // first character
  130|  2.81k|    switch (fc) {
  131|    179|    case '-':   // Error          "-<message>\r\n"
  ------------------
  |  Branch (131:5): [True: 179, False: 2.63k]
  ------------------
  132|    328|    case '+': { // Simple String  "+<string>\r\n"
  ------------------
  |  Branch (132:5): [True: 149, False: 2.66k]
  ------------------
  133|    328|        butil::IOBuf str;
  134|    328|        if (buf.cut_until(&str, "\r\n") != 0) {
  ------------------
  |  Branch (134:13): [True: 1, False: 327]
  ------------------
  135|      1|            const size_t len = buf.size();
  136|      1|            if (len > std::numeric_limits<uint32_t>::max()) {
  ------------------
  |  Branch (136:17): [True: 0, False: 1]
  ------------------
  137|      0|                LOG(ERROR) << "simple string is too long! max length=2^32-1,"
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  138|      0|                              " actually=" << len;
  139|      0|                return PARSE_ERROR_ABSOLUTELY_WRONG;
  140|      0|            }
  141|      1|            return PARSE_ERROR_NOT_ENOUGH_DATA;
  142|      1|        }
  143|    327|        const size_t len = str.size() - 1;
  144|    327|        if (len < sizeof(_data.short_str)) {
  ------------------
  |  Branch (144:13): [True: 202, False: 125]
  ------------------
  145|       |            // SSO short strings, including empty string.
  146|    202|            _type = (fc == '-' ? REDIS_REPLY_ERROR : REDIS_REPLY_STATUS);
  ------------------
  |  Branch (146:22): [True: 144, False: 58]
  ------------------
  147|    202|            _length = len;
  148|    202|            str.copy_to_cstr(_data.short_str, (size_t)-1L, 1/*skip fc*/);
  149|    202|            return PARSE_OK;
  150|    202|        }
  151|    125|        char* d = (char*)_arena->allocate((len/8 + 1)*8);
  152|    125|        if (d == NULL) {
  ------------------
  |  Branch (152:13): [True: 0, False: 125]
  ------------------
  153|      0|            LOG(FATAL) << "Fail to allocate string[" << len << "]";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  154|      0|            return PARSE_ERROR_ABSOLUTELY_WRONG;
  155|      0|        }
  156|    125|        CHECK_EQ(len, str.copy_to_cstr(d, (size_t)-1L, 1/*skip fc*/));
  ------------------
  |  |  692|    125|#define CHECK_EQ(val1, val2) BAIDU_CHECK_OP(EQ, ==, val1, val2)
  |  |  ------------------
  |  |  |  |  630|    125|    if (std::string* _result =                                          \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (630:22): [True: 0, False: 125]
  |  |  |  |  ------------------
  |  |  |  |  631|    125|        ::logging::Check##name##Impl((val1), (val2),                    \
  |  |  |  |  632|    125|                                     #val1 " " #op " " #val2))          \
  |  |  |  |  633|    125|        ::logging::LogMessage(__FILE__, __LINE__, __func__, _result).stream().SetCheck()
  |  |  ------------------
  ------------------
  157|    125|        _type = (fc == '-' ? REDIS_REPLY_ERROR : REDIS_REPLY_STATUS);
  ------------------
  |  Branch (157:18): [True: 35, False: 90]
  ------------------
  158|    125|        _length = len;
  159|    125|        _data.long_str = d;
  160|    125|        return PARSE_OK;
  161|    125|    }
  162|    483|    case '$':   // Bulk String   "$<length>\r\n<string>\r\n"
  ------------------
  |  Branch (162:5): [True: 483, False: 2.32k]
  ------------------
  163|  2.46k|    case '*':   // Array         "*<size>\r\n<sub-reply1><sub-reply2>..."
  ------------------
  |  Branch (163:5): [True: 1.98k, False: 826]
  ------------------
  164|  2.47k|    case ':': { // Integer       ":<integer>\r\n"
  ------------------
  |  Branch (164:5): [True: 4, False: 2.80k]
  ------------------
  165|  2.47k|        char intbuf[32];  // enough for fc + 64-bit decimal + \r\n
  166|  2.47k|        const size_t ncopied = buf.copy_to(intbuf, sizeof(intbuf) - 1);
  167|  2.47k|        intbuf[ncopied] = '\0';
  168|  2.47k|        const size_t crlf_pos = butil::StringPiece(intbuf, ncopied).find("\r\n");
  169|  2.47k|        if (crlf_pos == butil::StringPiece::npos) {  // not enough data
  ------------------
  |  Branch (169:13): [True: 15, False: 2.45k]
  ------------------
  170|     15|            return PARSE_ERROR_NOT_ENOUGH_DATA;
  171|     15|        }
  172|  2.45k|        char* endptr = NULL;
  173|  2.45k|        int64_t value = strtoll(intbuf + 1/*skip fc*/, &endptr, 10);
  174|  2.45k|        if (endptr != intbuf + crlf_pos) {
  ------------------
  |  Branch (174:13): [True: 5, False: 2.45k]
  ------------------
  175|      5|            LOG(ERROR) << '`' << intbuf + 1 << "' is not a valid 64-bit decimal";
  ------------------
  |  |  485|      5|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      5|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 5]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  176|      5|            return PARSE_ERROR_ABSOLUTELY_WRONG;
  177|      5|        }
  178|  2.45k|        if (fc == ':') {
  ------------------
  |  Branch (178:13): [True: 3, False: 2.45k]
  ------------------
  179|      3|            buf.pop_front(crlf_pos + 2/*CRLF*/);
  180|      3|            _type = REDIS_REPLY_INTEGER;
  181|      3|            _length = 0;
  182|      3|            _data.integer = value;
  183|      3|            return PARSE_OK;
  184|  2.45k|        } else if (fc == '$') {
  ------------------
  |  Branch (184:20): [True: 477, False: 1.97k]
  ------------------
  185|    477|            const int64_t len = value;  // `value' is length of the string
  186|    477|            if (len < 0) {  // redis nil
  ------------------
  |  Branch (186:17): [True: 128, False: 349]
  ------------------
  187|    128|                buf.pop_front(crlf_pos + 2/*CRLF*/);
  188|    128|                _type = REDIS_REPLY_NIL;
  189|    128|                _length = 0;
  190|    128|                _data.integer = 0;
  191|    128|                return PARSE_OK;
  192|    128|            }
  193|    349|            if (len > FLAGS_redis_max_allocation_size) {
  ------------------
  |  Branch (193:17): [True: 0, False: 349]
  ------------------
  194|      0|                LOG(ERROR) << "bulk string exceeds max allocation size! max=" 
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  195|      0|                           << FLAGS_redis_max_allocation_size << ", actually=" << len;
  196|      0|                return PARSE_ERROR_ABSOLUTELY_WRONG;
  197|      0|            }
  198|       |            // We provide c_str(), thus even if bulk string is started with
  199|       |            // length, we have to end it with \0.
  200|    349|            if (buf.size() < crlf_pos + 2 + (size_t)len + 2/*CRLF*/) {
  ------------------
  |  Branch (200:17): [True: 0, False: 349]
  ------------------
  201|      0|                return PARSE_ERROR_NOT_ENOUGH_DATA;
  202|      0|            }
  203|    349|            if ((size_t)len < sizeof(_data.short_str)) {
  ------------------
  |  Branch (203:17): [True: 314, False: 35]
  ------------------
  204|       |                // SSO short strings, including empty string.
  205|    314|                _type = REDIS_REPLY_STRING;
  206|    314|                _length = len;
  207|    314|                buf.pop_front(crlf_pos + 2);
  208|    314|                buf.cutn(_data.short_str, len);
  209|    314|                _data.short_str[len] = '\0';
  210|    314|            } else {
  211|     35|                char* d = (char*)_arena->allocate((len/8 + 1)*8);
  212|     35|                if (d == NULL) {
  ------------------
  |  Branch (212:21): [True: 0, False: 35]
  ------------------
  213|      0|                    LOG(FATAL) << "Fail to allocate string[" << len << "]";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  214|      0|                    return PARSE_ERROR_ABSOLUTELY_WRONG;
  215|      0|                }
  216|     35|                buf.pop_front(crlf_pos + 2/*CRLF*/);
  217|     35|                buf.cutn(d, len);
  218|     35|                d[len] = '\0';
  219|     35|                _type = REDIS_REPLY_STRING;
  220|     35|                _length = len;
  221|     35|                _data.long_str = d;
  222|     35|            }
  223|    349|            char crlf[2];
  224|    349|            buf.cutn(crlf, sizeof(crlf));
  225|    349|            if (crlf[0] != '\r' || crlf[1] != '\n') {
  ------------------
  |  Branch (225:17): [True: 6, False: 343]
  |  Branch (225:36): [True: 1, False: 342]
  ------------------
  226|      7|                LOG(ERROR) << "Bulk string is not ended with CRLF";
  ------------------
  |  |  485|      7|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      7|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 7]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  227|      7|                return PARSE_ERROR_ABSOLUTELY_WRONG;
  228|      7|            }
  229|    342|            return PARSE_OK;
  230|  1.97k|        } else {
  231|  1.97k|            const int64_t count = value;  // `value' is count of sub replies
  232|  1.97k|            if (count < 0) { // redis nil
  ------------------
  |  Branch (232:17): [True: 387, False: 1.58k]
  ------------------
  233|    387|                buf.pop_front(crlf_pos + 2/*CRLF*/);
  234|    387|                _type = REDIS_REPLY_NIL;
  235|    387|                _length = 0;
  236|    387|                _data.integer = 0;
  237|    387|                return PARSE_OK;
  238|    387|            }
  239|  1.58k|            if (count == 0) { // empty array
  ------------------
  |  Branch (239:17): [True: 267, False: 1.31k]
  ------------------
  240|    267|                buf.pop_front(crlf_pos + 2/*CRLF*/);
  241|    267|                _type = REDIS_REPLY_ARRAY;
  242|    267|                _length = 0;
  243|    267|                _data.array.last_index = -1;
  244|    267|                _data.array.replies = NULL;
  245|    267|                return PARSE_OK;
  246|    267|            }
  247|  1.31k|            int64_t max_count = FLAGS_redis_max_allocation_size / sizeof(RedisReply);
  248|  1.31k|            if (count > max_count) {
  ------------------
  |  Branch (248:17): [True: 2, False: 1.31k]
  ------------------
  249|      2|                LOG(ERROR) << "array allocation exceeds max allocation size! max=" 
  ------------------
  |  |  485|      2|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      2|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 2]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  250|      2|                           << max_count << ", actually=" << count;
  251|      2|                return PARSE_ERROR_ABSOLUTELY_WRONG;
  252|      2|            }
  253|       |            // FIXME(gejun): Call allocate_aligned instead.
  254|  1.31k|            RedisReply* subs = (RedisReply*)_arena->allocate(sizeof(RedisReply) * count);
  255|  1.31k|            if (subs == NULL) {
  ------------------
  |  Branch (255:17): [True: 0, False: 1.31k]
  ------------------
  256|      0|                LOG(FATAL) << "Fail to allocate RedisReply[" << count << "]";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  257|      0|                return PARSE_ERROR_ABSOLUTELY_WRONG;
  258|      0|            }
  259|   133M|            for (int64_t i = 0; i < count; ++i) {
  ------------------
  |  Branch (259:33): [True: 133M, False: 1.31k]
  ------------------
  260|   133M|                new (&subs[i]) RedisReply(_arena);
  261|   133M|            }
  262|  1.31k|            buf.pop_front(crlf_pos + 2/*CRLF*/);
  263|  1.31k|            _type = REDIS_REPLY_ARRAY;
  264|  1.31k|            _length = count;
  265|  1.31k|            _data.array.replies = subs;
  266|       |
  267|       |            // Recursively parse sub replies. If any of them fails, it will
  268|       |            // be continued in next calls by tracking _data.array.last_index.
  269|  1.31k|            _data.array.last_index = 0;
  270|  2.89k|            for (int64_t i = 0; i < count; ++i) {
  ------------------
  |  Branch (270:33): [True: 2.75k, False: 134]
  ------------------
  271|  2.75k|                ParseError err = subs[i].ConsumePartialIOBuf(buf, depth + 1);
  272|  2.75k|                if (err != PARSE_OK) {
  ------------------
  |  Branch (272:21): [True: 1.18k, False: 1.57k]
  ------------------
  273|  1.18k|                    return err;
  274|  1.18k|                }
  275|  1.57k|                ++_data.array.last_index;
  276|  1.57k|            }
  277|    134|            _data.array.last_index = -1;
  278|    134|            return PARSE_OK;
  279|  1.31k|        }
  280|  2.45k|    }
  281|     11|    default:
  ------------------
  |  Branch (281:5): [True: 11, False: 2.80k]
  ------------------
  282|     11|        LOG(ERROR) << "Invalid first character=" << (int)fc;
  ------------------
  |  |  485|     11|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|     11|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 11]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  283|     11|        return PARSE_ERROR_ABSOLUTELY_WRONG;
  284|  2.81k|    }
  285|      0|    return PARSE_ERROR_ABSOLUTELY_WRONG;
  286|  2.81k|}

_ZN4brpc10RedisReplyC2EPN5butil5ArenaE:
  184|   133M|    : _arena(arena) {
  185|   133M|    Reset();
  186|   133M|}
_ZN4brpc10RedisReply5ResetEv:
  175|   133M|inline void RedisReply::Reset() {
  176|   133M|    _type = REDIS_REPLY_NIL;
  177|   133M|    _length = 0;
  178|   133M|    _data.array.last_index = -1;
  179|   133M|    _data.array.replies = NULL;
  180|       |    // _arena should not be reset because further memory allocation needs it.
  181|   133M|}

bthread_self:
  392|     40|bthread_t bthread_self(void) {
  393|     40|    bthread::TaskGroup* g = bthread::BAIDU_GET_VOLATILE_THREAD_LOCAL(tls_task_group);
  ------------------
  |  |   69|     40|#define BAIDU_GET_VOLATILE_THREAD_LOCAL(var_name) get_##var_name()
  ------------------
  394|       |    // note: return 0 for main tasks now, which include main thread and
  395|       |    // all work threads. So that we can identify main tasks from logs
  396|       |    // more easily. This is probably questionable in the future.
  397|     40|    if (g != NULL && !g->is_current_main_task()/*note*/) {
  ------------------
  |  Branch (397:9): [True: 0, False: 40]
  |  Branch (397:22): [True: 0, False: 0]
  ------------------
  398|      0|        return g->current_tid();
  399|      0|    }
  400|     40|    return INVALID_BTHREAD;
  401|     40|}

_ZN7bthread11EpollThreadC2Ev:
  119|      2|        : _epfd(-1)
  120|      2|        , _stop(false)
  121|      2|        , _tid(0) {
  122|      2|    }
_ZN7bthread9LazyArrayIPN5butil6atomicIiEELm262144ELm256EEC2Ev:
   56|      2|    LazyArray() {
   57|      2|        memset(static_cast<void*>(_blocks), 0, sizeof(butil::atomic<Block*>) * NBLOCK);
   58|      2|    }

bthread_key_create2:
  590|      1|                        const void* dtor_args) {
  591|      1|    uint32_t index = 0;
  592|      1|    {
  593|      1|        BAIDU_SCOPED_LOCK(bthread::s_key_mutex);
  ------------------
  |  |   47|      1|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      1|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      1|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      1|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  594|      1|        if (bthread::nfreekey > 0) {
  ------------------
  |  Branch (594:13): [True: 0, False: 1]
  ------------------
  595|      0|            index = bthread::s_free_keys[--bthread::nfreekey];
  596|      1|        } else if (bthread::nkey < bthread::KEYS_MAX) {
  ------------------
  |  Branch (596:20): [True: 1, False: 0]
  ------------------
  597|      1|            index = bthread::nkey++;
  598|      1|        } else {
  599|      0|            return EAGAIN;  // what pthread_key_create returns in this case.
  600|      0|        }
  601|      1|    }
  602|      1|    bthread::s_key_info[index].dtor = dtor;
  603|      1|    bthread::s_key_info[index].dtor_args = dtor_args;
  604|      1|    key->index = index;
  605|      1|    key->version = bthread::s_key_info[index].version;
  606|      1|    if (key->version == 0) {
  ------------------
  |  Branch (606:9): [True: 1, False: 0]
  ------------------
  607|      1|        ++bthread::s_key_info[index].version;
  608|      1|        ++key->version;
  609|      1|    }
  610|      1|    return 0;
  611|      1|}
bthread_key_create:
  613|      1|int bthread_key_create(bthread_key_t* key, void (*dtor)(void*)) {
  614|      1|    if (dtor == NULL) {
  ------------------
  |  Branch (614:9): [True: 0, False: 1]
  ------------------
  615|      0|        return bthread_key_create2(key, NULL, NULL);
  616|      1|    } else {
  617|      1|        return bthread_key_create2(key, bthread::arg_as_dtor, (const void*)dtor);
  618|      1|    }
  619|      1|}
bthread_setspecific:
  644|      1|int bthread_setspecific(bthread_key_t key, void* data) {
  645|      1|    bthread::KeyTable* kt = bthread::tls_bls_ptr()->keytable;
  646|      1|    if (NULL == kt) {
  ------------------
  |  Branch (646:9): [True: 1, False: 0]
  ------------------
  647|      1|        kt = new (std::nothrow) bthread::KeyTable;
  648|      1|        if (NULL == kt) {
  ------------------
  |  Branch (648:13): [True: 0, False: 1]
  ------------------
  649|      0|            return ENOMEM;
  650|      0|        }
  651|      1|        bthread::tls_bls_ptr()->keytable = kt;
  652|      1|        bthread::TaskGroup* const g = bthread::BAIDU_GET_VOLATILE_THREAD_LOCAL(tls_task_group);
  ------------------
  |  |   69|      1|#define BAIDU_GET_VOLATILE_THREAD_LOCAL(var_name) get_##var_name()
  ------------------
  653|      1|        if (g) {
  ------------------
  |  Branch (653:13): [True: 0, False: 1]
  ------------------
  654|      0|            g->current_task()->local_storage.keytable = kt;
  655|      1|        } else {
  656|       |            // Only cleanup keytable created by pthread.
  657|       |            // keytable created by bthread will be deleted
  658|       |            // in `return_keytable' or `bthread_keytable_pool_destroy'.
  659|      1|            if (!bthread::BAIDU_GET_VOLATILE_THREAD_LOCAL(tls_ever_created_keytable)) {
  ------------------
  |  |   69|      1|#define BAIDU_GET_VOLATILE_THREAD_LOCAL(var_name) get_##var_name()
  ------------------
  |  Branch (659:17): [True: 1, False: 0]
  ------------------
  660|      1|                bthread::BAIDU_SET_VOLATILE_THREAD_LOCAL(tls_ever_created_keytable, true);
  ------------------
  |  |   71|      1|#define BAIDU_SET_VOLATILE_THREAD_LOCAL(var_name, value) set_##var_name(value)
  ------------------
  661|      1|                CHECK_EQ(0, butil::thread_atexit(bthread::cleanup_pthread, kt));
  ------------------
  |  |  692|      1|#define CHECK_EQ(val1, val2) BAIDU_CHECK_OP(EQ, ==, val1, val2)
  |  |  ------------------
  |  |  |  |  630|      1|    if (std::string* _result =                                          \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (630:22): [True: 0, False: 1]
  |  |  |  |  ------------------
  |  |  |  |  631|      1|        ::logging::Check##name##Impl((val1), (val2),                    \
  |  |  |  |  632|      1|                                     #val1 " " #op " " #val2))          \
  |  |  |  |  633|      1|        ::logging::LogMessage(__FILE__, __LINE__, __func__, _result).stream().SetCheck()
  |  |  ------------------
  ------------------
  662|      1|            }
  663|      1|        }
  664|      1|    }
  665|      1|    return kt->set_data(key, data);
  666|      1|}
bthread_getspecific:
  668|     40|void* bthread_getspecific(bthread_key_t key) {
  669|     40|    bthread::KeyTable* kt = bthread::tls_bls_ptr()->keytable;
  670|     40|    if (kt) {
  ------------------
  |  Branch (670:9): [True: 39, False: 1]
  ------------------
  671|     39|        return kt->get_data(key);
  672|     39|    }
  673|      1|    bthread::TaskGroup* const g = bthread::BAIDU_GET_VOLATILE_THREAD_LOCAL(tls_task_group);
  ------------------
  |  |   69|      1|#define BAIDU_GET_VOLATILE_THREAD_LOCAL(var_name) get_##var_name()
  ------------------
  674|      1|    if (g) {
  ------------------
  |  Branch (674:9): [True: 0, False: 1]
  ------------------
  675|      0|        bthread::TaskMeta* const task = g->current_task();
  676|      0|        kt = bthread::borrow_keytable(task->attr.keytable_pool);
  677|      0|        if (kt) {
  ------------------
  |  Branch (677:13): [True: 0, False: 0]
  ------------------
  678|      0|            g->current_task()->local_storage.keytable = kt;
  679|      0|            bthread::tls_bls_ptr()->keytable = kt;
  680|      0|            return kt->get_data(key);
  681|      0|        }
  682|      0|    }
  683|      1|    return NULL;
  684|      1|}
key.cpp:_ZN7bthreadL13get_key_countEPv:
  435|      4|static int get_key_count(void*) {
  436|      4|    BAIDU_SCOPED_LOCK(bthread::s_key_mutex);
  ------------------
  |  |   47|      4|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      4|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      4|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      4|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  437|      4|    return (int)nkey - (int)nfreekey;
  438|      4|}
key.cpp:_ZN7bthreadL18get_keytable_countEPv:
  439|      4|static size_t get_keytable_count(void*) {
  440|      4|    return nkeytable.load(butil::memory_order_relaxed);
  441|      4|}
key.cpp:_ZN7bthreadL19get_keytable_memoryEPv:
  442|      4|static size_t get_keytable_memory(void*) {
  443|      4|    const size_t n = nkeytable.load(butil::memory_order_relaxed);
  444|      4|    const size_t nsub = nsubkeytable.load(butil::memory_order_relaxed);
  445|      4|    return n * sizeof(KeyTable) + nsub * sizeof(SubKeyTable);
  446|      4|}
_ZN7bthread8KeyTableC2Ev:
  153|      1|    KeyTable() : next(NULL) {
  154|      1|        memset(_subs, 0, sizeof(_subs));
  155|      1|        nkeytable.fetch_add(1, butil::memory_order_relaxed);
  156|      1|    }
_ZN7bthread8KeyTable8set_dataE13bthread_key_tPv:
  195|      1|    inline int set_data(bthread_key_t key, void* data) {
  196|      1|        const uint32_t subidx = key.index / KEY_2NDLEVEL_SIZE;
  197|      1|        if (subidx < KEY_1STLEVEL_SIZE &&
  ------------------
  |  Branch (197:13): [True: 1, False: 0]
  ------------------
  198|      1|            key.version == s_key_info[key.index].version) {
  ------------------
  |  Branch (198:13): [True: 1, False: 0]
  ------------------
  199|      1|            SubKeyTable* sub_kt = _subs[subidx];
  200|      1|            if (sub_kt == NULL) {
  ------------------
  |  Branch (200:17): [True: 1, False: 0]
  ------------------
  201|      1|                sub_kt = new (std::nothrow) SubKeyTable;
  202|      1|                if (NULL == sub_kt) {
  ------------------
  |  Branch (202:21): [True: 0, False: 1]
  ------------------
  203|      0|                    return ENOMEM;
  204|      0|                }
  205|      1|                _subs[subidx] = sub_kt;
  206|      1|            }
  207|      1|            sub_kt->set_data(key.index - subidx * KEY_2NDLEVEL_SIZE,
  208|      1|                             key.version, data);
  209|      1|            return 0;
  210|      1|        }
  211|      0|        CHECK(false) << "bthread_setspecific is called on invalid " << key;
  ------------------
  |  |  617|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(FATAL).SetCheck(), !(condition))     \
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  618|      0|    << "Check failed: " #condition ". "
  ------------------
  212|       |        return EINVAL;
  213|      1|    }
_ZN7bthread11SubKeyTableC2Ev:
   93|      1|    SubKeyTable() {
   94|      1|        memset(_data, 0, sizeof(_data));
   95|      1|        nsubkeytable.fetch_add(1, butil::memory_order_relaxed);
   96|      1|    }
_ZN7bthread11SubKeyTable8set_dataEjjPv:
  136|      1|    inline void set_data(uint32_t index, uint32_t version, void* data) {
  137|      1|        _data[index].version = version;
  138|      1|        _data[index].ptr = data;
  139|      1|    }
_ZNK7bthread8KeyTable8get_dataE13bthread_key_t:
  183|     39|    inline void* get_data(bthread_key_t key) const {
  184|     39|        const uint32_t subidx = key.index / KEY_2NDLEVEL_SIZE;
  185|     39|        if (subidx < KEY_1STLEVEL_SIZE) {
  ------------------
  |  Branch (185:13): [True: 39, False: 0]
  ------------------
  186|     39|            const SubKeyTable* sub_kt = _subs[subidx];
  187|     39|            if (sub_kt) {
  ------------------
  |  Branch (187:17): [True: 39, False: 0]
  ------------------
  188|     39|                return sub_kt->get_data(
  189|     39|                    key.index - subidx * KEY_2NDLEVEL_SIZE, key.version);
  190|     39|            }
  191|     39|        }
  192|      0|        return NULL;
  193|     39|    }
_ZNK7bthread11SubKeyTable8get_dataEjj:
  130|     39|    inline void* get_data(uint32_t index, uint32_t version) const {
  131|     39|        if (_data[index].version == version) {
  ------------------
  |  Branch (131:13): [True: 39, False: 0]
  ------------------
  132|     39|            return _data[index].ptr;
  133|     39|        }
  134|      0|        return NULL;
  135|     39|    }

_ZN7bthread28first_sys_pthread_mutex_lockEP15pthread_mutex_t:
  496|      2|int first_sys_pthread_mutex_lock(pthread_mutex_t* mutex) {
  497|      2|    pthread_once(&init_sys_mutex_lock_once, init_sys_mutex_lock);
  498|      2|    return sys_pthread_mutex_lock(mutex);
  499|      2|}
pthread_mutex_init:
 1309|    193|                       const pthread_mutexattr_t* __restrict mutexattr) {
 1310|    193|    INIT_MUTEX_OWNER_MAP_ENTRY(mutex, mutexattr);
  ------------------
  |  |  795|    193|#define INIT_MUTEX_OWNER_MAP_ENTRY(mutex, mutexattr) ((void)0)
  ------------------
 1311|    193|    return bthread::sys_pthread_mutex_init(mutex, mutexattr);
 1312|    193|}
pthread_mutex_lock:
 1319|    255|int pthread_mutex_lock(pthread_mutex_t* mutex) {
 1320|    255|    return bthread::pthread_mutex_lock_impl(mutex);
 1321|    255|}
pthread_mutex_unlock:
 1334|    255|int pthread_mutex_unlock(pthread_mutex_t* mutex) {
 1335|    255|    return bthread::pthread_mutex_unlock_impl(mutex);
 1336|    255|}
mutex.cpp:_ZN7bthreadL19init_sys_mutex_lockEv:
  439|      2|static void init_sys_mutex_lock() {
  440|       |// When bRPC library is linked as a shared library, need to make sure bRPC
  441|       |// shared library is loaded before the pthread shared library. Otherwise,
  442|       |// it may cause runtime error: undefined symbol: pthread_mutex_xxx.
  443|       |// Alternatively, static linking can also avoid this problem.
  444|      2|#if defined(OS_LINUX)
  445|       |    // TODO: may need dlvsym when GLIBC has multiple versions of a same symbol.
  446|       |    // http://blog.fesnel.com/blog/2009/08/25/preloading-with-multiple-symbol-versions
  447|      2|    if (_dl_sym) {
  ------------------
  |  Branch (447:9): [True: 0, False: 2]
  ------------------
  448|      0|        sys_pthread_mutex_init = (MutexInitOp)_dl_sym(
  449|      0|            RTLD_NEXT, "pthread_mutex_init", (void*)init_sys_mutex_lock);
  450|      0|        sys_pthread_mutex_destroy = (MutexOp)_dl_sym(
  451|      0|            RTLD_NEXT, "pthread_mutex_destroy", (void*)init_sys_mutex_lock);
  452|      0|        sys_pthread_mutex_lock = (MutexOp)_dl_sym(
  453|      0|            RTLD_NEXT, "pthread_mutex_lock", (void*)init_sys_mutex_lock);
  454|      0|        sys_pthread_mutex_unlock = (MutexOp)_dl_sym(
  455|      0|            RTLD_NEXT, "pthread_mutex_unlock", (void*)init_sys_mutex_lock);
  456|      0|        sys_pthread_mutex_trylock = (MutexOp)_dl_sym(
  457|      0|            RTLD_NEXT, "pthread_mutex_trylock", (void*)init_sys_mutex_lock);
  458|      0|#if HAS_PTHREAD_MUTEX_TIMEDLOCK
  459|      0|        sys_pthread_mutex_timedlock = (TimedMutexOp)_dl_sym(
  460|      0|            RTLD_NEXT, "pthread_mutex_timedlock", (void*)init_sys_mutex_lock);
  461|      0|#endif // HAS_PTHREAD_MUTEX_TIMEDLOCK
  462|      2|    } else {
  463|       |        // _dl_sym may be undefined reference in some system, fallback to dlsym
  464|      2|        sys_pthread_mutex_init = (MutexInitOp)dlsym(RTLD_NEXT, "pthread_mutex_init");
  465|      2|        sys_pthread_mutex_destroy = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_destroy");
  466|      2|        sys_pthread_mutex_lock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_lock");
  467|      2|        sys_pthread_mutex_unlock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_unlock");
  468|      2|        sys_pthread_mutex_trylock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_trylock");
  469|      2|#if HAS_PTHREAD_MUTEX_TIMEDLOCK
  470|      2|        sys_pthread_mutex_timedlock = (TimedMutexOp)dlsym(RTLD_NEXT, "pthread_mutex_timedlock");
  471|      2|#endif // HAS_PTHREAD_MUTEX_TIMEDLOCK
  472|      2|    }
  473|       |#elif defined(OS_MACOSX)
  474|       |    // TODO: look workaround for dlsym on mac
  475|       |    sys_pthread_mutex_init = (MutexInitOp)dlsym(RTLD_NEXT, "pthread_mutex_init");
  476|       |    sys_pthread_mutex_destroy = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_destroy");
  477|       |    sys_pthread_mutex_lock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_lock");
  478|       |    sys_pthread_mutex_trylock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_trylock");
  479|       |    sys_pthread_mutex_unlock = (MutexOp)dlsym(RTLD_NEXT, "pthread_mutex_unlock");
  480|       |#endif
  481|      2|}
_ZN7bthread22AddTlsPthreadLockCountEv:
  560|    255|inline void AddTlsPthreadLockCount() {}
_ZN7bthread22SubTlsPthreadLockCountEv:
  561|    255|inline void SubTlsPthreadLockCount() {}
_ZN7bthread23pthread_mutex_lock_implEP15pthread_mutex_t:
  983|    255|BUTIL_FORCE_INLINE int pthread_mutex_lock_impl(pthread_mutex_t* mutex) {
  984|       |    return internal::pthread_mutex_lock_impl(mutex, NULL);
  985|    255|}
_ZN7bthread8internal23pthread_mutex_lock_implI15pthread_mutex_tEEiPT_PK8timespec:
  878|    255|BUTIL_FORCE_INLINE int pthread_mutex_lock_impl(Mutex* mutex, const struct timespec* abstime) {
  879|       |    // Don't change behavior of lock when profiler is off.
  880|    255|    if (!g_cp ||
  ------------------
  |  Branch (880:9): [True: 255, False: 0]
  ------------------
  881|       |        // collecting code including backtrace() and submit() may call
  882|       |        // pthread_mutex_lock and cause deadlock. Don't sample.
  883|    255|        BAIDU_GET_VOLATILE_THREAD_LOCAL(tls_inside_lock)) {
  ------------------
  |  |   69|      0|#define BAIDU_GET_VOLATILE_THREAD_LOCAL(var_name) get_##var_name()
  |  |  ------------------
  |  |  |  Branch (69:51): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  884|    255|        return pthread_mutex_lock_internal(mutex, abstime);
  885|    255|    }
  886|       |    // Don't slow down non-contended locks.
  887|      0|    int rc = pthread_mutex_trylock_internal(mutex);
  888|      0|    if (rc != EBUSY) {
  ------------------
  |  Branch (888:9): [True: 0, False: 0]
  ------------------
  889|      0|        return rc;
  890|      0|    }
  891|       |    // Ask bvar::Collector if this (contended) locking should be sampled
  892|      0|    const size_t sampling_range = bvar::is_collectable(&g_cp_sl);
  893|       |
  894|      0|    bthread_contention_site_t* csite = NULL;
  895|      0|#ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS
  896|      0|    TLSPthreadContentionSites& fast_alt =
  897|      0|        *BAIDU_GET_PTR_VOLATILE_THREAD_LOCAL(tls_csites);
  ------------------
  |  |   70|      0|#define BAIDU_GET_PTR_VOLATILE_THREAD_LOCAL(var_name) get_ptr_##var_name()
  ------------------
  898|      0|    if (fast_alt.cp_version != g_cp_version) {
  ------------------
  |  Branch (898:9): [True: 0, False: 0]
  ------------------
  899|      0|        fast_alt.cp_version = g_cp_version;
  900|      0|        fast_alt.count = 0;
  901|      0|    }
  902|      0|    if (fast_alt.count < TLS_MAX_COUNT) {
  ------------------
  |  Branch (902:9): [True: 0, False: 0]
  ------------------
  903|      0|        MutexAndContentionSite& entry = fast_alt.list[fast_alt.count++];
  904|      0|        entry.mutex = mutex;
  905|      0|        csite = &entry.csite;
  906|      0|        if (!bvar::is_sampling_range_valid(sampling_range)) {
  ------------------
  |  Branch (906:13): [True: 0, False: 0]
  ------------------
  907|      0|            make_contention_site_invalid(&entry.csite);
  908|      0|            return pthread_mutex_lock_internal(mutex, abstime);
  909|      0|        }
  910|      0|    }
  911|      0|#endif
  912|      0|    if (!bvar::is_sampling_range_valid(sampling_range)) {  // don't sample
  ------------------
  |  Branch (912:9): [True: 0, False: 0]
  ------------------
  913|      0|        return pthread_mutex_lock_internal(mutex, abstime);
  914|      0|    }
  915|       |    // Lock and monitor the waiting time.
  916|      0|    const int64_t start_ns = butil::cpuwide_time_ns();
  917|      0|    rc = pthread_mutex_lock_internal(mutex, abstime);
  918|      0|    if (!rc) { // Inside lock
  ------------------
  |  Branch (918:9): [True: 0, False: 0]
  ------------------
  919|      0|        if (!csite) {
  ------------------
  |  Branch (919:13): [True: 0, False: 0]
  ------------------
  920|      0|            csite = add_pthread_contention_site(mutex);
  921|      0|            if (csite == NULL) {
  ------------------
  |  Branch (921:17): [True: 0, False: 0]
  ------------------
  922|      0|                return rc;
  923|      0|            }
  924|      0|        }
  925|      0|        csite->duration_ns = butil::cpuwide_time_ns() - start_ns;
  926|      0|        csite->sampling_range = sampling_range;
  927|      0|    } // else rare
  928|      0|    return rc;
  929|      0|}
_ZN7bthread8internal27pthread_mutex_lock_internalEP15pthread_mutex_tPK8timespec:
  806|    255|                                                   const struct timespec* abstime) {
  807|    255|    int rc = 0;
  808|    255|    if (NULL == abstime) {
  ------------------
  |  Branch (808:9): [True: 255, False: 0]
  ------------------
  809|    255|        FIND_SYS_PTHREAD_MUTEX_OWNER_MAP_ENTRY(mutex);
  ------------------
  |  |  797|    255|#define FIND_SYS_PTHREAD_MUTEX_OWNER_MAP_ENTRY(mutex) ((void)0)
  ------------------
  810|    255|        SYS_PTHREAD_MUTEX_CHECK_OWNER;
  ------------------
  |  |  798|    255|#define SYS_PTHREAD_MUTEX_CHECK_OWNER ((void)0)
  ------------------
  811|    255|        rc = sys_pthread_mutex_lock(mutex);
  812|    255|        if (0 == rc) {
  ------------------
  |  Branch (812:13): [True: 255, False: 0]
  ------------------
  813|    255|            SYS_PTHREAD_MUTEX_SET_OWNER;
  ------------------
  |  |  799|    255|#define SYS_PTHREAD_MUTEX_SET_OWNER ((void)0)
  ------------------
  814|    255|        }
  815|    255|    } else {
  816|      0|        rc = sys_pthread_mutex_timedlock(mutex, abstime);
  817|      0|        if (0 == rc) {
  ------------------
  |  Branch (817:13): [True: 0, False: 0]
  ------------------
  818|      0|            FIND_SYS_PTHREAD_MUTEX_OWNER_MAP_ENTRY(mutex);
  ------------------
  |  |  797|      0|#define FIND_SYS_PTHREAD_MUTEX_OWNER_MAP_ENTRY(mutex) ((void)0)
  ------------------
  819|      0|            SYS_PTHREAD_MUTEX_SET_OWNER;
  ------------------
  |  |  799|      0|#define SYS_PTHREAD_MUTEX_SET_OWNER ((void)0)
  ------------------
  820|      0|        }
  821|      0|    }
  822|    255|    if (0 == rc) {
  ------------------
  |  Branch (822:9): [True: 255, False: 0]
  ------------------
  823|    255|        AddTlsPthreadLockCount();
  824|    255|    }
  825|    255|    return rc;
  826|    255|}
_ZN7bthread25pthread_mutex_unlock_implEP15pthread_mutex_t:
  998|    255|BUTIL_FORCE_INLINE int pthread_mutex_unlock_impl(pthread_mutex_t* mutex) {
  999|    255|    return internal::pthread_mutex_unlock_impl(mutex);
 1000|    255|}
_ZN7bthread8internal25pthread_mutex_unlock_implI15pthread_mutex_tEEiPT_:
  937|    255|BUTIL_FORCE_INLINE int pthread_mutex_unlock_impl(Mutex* mutex) {
  938|       |    // Don't change behavior of unlock when profiler is off.
  939|    255|    if (!g_cp || BAIDU_GET_VOLATILE_THREAD_LOCAL(tls_inside_lock)) {
  ------------------
  |  |   69|      0|#define BAIDU_GET_VOLATILE_THREAD_LOCAL(var_name) get_##var_name()
  |  |  ------------------
  |  |  |  Branch (69:51): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  |  Branch (939:9): [True: 255, False: 0]
  ------------------
  940|       |        // This branch brings an issue that an entry created by
  941|       |        // add_pthread_contention_site may not be cleared. Thus we add a
  942|       |        // 16-bit rolling version in the entry to find out such entry.
  943|    255|        return pthread_mutex_unlock_internal(mutex);
  944|    255|    }
  945|      0|    int64_t unlock_start_ns = 0;
  946|      0|    bool miss_in_tls = true;
  947|      0|    bthread_contention_site_t saved_csite = {0,0};
  948|      0|#ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS
  949|      0|    TLSPthreadContentionSites& fast_alt =
  950|      0|        *BAIDU_GET_PTR_VOLATILE_THREAD_LOCAL(tls_csites);
  ------------------
  |  |   70|      0|#define BAIDU_GET_PTR_VOLATILE_THREAD_LOCAL(var_name) get_ptr_##var_name()
  ------------------
  951|      0|    for (int i = fast_alt.count - 1; i >= 0; --i) {
  ------------------
  |  Branch (951:38): [True: 0, False: 0]
  ------------------
  952|      0|        if (fast_alt.list[i].mutex == mutex) {
  ------------------
  |  Branch (952:13): [True: 0, False: 0]
  ------------------
  953|      0|            if (is_contention_site_valid(fast_alt.list[i].csite)) {
  ------------------
  |  Branch (953:17): [True: 0, False: 0]
  ------------------
  954|      0|                saved_csite = fast_alt.list[i].csite;
  955|      0|                unlock_start_ns = butil::cpuwide_time_ns();
  956|      0|            }
  957|      0|            fast_alt.list[i] = fast_alt.list[--fast_alt.count];
  958|      0|            miss_in_tls = false;
  959|      0|            break;
  960|      0|        }
  961|      0|    }
  962|      0|#endif
  963|       |    // Check the map to see if the lock is sampled. Notice that we're still
  964|       |    // inside critical section.
  965|      0|    if (miss_in_tls) {
  ------------------
  |  Branch (965:9): [True: 0, False: 0]
  ------------------
  966|      0|        if (remove_pthread_contention_site(mutex, &saved_csite)) {
  ------------------
  |  Branch (966:13): [True: 0, False: 0]
  ------------------
  967|      0|            unlock_start_ns = butil::cpuwide_time_ns();
  968|      0|        }
  969|      0|    }
  970|      0|    const int rc = pthread_mutex_unlock_internal(mutex);
  971|       |    // [Outside lock]
  972|      0|    if (unlock_start_ns) {
  ------------------
  |  Branch (972:9): [True: 0, False: 0]
  ------------------
  973|      0|        const int64_t unlock_end_ns = butil::cpuwide_time_ns();
  974|      0|        saved_csite.duration_ns += unlock_end_ns - unlock_start_ns;
  975|      0|        submit_contention(saved_csite, unlock_end_ns);
  976|      0|    }
  977|      0|    return rc;
  978|    255|}
_ZN7bthread8internal29pthread_mutex_unlock_internalEP15pthread_mutex_t:
  851|    255|BUTIL_FORCE_INLINE int pthread_mutex_unlock_internal(pthread_mutex_t* mutex) {
  852|    255|    SYS_PTHREAD_MUTEX_RESET_OWNER(mutex);
  ------------------
  |  |  800|    255|#define SYS_PTHREAD_MUTEX_RESET_OWNER(mutex) ((void)0)
  ------------------
  853|    255|    SubTlsPthreadLockCount();
  854|    255|    return sys_pthread_mutex_unlock(mutex);
  855|    255|}

stack.cpp:_ZN7bthreadL15get_stack_countEPv:
   50|      4|static int64_t get_stack_count(void*) {
   51|      4|    return s_stack_count.load(butil::memory_order_relaxed);
   52|      4|}

_ZN7bthread11tls_bls_ptrEv:
   56|     42|inline LocalStorage* tls_bls_ptr() {
   57|     42|    return BAIDU_GET_PTR_VOLATILE_THREAD_LOCAL(tls_bls);
  ------------------
  |  |   70|     42|#define BAIDU_GET_PTR_VOLATILE_THREAD_LOCAL(var_name) get_ptr_##var_name()
  ------------------
   58|     42|}

_ZN5butil12ArenaOptionsC2Ev:
   27|    170|    : initial_block_size(64)
   28|    170|    , max_block_size(8192)
   29|    170|{}
_ZN5butil5ArenaC2ERKNS_12ArenaOptionsE:
   32|    170|    : _cur_block(NULL)
   33|    170|    , _isolated_blocks(NULL)
   34|    170|    , _block_size(options.initial_block_size)
   35|    170|    , _options(options) {
   36|    170|}
_ZN5butil5ArenaD2Ev:
   38|    168|Arena::~Arena() {
   39|    212|    while (_cur_block != NULL) {
  ------------------
  |  Branch (39:12): [True: 44, False: 168]
  ------------------
   40|     44|        Block* const saved_next = _cur_block->next;
   41|     44|        free(_cur_block);
   42|     44|        _cur_block = saved_next;
   43|     44|    }
   44|  1.82k|    while (_isolated_blocks != NULL) {
  ------------------
  |  Branch (44:12): [True: 1.65k, False: 168]
  ------------------
   45|  1.65k|        Block* const saved_next = _isolated_blocks->next;
   46|  1.65k|        free(_isolated_blocks);
   47|  1.65k|        _isolated_blocks = saved_next;
   48|  1.65k|    }
   49|    168|}
_ZN5butil5Arena18allocate_new_blockEm:
   66|  1.61k|void* Arena::allocate_new_block(size_t n) {
   67|       |    Block* b = (Block*)malloc(offsetof(Block, data) + n);
   68|  1.61k|    b->next = _isolated_blocks;
   69|  1.61k|    b->alloc_size = n;
   70|  1.61k|    b->size = n;
   71|  1.61k|    _isolated_blocks = b;
   72|  1.61k|    return b->data;
   73|  1.61k|}
_ZN5butil5Arena24allocate_in_other_blocksEm:
   75|  1.70k|void* Arena::allocate_in_other_blocks(size_t n) {
   76|  1.70k|    if (n > _block_size / 4) { // put outlier on separate blocks.
  ------------------
  |  Branch (76:9): [True: 1.61k, False: 91]
  ------------------
   77|  1.61k|        return allocate_new_block(n);
   78|  1.61k|    }
   79|       |    // Waste the left space. At most 1/4 of allocated spaces are wasted.
   80|       |
   81|       |    // Grow the block size gradually.
   82|     91|    if (_cur_block != NULL) {
  ------------------
  |  Branch (82:9): [True: 47, False: 44]
  ------------------
   83|     47|        _block_size = std::min(2 * _block_size, _options.max_block_size);
   84|     47|    }
   85|     91|    size_t new_size = _block_size;
   86|     91|    if (new_size < n) {
  ------------------
  |  Branch (86:9): [True: 0, False: 91]
  ------------------
   87|      0|        new_size = n;
   88|      0|    }
   89|     91|    Block* b = (Block*)malloc(offsetof(Block, data) + new_size);
   90|     91|    if (NULL == b) {
  ------------------
  |  Branch (90:9): [True: 0, False: 91]
  ------------------
   91|      0|        return NULL;
   92|      0|    }
   93|     91|    b->next = NULL;
   94|     91|    b->alloc_size = n;
   95|     91|    b->size = new_size;
   96|     91|    if (_cur_block) {
  ------------------
  |  Branch (96:9): [True: 47, False: 44]
  ------------------
   97|     47|        _cur_block->next = _isolated_blocks;
   98|     47|        _isolated_blocks = _cur_block;
   99|     47|    }
  100|     91|    _cur_block = b;
  101|     91|    return b->data;
  102|     91|}

_ZNK5butil5Arena5Block10left_spaceEv:
   52|  2.14k|        uint32_t left_space() const { return size - alloc_size; }
_ZN5butil5Arena8allocateEm:
   74|  3.72k|inline void* Arena::allocate(size_t n) {
   75|  3.72k|    if (_cur_block != NULL && _cur_block->left_space() >= n) {
  ------------------
  |  Branch (75:9): [True: 2.14k, False: 1.57k]
  |  Branch (75:31): [True: 2.02k, False: 123]
  ------------------
   76|  2.02k|        void* ret = _cur_block->data + _cur_block->alloc_size;
   77|  2.02k|        _cur_block->alloc_size += n;
   78|  2.02k|        return ret;
   79|  2.02k|    }
   80|  1.70k|    return allocate_in_other_blocks(n);
   81|  3.72k|}

_ZN5butil6atomicIiEC2Ei:
  235|      9|    atomic(T v) : ::std::atomic<T>(v) {}
_ZN5butil13static_atomicImE9fetch_addEmSt12memory_order:
  304|     18|    T fetch_add(T v, memory_order o) { return ref().fetch_add(v, o); }
_ZN5butil13static_atomicImE3refEv:
  316|     44|    atomic<T>& ref() {
  317|       |        // Suppress strict-alias warnings.
  318|     44|        atomic<T>* p = reinterpret_cast<atomic<T>*>(&val);
  319|     44|        return *p;
  320|     44|    }
_ZN5butil13static_atomicImE9fetch_subEmSt12memory_order:
  305|     14|    T fetch_sub(T v, memory_order o) { return ref().fetch_sub(v, o); }
_ZN5butil13static_atomicImE4loadESt12memory_order:
  293|     12|    T load(memory_order o) { return ref().load(o); }
_ZN5butil13static_atomicIlE3refEv:
  316|      4|    atomic<T>& ref() {
  317|       |        // Suppress strict-alias warnings.
  318|      4|        atomic<T>* p = reinterpret_cast<atomic<T>*>(&val);
  319|      4|        return *p;
  320|      4|    }
_ZN5butil13static_atomicIlE4loadESt12memory_order:
  293|      4|    T load(memory_order o) { return ref().load(o); }
_ZN5butil6atomicIPN7bthread9LazyArrayIPNS0_IiEELm262144ELm256EE5BlockEEC2Ev:
  234|   524k|    atomic() {}

atomicops_internals_x86_gcc.cc:_ZN12_GLOBAL__N_123AtomicOpsx86InitializerC2Ev:
   88|      2|  AtomicOpsx86Initializer() {
   89|      2|    AtomicOps_Internalx86CPUFeaturesInit();
   90|      2|  }
atomicops_internals_x86_gcc.cc:_ZN12_GLOBAL__N_136AtomicOps_Internalx86CPUFeaturesInitEv:
   48|      2|void AtomicOps_Internalx86CPUFeaturesInit() {
   49|      2|  uint32_t eax;
   50|      2|  uint32_t ebx;
   51|      2|  uint32_t ecx;
   52|      2|  uint32_t edx;
   53|       |
   54|       |  // Get vendor string (issue CPUID with eax = 0)
   55|      2|  cpuid(eax, ebx, ecx, edx, 0);
  ------------------
  |  |   30|      2|  asm("mov %%rbx, %%rdi\n"     \
  |  |   31|      2|      "cpuid\n"                \
  |  |   32|      2|      "xchg %%rdi, %%rbx\n"    \
  |  |   33|      2|      : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
  ------------------
   56|      2|  char vendor[13];
   57|      2|  memcpy(vendor, &ebx, 4);
   58|      2|  memcpy(vendor + 4, &edx, 4);
   59|      2|  memcpy(vendor + 8, &ecx, 4);
   60|      2|  vendor[12] = 0;
   61|       |
   62|       |  // get feature flags in ecx/edx, and family/model in eax
   63|      2|  cpuid(eax, ebx, ecx, edx, 1);
  ------------------
  |  |   30|      2|  asm("mov %%rbx, %%rdi\n"     \
  |  |   31|      2|      "cpuid\n"                \
  |  |   32|      2|      "xchg %%rdi, %%rbx\n"    \
  |  |   33|      2|      : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
  ------------------
   64|       |
   65|      2|  int family = (eax >> 8) & 0xf;        // family and model fields
   66|      2|  int model = (eax >> 4) & 0xf;
   67|      2|  if (family == 0xf) {                  // use extended family and model fields
  ------------------
  |  Branch (67:7): [True: 2, False: 0]
  ------------------
   68|      2|    family += (eax >> 20) & 0xff;
   69|      2|    model += ((eax >> 16) & 0xf) << 4;
   70|      2|  }
   71|       |
   72|       |  // Opteron Rev E has a bug in which on very rare occasions a locked
   73|       |  // instruction doesn't act as a read-acquire barrier if followed by a
   74|       |  // non-locked read-modify-write instruction.  Rev F has this bug in
   75|       |  // pre-release versions, but not in versions released to customers,
   76|       |  // so we test only for Rev E, which is family 15, model 32..63 inclusive.
   77|      2|  if (strcmp(vendor, "AuthenticAMD") == 0 &&       // AMD
  ------------------
  |  Branch (77:7): [True: 2, False: 0]
  ------------------
   78|      2|      family == 15 &&
  ------------------
  |  Branch (78:7): [True: 0, False: 2]
  ------------------
   79|      0|      32 <= model && model <= 63) {
  ------------------
  |  Branch (79:7): [True: 0, False: 0]
  |  Branch (79:22): [True: 0, False: 0]
  ------------------
   80|      0|    AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
   81|      2|  } else {
   82|      2|    AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
   83|      2|  }
   84|      2|}

_ZN5butil6subtle24NoBarrier_CompareAndSwapEPVlll:
  131|      2|                                         Atomic64 new_value) {
  132|      2|  Atomic64 prev;
  133|      2|  __asm__ __volatile__("lock; cmpxchgq %1,%2"
  134|      2|                       : "=a" (prev)
  135|      2|                       : "q" (new_value), "m" (*ptr), "0" (old_value)
  136|      2|                       : "memory");
  137|      2|  return prev;
  138|      2|}
_ZN5butil6subtle13Release_StoreEPVll:
  181|      4|inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
  182|      4|  ATOMICOPS_COMPILER_BARRIER();
  ------------------
  |  |   24|      4|#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
  ------------------
  183|       |
  184|      4|  *ptr = value; // An x86 store acts as a release barrier
  185|       |                // for current AMD/Intel chips as of Jan 2008.
  186|       |                // See also Acquire_Load(), below.
  187|       |
  188|       |  // When new chips come out, check:
  189|       |  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
  190|       |  //  System Programming Guide, Chatper 7: Multiple-processor management,
  191|       |  //  Section 7.2, Memory Ordering.
  192|       |  // Last seen at:
  193|       |  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
  194|       |  //
  195|       |  // x86 stores/loads fail to act as barriers for a few instructions (clflush
  196|       |  // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
  197|       |  // not generated by the compiler, and are rare.  Users of these instructions
  198|       |  // need to know about cache behaviour in any case since all of these involve
  199|       |  // either flushing cache lines or non-temporal cache hints.
  200|      4|}
_ZN5butil6subtle12Acquire_LoadEPVKl:
  206|     88|inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
  207|     88|  Atomic64 value = *ptr; // An x86 load acts as a acquire barrier,
  208|       |                         // for current AMD/Intel chips as of Jan 2008.
  209|       |                         // See also Release_Store(), above.
  210|     88|  ATOMICOPS_COMPILER_BARRIER();
  ------------------
  |  |   24|     88|#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
  ------------------
  211|     88|  return value;
  212|     88|}
_ZN5butil6subtle22Acquire_CompareAndSwapEPVlll:
  221|      2|                                       Atomic64 new_value) {
  222|      2|  Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
  223|      2|  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
  ------------------
  |  Branch (223:7): [True: 0, False: 2]
  ------------------
  224|      0|    __asm__ __volatile__("lfence" : : : "memory");
  225|      0|  }
  226|      2|  return x;
  227|      2|}

_ZN5butil8demangleB5cxx11EPKc:
   30|     50|std::string demangle(const char* name) {
   31|       |    // mangled_name
   32|       |    //   A NULL-terminated character string containing the name to
   33|       |    //   be demangled.
   34|       |    // output_buffer:
   35|       |    //   A region of memory, allocated with malloc, of *length bytes,
   36|       |    //   into which the demangled name is stored. If output_buffer is
   37|       |    //   not long enough, it is expanded using realloc. output_buffer
   38|       |    //   may instead be NULL; in that case, the demangled name is placed
   39|       |    //   in a region of memory allocated with malloc.
   40|       |    // length
   41|       |    //   If length is non-NULL, the length of the buffer containing the
   42|       |    //   demangled name is placed in *length.
   43|       |    // status
   44|       |    //   *status is set to one of the following values:
   45|       |    //    0: The demangling operation succeeded.
   46|       |    //   -1: A memory allocation failure occurred.
   47|       |    //   -2: mangled_name is not a valid name under the C++ ABI
   48|       |    //       mangling rules.
   49|       |    //   -3: One of the arguments is invalid.
   50|     50|    int status = 0;
   51|     50|    char* buf = abi::__cxa_demangle(name, NULL, NULL, &status);
   52|     50|    if (status == 0 && buf) {
  ------------------
  |  Branch (52:9): [True: 50, False: 0]
  |  Branch (52:24): [True: 50, False: 0]
  ------------------
   53|     50|        std::string s(buf);
   54|     50|        free(buf);
   55|     50|        return s;
   56|     50|    }
   57|      0|    return std::string(name);
   58|     50|}

_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EEC2Ev:
  435|      1|    : _index(0)
  436|      1|    , _wrapper_key(0) {
  437|      1|    BAIDU_CASSERT(!(AllowBthreadSuspended && !IsVoid<TLS>::value),
  ------------------
  |  |  196|      1|#define BAIDU_CASSERT(expr, msg) static_assert(expr, #msg)
  ------------------
  438|      1|                  "Forbidden to allow bthread suspended with non-Void TLS");
  439|       |
  440|      1|    _wrappers.reserve(64);
  441|      1|    pthread_mutex_init(&_modify_mutex, NULL);
  442|      1|    pthread_mutex_init(&_wrappers_mutex, NULL);
  443|      1|    _wrapper_key = WrapperTLSGroup::key_create();
  444|       |    // Initialize _data for some POD types. This is essential for pointer
  445|       |    // types because they should be Read() as NULL before any Modify().
  446|      1|    if (is_integral<T>::value || is_floating_point<T>::value ||
  ------------------
  |  Branch (446:9): [Folded, False: 0]
  |  Branch (446:34): [Folded, False: 0]
  ------------------
  447|      1|        is_pointer<T>::value || is_member_function_pointer<T>::value) {
  ------------------
  |  Branch (447:9): [True: 0, Folded]
  |  Branch (447:33): [Folded, False: 0]
  ------------------
  448|      1|        _data[0] = T();
  449|      1|        _data[1] = T();
  450|      1|    }
  451|      1|}
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE15WrapperTLSGroup10key_createEv:
  215|      1|    static WrapperTLSId key_create() {
  216|      1|        BAIDU_SCOPED_LOCK(_s_mutex);
  ------------------
  |  |   47|      1|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      1|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      1|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      1|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  217|      1|        WrapperTLSId id = 0;
  218|      1|        if (!_get_free_ids().empty()) {
  ------------------
  |  Branch (218:13): [True: 0, False: 1]
  ------------------
  219|      0|            id = _get_free_ids().back();
  220|      0|            _get_free_ids().pop_back();
  221|      1|        } else {
  222|      1|            id = _s_id++;
  223|      1|        }
  224|      1|        return id;
  225|      1|    }
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE15WrapperTLSGroup13_get_free_idsEv:
  271|      1|    inline static std::deque<WrapperTLSId>& _get_free_ids() {
  272|      1|        if (BAIDU_UNLIKELY(!_s_free_ids)) {
  ------------------
  |  |  272|      1|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 1, False: 0]
  |  |  ------------------
  ------------------
  273|      1|            _s_free_ids = new (std::nothrow) std::deque<WrapperTLSId>();
  274|      1|            RELEASE_ASSERT(_s_free_ids);
  ------------------
  |  |  476|      1|    do {                            \
  |  |  477|      1|        if (!(condition)) {         \
  |  |  ------------------
  |  |  |  Branch (477:13): [True: 0, False: 1]
  |  |  ------------------
  |  |  478|      0|            ::abort();              \
  |  |  479|      0|        }                           \
  |  |  480|      1|    } while (false)
  |  |  ------------------
  |  |  |  Branch (480:14): [Folded, False: 1]
  |  |  ------------------
  ------------------
  275|      1|        }
  276|      1|        return *_s_free_ids;
  277|      1|    }
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE9ScopedPtrC2Ev:
   97|     40|        ScopedPtr() : _data(NULL), _index(0), _w(NULL) {}
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE9ScopedPtrD2Ev:
   98|     40|        ~ScopedPtr() {
   99|     40|            if (_w) {
  ------------------
  |  Branch (99:17): [True: 40, False: 0]
  ------------------
  100|     40|                if (AllowBthreadSuspended) {
  ------------------
  |  Branch (100:21): [Folded, False: 40]
  ------------------
  101|      0|                    _w->EndRead(_index);
  102|     40|                } else {
  103|     40|                    _w->EndRead();
  104|     40|                }
  105|     40|            }
  106|     40|        }
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE7Wrapper7EndReadEv:
  340|     40|    inline void EndRead() {
  341|     40|        pthread_mutex_unlock(&_mutex);
  342|     40|    }
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE4ReadEPNS5_9ScopedPtrE:
  476|     40|    typename DoublyBufferedData<T, TLS, AllowBthreadSuspended>::ScopedPtr* ptr) {
  477|     40|    WrapperSharedPtr w = GetWrapper();
  478|     40|    if (BAIDU_UNLIKELY(w == NULL)) {
  ------------------
  |  |  272|     40|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 40]
  |  |  ------------------
  ------------------
  479|      0|        return -1;
  480|      0|    }
  481|       |
  482|     40|    if (AllowBthreadSuspended) {
  ------------------
  |  Branch (482:9): [Folded, False: 40]
  ------------------
  483|       |        // Use reference count instead of mutex to indicate read of
  484|       |        // foreground instance, so during the read process, there is
  485|       |        // no need to lock mutex and bthread is allowed to be suspended.
  486|      0|        w->BeginRead();
  487|       |        // UnsafeRead will update ptr->_index
  488|      0|        ptr->_data = UnsafeRead(ptr->_index);
  489|      0|        w->AddRef(ptr->_index);
  490|      0|        w->BeginReadRelease();
  491|     40|    } else {
  492|     40|        w->BeginRead();
  493|     40|        ptr->_data = UnsafeRead();
  494|     40|    }
  495|     40|    ptr->_w.swap(w);
  496|     40|    return 0;
  497|     40|}
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE10GetWrapperEv:
  404|     40|DoublyBufferedData<T, TLS, AllowBthreadSuspended>::GetWrapper() {
  405|     40|    WrapperSharedPtr w = WrapperTLSGroup::get_or_create_tls_data(_wrapper_key);
  406|     40|    if (NULL == w) {
  ------------------
  |  Branch (406:9): [True: 0, False: 40]
  ------------------
  407|      0|        return NULL;
  408|      0|    }
  409|     40|    if (w->_control == this) {
  ------------------
  |  Branch (409:9): [True: 39, False: 1]
  ------------------
  410|     39|        return w;
  411|     39|    }
  412|      1|    if (w->_control != NULL) {
  ------------------
  |  Branch (412:9): [True: 0, False: 1]
  ------------------
  413|      0|        LOG(FATAL) << "Get wrapper from tls but control != this";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  414|      0|        return NULL;
  415|      0|    }
  416|      1|    try {
  417|      1|        w->_control = this;
  418|      1|        BAIDU_SCOPED_LOCK(_wrappers_mutex);
  ------------------
  |  |   47|      1|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      1|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      1|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      1|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  419|      1|        _wrappers.push_back(w);
  420|       |        // The chance to remove expired weak_ptr.
  421|      1|        _wrappers.erase(
  422|      1|            std::remove_if(_wrappers.begin(), _wrappers.end(),
  423|      1|                           [](const WrapperWeakPtr& w) {
  424|      1|                    return w.expired();
  425|      1|                }),
  426|      1|            _wrappers.end());
  427|      1|    } catch (std::exception& e) {
  428|      0|        return NULL;
  429|      0|    }
  430|      1|    return w;
  431|      1|}
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE15WrapperTLSGroup22get_or_create_tls_dataEi:
  237|     40|    static WrapperSharedPtr get_or_create_tls_data(WrapperTLSId id) {
  238|     40|        if (BAIDU_UNLIKELY(id < 0)) {
  ------------------
  |  |  272|     40|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 40]
  |  |  ------------------
  ------------------
  239|      0|            CHECK(false) << "Invalid id=" << id;
  ------------------
  |  |  617|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(FATAL).SetCheck(), !(condition))     \
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  618|      0|    << "Check failed: " #condition ". "
  ------------------
  240|      0|            return NULL;
  241|      0|        }
  242|     40|        if (_s_tls_blocks == NULL) {
  ------------------
  |  Branch (242:13): [True: 1, False: 39]
  ------------------
  243|      1|            _s_tls_blocks = new std::vector<ThreadBlock*>;
  244|      1|            butil::thread_atexit(_destroy_tls_blocks);
  245|      1|        }
  246|     40|        const size_t block_id = (size_t)id / ELEMENTS_PER_BLOCK;
  247|     40|        if (block_id >= _s_tls_blocks->size()) {
  ------------------
  |  Branch (247:13): [True: 1, False: 39]
  ------------------
  248|       |            // The 32ul avoid pointless small resizes.
  249|      1|            _s_tls_blocks->resize(std::max(block_id + 1, 32ul));
  250|      1|        }
  251|     40|        ThreadBlock* tb = (*_s_tls_blocks)[block_id];
  252|     40|        if (tb == NULL) {
  ------------------
  |  Branch (252:13): [True: 1, False: 39]
  ------------------
  253|      1|            tb = new ThreadBlock;
  254|      1|            (*_s_tls_blocks)[block_id] = tb;
  255|      1|        }
  256|     40|        return tb->at(id - block_id * ELEMENTS_PER_BLOCK);
  257|     40|    }
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE15WrapperTLSGroup11ThreadBlock2atEm:
  204|     40|        WrapperSharedPtr at(size_t offset) {
  205|     40|            if (NULL == _data[offset]) {
  ------------------
  |  Branch (205:17): [True: 1, False: 39]
  ------------------
  206|      1|                _data[offset] = std::make_shared<Wrapper>();
  207|      1|            }
  208|     40|            return _data[offset];
  209|     40|        };
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE7WrapperC2Ev:
  307|      1|        : _control(NULL)
  308|      1|        , _modify_wait(false) {
  309|      1|        pthread_mutex_init(&_mutex, NULL);
  310|      1|        if (AllowBthreadSuspended) {
  ------------------
  |  Branch (310:13): [Folded, False: 1]
  ------------------
  311|      0|            pthread_cond_init(&_cond[0], NULL);
  312|       |            pthread_cond_init(&_cond[1], NULL);
  313|      0|        }
  314|      1|    }
_ZZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE10GetWrapperEvENKUlRKSt8weak_ptrINS5_7WrapperEEE_clESA_:
  423|      1|                           [](const WrapperWeakPtr& w) {
  424|      1|                    return w.expired();
  425|      1|                }),
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE7Wrapper9BeginReadEv:
  331|     40|    inline void BeginRead() {
  332|     40|        pthread_mutex_lock(&_mutex);
  333|     40|    }
_ZNK5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE10UnsafeReadEv:
  149|     40|    const T* UnsafeRead() const {
  150|     40|        return _data + _index.load(butil::memory_order_acquire);
  151|     40|    }
_ZNK5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE9ScopedPtrdeEv:
  108|     40|        const T& operator*() const { return *_data; }

_ZNK5butil13DefaultHasherINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEclERKS6_:
  562|     16|    std::size_t operator()(const std::string& s) const {
  563|     16|        std::size_t result = 0;
  564|    340|        for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
  ------------------
  |  Branch (564:57): [True: 324, False: 16]
  ------------------
  565|    324|            result = result * 101 + *i;
  566|    324|        }
  567|     16|        return result;        
  568|     16|    }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE6BucketC2Ev:
  283|  1.08k|        Bucket() : next((Bucket*)-1UL) {}
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE26init_buckets_and_thumbnailEPNSE_6BucketEPmm:
  369|    128|                                           size_t nbucket) {
  370|  66.6k|        for (size_t i = 0; i < nbucket; ++i) {
  ------------------
  |  Branch (370:28): [True: 66.5k, False: 128]
  ------------------
  371|  66.5k|            buckets[i].set_invalid();
  372|  66.5k|        }
  373|    128|        buckets[nbucket].next = NULL;
  374|    128|        if (_Sparse) {
  ------------------
  |  Branch (374:13): [Folded, False: 128]
  ------------------
  375|      0|            bit_array_clear(thumbnail, nbucket);
  376|      0|        }
  377|    128|    }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE6Bucket11set_invalidEv:
  292|  66.5k|        void set_invalid() { next = (Bucket*)-1UL; }
_ZNK5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE5emptyEv:
  274|     64|    bool empty() const { return _size == 0; }
_ZNK5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE18is_default_bucketsEv:
  363|    128|    bool is_default_buckets() const {
  364|    128|        return _buckets == (Bucket*)(&_default_buckets);
  365|    128|    }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE16init_load_factorEj:
  355|     64|    void init_load_factor(u_int load_factor) {
  356|     64|        if (_is_default_load_factor) {
  ------------------
  |  Branch (356:13): [True: 64, False: 0]
  ------------------
  357|     64|            _is_default_load_factor = false;
  358|     64|            _load_factor = load_factor;
  359|     64|        }
  360|     64|    }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE14is_too_crowdedEmmj:
  351|     64|    static bool is_too_crowded(size_t size, size_t nbucket, u_int load_factor) {
  352|     64|        return size * 100 >= nbucket * load_factor;
  353|     64|    }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoC2EPNSE_6BucketEPmm:
  327|     64|            : buckets(b), thumbnail(t), nbucket(n) {}
_ZNK5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE6Bucket8is_validEv:
  291|  1.16k|        bool is_valid() const { return next != (const Bucket*)-1UL; }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE6BucketC2ERKS6_:
  284|      8|        explicit Bucket(const _K& k) : next(NULL) {
  285|      8|            element_space_.Init(k);
  286|      8|        }
_ZN5butil14FlatMapElementINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryEEC2ERKS6_:
  486|      8|    explicit FlatMapElement(const K& k) : _key(k), _value(T()) {}
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE6Bucket7elementEv:
  294|      8|        Element& element() { return *element_space_; }
_ZN5butil14FlatMapElementINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryEE10second_refEv:
  496|      8|    T& second_ref() { return _value; }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE13get_allocatorEv:
  344|     64|    allocator_type& get_allocator() { return _pool.get_allocator(); }

_ZN5butil11find_power2Em:
   45|     64|inline uint64_t find_power2(uint64_t b) {
   46|     64|    b -= 1;
   47|     64|    b |= (b >> 1);
   48|     64|    b |= (b >> 2);
   49|     64|    b |= (b >> 4);
   50|     64|    b |= (b >> 8);
   51|     64|    b |= (b >> 16);
   52|     64|    b |= (b >> 32);
   53|     64|    return b + 1;
   54|     64|}
_ZN5butil13flatmap_roundEm:
   61|     64|inline size_t flatmap_round(size_t nbucket) {
   62|       |#ifdef FLAT_MAP_ROUND_BUCKET_BY_USE_NEXT_PRIME    
   63|       |    return find_next_prime(nbucket);
   64|       |#else
   65|       |    // the lowerbound fixes the corner case of nbucket=0 which results in coredump during seeking the map.
   66|     64|    return nbucket <= 8 ? 8 : find_power2(nbucket);
  ------------------
  |  Branch (66:12): [True: 0, False: 64]
  ------------------
   67|     64|#endif
   68|     64|}
_ZN5butil11flatmap_modEmm:
   70|     16|inline size_t flatmap_mod(size_t hash_code, size_t nbucket) {
   71|       |#ifdef FLAT_MAP_ROUND_BUCKET_BY_USE_NEXT_PRIME
   72|       |    return hash_code % nbucket;
   73|       |#else
   74|     16|    return hash_code & (nbucket - 1);
   75|     16|#endif
   76|     16|}
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EEC2ERKSA_RKSC_RKSD_:
  221|     64|    : _size(0)
  222|     64|    , _nbucket(DEFAULT_NBUCKET)
  223|     64|    , _buckets((Bucket*)(&_default_buckets))
  224|     64|    , _thumbnail(_S ? _default_thumbnail : NULL)
  ------------------
  |  Branch (224:18): [Folded, False: 64]
  ------------------
  225|     64|    , _load_factor(80)
  226|     64|    , _is_default_load_factor(true)
  227|     64|    , _hashfn(hashfn)
  228|     64|    , _eql(eql)
  229|     64|    , _pool(alloc) {
  230|     64|    init_buckets_and_thumbnail(_buckets, _thumbnail, _nbucket);
  231|     64|}
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE4initEmj:
  320|     64|int FlatMap<_K, _T, _H, _E, _S, _A, _M>::init(size_t nbucket, u_int load_factor) {
  321|     64|    if (nbucket <= _nbucket || load_factor < 10 || load_factor > 100 ||
  ------------------
  |  Branch (321:9): [True: 0, False: 64]
  |  Branch (321:32): [True: 0, False: 64]
  |  Branch (321:52): [True: 0, False: 64]
  ------------------
  322|     64|        !_is_default_load_factor || !empty() || !is_default_buckets()) {
  ------------------
  |  Branch (322:9): [True: 0, False: 64]
  |  Branch (322:37): [True: 0, False: 64]
  |  Branch (322:49): [True: 0, False: 64]
  ------------------
  323|      0|        return 0;
  324|      0|    }
  325|       |
  326|     64|    init_load_factor(load_factor);
  327|     64|    return resize(nbucket) ? 0 : -1;
  ------------------
  |  Branch (327:12): [True: 64, False: 0]
  ------------------
  328|     64|}
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE6resizeEm:
  755|     64|bool FlatMap<_K, _T, _H, _E, _S, _A, _M>::resize(size_t nbucket) {
  756|     64|    optional<NewBucketsInfo> info = new_buckets_and_thumbnail(_size, nbucket);
  757|     64|    if (!info.has_value()) {
  ------------------
  |  Branch (757:9): [True: 0, False: 64]
  ------------------
  758|      0|        return false;
  759|      0|    }
  760|       |
  761|     64|    for (iterator it = begin(); it != end(); ++it) {
  ------------------
  |  Branch (761:33): [True: 0, False: 64]
  ------------------
  762|      0|        const key_type& key = Element::first_ref_from_value(*it);
  763|      0|        const size_t index = flatmap_mod(_hashfn(key), info->nbucket);
  764|      0|        Bucket& first_node = info->buckets[index];
  765|      0|        if (!first_node.is_valid()) {
  ------------------
  |  Branch (765:13): [True: 0, False: 0]
  ------------------
  766|      0|            if (_S) {
  ------------------
  |  Branch (766:17): [Folded, False: 0]
  ------------------
  767|      0|                bit_array_set(info->thumbnail, index);
  768|      0|            }
  769|      0|            new (&first_node) Bucket(key);
  770|      0|            first_node.element().second_ref() =
  771|      0|                Element::second_movable_ref_from_value(*it);
  772|      0|        } else {
  773|      0|            Bucket* newp = new (_pool.get()) Bucket(key);
  774|      0|            newp->element().second_ref() =
  775|      0|                Element::second_movable_ref_from_value(*it);
  776|      0|            newp->next = first_node.next;
  777|      0|            first_node.next = newp;
  778|      0|        }
  779|      0|    }
  780|     64|    size_t saved_size = _size;
  781|     64|    clear();
  782|     64|    if (!is_default_buckets()) {
  ------------------
  |  Branch (782:9): [True: 0, False: 64]
  ------------------
  783|      0|        get_allocator().Free(_buckets);
  784|      0|        if (_S) {
  ------------------
  |  Branch (784:13): [Folded, False: 0]
  ------------------
  785|      0|            bit_array_free(_thumbnail);
  786|      0|        }
  787|      0|    }
  788|     64|    _nbucket = info->nbucket;
  789|     64|    _buckets = info->buckets;
  790|     64|    _thumbnail = info->thumbnail;
  791|     64|    _size = saved_size;
  792|       |
  793|     64|    return true;
  794|     64|}
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE25new_buckets_and_thumbnailEmm:
  716|     64|                                                               size_t new_nbucket) {
  717|     64|    size_t bump = 0;
  718|     64|    do {
  719|       |        // The first iteration uses 'new_nbucket + 0' ensures that when new_nbucket is a power
  720|       |        // of 2 and is already sufficient to accommodate `size`, it does not need to be doubled.
  721|       |        // Subsequent use of 'new_nbucket + 1' avoids an infinite loop.
  722|     64|        new_nbucket = flatmap_round(new_nbucket + bump);
  723|     64|        bump = 1;
  724|     64|    } while (is_too_crowded(size, new_nbucket, _load_factor));
  ------------------
  |  Branch (724:14): [True: 0, False: 64]
  ------------------
  725|     64|    if (_nbucket == new_nbucket) {
  ------------------
  |  Branch (725:9): [True: 0, False: 64]
  ------------------
  726|      0|        return nullopt;
  727|      0|    }
  728|       |    // Note: need an extra bucket to let iterator know where buckets end.
  729|     64|    auto buckets = (Bucket*)get_allocator().Alloc(
  730|     64|        sizeof(Bucket) * (new_nbucket + 1/*note*/));
  731|     64|    auto guard = MakeScopeGuard([buckets, this]() {
  732|     64|        get_allocator().Free(buckets);
  733|     64|    });
  734|     64|    if (NULL == buckets) {
  ------------------
  |  Branch (734:9): [True: 0, False: 64]
  ------------------
  735|      0|        LOG(FATAL) << "Fail to new Buckets";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  736|      0|        return nullopt;
  737|      0|    }
  738|       |
  739|     64|    uint64_t* thumbnail = NULL;
  740|     64|    if (_S) {
  ------------------
  |  Branch (740:9): [Folded, False: 64]
  ------------------
  741|      0|        thumbnail = bit_array_malloc(new_nbucket);
  742|      0|        if (NULL == thumbnail) {
  ------------------
  |  Branch (742:13): [True: 0, False: 0]
  ------------------
  743|      0|            LOG(FATAL) << "Fail to new thumbnail";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  744|      0|            return nullopt;
  745|      0|        }
  746|      0|    }
  747|       |
  748|     64|    guard.dismiss();
  749|     64|    init_buckets_and_thumbnail(buckets, thumbnail, new_nbucket);
  750|     64|    return NewBucketsInfo{buckets, thumbnail, new_nbucket};
  751|     64|}
_ZNK5butil15FlatMapIteratorINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EEESt4pairIKS7_S9_EEneERKSJ_:
  106|     64|    { return _node != rhs._node; }
_ZN5butil15FlatMapIteratorINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EEESt4pairIKS7_S9_EE23find_and_set_valid_nodeEv:
  137|    128|    void find_and_set_valid_node() {
  138|  1.15k|        for (; !_entry->is_valid(); ++_entry);
  ------------------
  |  Branch (138:16): [True: 1.02k, False: 128]
  ------------------
  139|    128|        _node = _entry;
  140|    128|    }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE5clearEv:
  512|     64|void FlatMap<_K, _T, _H, _E, _S, _A, _M>::clear() {
  513|     64|    if (0 == _size) {
  ------------------
  |  Branch (513:9): [True: 64, False: 0]
  ------------------
  514|     64|        return;
  515|     64|    }
  516|      0|    _size = 0;
  517|      0|    if (NULL != _buckets) {
  ------------------
  |  Branch (517:9): [True: 0, False: 0]
  ------------------
  518|      0|        for (size_t i = 0; i < _nbucket; ++i) {
  ------------------
  |  Branch (518:28): [True: 0, False: 0]
  ------------------
  519|      0|            Bucket& first_node = _buckets[i];
  520|      0|            if (first_node.is_valid()) {
  ------------------
  |  Branch (520:17): [True: 0, False: 0]
  ------------------
  521|      0|                first_node.destroy_element();
  522|      0|                Bucket* p = first_node.next;
  523|      0|                while (p) {
  ------------------
  |  Branch (523:24): [True: 0, False: 0]
  ------------------
  524|      0|                    Bucket* next_p = p->next;
  525|      0|                    p->destroy_element();
  526|      0|                    _pool.back(p);
  527|      0|                    p = next_p;
  528|      0|                }
  529|      0|                first_node.set_invalid();
  530|      0|            }
  531|      0|        }
  532|      0|    }
  533|      0|    if (NULL != _thumbnail) {
  ------------------
  |  Branch (533:9): [True: 0, False: 0]
  ------------------
  534|      0|        bit_array_clear(_thumbnail, _nbucket);
  535|      0|    }
  536|      0|}
_ZNK5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE4seekIS6_EEPS8_RKT_:
  548|      8|_T* FlatMap<_K, _T, _H, _E, _S, _A, _M>::seek(const K2& key) const {
  549|      8|    Bucket& first_node = _buckets[flatmap_mod(_hashfn(key), _nbucket)];
  550|      8|    if (!first_node.is_valid()) {
  ------------------
  |  Branch (550:9): [True: 8, False: 0]
  ------------------
  551|      8|        return NULL;
  552|      8|    }
  553|      0|    if (_eql(first_node.element().first_ref(), key)) {
  ------------------
  |  Branch (553:9): [True: 0, False: 0]
  ------------------
  554|      0|        return &first_node.element().second_ref();
  555|      0|    }
  556|      0|    Bucket *p = first_node.next;
  557|      0|    while (p) {
  ------------------
  |  Branch (557:12): [True: 0, False: 0]
  ------------------
  558|      0|        if (_eql(p->element().first_ref(), key)) {
  ------------------
  |  Branch (558:13): [True: 0, False: 0]
  ------------------
  559|      0|            return &p->element().second_ref();
  560|      0|        }
  561|      0|        p = p->next;
  562|      0|    }
  563|      0|    return NULL;
  564|      0|}
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EEixILb0EEENSt9enable_ifIXntT_ERS8_E4typeERKS6_:
  592|      8|FlatMap<_K, _T, _H, _E, _S, _A, _M>::operator[](const key_type& key) {
  593|      8|    const size_t index = flatmap_mod(_hashfn(key), _nbucket);
  594|      8|    Bucket& first_node = _buckets[index];
  595|      8|    if (!first_node.is_valid()) {
  ------------------
  |  Branch (595:9): [True: 8, False: 0]
  ------------------
  596|      8|        ++_size;
  597|      8|        if (_S) {
  ------------------
  |  Branch (597:13): [Folded, False: 8]
  ------------------
  598|      0|            bit_array_set(_thumbnail, index);
  599|      0|        }
  600|      8|        new (&first_node) Bucket(key);
  601|      8|        return first_node.element().second_ref();
  602|      8|    }
  603|      0|    Bucket *p = &first_node;
  604|      0|    while (true) {
  ------------------
  |  Branch (604:12): [True: 0, Folded]
  ------------------
  605|      0|        if (_eql(p->element().first_ref(), key)) {
  ------------------
  |  Branch (605:13): [True: 0, False: 0]
  ------------------
  606|      0|            return p->element().second_ref();
  607|      0|        }
  608|      0|        if (NULL == p->next) {
  ------------------
  |  Branch (608:13): [True: 0, False: 0]
  ------------------
  609|      0|            if (is_too_crowded(_size) && resize(_nbucket + 1)) {
  ------------------
  |  Branch (609:17): [True: 0, False: 0]
  |  Branch (609:42): [True: 0, False: 0]
  ------------------
  610|      0|                return operator[](key);
  611|      0|            }
  612|       |            // Fail to resize is OK.
  613|      0|            ++_size;
  614|      0|            Bucket* newp = new (_pool.get()) Bucket(key);
  615|      0|            p->next = newp;
  616|      0|            return newp->element().second_ref();
  617|      0|        }
  618|      0|        p = p->next;
  619|      0|    }
  620|      0|}
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE5beginEv:
  820|     64|FlatMap<_K, _T, _H, _E, _S, _A, _M>::begin() {
  821|     64|    return iterator(this, 0);
  822|     64|}
_ZN5butil15FlatMapIteratorINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EEESt4pairIKS7_S9_EEC2EPKSF_m:
   92|    128|    FlatMapIterator(const Map* map, size_t pos) {
   93|    128|        _entry = map->_buckets + pos;
   94|    128|        find_and_set_valid_node();
   95|    128|    }
_ZN5butil7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS6_EENS_14DefaultEqualToIS6_EELb0ENS_11PtAllocatorELb0EE3endEv:
  827|     64|FlatMap<_K, _T, _H, _E, _S, _A, _M>::end() {
  828|     64|    return iterator(this, _nbucket);
  829|     64|}

_ZN5butil8LinkNodeIN4bvar6detail7SamplerEE18InsertBeforeAsListEPS4_:
  102|      8|  void InsertBeforeAsList(LinkNode<T>* e) {
  103|      8|    LinkNode<T>* prev = this->previous_;
  104|      8|    prev->next_ = e;
  105|      8|    this->previous_ = e->previous_;
  106|      8|    e->previous_->next_ = this;
  107|      8|    e->previous_ = prev;
  108|      8|  }
_ZN5butil10LinkedListIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEEC2Ev:
  167|      2|  LinkedList() {}
_ZN5butil8LinkNodeIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEEC2Ev:
   88|    106|  LinkNode() : previous_(this), next_(this) {}
_ZNK5butil10LinkedListIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE4headEv:
  179|      4|  LinkNode<T>* head() const {
  180|      4|    return root_.next();
  181|      4|  }
_ZNK5butil10LinkedListIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE3endEv:
  187|      8|  const LinkNode<T>* end() const {
  188|      8|    return &root_;
  189|      8|  }
_ZN5butil8LinkNodeIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE5valueEv:
  150|      4|  T* value() {
  151|      4|    return static_cast<T*>(this);
  152|      4|  }
_ZNK5butil8LinkNodeIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE4nextEv:
  141|      8|  LinkNode<T>* next() const {
  142|      8|    return next_;
  143|      8|  }
_ZN5butil8LinkNodeIN4bvar6detail7SamplerEEC2Ev:
   88|     10|  LinkNode() : previous_(this), next_(this) {}
_ZNK5butil8LinkNodeIN4bvar6detail7SamplerEE4nextEv:
  141|     20|  LinkNode<T>* next() const {
  142|     20|    return next_;
  143|     20|  }
_ZN5butil8LinkNodeIN4bvar6detail7SamplerEE5valueEv:
  150|     16|  T* value() {
  151|     16|    return static_cast<T*>(this);
  152|     16|  }
_ZN5butil10LinkedListIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE6AppendEPNS_8LinkNodeIS8_EE:
  170|      2|  void Append(LinkNode<T>* e) {
  171|      2|    e->InsertBefore(&root_);
  172|      2|  }
_ZN5butil8LinkNodeIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE12InsertBeforeEPS9_:
   94|      2|  void InsertBefore(LinkNode<T>* e) {
   95|      2|    this->next_ = e;
   96|      2|    this->previous_ = e->previous_;
   97|      2|    e->previous_->next_ = this;
   98|      2|    e->previous_ = this;
   99|      2|  }

_ZN5butil5debug10StackTraceC2Eb:
  766|      2|StackTrace::StackTrace(bool exclude_self) {
  767|       |  // NOTE: This code MUST be async-signal safe (it's used by in-process
  768|       |  // stack dumping signal handler). NO malloc or stdio is allowed here.
  769|       |
  770|      2|  if (GetStackTrace) {
  ------------------
  |  Branch (770:7): [True: 0, False: 2]
  ------------------
  771|      0|    count_ = GetStackTrace(trace_, arraysize(trace_), exclude_self ? 1 : 0);
  ------------------
  |  |  122|      0|#define arraysize(array) (sizeof(::butil::ArraySizeHelper(array)))
  ------------------
  |  Branch (771:55): [True: 0, False: 0]
  ------------------
  772|      2|  } else {
  773|      2|#if !defined(__UCLIBC__)
  774|       |    // Though the backtrace API man page does not list any possible negative
  775|       |    // return values, we take no chance.
  776|      2|    count_ = butil::saturated_cast<size_t>(backtrace(trace_, arraysize(trace_)));
  ------------------
  |  |  122|      2|#define arraysize(array) (sizeof(::butil::ArraySizeHelper(array)))
  ------------------
  777|      2|    if (exclude_self && count_ > 1) {
  ------------------
  |  Branch (777:9): [True: 0, False: 2]
  |  Branch (777:25): [True: 0, False: 0]
  ------------------
  778|       |      // Skip the top frame.
  779|      0|      memmove(trace_, trace_ + 1, (count_ - 1) * sizeof(void*));
  780|      0|      count_--;
  781|      0|    }
  782|       |#else
  783|       |    count_ = 0;
  784|       |#endif
  785|      2|  }
  786|      2|}

_ZN5butil23DescribeCustomizedErrnoEiPKcS1_:
   40|      2|    int error_code, const char* error_name, const char* description) {
   41|      2|    BAIDU_SCOPED_LOCK(modify_desc_mutex);
  ------------------
  |  |   47|      2|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      2|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      2|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      2|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   42|      2|    if (error_code < ERRNO_BEGIN || error_code >= ERRNO_END) {
  ------------------
  |  Branch (42:9): [True: 0, False: 2]
  |  Branch (42:37): [True: 0, False: 2]
  ------------------
   43|       |        // error() is a non-portable GNU extension that should not be used.
   44|      0|        fprintf(stderr, "Fail to define %s(%d) which is out of range, abort.",
   45|      0|              error_name, error_code);
   46|      0|        _exit(1);
   47|      0|    }
   48|      2|    const char* desc = errno_desc[error_code - ERRNO_BEGIN];
   49|      2|    if (desc) {
  ------------------
  |  Branch (49:9): [True: 0, False: 2]
  ------------------
   50|      0|        if (strcmp(desc, description) == 0) {
  ------------------
  |  Branch (50:13): [True: 0, False: 0]
  ------------------
   51|      0|            fprintf(stderr, "WARNING: Detected shared library loading\n");
   52|      0|            return -1;
   53|      0|        }
   54|      2|    } else {
   55|       |#if defined(OS_MACOSX)
   56|       |        const int rc = strerror_r(error_code, tls_error_buf, ERROR_BUFSIZE);
   57|       |        if (rc != EINVAL)
   58|       |#else
   59|      2|        desc = strerror_r(error_code, tls_error_buf, ERROR_BUFSIZE);
   60|      2|        if (desc && strncmp(desc, "Unknown error", 13) != 0)
  ------------------
  |  Branch (60:13): [True: 2, False: 0]
  |  Branch (60:21): [True: 0, False: 2]
  ------------------
   61|      0|#endif
   62|      0|        {
   63|      0|            fprintf(stderr, "WARNING: Fail to define %s(%d) which is already defined as `%s'",
   64|      0|                    error_name, error_code, desc);
   65|      0|        }
   66|      2|    }
   67|      2|    errno_desc[error_code - ERRNO_BEGIN] = description;
   68|      2|    return 0;  // must
   69|      2|}

_ZN5butil5IOBuf35_push_or_move_back_ref_to_smallviewILb1EEEvRKNS0_8BlockRefE:
  501|      1|void IOBuf::_push_or_move_back_ref_to_smallview(const BlockRef& r) {
  502|      1|    BlockRef* const refs = _sv.refs;
  503|      1|    if (NULL == refs[0].block) {
  ------------------
  |  Branch (503:9): [True: 1, False: 0]
  ------------------
  504|      1|        refs[0] = r;
  505|      1|        if (!MOVE) {
  ------------------
  |  Branch (505:13): [Folded, False: 1]
  ------------------
  506|      0|            r.block->inc_ref();
  507|      0|        }
  508|      1|        return;
  509|      1|    }
  510|      0|    if (NULL == refs[1].block) {
  ------------------
  |  Branch (510:9): [True: 0, False: 0]
  ------------------
  511|      0|        if (refs[0].block == r.block &&
  ------------------
  |  Branch (511:13): [True: 0, False: 0]
  ------------------
  512|      0|            refs[0].offset + refs[0].length == r.offset) { // Merge ref
  ------------------
  |  Branch (512:13): [True: 0, False: 0]
  ------------------
  513|      0|            refs[0].length += r.length;
  514|      0|            if (MOVE) {
  ------------------
  |  Branch (514:17): [True: 0, Folded]
  ------------------
  515|      0|                r.block->dec_ref();
  516|      0|            }
  517|      0|            return;
  518|      0|        }
  519|      0|        refs[1] = r;
  520|      0|        if (!MOVE) {
  ------------------
  |  Branch (520:13): [Folded, False: 0]
  ------------------
  521|      0|            r.block->inc_ref();
  522|      0|        }
  523|      0|        return;
  524|      0|    }
  525|      0|    if (refs[1].block == r.block &&
  ------------------
  |  Branch (525:9): [True: 0, False: 0]
  ------------------
  526|      0|        refs[1].offset + refs[1].length == r.offset) { // Merge ref
  ------------------
  |  Branch (526:9): [True: 0, False: 0]
  ------------------
  527|      0|        refs[1].length += r.length;
  528|      0|        if (MOVE) {
  ------------------
  |  Branch (528:13): [True: 0, Folded]
  ------------------
  529|      0|            r.block->dec_ref();
  530|      0|        }
  531|      0|        return;
  532|      0|    }
  533|       |    // Convert to BigView
  534|      0|    BlockRef* new_refs = iobuf::acquire_blockref_array();
  535|      0|    new_refs[0] = refs[0];
  536|      0|    new_refs[1] = refs[1];
  537|      0|    new_refs[2] = r;
  538|      0|    const size_t new_nbytes = refs[0].length + refs[1].length + r.length;
  539|      0|    if (!MOVE) {
  ------------------
  |  Branch (539:9): [Folded, False: 0]
  ------------------
  540|      0|        r.block->inc_ref();
  541|      0|    }
  542|      0|    _bv.magic = -1;
  543|      0|    _bv.start = 0;
  544|      0|    _bv.refs = new_refs;
  545|      0|    _bv.nref = 3;
  546|      0|    _bv.cap_mask = INITIAL_CAP - 1;
  547|      0|    _bv.nbytes = new_nbytes;
  548|      0|}
_ZN5butil5IOBuf35_push_or_move_back_ref_to_smallviewILb0EEEvRKNS0_8BlockRefE:
  501|    418|void IOBuf::_push_or_move_back_ref_to_smallview(const BlockRef& r) {
  502|    418|    BlockRef* const refs = _sv.refs;
  503|    418|    if (NULL == refs[0].block) {
  ------------------
  |  Branch (503:9): [True: 410, False: 8]
  ------------------
  504|    410|        refs[0] = r;
  505|    410|        if (!MOVE) {
  ------------------
  |  Branch (505:13): [True: 410, Folded]
  ------------------
  506|    410|            r.block->inc_ref();
  507|    410|        }
  508|    410|        return;
  509|    410|    }
  510|      8|    if (NULL == refs[1].block) {
  ------------------
  |  Branch (510:9): [True: 8, False: 0]
  ------------------
  511|      8|        if (refs[0].block == r.block &&
  ------------------
  |  Branch (511:13): [True: 0, False: 8]
  ------------------
  512|      0|            refs[0].offset + refs[0].length == r.offset) { // Merge ref
  ------------------
  |  Branch (512:13): [True: 0, False: 0]
  ------------------
  513|      0|            refs[0].length += r.length;
  514|      0|            if (MOVE) {
  ------------------
  |  Branch (514:17): [Folded, False: 0]
  ------------------
  515|      0|                r.block->dec_ref();
  516|      0|            }
  517|      0|            return;
  518|      0|        }
  519|      8|        refs[1] = r;
  520|      8|        if (!MOVE) {
  ------------------
  |  Branch (520:13): [True: 8, Folded]
  ------------------
  521|      8|            r.block->inc_ref();
  522|      8|        }
  523|      8|        return;
  524|      8|    }
  525|      0|    if (refs[1].block == r.block &&
  ------------------
  |  Branch (525:9): [True: 0, False: 0]
  ------------------
  526|      0|        refs[1].offset + refs[1].length == r.offset) { // Merge ref
  ------------------
  |  Branch (526:9): [True: 0, False: 0]
  ------------------
  527|      0|        refs[1].length += r.length;
  528|      0|        if (MOVE) {
  ------------------
  |  Branch (528:13): [Folded, False: 0]
  ------------------
  529|      0|            r.block->dec_ref();
  530|      0|        }
  531|      0|        return;
  532|      0|    }
  533|       |    // Convert to BigView
  534|      0|    BlockRef* new_refs = iobuf::acquire_blockref_array();
  535|      0|    new_refs[0] = refs[0];
  536|      0|    new_refs[1] = refs[1];
  537|      0|    new_refs[2] = r;
  538|      0|    const size_t new_nbytes = refs[0].length + refs[1].length + r.length;
  539|      0|    if (!MOVE) {
  ------------------
  |  Branch (539:9): [True: 0, Folded]
  ------------------
  540|      0|        r.block->inc_ref();
  541|      0|    }
  542|      0|    _bv.magic = -1;
  543|      0|    _bv.start = 0;
  544|      0|    _bv.refs = new_refs;
  545|      0|    _bv.nref = 3;
  546|      0|    _bv.cap_mask = INITIAL_CAP - 1;
  547|      0|    _bv.nbytes = new_nbytes;
  548|      0|}
_ZN5butil5IOBuf25_pop_or_moveout_front_refILb1EEEiv:
  597|      1|int IOBuf::_pop_or_moveout_front_ref() {
  598|      1|    if (_small()) {
  ------------------
  |  Branch (598:9): [True: 1, False: 0]
  ------------------
  599|      1|        if (_sv.refs[0].block != NULL) {
  ------------------
  |  Branch (599:13): [True: 1, False: 0]
  ------------------
  600|      1|            if (!MOVEOUT) {
  ------------------
  |  Branch (600:17): [Folded, False: 1]
  ------------------
  601|      0|                _sv.refs[0].block->dec_ref();
  602|      0|            }
  603|      1|            _sv.refs[0] = _sv.refs[1];
  604|      1|            reset_block_ref(_sv.refs[1]);
  605|      1|            return 0;
  606|      1|        }
  607|      0|        return -1;
  608|      1|    } else {
  609|       |        // _bv.nref must be greater than 2
  610|      0|        const uint32_t start = _bv.start;
  611|      0|        if (!MOVEOUT) {
  ------------------
  |  Branch (611:13): [Folded, False: 0]
  ------------------
  612|      0|            _bv.refs[start].block->dec_ref();
  613|      0|        }
  614|      0|        if (--_bv.nref > 2) {
  ------------------
  |  Branch (614:13): [True: 0, False: 0]
  ------------------
  615|      0|            _bv.start = (start + 1) & _bv.cap_mask;
  616|      0|            _bv.nbytes -= _bv.refs[start].length;
  617|      0|        } else {  // count==2, fall back to SmallView
  618|      0|            BlockRef* const saved_refs = _bv.refs;
  619|      0|            const uint32_t saved_cap_mask = _bv.cap_mask;
  620|      0|            _sv.refs[0] = saved_refs[(start + 1) & saved_cap_mask];
  621|      0|            _sv.refs[1] = saved_refs[(start + 2) & saved_cap_mask];
  622|      0|            iobuf::release_blockref_array(saved_refs, saved_cap_mask + 1);
  623|      0|        }
  624|      0|        return 0;
  625|      0|    }
  626|      1|}
_ZN5butil5IOBuf25_pop_or_moveout_front_refILb0EEEiv:
  597|     16|int IOBuf::_pop_or_moveout_front_ref() {
  598|     16|    if (_small()) {
  ------------------
  |  Branch (598:9): [True: 16, False: 0]
  ------------------
  599|     16|        if (_sv.refs[0].block != NULL) {
  ------------------
  |  Branch (599:13): [True: 16, False: 0]
  ------------------
  600|     16|            if (!MOVEOUT) {
  ------------------
  |  Branch (600:17): [True: 16, Folded]
  ------------------
  601|     16|                _sv.refs[0].block->dec_ref();
  602|     16|            }
  603|     16|            _sv.refs[0] = _sv.refs[1];
  604|     16|            reset_block_ref(_sv.refs[1]);
  605|     16|            return 0;
  606|     16|        }
  607|      0|        return -1;
  608|     16|    } else {
  609|       |        // _bv.nref must be greater than 2
  610|      0|        const uint32_t start = _bv.start;
  611|      0|        if (!MOVEOUT) {
  ------------------
  |  Branch (611:13): [True: 0, Folded]
  ------------------
  612|      0|            _bv.refs[start].block->dec_ref();
  613|      0|        }
  614|      0|        if (--_bv.nref > 2) {
  ------------------
  |  Branch (614:13): [True: 0, False: 0]
  ------------------
  615|      0|            _bv.start = (start + 1) & _bv.cap_mask;
  616|      0|            _bv.nbytes -= _bv.refs[start].length;
  617|      0|        } else {  // count==2, fall back to SmallView
  618|      0|            BlockRef* const saved_refs = _bv.refs;
  619|      0|            const uint32_t saved_cap_mask = _bv.cap_mask;
  620|      0|            _sv.refs[0] = saved_refs[(start + 1) & saved_cap_mask];
  621|      0|            _sv.refs[1] = saved_refs[(start + 2) & saved_cap_mask];
  622|      0|            iobuf::release_blockref_array(saved_refs, saved_cap_mask + 1);
  623|      0|        }
  624|      0|        return 0;
  625|      0|    }
  626|     16|}
_ZN5butil19GetDefaultBlockSizeEv:
   49|      8|size_t GetDefaultBlockSize() {
   50|      8|    return default_block_size;
   51|      8|}
_ZN5butil5iobuf2cpEPvPKvm:
  207|  5.55k|void* cp(void *__restrict dest, const void *__restrict src, size_t n) {
  208|       |#if defined(HAS_RVV_CP)
  209|       |    return cp_rvv(dest, src, n);
  210|       |#else
  211|       |    // memcpy in gcc 4.8 seems to be faster enough.
  212|  5.55k|    return memcpy(dest, src, n);
  213|  5.55k|#endif
  214|  5.55k|}
_ZN5butil5iobuf12inc_g_nblockEv:
  235|      8|void inc_g_nblock() {
  236|      8|    g_nblock.fetch_add(1, butil::memory_order_relaxed);
  237|      8|}
_ZN5butil5iobuf12dec_g_nblockEv:
  238|      7|void dec_g_nblock() {
  239|      7|    g_nblock.fetch_sub(1, butil::memory_order_relaxed);
  240|      7|}
_ZN5butil5iobuf14inc_g_blockmemEv:
  242|      8|void inc_g_blockmem() {
  243|      8|    g_blockmem.fetch_add(1, butil::memory_order_relaxed);
  244|      8|}
_ZN5butil5iobuf14dec_g_blockmemEv:
  245|      7|void dec_g_blockmem() {
  246|      7|    g_blockmem.fetch_sub(1, butil::memory_order_relaxed);
  247|      7|}
_ZN5butil5iobuf15share_tls_blockEv:
  341|     91|IOBuf::Block* share_tls_block() {
  342|     91|    TLSData& tls_data = g_tls_data;
  343|     91|    IOBuf::Block* const b = tls_data.block_head;
  344|     91|    if (b != NULL && !b->full()) {
  ------------------
  |  Branch (344:9): [True: 90, False: 1]
  |  Branch (344:22): [True: 83, False: 7]
  ------------------
  345|     83|        return b;
  346|     83|    }
  347|      8|    IOBuf::Block* new_block = NULL;
  348|      8|    if (b) {
  ------------------
  |  Branch (348:9): [True: 7, False: 1]
  ------------------
  349|      7|        new_block = b;
  350|     14|        while (new_block && new_block->full()) {
  ------------------
  |  Branch (350:16): [True: 7, False: 7]
  |  Branch (350:29): [True: 7, False: 0]
  ------------------
  351|      7|            IOBuf::Block* const saved_next = new_block->u.portal_next;
  352|      7|            new_block->dec_ref();
  353|      7|            --tls_data.num_blocks;
  354|      7|            new_block = saved_next;
  355|      7|        }
  356|      7|    } else if (!tls_data.registered) {
  ------------------
  |  Branch (356:16): [True: 1, False: 0]
  ------------------
  357|      1|        tls_data.registered = true;
  358|       |        // Only register atexit at the first time
  359|      1|        butil::thread_atexit(remove_tls_block_chain);
  360|      1|    }
  361|      8|    if (!new_block) {
  ------------------
  |  Branch (361:9): [True: 8, False: 0]
  ------------------
  362|      8|        new_block = create_block(); // may be NULL
  363|      8|        if (new_block) {
  ------------------
  |  Branch (363:13): [True: 8, False: 0]
  ------------------
  364|      8|            ++tls_data.num_blocks;
  365|      8|        }
  366|      8|    }
  367|      8|    tls_data.block_head = new_block;
  368|      8|    return new_block;
  369|     91|}
_ZN5butil5IOBuf5clearEv:
  661|    442|void IOBuf::clear() {
  662|    442|    if (_small()) {
  ------------------
  |  Branch (662:9): [True: 442, False: 0]
  ------------------
  663|    442|        if (_sv.refs[0].block != NULL) {
  ------------------
  |  Branch (663:13): [True: 400, False: 42]
  ------------------
  664|    400|            _sv.refs[0].block->dec_ref();
  665|    400|            reset_block_ref(_sv.refs[0]);
  666|       |                        
  667|    400|            if (_sv.refs[1].block != NULL) {
  ------------------
  |  Branch (667:17): [True: 2, False: 398]
  ------------------
  668|      2|                _sv.refs[1].block->dec_ref();
  669|      2|                reset_block_ref(_sv.refs[1]);
  670|      2|            }
  671|    400|        }
  672|    442|    } else {
  673|      0|        for (uint32_t i = 0; i < _bv.nref; ++i) { 
  ------------------
  |  Branch (673:30): [True: 0, False: 0]
  ------------------
  674|      0|            _bv.ref_at(i).block->dec_ref();
  675|      0|        }
  676|      0|        iobuf::release_blockref_array(_bv.refs, _bv.capacity());
  677|      0|        new (this) IOBuf;
  678|      0|    }
  679|    442|}
_ZN5butil5IOBuf9pop_frontEm:
  681|  3.90k|size_t IOBuf::pop_front(size_t n) {
  682|  3.90k|    const size_t len = length();
  683|  3.90k|    if (n >= len) {
  ------------------
  |  Branch (683:9): [True: 30, False: 3.87k]
  ------------------
  684|     30|        clear();
  685|     30|        return len;
  686|     30|    }
  687|  3.87k|    const size_t saved_n = n;
  688|  3.87k|    while (n) {  // length() == 0 does not enter
  ------------------
  |  Branch (688:12): [True: 3.87k, False: 0]
  ------------------
  689|  3.87k|        IOBuf::BlockRef &r = _front_ref();
  690|  3.87k|        if (r.length > n) {
  ------------------
  |  Branch (690:13): [True: 3.87k, False: 4]
  ------------------
  691|  3.87k|            r.offset += n;
  692|  3.87k|            r.length -= n;
  693|  3.87k|            if (!_small()) {
  ------------------
  |  Branch (693:17): [True: 0, False: 3.87k]
  ------------------
  694|      0|                _bv.nbytes -= n;
  695|      0|            }
  696|  3.87k|            return saved_n;
  697|  3.87k|        }
  698|      4|        n -= r.length;
  699|      4|        _pop_front_ref();
  700|      4|    }
  701|      0|    return saved_n;
  702|  3.87k|}
_ZN5butil5IOBuf4cutnEPS0_m:
  744|    327|size_t IOBuf::cutn(IOBuf* out, size_t n) {
  745|    327|    const size_t len = length();
  746|    327|    if (n > len) {
  ------------------
  |  Branch (746:9): [True: 0, False: 327]
  ------------------
  747|      0|        n = len;
  748|      0|    }
  749|    327|    const size_t saved_n = n;
  750|    328|    while (n) {   // length() == 0 does not enter
  ------------------
  |  Branch (750:12): [True: 328, False: 0]
  ------------------
  751|    328|        IOBuf::BlockRef &r = _front_ref();
  752|    328|        if (r.length <= n) {
  ------------------
  |  Branch (752:13): [True: 1, False: 327]
  ------------------
  753|      1|            n -= r.length;
  754|      1|            out->_move_back_ref(r);
  755|      1|            _moveout_front_ref();
  756|    327|        } else {
  757|    327|            const IOBuf::BlockRef cr = { r.offset, (uint32_t)n, r.block };
  758|    327|            out->_push_back_ref(cr);
  759|       |            
  760|    327|            r.offset += n;
  761|    327|            r.length -= n;
  762|    327|            if (!_small()) {
  ------------------
  |  Branch (762:17): [True: 0, False: 327]
  ------------------
  763|      0|                _bv.nbytes -= n;
  764|      0|            }
  765|    327|            return saved_n;
  766|    327|        }
  767|    328|    }
  768|      0|    return saved_n;
  769|    327|}
_ZN5butil5IOBuf4cutnEPvm:
  771|  2.81k|size_t IOBuf::cutn(void* out, size_t n) {
  772|  2.81k|    const size_t len = length();
  773|  2.81k|    if (n > len) {
  ------------------
  |  Branch (773:9): [True: 0, False: 2.81k]
  ------------------
  774|      0|        n = len;
  775|      0|    }
  776|  2.81k|    const size_t saved_n = n;
  777|  2.83k|    while (n) {   // length() == 0 does not enter
  ------------------
  |  Branch (777:12): [True: 1.54k, False: 1.28k]
  ------------------
  778|  1.54k|        IOBuf::BlockRef &r = _front_ref();
  779|  1.54k|        if (r.length <= n) {
  ------------------
  |  Branch (779:13): [True: 12, False: 1.53k]
  ------------------
  780|     12|            iobuf::cp(out, r.block->data + r.offset, r.length);
  781|     12|            out = (char*)out + r.length;
  782|     12|            n -= r.length;
  783|     12|            _pop_front_ref();
  784|  1.53k|        } else {
  785|  1.53k|            iobuf::cp(out, r.block->data + r.offset, n);
  786|  1.53k|            out = (char*)out + n;
  787|  1.53k|            r.offset += n;
  788|  1.53k|            r.length -= n;
  789|  1.53k|            if (!_small()) {
  ------------------
  |  Branch (789:17): [True: 0, False: 1.53k]
  ------------------
  790|      0|                _bv.nbytes -= n;
  791|      0|            }
  792|  1.53k|            return saved_n;
  793|  1.53k|        }
  794|  1.54k|    }
  795|  1.28k|    return saved_n;
  796|  2.81k|}
_ZN5butil5IOBuf13_cut_by_delimEPS0_PKcm:
  831|    328|int IOBuf::_cut_by_delim(IOBuf* out, char const* dbegin, size_t ndelim) {
  832|    328|    typedef unsigned long SigType;
  833|    328|    const size_t NMAX = sizeof(SigType);
  834|       |    
  835|    328|    if (ndelim > NMAX || ndelim > length()) {
  ------------------
  |  Branch (835:9): [True: 0, False: 328]
  |  Branch (835:26): [True: 0, False: 328]
  ------------------
  836|      0|        return -1;
  837|      0|    }
  838|       |    
  839|    328|    SigType dsig = 0;
  840|    984|    for (size_t i = 0; i < ndelim; ++i) {
  ------------------
  |  Branch (840:24): [True: 656, False: 328]
  ------------------
  841|    656|        dsig = (dsig << CHAR_BIT) | static_cast<SigType>(dbegin[i]);
  842|    656|    }
  843|       |    
  844|    328|    const SigType SIGMASK =
  845|    328|        (ndelim == NMAX ? (SigType)-1 : (((SigType)1 << (ndelim * CHAR_BIT)) - 1));
  ------------------
  |  Branch (845:10): [True: 0, False: 328]
  ------------------
  846|       |
  847|    328|    const size_t nref = _ref_num();
  848|    328|    SigType sig = 0;
  849|    328|    size_t n = 0;
  850|       |
  851|    331|    for (size_t i = 0; i < nref; ++i) {
  ------------------
  |  Branch (851:24): [True: 330, False: 1]
  ------------------
  852|    330|        IOBuf::BlockRef const& r = _ref_at(i);
  853|    330|        char const* const s = r.block->data + r.offset;
  854|       |        
  855|  11.0k|        for (uint32_t j = 0; j < r.length; ++j, ++n) {
  ------------------
  |  Branch (855:30): [True: 11.0k, False: 3]
  ------------------
  856|  11.0k|            sig = ((sig << CHAR_BIT) | static_cast<SigType>(s[j])) & SIGMASK;
  857|  11.0k|            if (sig == dsig) {
  ------------------
  |  Branch (857:17): [True: 327, False: 10.7k]
  ------------------
  858|       |                // There's no way cutn/pop_front fails
  859|    327|                cutn(out, n + 1 - ndelim);
  860|    327|                pop_front(ndelim);
  861|    327|                return 0;
  862|    327|            }
  863|  11.0k|        }
  864|    330|    }
  865|       |
  866|      1|    return -1;
  867|    328|}
_ZN5butil5IOBuf6appendEPKvm:
 1117|     84|int IOBuf::append(void const* data, size_t count) {
 1118|     84|    if (BAIDU_UNLIKELY(!data)) {
  ------------------
  |  |  272|     84|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 84]
  |  |  ------------------
  ------------------
 1119|      0|        return -1;
 1120|      0|    }
 1121|     84|    if (count == 1) {
  ------------------
  |  Branch (1121:9): [True: 0, False: 84]
  ------------------
 1122|      0|        return push_back(*((char const*)data));
 1123|      0|    }
 1124|     84|    size_t total_nc = 0;
 1125|    175|    while (total_nc < count) {  // excluded count == 0
  ------------------
  |  Branch (1125:12): [True: 91, False: 84]
  ------------------
 1126|     91|        IOBuf::Block* b = iobuf::share_tls_block();
 1127|     91|        if (BAIDU_UNLIKELY(!b)) {
  ------------------
  |  |  272|     91|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 91]
  |  |  ------------------
  ------------------
 1128|      0|            return -1;
 1129|      0|        }
 1130|     91|        const size_t nc = std::min(count - total_nc, b->left_space());
 1131|     91|        iobuf::cp(b->data + b->size, (char*)data + total_nc, nc);
 1132|       |        
 1133|     91|        const IOBuf::BlockRef r = { (uint32_t)b->size, (uint32_t)nc, b };
 1134|     91|        _push_back_ref(r);
 1135|     91|        b->size += nc;
 1136|     91|        total_nc += nc;
 1137|     91|    }
 1138|     84|    return 0;
 1139|     84|}
_ZNK5butil5IOBuf7copy_toEPvmm:
 1341|  3.92k|size_t IOBuf::copy_to(void* d, size_t n, size_t pos) const {
 1342|  3.92k|    const size_t nref = _ref_num();
 1343|       |    // Skip `pos' bytes. `offset' is the starting position in starting BlockRef.
 1344|  3.92k|    size_t offset = pos;
 1345|  3.92k|    size_t i = 0;
 1346|  3.96k|    for (; offset != 0 && i < nref; ++i) {
  ------------------
  |  Branch (1346:12): [True: 327, False: 3.63k]
  |  Branch (1346:27): [True: 327, False: 0]
  ------------------
 1347|    327|        IOBuf::BlockRef const& r = _ref_at(i);
 1348|    327|        if (offset < (size_t)r.length) {
  ------------------
  |  Branch (1348:13): [True: 295, False: 32]
  ------------------
 1349|    295|            break;
 1350|    295|        }
 1351|     32|        offset -= r.length;
 1352|     32|    }
 1353|  3.92k|    size_t m = n;
 1354|  7.84k|    for (; m != 0 && i < nref; ++i) {
  ------------------
  |  Branch (1354:12): [True: 4.40k, False: 3.44k]
  |  Branch (1354:22): [True: 3.91k, False: 483]
  ------------------
 1355|  3.91k|        IOBuf::BlockRef const& r = _ref_at(i);
 1356|  3.91k|        const size_t nc = std::min(m, (size_t)r.length - offset);
 1357|  3.91k|        iobuf::cp(d, r.block->data + r.offset + offset, nc);
 1358|  3.91k|        offset = 0;
 1359|  3.91k|        d = (char*)d + nc;
 1360|  3.91k|        m -= nc;
 1361|  3.91k|    }
 1362|       |    // If nref == 0, here returns 0 correctly
 1363|  3.92k|    return n - m;
 1364|  3.92k|}
_ZNK5butil5IOBuf12copy_to_cstrEPcmm:
 1392|    327|size_t IOBuf::copy_to_cstr(char* s, size_t n, size_t pos) const {
 1393|    327|    const size_t nc = copy_to(s, n, pos);
 1394|    327|    s[nc] = '\0';
 1395|    327|    return nc;
 1396|    327|}
_ZNK5butil5IOBuf6fetch1Ev:
 1422|  3.99k|const void* IOBuf::fetch1() const {
 1423|  3.99k|    if (!empty()) {
  ------------------
  |  Branch (1423:9): [True: 3.96k, False: 33]
  ------------------
 1424|  3.96k|        const IOBuf::BlockRef& r0 = _front_ref();
 1425|  3.96k|        return r0.block->data + r0.offset;
 1426|  3.96k|    }
 1427|     33|    return NULL;
 1428|  3.99k|}
_ZNK5butil5IOBuf13backing_blockB5cxx11Em:
 1455|     39|StringPiece IOBuf::backing_block(size_t i) const {
 1456|     39|    if (i < _ref_num()) {
  ------------------
  |  Branch (1456:9): [True: 39, False: 0]
  ------------------
 1457|     39|        const BlockRef& r = _ref_at(i);
 1458|     39|        return StringPiece(r.block->data + r.offset, r.length);
 1459|     39|    }
 1460|      0|    return StringPiece();
 1461|     39|}

_ZN5butil5IOBufD2Ev:
  124|    412|    ~IOBuf() { clear(); }
_ZNK5butil5IOBuf4sizeEv:
  355|  1.74k|    size_t size() const { return length(); }
_ZN5butil5IOBuf14_pop_front_refEv:
  398|     16|    int _pop_front_ref() { return _pop_or_moveout_front_ref<false>(); }
_ZN5butil5IOBuf18_moveout_front_refEv:
  402|      1|    int _moveout_front_ref() { return _pop_or_moveout_front_ref<true>(); }
_ZNK5butil18IOBufBytesIteratordeEv:
  901|  15.3k|    unsigned char operator*() const { return (unsigned char)*_block_begin; }
_ZNK5butil18IOBufBytesIteratorcvPKvEv:
  902|  15.3k|    operator const void*() const { return (const void*)!!_bytes_left; }

_ZN5butil5IOBufC2Ev:
   77|    414|inline IOBuf::IOBuf() {
   78|    414|    reset_block_ref(_sv.refs[0]);
   79|    414|    reset_block_ref(_sv.refs[1]);
   80|    414|}
_ZN5butil15reset_block_refERNS_5IOBuf8BlockRefE:
   71|  1.24k|inline void reset_block_ref(IOBuf::BlockRef& ref) {
   72|  1.24k|    ref.offset = 0;
   73|  1.24k|    ref.length = 0;
   74|       |    ref.block = NULL;
   75|  1.24k|}
_ZN5butil5IOBuf6appendERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE:
  130|     84|inline int IOBuf::append(const std::string& s) {
  131|     84|    return append(s.data(), s.length());
  132|     84|}
_ZN5butil5IOBuf5BlockC2EPcj:
  481|      8|        : nshared(1)
  482|      8|        , flags(0)
  483|      8|        , abi_check(0)
  484|      8|        , size(0)
  485|      8|        , cap(data_size)
  486|      8|        , u({NULL})
  487|      8|        , data(data_in) {
  488|      8|        iobuf::inc_g_nblock();
  489|      8|        iobuf::inc_g_blockmem();
  490|      8|        if (is_samplable()) {
  ------------------
  |  Branch (490:13): [True: 0, False: 8]
  ------------------
  491|      0|            SubmitIOBufSample(this, 1);
  492|      0|        }
  493|      8|    }
_ZN5butil5IOBuf5Block9check_abiEv:
  516|    843|    inline void check_abi() {
  517|       |#ifndef NDEBUG
  518|       |    if (abi_check != 0) {
  519|       |        LOG(FATAL) << "Your program seems to wrongly contain two "
  520|       |            "ABI-incompatible implementations of IOBuf";
  521|       |    }
  522|       |#endif
  523|    843|}
_ZN5butil5IOBuf5Block7inc_refEv:
  525|    418|    void inc_ref() {
  526|    418|        check_abi();
  527|    418|        nshared.fetch_add(1, butil::memory_order_relaxed);
  528|    418|        if (sampled()) {
  ------------------
  |  Branch (528:13): [True: 0, False: 418]
  ------------------
  529|      0|            SubmitIOBufSample(this, 1);
  530|      0|        }
  531|    418|    }
_ZN5butil5IOBuf5Block7dec_refEv:
  533|    425|    void dec_ref() {
  534|    425|        check_abi();
  535|    425|        if (sampled()) {
  ------------------
  |  Branch (535:13): [True: 0, False: 425]
  ------------------
  536|      0|            SubmitIOBufSample(this, -1);
  537|      0|        }
  538|    425|        if (nshared.fetch_sub(1, butil::memory_order_release) == 1) {
  ------------------
  |  Branch (538:13): [True: 7, False: 418]
  ------------------
  539|      7|            butil::atomic_thread_fence(butil::memory_order_acquire);
  540|      7|            if (!is_user_data()) {
  ------------------
  |  Branch (540:17): [True: 7, False: 0]
  ------------------
  541|      7|                iobuf::dec_g_nblock();
  542|      7|                iobuf::dec_g_blockmem();
  543|      7|                this->~Block();
  544|      7|                iobuf::blockmem_deallocate(this);
  545|      7|            } else if (flags & IOBUF_BLOCK_FLAGS_USER_DATA) {
  ------------------
  |  Branch (545:24): [True: 0, False: 0]
  ------------------
  546|      0|                auto ext = get_user_data_extension();
  547|      0|                ext->deleter(data);
  548|      0|                ext->~UserDataExtension();
  549|      0|                this->~Block();
  550|      0|                free(this);
  551|      0|            }
  552|      7|        }
  553|    425|    }
_ZNK5butil5IOBuf5Block4fullEv:
  559|     97|    bool full() const { return size >= cap; }
_ZNK5butil5IOBuf5Block10left_spaceEv:
  560|     91|    size_t left_space() const { return cap - size; }
_ZN5butil5IOBuf5Block12is_samplableEv:
  563|      8|    bool is_samplable() {
  564|      8|        if (IsIOBufProfilerSamplable()) {
  ------------------
  |  Branch (564:13): [True: 0, False: 8]
  ------------------
  565|      0|            flags |= IOBUF_BLOCK_FLAGS_SAMPLED;
  566|      0|            return true;
  567|      0|        }
  568|      8|        return false;
  569|      8|    }
_ZNK5butil5IOBuf5Block7sampledEv:
  571|    843|    bool sampled() const {
  572|    843|        return flags & IOBUF_BLOCK_FLAGS_SAMPLED;
  573|    843|    }
_ZNK5butil5IOBuf5Block12is_user_dataEv:
  575|      7|    bool is_user_data() const {
  576|      7|        return flags & IOBUF_BLOCK_FLAGS_USER_DATA;
  577|      7|    }
_ZN5butil5IOBuf9cut_untilEPS0_PKc:
  109|    328|inline int IOBuf::cut_until(IOBuf* out, char const* delim) {
  110|    328|    if (*delim) {
  ------------------
  |  Branch (110:9): [True: 328, False: 0]
  ------------------
  111|    328|        if (!*(delim+1)) {
  ------------------
  |  Branch (111:13): [True: 0, False: 328]
  ------------------
  112|      0|            return _cut_by_char(out, *delim);
  113|    328|        } else {
  114|    328|            return _cut_by_delim(out, delim, strlen(delim));
  115|    328|        }
  116|    328|    }
  117|      0|    return -1;
  118|    328|}
_ZNK5butil5IOBuf5emptyEv:
  140|  3.99k|inline bool IOBuf::empty() const {
  141|  3.99k|    return _small() ? !_sv.refs[0].block : !_bv.nbytes;
  ------------------
  |  Branch (141:12): [True: 3.99k, False: 0]
  ------------------
  142|  3.99k|}
_ZNK5butil5IOBuf6lengthEv:
  144|  9.15k|inline size_t IOBuf::length() const {
  145|  9.15k|    return _small() ?
  ------------------
  |  Branch (145:12): [True: 9.15k, False: 0]
  ------------------
  146|  9.15k|        (_sv.refs[0].length + _sv.refs[1].length) : _bv.nbytes;
  147|  9.15k|}
_ZNK5butil5IOBuf6_smallEv:
  149|  38.3k|inline bool IOBuf::_small() const {
  150|  38.3k|    return _bv.magic >= 0;
  151|  38.3k|}
_ZNK5butil5IOBuf8_ref_numEv:
  153|  4.29k|inline size_t IOBuf::_ref_num() const {
  154|  4.29k|    return _small()
  ------------------
  |  Branch (154:12): [True: 4.29k, False: 0]
  ------------------
  155|  4.29k|        ? (!!_sv.refs[0].block + !!_sv.refs[1].block) : _bv.nref;
  156|  4.29k|}
_ZN5butil5IOBuf10_front_refEv:
  158|  5.75k|inline IOBuf::BlockRef& IOBuf::_front_ref() {
  159|  5.75k|    return _small() ? _sv.refs[0] : _bv.refs[_bv.start];
  ------------------
  |  Branch (159:12): [True: 5.75k, False: 0]
  ------------------
  160|  5.75k|}
_ZNK5butil5IOBuf10_front_refEv:
  162|  3.96k|inline const IOBuf::BlockRef& IOBuf::_front_ref() const {
  163|  3.96k|    return _small() ? _sv.refs[0] : _bv.refs[_bv.start];
  ------------------
  |  Branch (163:12): [True: 3.96k, False: 0]
  ------------------
  164|  3.96k|}
_ZN5butil5IOBuf7_ref_atEm:
  174|    330|inline IOBuf::BlockRef& IOBuf::_ref_at(size_t i) {
  175|    330|    return _small() ? _sv.refs[i] : _bv.ref_at(i);
  ------------------
  |  Branch (175:12): [True: 330, False: 0]
  ------------------
  176|    330|}
_ZNK5butil5IOBuf7_ref_atEm:
  178|  4.28k|inline const IOBuf::BlockRef& IOBuf::_ref_at(size_t i) const {
  179|  4.28k|    return _small() ? _sv.refs[i] : _bv.ref_at(i);
  ------------------
  |  Branch (179:12): [True: 4.28k, False: 0]
  ------------------
  180|  4.28k|}
_ZN5butil5IOBuf14_push_back_refERKNS0_8BlockRefE:
  199|    418|inline void IOBuf::_push_back_ref(const BlockRef& r) {
  200|    418|    if (_small()) {
  ------------------
  |  Branch (200:9): [True: 418, False: 0]
  ------------------
  201|    418|        return _push_or_move_back_ref_to_smallview<false>(r);
  202|    418|    } else {
  203|      0|        return _push_or_move_back_ref_to_bigview<false>(r);
  204|      0|    }
  205|    418|}
_ZN5butil5IOBuf14_move_back_refERKNS0_8BlockRefE:
  207|      1|inline void IOBuf::_move_back_ref(const BlockRef& r) {
  208|      1|    if (_small()) {
  ------------------
  |  Branch (208:9): [True: 1, False: 0]
  ------------------
  209|      1|        return _push_or_move_back_ref_to_smallview<true>(r);
  210|      1|    } else {
  211|      0|        return _push_or_move_back_ref_to_bigview<true>(r);
  212|      0|    }
  213|      1|}
_ZN5butil18IOBufBytesIterator14try_next_blockEv:
  383|     43|inline void IOBufBytesIterator::try_next_block() {
  384|     43|    if (_bytes_left == 0) {
  ------------------
  |  Branch (384:9): [True: 4, False: 39]
  ------------------
  385|      4|        return;
  386|      4|    }
  387|     39|    butil::StringPiece s = _buf->backing_block(_block_count++);
  388|     39|    _block_begin = s.data();
  389|     39|    _block_end = s.data() + std::min(s.size(), (size_t)_bytes_left);
  390|     39|}
_ZN5butil18IOBufBytesIteratorppEv:
  392|  15.2k|inline void IOBufBytesIterator::operator++() {
  393|  15.2k|    ++_block_begin;
  394|  15.2k|    --_bytes_left;
  395|  15.2k|    if (_block_begin == _block_end) {
  ------------------
  |  Branch (395:9): [True: 4, False: 15.2k]
  ------------------
  396|      4|        try_next_block();
  397|      4|    }
  398|  15.2k|}
_ZN5butil5iobuf12create_blockEm:
  629|      8|inline IOBuf::Block* create_block(const size_t block_size) {
  630|      8|    if (block_size > 0xFFFFFFFFULL) {
  ------------------
  |  Branch (630:9): [True: 0, False: 8]
  ------------------
  631|      0|        LOG(FATAL) << "block_size=" << block_size << " is too large";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  632|      0|        return NULL;
  633|      0|    }
  634|      8|    char* mem = (char*)iobuf::blockmem_allocate(block_size);
  635|      8|    if (mem == NULL) {
  ------------------
  |  Branch (635:9): [True: 0, False: 8]
  ------------------
  636|      0|        return NULL;
  637|      0|    }
  638|      8|    return new (mem) IOBuf::Block(mem + sizeof(IOBuf::Block),
  639|      8|                                  block_size - sizeof(IOBuf::Block));
  640|      8|}
_ZN5butil5iobuf12create_blockEv:
  642|      8|inline IOBuf::Block* create_block() {
  643|      8|    return create_block(butil::GetDefaultBlockSize());
  644|      8|}
_ZN5butil18IOBufBytesIteratorC2ERKNS_5IOBufE:
  357|     39|    : _block_begin(NULL), _block_end(NULL), _block_count(0), 
  358|     39|      _bytes_left(buf.length()), _buf(&buf) {
  359|     39|    try_next_block();
  360|     39|}

_ZN5butil22IsIOBufProfilerEnabledEv:
   70|      8|bool IsIOBufProfilerEnabled() {
   71|      8|    pthread_once(&g_iobuf_profiler_info_once, InitGlobalIOBufProfilerInfo);
   72|      8|    return g_iobuf_profiler_enabled;
   73|      8|}
_ZN5butil24IsIOBufProfilerSamplableEv:
   75|      8|bool IsIOBufProfilerSamplable() {
   76|      8|    if (!IsIOBufProfilerEnabled()) {
  ------------------
  |  Branch (76:9): [True: 8, False: 0]
  ------------------
   77|      8|        return false;
   78|      8|    }
   79|      0|    if (g_iobuf_profiler_sample_rate == 100) {
  ------------------
  |  Branch (79:9): [True: 0, False: 0]
  ------------------
   80|      0|        return true;
   81|      0|    }
   82|      0|    return fast_rand_less_than(100) + 1 <= g_iobuf_profiler_sample_rate;
   83|      0|}
iobuf_profiler.cpp:_ZN5butilL27InitGlobalIOBufProfilerInfoEv:
   47|      1|static void InitGlobalIOBufProfilerInfo() {
   48|      1|    const char* enabled = getenv("ENABLE_IOBUF_PROFILER");
   49|      1|    g_iobuf_profiler_enabled = enabled && strcmp("1", enabled) == 0 && ::GetStackTrace != NULL;
  ------------------
  |  Branch (49:32): [True: 0, False: 1]
  |  Branch (49:43): [True: 0, False: 0]
  |  Branch (49:72): [True: 0, False: 0]
  ------------------
   50|      1|    if (!g_iobuf_profiler_enabled) {
  ------------------
  |  Branch (50:9): [True: 1, False: 0]
  ------------------
   51|      1|        return;
   52|      1|    }
   53|       |
   54|      0|    char* rate = getenv("IOBUF_PROFILER_SAMPLE_RATE");
   55|      0|    if (rate) {
  ------------------
  |  Branch (55:9): [True: 0, False: 0]
  ------------------
   56|      0|        int tmp = 0;
   57|      0|        if (butil::StringToInt(rate, &tmp)) {
  ------------------
  |  Branch (57:13): [True: 0, False: 0]
  ------------------
   58|      0|            if (tmp > 0 && tmp <= 100) {
  ------------------
  |  Branch (58:17): [True: 0, False: 0]
  |  Branch (58:28): [True: 0, False: 0]
  ------------------
   59|      0|                g_iobuf_profiler_sample_rate = tmp;
   60|      0|            } else {
   61|      0|                LOG(ERROR) << "IOBUF_PROFILER_SAMPLE_RATE should be in (0, 100], but get " << rate;
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   62|      0|            }
   63|      0|        } else {
   64|      0|            LOG(ERROR) << "IOBUF_PROFILER_SAMPLE_RATE should be a number, but get " << rate;
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   65|      0|        }
   66|      0|    }
   67|      0|    LOG(INFO) << "g_iobuf_profiler_sample_rate=" << g_iobuf_profiler_sample_rate;
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   68|      0|}

_ZN7logging12GetTimestampEv:
  463|     40|TimeVal GetTimestamp() {
  464|     40|#if defined(OS_LINUX) || defined(OS_MACOSX)
  465|     40|    timeval tv;
  466|     40|    gettimeofday(&tv, NULL);
  467|     40|    return tv;
  468|       |#else
  469|       |    return { time(NULL) };
  470|       |#endif
  471|     40|}
_ZN7logging15LogInfoToLogStrEiN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEiS8_S8_:
  566|     40|                            butil::StringPiece content) {
  567|       |    // There's a copy here to concatenate prefix and content. Since
  568|       |    // DefaultLogSink is hardly used right now, the copy is irrelevant.
  569|       |    // A LogSink focused on performance should also be able to handle
  570|       |    // non-continuous inputs which is a must to maximize performance.
  571|     40|    std::ostringstream os;
  572|     40|    PrintLog(os, severity, file.data(), line, func.data(), content);
  573|     40|    os << '\n';
  574|     40|    return os.str();
  575|     40|}
_ZN7logging14GetMinLogLevelEv:
  823|     40|int GetMinLogLevel() {
  824|     40|    return FLAGS_minloglevel;
  825|     40|}
_ZN7logging14PrintLogPrefixERSoiN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEiS9_7timeval:
  851|     40|                    butil::StringPiece func, TimeVal tv) {
  852|     40|    PrintLogSeverity(os, severity);
  853|     40|    time_t t = tv.tv_sec;
  854|     40|    struct tm local_tm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL};
  855|       |#if _MSC_VER >= 1400
  856|       |    localtime_s(&local_tm, &t);
  857|       |#else
  858|     40|    localtime_r(&t, &local_tm);
  859|     40|#endif
  860|     40|    const char prev_fill = os.fill('0');
  861|     40|    if (FLAGS_log_year) {
  ------------------
  |  Branch (861:9): [True: 0, False: 40]
  ------------------
  862|      0|        os << std::setw(4) << local_tm.tm_year + 1900;
  863|      0|    }
  864|     40|    os << std::setw(2) << local_tm.tm_mon + 1
  865|     40|       << std::setw(2) << local_tm.tm_mday << ' '
  866|     40|       << std::setw(2) << local_tm.tm_hour << ':'
  867|     40|       << std::setw(2) << local_tm.tm_min << ':'
  868|     40|       << std::setw(2) << local_tm.tm_sec;
  869|     40|#if defined(OS_LINUX) || defined(OS_MACOSX)
  870|     40|    os << '.' << std::setw(6) << tv.tv_usec;
  871|     40|#endif
  872|     40|    if (FLAGS_log_pid) {
  ------------------
  |  Branch (872:9): [True: 0, False: 40]
  ------------------
  873|      0|        int32_t pid = BAIDU_GET_VOLATILE_THREAD_LOCAL(tls_log_pid);
  ------------------
  |  |   69|      0|#define BAIDU_GET_VOLATILE_THREAD_LOCAL(var_name) get_##var_name()
  ------------------
  874|      0|        if (pid == 0) {
  ------------------
  |  Branch (874:13): [True: 0, False: 0]
  ------------------
  875|      0|            pid = CurrentProcessId();
  876|      0|            BAIDU_SET_VOLATILE_THREAD_LOCAL(tls_log_pid, pid);
  ------------------
  |  |   71|      0|#define BAIDU_SET_VOLATILE_THREAD_LOCAL(var_name, value) set_##var_name(value)
  ------------------
  877|      0|        }
  878|      0|        os << ' ' << std::setfill(' ') << std::setw(5) << pid;
  879|      0|    }
  880|     40|    butil::PlatformThreadId tid = BAIDU_GET_VOLATILE_THREAD_LOCAL(tls_log_tid);
  ------------------
  |  |   69|     40|#define BAIDU_GET_VOLATILE_THREAD_LOCAL(var_name) get_##var_name()
  ------------------
  881|     40|    if (tid == 0) {
  ------------------
  |  Branch (881:9): [True: 1, False: 39]
  ------------------
  882|      1|        tid = butil::PlatformThread::CurrentId();
  883|      1|        BAIDU_SET_VOLATILE_THREAD_LOCAL(tls_log_tid, tid);
  ------------------
  |  |   71|      1|#define BAIDU_SET_VOLATILE_THREAD_LOCAL(var_name, value) set_##var_name(value)
  ------------------
  884|      1|    }
  885|     40|    os << ' ' << std::setfill(' ') << std::setw(5) << tid << std::setfill('0');
  886|     40|    if (FLAGS_log_bid && bthread_self) {
  ------------------
  |  Branch (886:9): [True: 40, False: 0]
  |  Branch (886:26): [True: 40, False: 0]
  ------------------
  887|     40|        os << ' ' << std::setfill(' ') << std::setw(5) << bthread_self();
  888|     40|    }
  889|     40|    if (FLAGS_log_hostname) {
  ------------------
  |  Branch (889:9): [True: 0, False: 40]
  ------------------
  890|      0|        butil::StringPiece hostname(butil::my_hostname());
  891|      0|        if (hostname.ends_with(".baidu.com")) { // make it shorter
  ------------------
  |  Branch (891:13): [True: 0, False: 0]
  ------------------
  892|      0|            hostname.remove_suffix(10);
  893|      0|        }
  894|      0|        os << ' ' << hostname;
  895|      0|    }
  896|     40|    os << ' ' << file << ':' << line;
  897|     40|    if (!func.empty()) {
  ------------------
  |  Branch (897:9): [True: 40, False: 0]
  ------------------
  898|     40|        os << " " << func;
  899|     40|    }
  900|     40|    os << "] ";
  901|       |
  902|     40|    os.fill(prev_fill);
  903|     40|}
_ZN7logging8PrintLogERSoiPKciS2_RKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE:
  990|     40|              const char* func, const butil::StringPiece& content) {
  991|     40|    if (!FLAGS_log_as_json) {
  ------------------
  |  Branch (991:9): [True: 40, False: 0]
  ------------------
  992|     40|        PrintLogPrefix(os, severity, file, line, func, GetTimestamp());
  993|     40|        OutputLog(os, content);
  994|     40|    } else {
  995|      0|        os << '{';
  996|      0|        PrintLogPrefixAsJSON(os, severity, file, func, line, GetTimestamp());
  997|      0|        bool pair_quote = false;
  998|      0|        if (content.empty() || content[0] != '"') {
  ------------------
  |  Branch (998:13): [True: 0, False: 0]
  |  Branch (998:32): [True: 0, False: 0]
  ------------------
  999|       |            // not a json, add a 'M' field
 1000|      0|            os << ",\"M\":\"";
 1001|      0|            pair_quote = true;
 1002|      0|        } else {
 1003|      0|            os << ',';
 1004|      0|        }
 1005|      0|        OutputLog(os, content);
 1006|      0|        if (pair_quote) {
  ------------------
  |  Branch (1006:13): [True: 0, False: 0]
  ------------------
 1007|      0|            os << '"';
 1008|      0|        } else if (!content.empty() && content[content.size() -1 ] != '"') {
  ------------------
  |  Branch (1008:20): [True: 0, False: 0]
  |  Branch (1008:40): [True: 0, False: 0]
  ------------------
 1009|       |            // Controller may write `"M":"...` which misses the last quote
 1010|      0|            os << '"';
 1011|      0|        }
 1012|      0|        os << '}';
 1013|      0|    }
 1014|     40|}
_ZN7logging21DoublyBufferedLogSink11GetInstanceEv:
 1032|     40|DoublyBufferedLogSink* DoublyBufferedLogSink::GetInstance() {
 1033|     40|    return Singleton<DoublyBufferedLogSink,
 1034|     40|                     LeakySingletonTraits<DoublyBufferedLogSink> >::get();
 1035|     40|}
_ZN7logging18CharArrayStreamBuf8overflowEi:
 1145|      2|int CharArrayStreamBuf::overflow(int ch) {
 1146|      2|    if (ch == std::streambuf::traits_type::eof()) {
  ------------------
  |  Branch (1146:9): [True: 0, False: 2]
  ------------------
 1147|      0|        return ch;
 1148|      0|    }
 1149|      2|    size_t new_size = std::max(_size * 3 / 2, (size_t)64);
 1150|      2|    char* new_data = (char*)malloc(new_size);
 1151|      2|    if (BAIDU_UNLIKELY(new_data == NULL)) {
  ------------------
  |  |  272|      2|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 2]
  |  |  ------------------
  ------------------
 1152|      0|        setp(NULL, NULL);
 1153|      0|        return std::streambuf::traits_type::eof();
 1154|      0|    }
 1155|      2|    memcpy(new_data, _data, _size);
 1156|      2|    free(_data);
 1157|      2|    _data = new_data;
 1158|      2|    const size_t old_size = _size;
 1159|      2|    _size = new_size;
 1160|      2|    setp(_data, _data + new_size);
 1161|      2|    pbump(old_size);
 1162|       |    // if size == 1, this function will call overflow again.
 1163|      2|    return sputc(ch);
 1164|      2|}
_ZN7logging18CharArrayStreamBuf5resetEv:
 1171|     40|void CharArrayStreamBuf::reset() {
 1172|     40|    setp(_data, _data + _size);
 1173|     40|}
_ZN7logging9LogStream11SetPositionEPKciS2_i:
 1185|     40|                                  LogSeverity severity) {
 1186|     40|    _file = file;
 1187|     40|    _line = line;
 1188|     40|    _func = func;
 1189|     40|    _severity = severity;
 1190|     40|    return *this;
 1191|     40|}
_ZN7logging9LogStream17FlushWithoutResetEv:
 1359|     40|void LogStream::FlushWithoutReset() {
 1360|     40|    if (empty()) {
  ------------------
  |  Branch (1360:9): [True: 0, False: 40]
  ------------------
 1361|       |        // Nothing to flush.
 1362|      0|        return;
 1363|      0|    }
 1364|       |
 1365|     40|#if !defined(OS_NACL) && !defined(__UCLIBC__)
 1366|     40|    if ((FLAGS_print_stack_on_check && _is_check && _severity == BLOG_FATAL) || _backtrace) {
  ------------------
  |  Branch (1366:10): [True: 40, False: 0]
  |  Branch (1366:40): [True: 0, False: 40]
  |  Branch (1366:53): [True: 0, False: 0]
  |  Branch (1366:81): [True: 0, False: 40]
  ------------------
 1367|       |        // Include a stack trace on a fatal.
 1368|      0|        butil::debug::StackTrace trace;
 1369|      0|        size_t count = 0;
 1370|      0|        const void* const* addrs = trace.Addresses(&count);
 1371|       |
 1372|      0|        *this << std::endl;  // Newline to separate from log message.
 1373|      0|        if (count > 3) {
  ------------------
  |  Branch (1373:13): [True: 0, False: 0]
  ------------------
 1374|       |            // Remove top 3 frames which are useless to users.
 1375|       |            // #2 may be ~LogStream
 1376|       |            //   #0 0x00000059ccae butil::debug::StackTrace::StackTrace()
 1377|       |            //   #1 0x0000005947c7 logging::LogStream::FlushWithoutReset()
 1378|       |            //   #2 0x000000594b88 logging::LogMessage::~LogMessage()
 1379|      0|            butil::debug::StackTrace trace_stripped(addrs + 3, count - 3);
 1380|      0|            trace_stripped.OutputToStream(this);
 1381|      0|        } else {
 1382|      0|            trace.OutputToStream(this);
 1383|      0|        }
 1384|      0|    }
 1385|     40|#endif
 1386|       |    // End the data with zero because sink is likely to assume this.
 1387|     40|    *this << std::ends;
 1388|       |    // Move back one step because we don't want to count the zero.
 1389|     40|    pbump(-1); 
 1390|       |
 1391|       |    // Give any logsink first dibs on the message.
 1392|       |#ifdef BAIDU_INTERNAL
 1393|       |    // If the logsink fails and it's not comlog, try comlog. stderr on last try.
 1394|       |    bool tried_comlog = false;
 1395|       |#endif
 1396|     40|    bool tried_default = false;
 1397|     40|    {
 1398|     40|        DoublyBufferedLogSink::ScopedPtr ptr;
 1399|     40|        if (DoublyBufferedLogSink::GetInstance()->Read(&ptr) == 0 &&
  ------------------
  |  Branch (1399:13): [True: 40, False: 0]
  ------------------
 1400|     40|            (*ptr) != NULL) {
  ------------------
  |  Branch (1400:13): [True: 0, False: 40]
  ------------------
 1401|      0|            bool result = (*ptr)->OnLogMessage(
 1402|      0|                _severity, _file, _line, _func, content());
 1403|      0|            if (result) {
  ------------------
  |  Branch (1403:17): [True: 0, False: 0]
  ------------------
 1404|      0|                goto FINISH_LOGGING;
 1405|      0|            }
 1406|       |#ifdef BAIDU_INTERNAL
 1407|       |            tried_comlog = (*ptr == ComlogSink::GetInstance());
 1408|       |#endif
 1409|      0|            tried_default = (*ptr == DefaultLogSink::GetInstance());
 1410|      0|        }
 1411|     40|    }
 1412|       |
 1413|       |#ifdef BAIDU_INTERNAL
 1414|       |    if (!tried_comlog) {
 1415|       |        if (ComlogSink::GetInstance()->OnLogMessage(
 1416|       |                _severity, _file, _line, _func, content())) {
 1417|       |            goto FINISH_LOGGING;
 1418|       |        }
 1419|       |    }
 1420|       |#endif
 1421|     40|    if (!tried_default) {
  ------------------
  |  Branch (1421:9): [True: 40, False: 0]
  ------------------
 1422|     40|        DefaultLogSink::GetInstance()->OnLogMessage(
 1423|     40|            _severity, _file, _line, _func, content());
 1424|     40|    }
 1425|       |
 1426|     40|FINISH_LOGGING:
 1427|     40|    if (FLAGS_crash_on_fatal_log && _severity == BLOG_FATAL) {
  ------------------
  |  Branch (1427:9): [True: 0, False: 40]
  |  Branch (1427:37): [True: 0, False: 0]
  ------------------
 1428|       |        // Ensure the first characters of the string are on the stack so they
 1429|       |        // are contained in minidumps for diagnostic purposes.
 1430|      0|        butil::StringPiece str = content();
 1431|      0|        char str_stack[1024];
 1432|      0|        str.copy(str_stack, arraysize(str_stack));
  ------------------
  |  |  122|      0|#define arraysize(array) (sizeof(::butil::ArraySizeHelper(array)))
  ------------------
 1433|      0|        butil::debug::Alias(str_stack);
 1434|       |
 1435|      0|        if (log_assert_handler) {
  ------------------
  |  Branch (1435:13): [True: 0, False: 0]
  ------------------
 1436|       |            // Make a copy of the string for the handler out of paranoia.
 1437|      0|            log_assert_handler(str.as_string());
 1438|      0|        } else {
 1439|       |            // Don't use the string with the newline, get a fresh version to send to
 1440|       |            // the debug message process. We also don't display assertions to the
 1441|       |            // user in release mode. The enduser can't do anything with this
 1442|       |            // information, and displaying message boxes when the application is
 1443|       |            // hosed can cause additional problems.
 1444|       |#ifndef NDEBUG
 1445|       |            DisplayDebugMessageInDialog(str.as_string());
 1446|       |#endif
 1447|       |            // Crash the process to generate a dump.
 1448|      0|            butil::debug::BreakDebugger();
 1449|      0|        }
 1450|      0|    }
 1451|     40|}
_ZN7logging10LogMessageC2EPKciS2_i:
 1457|     40|                       const char* func, LogSeverity severity) {
 1458|     40|    _stream = CreateLogStream(file, line, func, severity);
 1459|     40|}
_ZN7logging10LogMessageD2Ev:
 1482|     40|LogMessage::~LogMessage() {
 1483|     40|    DestroyLogStream(_stream);
 1484|     40|}
_ZN7logging22GetLastSystemErrorCodeEv:
 1493|     40|SystemErrorCode GetLastSystemErrorCode() {
 1494|       |#if defined(OS_WIN)
 1495|       |    return ::GetLastError();
 1496|       |#elif defined(OS_POSIX)
 1497|     40|    return errno;
 1498|       |#else
 1499|       |#error Not implemented
 1500|       |#endif
 1501|     40|}
_ZN7logging22SetLastSystemErrorCodeEi:
 1503|     40|void SetLastSystemErrorCode(SystemErrorCode err) {
 1504|       |#if defined(OS_WIN)
 1505|       |    ::SetLastError(err);
 1506|       |#elif defined(OS_POSIX)
 1507|     40|    errno = err;
 1508|       |#else
 1509|       |#error Not implemented
 1510|       |#endif
 1511|     40|}
logging.cc:_ZN7loggingL16PrintLogSeverityERSoi:
  838|     40|static void PrintLogSeverity(std::ostream& os, int severity) {
  839|     40|    if (severity < 0) {
  ------------------
  |  Branch (839:9): [True: 0, False: 40]
  ------------------
  840|       |        // Add extra space to separate from following datetime.
  841|      0|        os << 'V' << -severity << ' ';
  842|     40|    } else if (severity < LOG_NUM_SEVERITIES) {
  ------------------
  |  Branch (842:16): [True: 40, False: 0]
  ------------------
  843|     40|        os << log_severity_names[severity][0];
  844|     40|    } else {
  845|      0|        os << 'U';
  846|      0|    }
  847|     40|}
_ZN7logging9OutputLogERSoRKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE:
  981|     40|inline void OutputLog(std::ostream& os, const butil::StringPiece& s) {
  982|     40|    if (FLAGS_escape_log) {
  ------------------
  |  Branch (982:9): [True: 0, False: 40]
  ------------------
  983|      0|        EscapeJson(os, s);
  984|     40|    } else {
  985|     40|        os.write(s.data(), s.length());
  986|     40|    }
  987|     40|}
_ZN7logging14DefaultLogSink11GetInstanceEv:
 1303|     40|    static DefaultLogSink* GetInstance() {
 1304|     40|        return Singleton<DefaultLogSink,
 1305|     40|                         LeakySingletonTraits<DefaultLogSink> >::get();
 1306|     40|    }
_ZN7logging14DefaultLogSinkC2Ev:
 1354|      1|    DefaultLogSink() = default;
_ZN7logging14DefaultLogSink12OnLogMessageEiPKciS2_RKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE:
 1315|     40|                      const butil::StringPiece& content) override {
 1316|     40|        std::string log;
 1317|     40|        if ((logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0 ||
  ------------------
  |  Branch (1317:13): [True: 40, False: 0]
  ------------------
 1318|     40|            severity >= kAlwaysPrintErrorLevel) {
  ------------------
  |  Branch (1318:13): [True: 0, False: 0]
  ------------------
 1319|     40|            log = LogInfoToLogStr(severity, file, line, func, content);
 1320|       |            // When we're only outputting to a log file, above a certain log level, we
 1321|       |            // should still output to stderr so that we can better detect and diagnose
 1322|       |            // problems with unit tests, especially on the buildbots.
 1323|     40|            fwrite(log.data(), log.size(), 1, stderr);
 1324|     40|            fflush(stderr);
 1325|     40|        }
 1326|       |        // write to log file
 1327|     40|        if ((logging_destination & LOG_TO_FILE) != 0) {
  ------------------
  |  Branch (1327:13): [True: 0, False: 40]
  ------------------
 1328|      0|            if ((FLAGS_crash_on_fatal_log && severity == BLOG_FATAL) ||
  ------------------
  |  Branch (1328:18): [True: 0, False: 0]
  |  Branch (1328:46): [True: 0, False: 0]
  ------------------
 1329|      0|                !FLAGS_async_log) {
  ------------------
  |  Branch (1329:17): [True: 0, False: 0]
  ------------------
 1330|      0|                if (log.empty()) {
  ------------------
  |  Branch (1330:21): [True: 0, False: 0]
  ------------------
 1331|      0|                    log = LogInfoToLogStr(severity, file, line, func, content);
 1332|      0|                }
 1333|      0|                Log2File(log);
 1334|      0|            } else {
 1335|      0|                LogInfo info;
 1336|      0|                if (log.empty()) {
  ------------------
  |  Branch (1336:21): [True: 0, False: 0]
  ------------------
 1337|      0|                    info.severity = severity;
 1338|      0|                    info.timestamp = GetTimestamp();
 1339|      0|                    info.file = file;
 1340|      0|                    info.func = func;
 1341|      0|                    info.line = line;
 1342|      0|                    info.content = content.as_string();
 1343|      0|                    info.raw = true;
 1344|      0|                } else {
 1345|      0|                    info.content = std::move(log);
 1346|      0|                    info.raw = false;
 1347|      0|                }
 1348|      0|                AsyncLogger::GetInstance()->Log(std::move(info));
 1349|      0|            }
 1350|      0|        }
 1351|     40|        return true;
 1352|     40|    }
_ZN7logging15CreateLogStreamEPKciS1_i:
 1249|     40|                                  LogSeverity severity) {
 1250|     40|    int slot = 0;
 1251|     40|    if (severity >= 0) {
  ------------------
  |  Branch (1251:9): [True: 40, False: 0]
  ------------------
 1252|     40|        DCHECK_LT(severity, LOG_NUM_SEVERITIES);
  ------------------
  |  |  887|     40|#define DCHECK_LT(val1, val2) BAIDU_DCHECK_OP(LT, < , val1, val2)
  |  |  ------------------
  |  |  |  |  856|     40|    if (DCHECK_IS_ON())                                                   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  700|     40|#define DCHECK_IS_ON() 0
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (700:24): [Folded, False: 40]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  857|     40|        if (std::string* _result =                                      \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (857:26): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  858|      0|            ::logging::Check##name##Impl((val1), (val2),                \
  |  |  |  |  859|      0|                                         #val1 " " #op " " #val2))      \
  |  |  |  |  860|      0|            ::logging::LogMessage(                                      \
  |  |  |  |  861|      0|                __FILE__, __LINE__, __func__,                           \
  |  |  |  |  862|      0|                ::logging::BLOG_DCHECK,                                 \
  |  |  |  |  863|      0|                _result).stream()
  |  |  ------------------
  ------------------
 1253|     40|        slot = severity + 1;
 1254|     40|    } // else vlog
 1255|     40|    LogStream** stream_array = get_or_new_tls_stream_array();
 1256|     40|    LogStream* stream = stream_array[slot];
 1257|     40|    if (stream == NULL) {
  ------------------
  |  Branch (1257:9): [True: 1, False: 39]
  ------------------
 1258|      1|        stream = new LogStream;
 1259|      1|        stream_array[slot] = stream;
 1260|      1|    }
 1261|     40|    if (stream->empty()) {
  ------------------
  |  Branch (1261:9): [True: 40, False: 0]
  ------------------
 1262|     40|        stream->SetPosition(file, line, func, severity);
 1263|     40|    }
 1264|     40|    return stream;
 1265|     40|}
logging.cc:_ZN7loggingL27get_or_new_tls_stream_arrayEv:
 1232|     40|static LogStream** get_or_new_tls_stream_array() {
 1233|     40|    LogStream** a = get_tls_stream_array();
 1234|     40|    if (a == NULL) {
  ------------------
  |  Branch (1234:9): [True: 1, False: 39]
  ------------------
 1235|      1|        a = new LogStream*[LOG_NUM_SEVERITIES + 1];
 1236|      1|        memset(a, 0, sizeof(LogStream*) * (LOG_NUM_SEVERITIES + 1));
 1237|      1|        if (is_bthread_linked()) {
  ------------------
  |  Branch (1237:13): [True: 1, False: 0]
  ------------------
 1238|      1|            bthread_setspecific(stream_bkey, a);
 1239|      1|        } else {
 1240|      0|            pthread_setspecific(stream_pkey, a);
 1241|      0|        }
 1242|      1|    }
 1243|     40|    return a;
 1244|     40|}
logging.cc:_ZN7loggingL20get_tls_stream_arrayEv:
 1223|     40|static LogStream** get_tls_stream_array() {
 1224|     40|    pthread_once(&create_stream_key_once, create_stream_key_or_die);
 1225|     40|    if (is_bthread_linked()) {
  ------------------
  |  Branch (1225:9): [True: 40, False: 0]
  ------------------
 1226|     40|        return (LogStream**)bthread_getspecific(stream_bkey);
 1227|     40|    } else {
 1228|      0|        return (LogStream**)pthread_getspecific(stream_pkey);
 1229|      0|    }
 1230|     40|}
logging.cc:_ZN7loggingL24create_stream_key_or_dieEv:
 1208|      1|static void create_stream_key_or_die() {
 1209|      1|    if (is_bthread_linked()) {
  ------------------
  |  Branch (1209:9): [True: 1, False: 0]
  ------------------
 1210|      1|        int rc = bthread_key_create(&stream_bkey, destroy_tls_streams);
 1211|      1|        if (rc) {
  ------------------
  |  Branch (1211:13): [True: 0, False: 1]
  ------------------
 1212|      0|            fprintf(stderr, "Fail to bthread_key_create");
 1213|      0|            exit(1);
 1214|      0|        }
 1215|      1|    } else {
 1216|      0|        int rc = pthread_key_create(&stream_pkey, destroy_tls_streams);
 1217|      0|        if (rc) {
  ------------------
  |  Branch (1217:13): [True: 0, False: 0]
  ------------------
 1218|       |            fprintf(stderr, "Fail to pthread_key_create");
 1219|      0|            exit(1);
 1220|      0|        }
 1221|      0|    }
 1222|      1|}
_ZN7logging17is_bthread_linkedEv:
 1197|     42|inline bool is_bthread_linked() { return bthread_key_create != NULL; }
_ZN7logging16DestroyLogStreamEPNS_9LogStreamE:
 1273|     40|inline void DestroyLogStream(LogStream* stream) {
 1274|     40|    if (stream != NULL) {
  ------------------
  |  Branch (1274:9): [True: 40, False: 0]
  ------------------
 1275|     40|        stream->Flush();
 1276|     40|    }
 1277|     40|}
_ZN7logging21DoublyBufferedLogSinkC2Ev:
 1025|      1|    DoublyBufferedLogSink() {}

_ZN7logging7LogSinkC2Ev:
  322|      1|    LogSink() {}
_ZN7logging18CharArrayStreamBufC2Ev:
  908|      1|    explicit CharArrayStreamBuf() : _data(NULL), _size(0) {}
_ZN7logging9LogStreamlsEPFRSoS1_E:
  939|     40|    inline LogStream& operator<<(std::ostream& (*m)(std::ostream&)) {
  940|     40|        m(*(std::ostream*)this);
  941|     40|        return *this;
  942|     40|    }
_ZNK7logging9LogStream5emptyEv:
  971|     80|    bool empty() const { return pbase() == pptr(); }
_ZNK7logging9LogStream7contentB5cxx11Ev:
  974|     40|    { return butil::StringPiece(pbase(), pptr() - pbase()); }
_ZN7logging9LogStream5FlushEv:
  990|     40|    inline void Flush() {
  991|     40|        const bool res = _noflush;
  992|     40|        _noflush = false;
  993|     40|        if (!res) {
  ------------------
  |  Branch (993:13): [True: 40, False: 0]
  ------------------
  994|       |            // Save and restore thread-local error code after Flush().
  995|     40|            const SystemErrorCode err = GetLastSystemErrorCode();
  996|     40|            FlushWithoutReset();
  997|     40|            reset();
  998|     40|            clear();
  999|     40|            SetLastSystemErrorCode(err);
 1000|     40|            _is_check = false;
 1001|     40|            _backtrace = false;
 1002|     40|        }
 1003|     40|    }
_ZN7logging10LogMessage6streamEv:
 1044|     40|    LogStream& stream() { return *_stream; }
_ZN7logging17LogMessageVoidifyC2Ev:
 1065|     40|    LogMessageVoidify() { }
_ZN7logging17LogMessageVoidifyanERSo:
 1068|     40|    void operator&(std::ostream&) { }
_ZN7logging9LogStreamlsIA12_cEERS0_RKT_:
  944|      3|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      3|        *(std::ostream*)this << t;
  946|      3|        return *this;
  947|      3|    }
_ZN7logging9LogStreamlsIA32_cEERS0_RKT_:
  944|      5|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      5|        *(std::ostream*)this << t;
  946|      5|        return *this;
  947|      5|    }
_ZN7logging9LogStreamlsIA36_cEERS0_RKT_:
  944|      1|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      1|        *(std::ostream*)this << t;
  946|      1|        return *this;
  947|      1|    }
_ZN7logging9LogStreamlsIA51_cEERS0_RKT_:
  944|      2|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      2|        *(std::ostream*)this << t;
  946|      2|        return *this;
  947|      2|    }
_ZN7logging9LogStreamlsIPcEERS0_RKT_:
  944|      5|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      5|        *(std::ostream*)this << t;
  946|      5|        return *this;
  947|      5|    }
_ZN7logging9LogStreamlsIlEERS0_RKT_:
  944|      4|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      4|        *(std::ostream*)this << t;
  946|      4|        return *this;
  947|      4|    }
_ZN7logging9LogStreamlsIiEERS0_RKT_:
  944|     13|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|     13|        *(std::ostream*)this << t;
  946|     13|        return *this;
  947|     13|    }
_ZN7logging9LogStreamlsIA35_cEERS0_RKT_:
  944|      7|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      7|        *(std::ostream*)this << t;
  946|      7|        return *this;
  947|      7|    }
_ZN7logging9LogStreamlsIA26_cEERS0_RKT_:
  944|      8|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      8|        *(std::ostream*)this << t;
  946|      8|        return *this;
  947|      8|    }
_ZN7logging9LogStreamlsIA41_cEERS0_RKT_:
  944|      6|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      6|        *(std::ostream*)this << t;
  946|      6|        return *this;
  947|      6|    }
_ZN7logging9LogStreamlsIcEERS0_RKT_:
  944|      5|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      5|        *(std::ostream*)this << t;
  946|      5|        return *this;
  947|      5|    }
_ZN7logging9LogStreamlsIA25_cEERS0_RKT_:
  944|     11|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|     11|        *(std::ostream*)this << t;
  946|     11|        return *this;
  947|     11|    }
_ZN7logging9LogStreamC1Ev:
  926|      1|        : std::ostream(this), _file("-"), _line(0), _func("-")
  927|      1|        , _severity(0) , _noflush(false), _is_check(false), _backtrace(false) {
  928|      1|    }

_ZN5butil13AlignedMemoryILm48ELm8EE9void_dataEv:
   71|     16|      void* void_data() { return static_cast<void*>(data_); }     \
_ZN5butil13AlignedMemoryILm48ELm8EE7data_asINS_14FlatMapElementINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryEEEEEPT_v:
   76|      8|      Type* data_as() { return static_cast<Type*>(void_data()); } \

_ZN5butil17ManualConstructorINS_14FlatMapElementINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryEEEE4InitIJRKS7_EEEvDpOT_:
   62|      8|    void Init(Args&&... args) {
   63|      8|        new (_space.void_data()) Type(std::forward<Args>(args)...);
   64|      8|    }
_ZN5butil17ManualConstructorINS_14FlatMapElementINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryEEEEdeEv:
   58|      8|    Type& operator*() { return *get(); }
_ZN5butil17ManualConstructorINS_14FlatMapElementINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryEEEE3getEv:
   47|      8|    Type* get() {
   48|      8|        return _space.template data_as<Type>();
   49|      8|    }

_ZN5butil14MakeScopeGuardIZNS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE25new_buckets_and_thumbnailEmmEUlvE_EENS_10ScopeGuardIT_St9enable_ifIXsr14is_result_voidISI_EE5valueEvEEEOSI_:
   76|     64|ScopeGuard<Callback> MakeScopeGuard(Callback&& callback) noexcept {
   77|     64|    return ScopeGuard<Callback>{ std::forward<Callback>(callback)};
   78|     64|}
_ZN5butil10ScopeGuardIZNS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE25new_buckets_and_thumbnailEmmEUlvE_St9enable_ifILb1EvEEC2EOSG_:
   64|     64|        :_callback(std::forward<Callback>(callback))
   65|     64|        , _dismiss(false) {}
_ZN5butil10ScopeGuardIZNS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE25new_buckets_and_thumbnailEmmEUlvE_St9enable_ifILb1EvEE7dismissEv:
   50|     64|    void dismiss() noexcept {
   51|     64|        _dismiss = true;
   52|     64|    }
_ZN5butil10ScopeGuardIZNS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE25new_buckets_and_thumbnailEmmEUlvE_St9enable_ifILb1EvEED2Ev:
   44|     64|    ~ScopeGuard() noexcept {
   45|     64|        if(!_dismiss) {
  ------------------
  |  Branch (45:12): [True: 0, False: 64]
  ------------------
   46|      0|            _callback();
   47|      0|        }
   48|     64|    }

_ZN9SingletonIN7logging14DefaultLogSinkE20LeakySingletonTraitsIS1_ES1_E3getEv:
  242|     40|  static Type* get() {
  243|       |    // The load has acquire memory ordering as the thread which reads the
  244|       |    // instance_ pointer must acquire visibility over the singleton data.
  245|     40|    butil::subtle::AtomicWord value = butil::subtle::Acquire_Load(&instance_);
  246|     40|    if (value != 0 && value != butil::internal::kBeingCreatedMarker) {
  ------------------
  |  Branch (246:9): [True: 39, False: 1]
  |  Branch (246:23): [True: 39, False: 0]
  ------------------
  247|       |      // See the corresponding HAPPENS_BEFORE below.
  248|     39|      ANNOTATE_HAPPENS_AFTER(&instance_);
  249|     39|      return reinterpret_cast<Type*>(value);
  250|     39|    }
  251|       |
  252|       |    // Object isn't created yet, maybe we will get to create it, let's try...
  253|      1|    if (butil::subtle::Acquire_CompareAndSwap(
  ------------------
  |  Branch (253:9): [True: 1, False: 0]
  ------------------
  254|      1|          &instance_, 0, butil::internal::kBeingCreatedMarker) == 0) {
  255|       |      // instance_ was NULL and is now kBeingCreatedMarker.  Only one thread
  256|       |      // will ever get here.  Threads might be spinning on us, and they will
  257|       |      // stop right after we do this store.
  258|      1|      Type* newval = Traits::New();
  259|       |
  260|       |      // This annotation helps race detectors recognize correct lock-less
  261|       |      // synchronization between different threads calling get().
  262|       |      // See the corresponding HAPPENS_AFTER below and above.
  263|      1|      ANNOTATE_HAPPENS_BEFORE(&instance_);
  264|       |      // Releases the visibility over instance_ to the readers.
  265|      1|      butil::subtle::Release_Store(
  266|      1|          &instance_, reinterpret_cast<butil::subtle::AtomicWord>(newval));
  267|       |
  268|      1|      if (newval != NULL && Traits::kRegisterAtExit) {
  ------------------
  |  Branch (268:11): [True: 1, False: 0]
  |  Branch (268:29): [Folded, False: 1]
  ------------------
  269|      0|        butil::AtExitManager::RegisterCallback(OnExit, NULL);
  270|      0|      }
  271|       |
  272|      1|      return newval;
  273|      1|    }
  274|       |
  275|       |    // We hit a race. Wait for the other thread to complete it.
  276|      0|    value = butil::internal::WaitForInstance(&instance_);
  277|       |
  278|       |    // See the corresponding HAPPENS_BEFORE above.
  279|      0|    ANNOTATE_HAPPENS_AFTER(&instance_);
  280|      0|    return reinterpret_cast<Type*>(value);
  281|      1|  }
_ZN22DefaultSingletonTraitsIN7logging14DefaultLogSinkEE3NewEv:
   50|      1|  static Type* New() {
   51|       |    // The parenthesis is very important here; it forces POD type
   52|       |    // initialization.
   53|      1|    return new Type();
   54|      1|  }
_ZN9SingletonIN7logging21DoublyBufferedLogSinkE20LeakySingletonTraitsIS1_ES1_E3getEv:
  242|     40|  static Type* get() {
  243|       |    // The load has acquire memory ordering as the thread which reads the
  244|       |    // instance_ pointer must acquire visibility over the singleton data.
  245|     40|    butil::subtle::AtomicWord value = butil::subtle::Acquire_Load(&instance_);
  246|     40|    if (value != 0 && value != butil::internal::kBeingCreatedMarker) {
  ------------------
  |  Branch (246:9): [True: 39, False: 1]
  |  Branch (246:23): [True: 39, False: 0]
  ------------------
  247|       |      // See the corresponding HAPPENS_BEFORE below.
  248|     39|      ANNOTATE_HAPPENS_AFTER(&instance_);
  249|     39|      return reinterpret_cast<Type*>(value);
  250|     39|    }
  251|       |
  252|       |    // Object isn't created yet, maybe we will get to create it, let's try...
  253|      1|    if (butil::subtle::Acquire_CompareAndSwap(
  ------------------
  |  Branch (253:9): [True: 1, False: 0]
  ------------------
  254|      1|          &instance_, 0, butil::internal::kBeingCreatedMarker) == 0) {
  255|       |      // instance_ was NULL and is now kBeingCreatedMarker.  Only one thread
  256|       |      // will ever get here.  Threads might be spinning on us, and they will
  257|       |      // stop right after we do this store.
  258|      1|      Type* newval = Traits::New();
  259|       |
  260|       |      // This annotation helps race detectors recognize correct lock-less
  261|       |      // synchronization between different threads calling get().
  262|       |      // See the corresponding HAPPENS_AFTER below and above.
  263|      1|      ANNOTATE_HAPPENS_BEFORE(&instance_);
  264|       |      // Releases the visibility over instance_ to the readers.
  265|      1|      butil::subtle::Release_Store(
  266|      1|          &instance_, reinterpret_cast<butil::subtle::AtomicWord>(newval));
  267|       |
  268|      1|      if (newval != NULL && Traits::kRegisterAtExit) {
  ------------------
  |  Branch (268:11): [True: 1, False: 0]
  |  Branch (268:29): [Folded, False: 1]
  ------------------
  269|      0|        butil::AtExitManager::RegisterCallback(OnExit, NULL);
  270|      0|      }
  271|       |
  272|      1|      return newval;
  273|      1|    }
  274|       |
  275|       |    // We hit a race. Wait for the other thread to complete it.
  276|      0|    value = butil::internal::WaitForInstance(&instance_);
  277|       |
  278|       |    // See the corresponding HAPPENS_BEFORE above.
  279|      0|    ANNOTATE_HAPPENS_AFTER(&instance_);
  280|      0|    return reinterpret_cast<Type*>(value);
  281|      1|  }
_ZN22DefaultSingletonTraitsIN7logging21DoublyBufferedLogSinkEE3NewEv:
   50|      1|  static Type* New() {
   51|       |    // The parenthesis is very important here; it forces POD type
   52|       |    // initialization.
   53|      1|    return new Type();
   54|      1|  }

_ZN5butil19get_leaky_singletonIN4bvar6detail16SamplerCollectorEEEPT_v:
   60|      8|inline T* get_leaky_singleton() {
   61|      8|    const butil::subtle::AtomicWord value = butil::subtle::Acquire_Load(
   62|      8|        &GetLeakySingleton<T>::g_leaky_singleton_untyped);
   63|      8|    if (value) {
  ------------------
  |  Branch (63:9): [True: 6, False: 2]
  ------------------
   64|      6|        return reinterpret_cast<T*>(value);
   65|      6|    }
   66|      2|    pthread_once(&GetLeakySingleton<T>::g_create_leaky_singleton_once,
   67|      2|                 GetLeakySingleton<T>::create_leaky_singleton);
   68|      2|    return reinterpret_cast<T*>(
   69|      2|        GetLeakySingleton<T>::g_leaky_singleton_untyped);
   70|      8|}
_ZN5butil17GetLeakySingletonIN4bvar6detail16SamplerCollectorEE22create_leaky_singletonEv:
   47|      2|void GetLeakySingleton<T>::create_leaky_singleton() {
   48|      2|    T* obj = create_leaky_singleton_obj<T>();
   49|      2|    butil::subtle::Release_Store(
   50|      2|        &g_leaky_singleton_untyped,
   51|      2|        reinterpret_cast<butil::subtle::AtomicWord>(obj));
   52|      2|}
_ZN5butil26create_leaky_singleton_objIN4bvar6detail16SamplerCollectorEEEPT_v:
   29|      2|T* create_leaky_singleton_obj() {
   30|      2|    return new T();
   31|      2|}

_ZN5butil14saturated_castImiEET_T0_:
   36|      2|inline Dst saturated_cast(Src value) {
   37|       |  // Optimization for floating point values, which already saturate.
   38|      2|  if (std::numeric_limits<Dst>::is_iec559)
  ------------------
  |  Branch (38:7): [Folded, False: 2]
  ------------------
   39|      0|    return static_cast<Dst>(value);
   40|       |
   41|      2|  switch (internal::DstRangeRelationToSrcRange<Dst>(value)) {
  ------------------
  |  Branch (41:11): [True: 2, False: 0]
  ------------------
   42|      2|    case internal::RANGE_VALID:
  ------------------
  |  Branch (42:5): [True: 2, False: 0]
  ------------------
   43|      2|      return static_cast<Dst>(value);
   44|       |
   45|      0|    case internal::RANGE_UNDERFLOW:
  ------------------
  |  Branch (45:5): [True: 0, False: 2]
  ------------------
   46|      0|      return std::numeric_limits<Dst>::min();
   47|       |
   48|      0|    case internal::RANGE_OVERFLOW:
  ------------------
  |  Branch (48:5): [True: 0, False: 2]
  ------------------
   49|      0|      return std::numeric_limits<Dst>::max();
   50|       |
   51|       |    // Should fail only on attempting to assign NaN to a saturated integer.
   52|      0|    case internal::RANGE_INVALID:
  ------------------
  |  Branch (52:5): [True: 0, False: 2]
  ------------------
   53|      0|      CHECK(false);
  ------------------
  |  |  617|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(FATAL).SetCheck(), !(condition))     \
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  618|      0|    << "Check failed: " #condition ". "
  ------------------
   54|      0|      return std::numeric_limits<Dst>::max();
   55|      2|  }
   56|       |
   57|      0|  NOTREACHED();
  ------------------
  |  | 1224|      2|#define NOTREACHED() DCHECK(false)
  |  |  ------------------
  |  |  |  |  846|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON() && !(condition)) \
  |  |  |  |  ------------------
  |  |  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (472:7): [Folded, False: 0]
  |  |  |  |  |  |  |  Branch (472:7): [True: 0, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  847|      0|    << "Check failed: " #condition ". "
  |  |  ------------------
  ------------------
   58|      0|  return static_cast<Dst>(value);
   59|      2|}

_ZN5butil8internal26DstRangeRelationToSrcRangeImiEENS0_15RangeConstraintET0_:
  205|      2|inline RangeConstraint DstRangeRelationToSrcRange(Src value) {
  206|      2|  COMPILE_ASSERT(std::numeric_limits<Src>::is_specialized,
  ------------------
  |  |  241|      2|#define COMPILE_ASSERT(expr, msg)  BAIDU_CASSERT(expr, msg)
  |  |  ------------------
  |  |  |  |  196|      2|#define BAIDU_CASSERT(expr, msg) static_assert(expr, #msg)
  |  |  ------------------
  ------------------
  207|      2|                 argument_must_be_numeric);
  208|      2|  COMPILE_ASSERT(std::numeric_limits<Dst>::is_specialized,
  ------------------
  |  |  241|      2|#define COMPILE_ASSERT(expr, msg)  BAIDU_CASSERT(expr, msg)
  |  |  ------------------
  |  |  |  |  196|      2|#define BAIDU_CASSERT(expr, msg) static_assert(expr, #msg)
  |  |  ------------------
  ------------------
  209|      2|                 result_must_be_numeric);
  210|      2|  return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value);
  211|      2|}
_ZN5butil8internal30DstRangeRelationToSrcRangeImplImiLNS0_21IntegerRepresentationE0ELS2_1ELNS0_26NumericRangeRepresentationE0EE5CheckEi:
  195|      2|  static RangeConstraint Check(Src value) {
  196|      2|    return (MaxExponent<Dst>::value >= MaxExponent<Src>::value)
  ------------------
  |  Branch (196:12): [True: 2, Folded]
  ------------------
  197|      2|               ? GetRangeConstraint(true, value >= static_cast<Src>(0))
  198|      2|               : GetRangeConstraint(
  199|      0|                     value <= static_cast<Src>(std::numeric_limits<Dst>::max()),
  200|      0|                     value >= static_cast<Src>(0));
  201|      2|  }
_ZN5butil8internal18GetRangeConstraintEbb:
  107|      2|                                   bool is_in_lower_bound) {
  108|      2|  return GetRangeConstraint((is_in_upper_bound ? 0 : RANGE_OVERFLOW) |
  ------------------
  |  Branch (108:30): [True: 2, False: 0]
  ------------------
  109|      2|                            (is_in_lower_bound ? 0 : RANGE_UNDERFLOW));
  ------------------
  |  Branch (109:30): [True: 2, False: 0]
  ------------------
  110|      2|}
_ZN5butil8internal18GetRangeConstraintEi:
   97|      2|inline RangeConstraint GetRangeConstraint(int integer_range_constraint) {
   98|      2|  DCHECK(integer_range_constraint >= RANGE_VALID &&
  ------------------
  |  |  846|      2|    BAIDU_LAZY_STREAM(LOG_STREAM(DCHECK), DCHECK_IS_ON() && !(condition)) \
  |  |  ------------------
  |  |  |  |  472|      2|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:7): [True: 0, False: 0]
  |  |  |  |  |  Branch (472:7): [True: 0, False: 0]
  |  |  |  |  |  Branch (472:7): [Folded, False: 2]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  847|      0|    << "Check failed: " #condition ". "
  ------------------
   99|      2|         integer_range_constraint <= RANGE_INVALID);
  100|      2|  return static_cast<RangeConstraint>(integer_range_constraint);
  101|      2|}

_ZN5butil30RegisterFlagValidatorOrDieImplIbEEbPKT_PFbPKcS1_E:
   64|     18|    const T* flag, bool (*validate_fn)(const char*, T val)) {
   65|     18|    static_assert(!butil::is_same<std::string, T>::value,
   66|     18|                  "Not support string flags");
   67|     18|    if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) {
  ------------------
  |  Branch (67:9): [True: 18, False: 0]
  ------------------
   68|     18|        return true;
   69|     18|    }
   70|       |    // Error printed by gflags does not have newline. Add one to it.
   71|      0|    char newline = '\n';
   72|      0|    butil::ignore_result(write(2, &newline, 1));
   73|      0|    _exit(1);
   74|     18|}
_ZN5butil30RegisterFlagValidatorOrDieImplIiEEbPKT_PFbPKcS1_E:
   64|     26|    const T* flag, bool (*validate_fn)(const char*, T val)) {
   65|     26|    static_assert(!butil::is_same<std::string, T>::value,
   66|     26|                  "Not support string flags");
   67|     26|    if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) {
  ------------------
  |  Branch (67:9): [True: 26, False: 0]
  ------------------
   68|     26|        return true;
   69|     26|    }
   70|       |    // Error printed by gflags does not have newline. Add one to it.
   71|      0|    char newline = '\n';
   72|      0|    butil::ignore_result(write(2, &newline, 1));
   73|      0|    _exit(1);
   74|     26|}
_ZN5butil30RegisterFlagValidatorOrDieImplIjEEbPKT_PFbPKcS1_E:
   64|      2|    const T* flag, bool (*validate_fn)(const char*, T val)) {
   65|      2|    static_assert(!butil::is_same<std::string, T>::value,
   66|      2|                  "Not support string flags");
   67|      2|    if (::GFLAGS_NAMESPACE::RegisterFlagValidator(flag, validate_fn)) {
  ------------------
  |  Branch (67:9): [True: 2, False: 0]
  ------------------
   68|      2|        return true;
   69|      2|    }
   70|       |    // Error printed by gflags does not have newline. Add one to it.
   71|      0|    char newline = '\n';
   72|      0|    butil::ignore_result(write(2, &newline, 1));
   73|      0|    _exit(1);
   74|      2|}

_ZNSt10lock_guardI15pthread_mutex_tEC2ERS0_:
  155|     35|    explicit lock_guard(pthread_mutex_t & mutex) : _pmutex(&mutex) {
  156|       |#if !defined(NDEBUG)
  157|       |        const int rc = pthread_mutex_lock(_pmutex);
  158|       |        if (rc) {
  159|       |            LOG(FATAL) << "Fail to lock pthread_mutex_t=" << _pmutex << ", " << berror(rc);
  160|       |            _pmutex = NULL;
  161|       |        }
  162|       |#else
  163|     35|        pthread_mutex_lock(_pmutex);
  164|     35|#endif  // NDEBUG
  165|     35|    }
_ZNSt10lock_guardI15pthread_mutex_tED2Ev:
  167|     35|    ~lock_guard() {
  168|       |#ifndef NDEBUG
  169|       |        if (_pmutex) {
  170|       |            pthread_mutex_unlock(_pmutex);
  171|       |        }
  172|       |#else
  173|     35|        pthread_mutex_unlock(_pmutex);
  174|     35|#endif
  175|     35|    }

_ZN5butil11PtAllocator5AllocEm:
   35|     64|    void* Alloc(size_t n) { return malloc(n); }
_ZN5butil18SingleThreadedPoolILm56ELm1024ELm16ENS_11PtAllocatorEEC2ERKS1_:
   65|     64|        : _free_nodes(NULL), _blocks(NULL), _allocator(alloc) {}
_ZN5butil18SingleThreadedPoolILm56ELm1024ELm16ENS_11PtAllocatorEE13get_allocatorEv:
  136|     64|    Allocator& get_allocator() { return _allocator; }

_ZN5butillsERSoRKNS_16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE:
   46|     80|std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
   47|     80|  o.write(piece.data(), static_cast<std::streamsize>(piece.size()));
   48|     80|  return o;
   49|     80|}
_ZN5butil8internal4findERKNS_16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESA_m:
  115|  3.56k|size_t find(const StringPiece& self, const StringPiece& s, size_t pos) {
  116|  3.56k|  return findT(self, s, pos);
  117|  3.56k|}
_ZN5butil8internal5findTINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEmRKNS_16BasicStringPieceIT_EESC_m:
  104|  3.56k|             size_t pos) {
  105|  3.56k|  if (pos > self.size())
  ------------------
  |  Branch (105:7): [True: 0, False: 3.56k]
  ------------------
  106|      0|    return BasicStringPiece<STR>::npos;
  107|       |
  108|  3.56k|  typename BasicStringPiece<STR>::const_iterator result =
  109|  3.56k|      std::search(self.begin() + pos, self.end(), s.begin(), s.end());
  110|  3.56k|  const size_t xpos =
  111|  3.56k|    static_cast<size_t>(result - self.begin());
  112|  3.56k|  return xpos + s.size() <= self.size() ? xpos : BasicStringPiece<STR>::npos;
  ------------------
  |  Branch (112:10): [True: 3.54k, False: 16]
  ------------------
  113|  3.56k|}

_ZN5butil9back_charERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE:
  479|     16|inline char back_char(const std::string& s) { return s[s.size() - 1]; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4dataEv:
  214|    456|  const value_type* data() const { return ptr_; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4sizeEv:
  215|  11.0k|  size_type size() const { return length_; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5beginEv:
  280|  10.6k|  const_iterator begin() const { return ptr_; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3endEv:
  281|  7.12k|  const_iterator end() const { return ptr_ + length_; }
_ZN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEC2EPKcm:
  202|  4.79k|      : ptr_(offset), length_(len) {}
_ZN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEC2Ev:
  190|  10.3k|  BasicStringPiece() : ptr_(NULL), length_(0) {}
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5emptyEv:
  217|     56|  bool empty() const { return length_ == 0; }
_ZN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEC2EPKc:
  192|  3.73k|      : ptr_(str),
  193|  3.73k|        length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
  ------------------
  |  Branch (193:17): [True: 0, False: 3.73k]
  ------------------
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE6lengthEv:
  216|     40|  size_type length() const { return length_; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4findERKS7_m:
  332|  3.56k|                 size_type pos = 0) const {
  333|  3.56k|    return internal::find(*this, s, pos);
  334|  3.56k|  }
_ZN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3setEPKcm:
  228|  1.06k|  void set(const value_type* data, size_type len) {
  229|  1.06k|    ptr_ = data;
  230|  1.06k|    length_ = len;
  231|  1.06k|  }

_ZN5butil5MutexC2Ev:
   50|    116|    Mutex() {
   51|       |#if defined(OS_WIN)
   52|       |    // The second parameter is the spin count, for short-held locks it avoid the
   53|       |    // contending thread from going to sleep which helps performance greatly.
   54|       |        ::InitializeCriticalSectionAndSpinCount(&_native_handle, 2000);
   55|       |#elif defined(OS_POSIX)
   56|       |        pthread_mutex_init(&_native_handle, NULL);
   57|    116|#endif
   58|    116|    }
_ZN5butil5Mutex4lockEv:
   70|     36|    void lock() {
   71|       |#if defined(OS_WIN)
   72|       |        ::EnterCriticalSection(&_native_handle);
   73|       |#elif defined(OS_POSIX)
   74|       |        pthread_mutex_lock(&_native_handle);
   75|     36|#endif
   76|     36|    }
_ZN5butil5Mutex6unlockEv:
   80|     36|    void unlock() {
   81|       |#if defined(OS_WIN)
   82|       |        ::LeaveCriticalSection(&_native_handle);
   83|       |#elif defined(OS_POSIX)
   84|       |        pthread_mutex_unlock(&_native_handle);
   85|     36|#endif
   86|     36|    }
_ZN5butil4LockC2Ev:
  126|    106|    Lock() {}
_ZN5butil4Lock7AcquireEv:
  128|     20|    void Acquire() { lock(); }
_ZN5butil4Lock7ReleaseEv:
  129|     20|    void Release() { unlock(); }
_ZNK5butil4Lock14AssertAcquiredEv:
  131|     20|    void AssertAcquired() const {}
_ZN5butil8AutoLockC2ERNS_4LockE:
  139|     20|    explicit AutoLock(Lock& lock) : lock_(lock) {
  140|     20|        lock_.Acquire();
  141|     20|    }
_ZN5butil8AutoLockD2Ev:
  147|     20|    ~AutoLock() {
  148|     20|        lock_.AssertAcquired();
  149|     20|        lock_.Release();
  150|     20|    }

_ZN5butil6detail29get_or_new_thread_exit_helperEv:
   99|      5|detail::ThreadExitHelper* get_or_new_thread_exit_helper() {
  100|      5|    pthread_once(&detail::thread_atexit_once, detail::make_thread_atexit_key);
  101|       |
  102|      5|    detail::ThreadExitHelper* h =
  103|      5|        (detail::ThreadExitHelper*)pthread_getspecific(detail::thread_atexit_key);
  104|      5|    if (NULL == h) {
  ------------------
  |  Branch (104:9): [True: 2, False: 3]
  ------------------
  105|      2|        h = new (std::nothrow) detail::ThreadExitHelper;
  106|      2|        if (NULL != h) {
  ------------------
  |  Branch (106:13): [True: 2, False: 0]
  ------------------
  107|      2|            pthread_setspecific(detail::thread_atexit_key, h);
  108|      2|        }
  109|      2|    }
  110|      5|    return h;
  111|      5|}
_ZN5butil13thread_atexitEPFvPvES0_:
  124|      5|int thread_atexit(void (*fn)(void*), void* arg) {
  125|      5|    if (NULL == fn) {
  ------------------
  |  Branch (125:9): [True: 0, False: 5]
  ------------------
  126|      0|        errno = EINVAL;
  127|      0|        return -1;
  128|      0|    }
  129|      5|    detail::ThreadExitHelper* h = detail::get_or_new_thread_exit_helper();
  130|      5|    if (h) {
  ------------------
  |  Branch (130:9): [True: 5, False: 0]
  ------------------
  131|      5|        return h->add(fn, arg);
  132|      5|    }
  133|      5|    errno = ENOMEM;
  134|      0|    return -1;
  135|      5|}
_ZN5butil13thread_atexitEPFvvE:
  137|      4|int thread_atexit(void (*fn)()) {
  138|      4|    if (NULL == fn) {
  ------------------
  |  Branch (138:9): [True: 0, False: 4]
  ------------------
  139|      0|        errno = EINVAL;
  140|      0|        return -1;
  141|      0|    }
  142|      4|    return thread_atexit(detail::call_single_arg_fn, (void*)fn);
  143|      4|}
thread_local.cpp:_ZN5butil6detailL22make_thread_atexit_keyEv:
   89|      2|static void make_thread_atexit_key() {
   90|      2|    if (pthread_key_create(&thread_atexit_key, delete_thread_exit_helper) != 0) {
  ------------------
  |  Branch (90:9): [True: 0, False: 2]
  ------------------
   91|      0|        fprintf(stderr, "Fail to create thread_atexit_key, abort\n");
   92|      0|        abort();
   93|      0|    }
   94|       |    // If caller is not pthread, delete_thread_exit_helper will not be called.
   95|       |    // We have to rely on atexit().
   96|      2|    atexit(helper_exit_global);
   97|      2|}
_ZN5butil6detail16ThreadExitHelper3addEPFvPvES2_:
   45|      5|    int add(Fn fn, void* arg) {
   46|      5|        try {
   47|      5|            if (_fns.capacity() < 16) {
  ------------------
  |  Branch (47:17): [True: 2, False: 3]
  ------------------
   48|      2|                _fns.reserve(16);
   49|      2|            }
   50|      5|            _fns.emplace_back(fn, arg);
   51|      5|        } catch (...) {
   52|      0|            errno = ENOMEM;
   53|      0|            return -1;
   54|      0|        }
   55|      5|        return 0;
   56|      5|    }

_ZN7bthread18get_tls_task_groupEv:
   35|     42|  __attribute__((noinline, unused)) type get_##var_name(void) {                \
   36|     42|    asm volatile("");                                                          \
   37|     42|    return var_name;                                                           \
   38|     42|  }                                                                            \
_ZN7bthread15get_ptr_tls_blsEv:
   39|     42|  __attribute__((noinline, unused)) type *get_ptr_##var_name(void) {           \
   40|     42|    type *ptr = &var_name;                                                     \
   41|     42|    asm volatile("" : "+rm"(ptr));                                             \
   42|     42|    return ptr;                                                                \
   43|     42|  }                                                                            \
logging.cc:_ZN7logging12_GLOBAL__N_115get_tls_log_tidEv:
   35|     40|  __attribute__((noinline, unused)) type get_##var_name(void) {                \
   36|     40|    asm volatile("");                                                          \
   37|     40|    return var_name;                                                           \
   38|     40|  }                                                                            \
logging.cc:_ZN7logging12_GLOBAL__N_115set_tls_log_tidEi:
   44|      1|  __attribute__((noinline, unused)) void set_##var_name(type v) {              \
   45|      1|    asm volatile("");                                                          \
   46|      1|    var_name = v;                                                              \
   47|      1|  }
_ZN7bthread29get_tls_ever_created_keytableEv:
   35|      1|  __attribute__((noinline, unused)) type get_##var_name(void) {                \
   36|      1|    asm volatile("");                                                          \
   37|      1|    return var_name;                                                           \
   38|      1|  }                                                                            \
_ZN7bthread29set_tls_ever_created_keytableEb:
   44|      1|  __attribute__((noinline, unused)) void set_##var_name(type v) {              \
   45|      1|    asm volatile("");                                                          \
   46|      1|    var_name = v;                                                              \
   47|      1|  }

_ZN5butil14PlatformThread13SetNameSimpleEPKc:
   60|      2|void PlatformThread::SetNameSimple(const char* name) {
   61|      2|#if !defined(OS_NACL)
   62|       |  // On linux we can get the thread names to show up in the debugger by setting
   63|       |  // the process name for the LWP.  We don't want to do this for the main
   64|       |  // thread because that would rename the process, causing tools like killall
   65|       |  // to stop working.
   66|      2|  if (PlatformThread::CurrentId() == getpid())
  ------------------
  |  Branch (66:7): [True: 0, False: 2]
  ------------------
   67|      0|    return;
   68|       |
   69|       |  // http://0pointer.de/blog/projects/name-your-threads.html
   70|       |  // Set the name for the LWP (which gets truncated to 15 characters).
   71|       |  // Note that glibc also has a 'pthread_setname_np' api, but it may not be
   72|       |  // available everywhere and it's only benefit over using prctl directly is
   73|       |  // that it can set the name of threads other than the current thread.
   74|      2|  int err = prctl(PR_SET_NAME, name);
   75|       |  // We expect EPERM failures in sandboxed processes, just ignore those.
   76|      2|  if (err < 0 && errno != EPERM)
  ------------------
  |  Branch (76:7): [True: 0, False: 2]
  |  Branch (76:18): [True: 0, False: 0]
  ------------------
   77|      0|    DPLOG(ERROR) << "prctl(PR_SET_NAME)";
  ------------------
  |  |  749|      0|    BAIDU_LAZY_STREAM(PLOG_STREAM(severity), DLOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, Folded]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   78|      2|#endif  //  !defined(OS_NACL)
   79|      2|}

_ZN5butil14PlatformThread9CurrentIdEv:
  145|      3|PlatformThreadId PlatformThread::CurrentId() {
  146|       |  // Pthreads doesn't have the concept of a thread ID, so we have to reach down
  147|       |  // into the kernel.
  148|       |#if defined(OS_MACOSX)
  149|       |  return pthread_mach_thread_np(pthread_self());
  150|       |#elif defined(OS_LINUX)
  151|      3|  return syscall(__NR_gettid);
  152|       |#elif defined(OS_ANDROID)
  153|       |  return gettid();
  154|       |#elif defined(OS_SOLARIS) || defined(OS_QNX)
  155|       |  return pthread_self();
  156|       |#elif defined(OS_NACL) && defined(__GLIBC__)
  157|       |  return pthread_self();
  158|       |#elif defined(OS_NACL) && !defined(__GLIBC__)
  159|       |  // Pointers are 32-bits in NaCl.
  160|       |  return reinterpret_cast<int32_t>(pthread_self());
  161|       |#elif defined(OS_POSIX)
  162|       |  return reinterpret_cast<int64_t>(pthread_self());
  163|       |#endif
  164|      3|}

_ZN5butil15cpuwide_time_nsEv:
  283|     10|inline int64_t cpuwide_time_ns() {
  284|     10|#if !defined(BAIDU_INTERNAL) && !BUTIL_USE_CPU_FREQUENCY
  285|       |    // nearly impossible to get the correct invariant cpu frequency on
  286|       |    // different CPU and machines. CPU-ID rarely works and frequencies
  287|       |    // in "model name" and "cpu Mhz" are both unreliable.
  288|       |    // Since clock_gettime() in newer glibc/kernel is much faster(~30ns)
  289|       |    // which is closer to the previous impl. of cpuwide_time(~10ns), we
  290|       |    // simply use the monotonic time to get rid of all related issues.
  291|     10|    timespec now;
  292|     10|    clock_gettime(CLOCK_MONOTONIC, &now);
  293|     10|    return now.tv_sec * 1000000000L + now.tv_nsec;
  294|       |#else
  295|       |    int64_t cpu_freq = detail::invariant_cpu_freq;
  296|       |    if (cpu_freq > 0) {
  297|       |        const uint64_t tsc = detail::clock_cycles();
  298|       |        //Try to avoid overflow
  299|       |        const uint64_t sec = tsc / cpu_freq;
  300|       |        const uint64_t remain = tsc % cpu_freq;
  301|       |        // TODO: should be OK until CPU's frequency exceeds 16GHz.
  302|       |        return remain * 1000000000L / cpu_freq + sec * 1000000000L;
  303|       |    } else {
  304|       |        // Lack of necessary features, return system-wide monotonic time instead.
  305|       |        return monotonic_time_ns();
  306|       |    }
  307|       |#endif // defined(BAIDU_INTERNAL) || BUTIL_USE_CPU_FREQUENCY
  308|     10|}
_ZN5butil15cpuwide_time_usEv:
  318|     10|inline int64_t cpuwide_time_us() {
  319|     10|    return cpuwide_time_ns() / 1000L;
  320|     10|}

_ZN4bvar6detail10AgentGroupINS0_13AgentCombinerIPNS0_7SamplerES4_NS0_14CombineSamplerEE5AgentEE16create_new_agentEv:
   89|      2|    inline static AgentId create_new_agent() {
   90|      2|        BAIDU_SCOPED_LOCK(_s_mutex);
  ------------------
  |  |   47|      2|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      2|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      2|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      2|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   91|      2|        AgentId agent_id = 0;
   92|      2|        if (!_get_free_ids().empty()) {
  ------------------
  |  Branch (92:13): [True: 0, False: 2]
  ------------------
   93|      0|            agent_id = _get_free_ids().back();
   94|      0|            _get_free_ids().pop_back();
   95|      2|        } else {
   96|      2|            agent_id = _s_agent_kinds++;
   97|      2|        }
   98|      2|        return agent_id;
   99|      2|    }
_ZN4bvar6detail10AgentGroupINS0_13AgentCombinerIPNS0_7SamplerES4_NS0_14CombineSamplerEE5AgentEE13_get_free_idsEv:
  172|      2|    inline static std::deque<AgentId> &_get_free_ids() {
  173|      2|        if (__builtin_expect(!_s_free_ids, 0)) {
  ------------------
  |  Branch (173:13): [True: 2, False: 0]
  ------------------
  174|      2|            _s_free_ids = new (std::nothrow) std::deque<AgentId>();
  175|      2|            RELEASE_ASSERT(_s_free_ids);
  ------------------
  |  |  476|      2|    do {                            \
  |  |  477|      2|        if (!(condition)) {         \
  |  |  ------------------
  |  |  |  Branch (477:13): [True: 0, False: 2]
  |  |  ------------------
  |  |  478|      0|            ::abort();              \
  |  |  479|      0|        }                           \
  |  |  480|      2|    } while (false)
  |  |  ------------------
  |  |  |  Branch (480:14): [Folded, False: 2]
  |  |  ------------------
  ------------------
  176|      2|        }
  177|      2|        return *_s_free_ids;
  178|      2|    }
_ZN4bvar6detail10AgentGroupINS0_13AgentCombinerIPNS0_7SamplerES4_NS0_14CombineSamplerEE5AgentEE13get_tls_agentEi:
  114|      8|    inline static Agent* get_tls_agent(AgentId id) {
  115|      8|        if (__builtin_expect(id >= 0, 1)) {
  ------------------
  |  Branch (115:13): [True: 8, False: 0]
  ------------------
  116|      8|            if (_s_tls_blocks) {
  ------------------
  |  Branch (116:17): [True: 6, False: 2]
  ------------------
  117|      6|                const size_t block_id = (size_t)id / ELEMENTS_PER_BLOCK;
  118|      6|                if (block_id < _s_tls_blocks->size()) {
  ------------------
  |  Branch (118:21): [True: 6, False: 0]
  ------------------
  119|      6|                    ThreadBlock* const tb = (*_s_tls_blocks)[block_id];
  120|      6|                    if (tb) {
  ------------------
  |  Branch (120:25): [True: 6, False: 0]
  ------------------
  121|      6|                        return tb->at(id - block_id * ELEMENTS_PER_BLOCK);
  122|      6|                    }
  123|      6|                }
  124|      6|            }
  125|      8|        }
  126|      2|        return nullptr;
  127|      8|    }
_ZN4bvar6detail10AgentGroupINS0_13AgentCombinerIPNS0_7SamplerES4_NS0_14CombineSamplerEE5AgentEE11ThreadBlock2atEm:
   83|      8|        inline Agent* at(size_t offset) { return _agents + offset; };
_ZN4bvar6detail10AgentGroupINS0_13AgentCombinerIPNS0_7SamplerES4_NS0_14CombineSamplerEE5AgentEE23get_or_create_tls_agentEi:
  130|      2|    inline static Agent* get_or_create_tls_agent(AgentId id) {
  131|      2|        if (__builtin_expect(id < 0, 0)) {
  ------------------
  |  Branch (131:13): [True: 0, False: 2]
  ------------------
  132|      0|            CHECK(false) << "Invalid id=" << id;
  ------------------
  |  |  617|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(FATAL).SetCheck(), !(condition))     \
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  618|      0|    << "Check failed: " #condition ". "
  ------------------
  133|      0|            return nullptr;
  134|      0|        }
  135|      2|        if (_s_tls_blocks == nullptr) {
  ------------------
  |  Branch (135:13): [True: 2, False: 0]
  ------------------
  136|      2|            _s_tls_blocks = new (std::nothrow) std::vector<ThreadBlock *>;
  137|      2|            if (__builtin_expect(_s_tls_blocks == nullptr, 0)) {
  ------------------
  |  Branch (137:17): [True: 0, False: 2]
  ------------------
  138|      0|                LOG(FATAL) << "Fail to create vector, " << berror();
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  139|      0|                return nullptr;
  140|      0|            }
  141|      2|            butil::thread_atexit(_destroy_tls_blocks);
  142|      2|        }
  143|      2|        const size_t block_id = (size_t)id / ELEMENTS_PER_BLOCK; 
  144|      2|        if (block_id >= _s_tls_blocks->size()) {
  ------------------
  |  Branch (144:13): [True: 2, False: 0]
  ------------------
  145|       |            // The 32ul avoid pointless small resizes.
  146|      2|            _s_tls_blocks->resize(std::max(block_id + 1, 32ul));
  147|      2|        }
  148|      2|        ThreadBlock* tb = (*_s_tls_blocks)[block_id];
  149|      2|        if (tb == nullptr) {
  ------------------
  |  Branch (149:13): [True: 2, False: 0]
  ------------------
  150|      2|            ThreadBlock *new_block = new (std::nothrow) ThreadBlock;
  151|      2|            if (__builtin_expect(new_block == nullptr, 0)) {
  ------------------
  |  Branch (151:17): [True: 0, False: 2]
  ------------------
  152|      0|                return nullptr;
  153|      0|            }
  154|      2|            tb = new_block;
  155|      2|            (*_s_tls_blocks)[block_id] = new_block;
  156|      2|        }
  157|      2|        return tb->at(id - block_id * ELEMENTS_PER_BLOCK);
  158|      2|    }

_ZN4bvar6detail22call_op_returning_voidINS0_14CombineSamplerEPNS0_7SamplerES4_EEvRKT_RT0_RKT1_:
   28|     12|    const Op& op, T1& v1, const T2& v2) {
   29|     12|    return op(v1, v2);
   30|     12|}

_ZN4bvar6detail13AgentCombinerIPNS0_7SamplerES3_NS0_14CombineSamplerEEC2ES3_S3_RKS4_:
  227|      2|        : _id(AgentGroup::create_new_agent())
  228|      2|        , _op(op)
  229|      2|        , _global_result(result_identity)
  230|      2|        , _result_identity(result_identity)
  231|      2|        , _element_identity(element_identity) {
  232|      2|    }
_ZNK4bvar6detail13AgentCombinerIPNS0_7SamplerES3_NS0_14CombineSamplerEE2opEv:
  379|      8|    const BinaryOp& op() const { return _op; }
_ZN4bvar6detail13AgentCombinerIPNS0_7SamplerES3_NS0_14CombineSamplerEE16reset_all_agentsEv:
  292|      4|    ResultTp reset_all_agents() {
  293|      4|        ElementTp prev;
  294|      4|        butil::AutoLock guard(_lock);
  295|      4|        ResultTp tmp = _global_result;
  296|      4|        _global_result = _result_identity;
  297|      4|        for (butil::LinkNode<Agent>* node = _agents.head();
  298|      8|             node != _agents.end(); node = node->next()) {
  ------------------
  |  Branch (298:14): [True: 4, False: 4]
  ------------------
  299|      4|            node->value()->element.exchange(&prev, _element_identity);
  300|      4|            call_op_returning_void(_op, tmp, prev);
  301|      4|        }
  302|      4|        return tmp;
  303|      4|    }
_ZN4bvar6detail16ElementContainerIPNS0_7SamplerEvE8exchangeEPS3_RKS3_:
   86|      4|    void exchange(T* prev, const T& new_value) {
   87|      4|        butil::AutoLock guard(_lock);
   88|      4|        *prev = _value;
   89|      4|        _value = new_value;
   90|      4|    }
_ZN4bvar6detail13AgentCombinerIPNS0_7SamplerES3_NS0_14CombineSamplerEE23get_or_create_tls_agentEv:
  331|      8|    Agent* get_or_create_tls_agent() {
  332|      8|        Agent* agent = AgentGroup::get_tls_agent(_id);
  333|      8|        if (!agent) {
  ------------------
  |  Branch (333:13): [True: 2, False: 6]
  ------------------
  334|       |            // Create the agent
  335|      2|            agent = AgentGroup::get_or_create_tls_agent(_id);
  336|      2|            if (nullptr == agent) {
  ------------------
  |  Branch (336:17): [True: 0, False: 2]
  ------------------
  337|      0|                LOG(FATAL) << "Fail to create agent";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  338|      0|                return nullptr;
  339|      0|            }
  340|      2|        }
  341|      8|        if (!agent->combiner.expired()) {
  ------------------
  |  Branch (341:13): [True: 6, False: 2]
  ------------------
  342|      6|            return agent;
  343|      6|        }
  344|      2|        agent->reset(_element_identity, this->shared_from_this());
  345|       |        // TODO: Is uniqueness-checking necessary here?
  346|      2|        {
  347|      2|            butil::AutoLock guard(_lock);
  348|      2|            _agents.Append(agent);
  349|      2|        }
  350|      2|        return agent;
  351|      8|    }
_ZN4bvar6detail13AgentCombinerIPNS0_7SamplerES3_NS0_14CombineSamplerEE5Agent5resetERKS3_RKSt10shared_ptrIS5_E:
  175|      2|        void reset(const ElementTp& val, const self_shared_type& c) {
  176|      2|            combiner = c;
  177|      2|            element.store(val);
  178|      2|        }
_ZN4bvar6detail16ElementContainerIPNS0_7SamplerEvE5storeERKS3_:
   81|      2|    void store(const T& new_value) {
   82|      2|        butil::AutoLock guard(_lock);
   83|      2|        _value = new_value;
   84|      2|    }
_ZN4bvar6detail16ElementContainerIPNS0_7SamplerEvE6modifyINS0_14CombineSamplerES3_EEvRKT_RKT0_:
   93|      8|    void modify(const Op &op, const T1 &value2) {
   94|      8|        butil::AutoLock guard(_lock);
   95|      8|        call_op_returning_void(op, _value, value2);
   96|      8|    }

_ZN4bvar6detail16SamplerCollector3runEv:
  135|      2|void SamplerCollector::run() {
  136|      2|    ::usleep(FLAGS_bvar_sampler_thread_start_delay_us);
  137|       |    
  138|       |#ifndef UNIT_TEST
  139|       |    // NOTE:
  140|       |    // * Following vars can't be created on thread's stack since this thread
  141|       |    //   may be abandoned at any time after forking.
  142|       |    // * They can't created inside the constructor of SamplerCollector as well,
  143|       |    //   which results in deadlock.
  144|       |    if (s_cumulated_time_bvar == nullptr) {
  145|       |        s_cumulated_time_bvar =
  146|       |            new PassiveStatus<double>(get_cumulated_time, this);
  147|       |    }
  148|       |    if (s_sampling_thread_usage_bvar == nullptr) {
  149|       |        s_sampling_thread_usage_bvar =
  150|       |            new bvar::PerSecond<bvar::PassiveStatus<double> >(
  151|       |                    "bvar_sampler_collector_usage", s_cumulated_time_bvar, 10);
  152|       |    }
  153|       |#endif
  154|       |
  155|      2|    butil::LinkNode<Sampler> root;
  156|      2|    int consecutive_nosleep = 0;
  157|      6|    while (!_stop) {
  ------------------
  |  Branch (157:12): [True: 4, False: 2]
  ------------------
  158|      4|        int64_t abstime = butil::cpuwide_time_us();
  159|      4|        Sampler* s = this->reset();
  160|      4|        if (s) {
  ------------------
  |  Branch (160:13): [True: 2, False: 2]
  ------------------
  161|      2|            s->InsertBeforeAsList(&root);
  162|      2|        }
  163|     20|        for (butil::LinkNode<Sampler>* p = root.next(); p != &root;) {
  ------------------
  |  Branch (163:57): [True: 16, False: 4]
  ------------------
  164|       |            // We may remove p from the list, save next first.
  165|     16|            butil::LinkNode<Sampler>* saved_next = p->next();
  166|     16|            Sampler* s = p->value();
  167|     16|            s->_mutex.lock();
  168|     16|            if (!s->_used) {
  ------------------
  |  Branch (168:17): [True: 0, False: 16]
  ------------------
  169|      0|                s->_mutex.unlock();
  170|      0|                p->RemoveFromList();
  171|      0|                delete s;
  172|     16|            } else {
  173|     16|                s->take_sample();
  174|     16|                s->_mutex.unlock();
  175|     16|            }
  176|     16|            p = saved_next;
  177|     16|        }
  178|      4|        bool slept = false;
  179|      4|        int64_t now = butil::cpuwide_time_us();
  180|      4|        _cumulated_time_us += now - abstime;
  181|      4|        abstime += 1000000L;
  182|      8|        while (abstime > now) {
  ------------------
  |  Branch (182:16): [True: 4, False: 4]
  ------------------
  183|      4|            ::usleep(abstime - now);
  184|      4|            slept = true;
  185|      4|            now = butil::cpuwide_time_us();
  186|      4|        }
  187|      4|        if (slept) {
  ------------------
  |  Branch (187:13): [True: 2, False: 2]
  ------------------
  188|      2|            consecutive_nosleep = 0;
  189|      2|        } else {            
  190|      2|            if (++consecutive_nosleep >= WARN_NOSLEEP_THRESHOLD) {
  ------------------
  |  Branch (190:17): [True: 0, False: 2]
  ------------------
  191|      0|                consecutive_nosleep = 0;
  192|      0|                LOG(WARNING) << "bvar is busy at sampling for "
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  193|      0|                             << WARN_NOSLEEP_THRESHOLD << " seconds!";
  194|      0|            }
  195|      2|        }
  196|      4|    }
  197|      2|}
_ZN4bvar6detail7SamplerC2Ev:
  199|      8|Sampler::Sampler() : _used(true) {}
_ZN4bvar6detail7Sampler8scheduleEv:
  205|      8|void Sampler::schedule() {
  206|       |    // since the SamplerCollector is initialized before the program starts
  207|       |    // flags will not take effect if used in the SamplerCollector constructor
  208|      8|    if (FLAGS_bvar_enable_sampling) {
  ------------------
  |  Branch (208:9): [True: 8, False: 0]
  ------------------
  209|      8|        *butil::get_leaky_singleton<SamplerCollector>() << this;
  210|      8|    }
  211|      8|}
_ZN4bvar6detail16SamplerCollectorC2Ev:
   66|      2|        : _created(false)
   67|      2|        , _stop(false)
   68|      2|        , _cumulated_time_us(0) {
   69|      2|        create_sampling_thread();
   70|      2|    }
_ZN4bvar6detail16SamplerCollector22create_sampling_threadEv:
   91|      2|    void create_sampling_thread() {
   92|      2|        const int rc = pthread_create(&_tid, nullptr, sampling_thread, this);
   93|      2|        if (rc != 0) {
  ------------------
  |  Branch (93:13): [True: 0, False: 2]
  ------------------
   94|      0|            LOG(FATAL) << "Fail to create sampling_thread, " << berror(rc);
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   95|      2|        } else {
   96|      2|            _created = true;
   97|      2|            if (!registered_atfork) {
  ------------------
  |  Branch (97:17): [True: 2, False: 0]
  ------------------
   98|      2|                registered_atfork = true;
   99|      2|                pthread_atfork(nullptr, nullptr, child_callback_atfork);
  100|      2|            }
  101|      2|        }
  102|      2|    }
_ZN4bvar6detail16SamplerCollector15sampling_threadEPv:
  111|      2|    static void* sampling_thread(void* arg) {
  112|      2|        butil::PlatformThread::SetNameSimple("bvar_sampler");
  113|      2|        static_cast<SamplerCollector*>(arg)->run();
  114|      2|        return nullptr;
  115|      2|    }
_ZNK4bvar6detail14CombineSamplerclERPNS0_7SamplerES3_:
   36|     12|    void operator()(Sampler* & s1, Sampler* s2) const {
   37|     12|        if (s2 == nullptr) {
  ------------------
  |  Branch (37:13): [True: 2, False: 10]
  ------------------
   38|      2|            return;
   39|      2|        }
   40|     10|        if (s1 == nullptr) {
  ------------------
  |  Branch (40:13): [True: 4, False: 6]
  ------------------
   41|      4|            s1 = s2;
   42|      4|            return;
   43|      4|        }
   44|      6|        s1->InsertBeforeAsList(s2);
   45|      6|    }

_ZN4bvar6detail6SeriesIlNS0_5AddToIlEEEC2ERKS3_:
  218|      2|    explicit Series(const Op& op) : Base(op) {}
_ZN4bvar6detail10SeriesBaseIlNS0_5AddToIlEEEC2ERKS3_:
  103|      2|        : _op(op)
  104|      2|        , _nsecond(0)
  105|      2|        , _nminute(0)
  106|      2|        , _nhour(0)
  107|      2|        , _nday(0) {
  108|      2|        pthread_mutex_init(&_mutex, nullptr);
  109|      2|    }
_ZN4bvar6detail10SeriesBaseIlNS0_5AddToIlEEE4DataC2Ev:
  127|      2|        Data() {
  128|       |            // is_pod does not work for gcc 3.4
  129|      2|            if (butil::is_integral<T>::value ||
  ------------------
  |  Branch (129:17): [True: 2, Folded]
  ------------------
  130|      2|                butil::is_floating_point<T>::value) {
  ------------------
  |  Branch (130:17): [Folded, False: 0]
  ------------------
  131|      2|                memset(static_cast<void*>(_array), 0, sizeof(_array));
  132|      2|            }
  133|      2|        }
_ZN4bvar6detail10SeriesBaseIlNS0_5AddToIlEEE6appendERKl:
  114|      4|    void append(const T& value) {
  115|      4|        BAIDU_SCOPED_LOCK(_mutex);
  ------------------
  |  |   47|      4|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      4|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      4|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      4|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  116|      4|        return append_second(value, _op);
  117|      4|    }
_ZN4bvar6detail10SeriesBaseIlNS0_5AddToIlEEE13append_secondERKlRKS3_:
  161|      4|void SeriesBase<T, Op>::append_second(const T& value, const Op& op) {
  162|      4|    _data.second(_nsecond) = value;
  163|      4|    ++_nsecond;
  164|      4|    if (_nsecond >= 60) {
  ------------------
  |  Branch (164:9): [True: 0, False: 4]
  ------------------
  165|      0|        _nsecond = 0;
  166|      0|        T tmp = _data.second(0);
  167|      0|        for (int i = 1; i < 60; ++i) {
  ------------------
  |  Branch (167:25): [True: 0, False: 0]
  ------------------
  168|      0|            call_op_returning_void(op, tmp, _data.second(i));
  169|      0|        }
  170|      0|        DivideOnAddition<T, Op>::inplace_divide(tmp, op, 60);
  171|      0|        append_minute(tmp, op);
  172|      0|    }
  173|      4|}
_ZN4bvar6detail10SeriesBaseIlNS0_5AddToIlEEE4Data6secondEi:
  135|      4|        T& second(int index) { return _array[index]; }
_ZN4bvar6detail6SeriesImNS0_5AddToImEEEC2ERKS3_:
  218|      4|    explicit Series(const Op& op) : Base(op) {}
_ZN4bvar6detail10SeriesBaseImNS0_5AddToImEEEC2ERKS3_:
  103|      4|        : _op(op)
  104|      4|        , _nsecond(0)
  105|      4|        , _nminute(0)
  106|      4|        , _nhour(0)
  107|      4|        , _nday(0) {
  108|      4|        pthread_mutex_init(&_mutex, nullptr);
  109|      4|    }
_ZN4bvar6detail10SeriesBaseImNS0_5AddToImEEE4DataC2Ev:
  127|      4|        Data() {
  128|       |            // is_pod does not work for gcc 3.4
  129|      4|            if (butil::is_integral<T>::value ||
  ------------------
  |  Branch (129:17): [True: 4, Folded]
  ------------------
  130|      4|                butil::is_floating_point<T>::value) {
  ------------------
  |  Branch (130:17): [Folded, False: 0]
  ------------------
  131|      4|                memset(static_cast<void*>(_array), 0, sizeof(_array));
  132|      4|            }
  133|      4|        }
_ZN4bvar6detail10SeriesBaseImNS0_5AddToImEEE6appendERKm:
  114|      8|    void append(const T& value) {
  115|      8|        BAIDU_SCOPED_LOCK(_mutex);
  ------------------
  |  |   47|      8|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      8|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      8|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      8|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  116|      8|        return append_second(value, _op);
  117|      8|    }
_ZN4bvar6detail10SeriesBaseImNS0_5AddToImEEE13append_secondERKmRKS3_:
  161|      8|void SeriesBase<T, Op>::append_second(const T& value, const Op& op) {
  162|      8|    _data.second(_nsecond) = value;
  163|      8|    ++_nsecond;
  164|      8|    if (_nsecond >= 60) {
  ------------------
  |  Branch (164:9): [True: 0, False: 8]
  ------------------
  165|      0|        _nsecond = 0;
  166|      0|        T tmp = _data.second(0);
  167|      0|        for (int i = 1; i < 60; ++i) {
  ------------------
  |  Branch (167:25): [True: 0, False: 0]
  ------------------
  168|      0|            call_op_returning_void(op, tmp, _data.second(i));
  169|      0|        }
  170|      0|        DivideOnAddition<T, Op>::inplace_divide(tmp, op, 60);
  171|      0|        append_minute(tmp, op);
  172|      0|    }
  173|      8|}
_ZN4bvar6detail10SeriesBaseImNS0_5AddToImEEE4Data6secondEi:
  135|      8|        T& second(int index) { return _array[index]; }
_ZN4bvar6detail6SeriesIiNS0_5AddToIiEEEC2ERKS3_:
  218|      2|    explicit Series(const Op& op) : Base(op) {}
_ZN4bvar6detail10SeriesBaseIiNS0_5AddToIiEEEC2ERKS3_:
  103|      2|        : _op(op)
  104|      2|        , _nsecond(0)
  105|      2|        , _nminute(0)
  106|      2|        , _nhour(0)
  107|      2|        , _nday(0) {
  108|      2|        pthread_mutex_init(&_mutex, nullptr);
  109|      2|    }
_ZN4bvar6detail10SeriesBaseIiNS0_5AddToIiEEE4DataC2Ev:
  127|      2|        Data() {
  128|       |            // is_pod does not work for gcc 3.4
  129|      2|            if (butil::is_integral<T>::value ||
  ------------------
  |  Branch (129:17): [True: 2, Folded]
  ------------------
  130|      2|                butil::is_floating_point<T>::value) {
  ------------------
  |  Branch (130:17): [Folded, False: 0]
  ------------------
  131|      2|                memset(static_cast<void*>(_array), 0, sizeof(_array));
  132|      2|            }
  133|      2|        }
_ZN4bvar6detail10SeriesBaseIiNS0_5AddToIiEEE6appendERKi:
  114|      4|    void append(const T& value) {
  115|      4|        BAIDU_SCOPED_LOCK(_mutex);
  ------------------
  |  |   47|      4|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      4|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      4|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      4|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  116|      4|        return append_second(value, _op);
  117|      4|    }
_ZN4bvar6detail10SeriesBaseIiNS0_5AddToIiEEE13append_secondERKiRKS3_:
  161|      4|void SeriesBase<T, Op>::append_second(const T& value, const Op& op) {
  162|      4|    _data.second(_nsecond) = value;
  163|      4|    ++_nsecond;
  164|      4|    if (_nsecond >= 60) {
  ------------------
  |  Branch (164:9): [True: 0, False: 4]
  ------------------
  165|      0|        _nsecond = 0;
  166|      0|        T tmp = _data.second(0);
  167|      0|        for (int i = 1; i < 60; ++i) {
  ------------------
  |  Branch (167:25): [True: 0, False: 0]
  ------------------
  168|      0|            call_op_returning_void(op, tmp, _data.second(i));
  169|      0|        }
  170|      0|        DivideOnAddition<T, Op>::inplace_divide(tmp, op, 60);
  171|      0|        append_minute(tmp, op);
  172|      0|    }
  173|      4|}
_ZN4bvar6detail10SeriesBaseIiNS0_5AddToIiEEE4Data6secondEi:
  135|      4|        T& second(int index) { return _array[index]; }

_ZNK4bvar13PassiveStatusIlE9get_valueEv:
  139|      4|    Tp get_value() const {
  140|      4|        return (_getfn ? _getfn(_arg) : Tp());
  ------------------
  |  Branch (140:17): [True: 4, False: 0]
  ------------------
  141|      4|    }
_ZN4bvar13PassiveStatusIlE11expose_implERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESC_NS_13DisplayFilterE:
  172|      2|                    DisplayFilter display_filter) override {
  173|      2|        const int rc = Variable::expose_impl(prefix, name, display_filter);
  174|      2|        if (ADDITIVE &&
  ------------------
  |  Branch (174:13): [True: 2, Folded]
  ------------------
  175|      2|            rc == 0 &&
  ------------------
  |  Branch (175:13): [True: 2, False: 0]
  ------------------
  176|      2|            _series_sampler == nullptr &&
  ------------------
  |  Branch (176:13): [True: 2, False: 0]
  ------------------
  177|      2|            FLAGS_save_series) {
  ------------------
  |  Branch (177:13): [True: 2, False: 0]
  ------------------
  178|      2|            _series_sampler = new SeriesSampler(this);
  179|      2|            _series_sampler->schedule();
  180|      2|        }
  181|      2|        return rc;
  182|      2|    }
_ZN4bvar13PassiveStatusIlE13SeriesSamplerC2EPS1_:
   58|      2|            : _owner(owner), _vector_names(nullptr), _series(Op()) {}
_ZN4bvar13PassiveStatusIlE13SeriesSampler11take_sampleEv:
   62|      4|        void take_sample() override { _series.append(_owner->get_value()); }
_ZN4bvar13PassiveStatusIlEC2ERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEPFlPvESD_:
   81|      2|        : _getfn(getfn)
   82|      2|        , _arg(arg)
   83|      2|        , _sampler(nullptr)
   84|      2|        , _series_sampler(nullptr) {
   85|      2|        expose(name);
   86|      2|    }
_ZNK4bvar13PassiveStatusImE9get_valueEv:
  139|      8|    Tp get_value() const {
  140|      8|        return (_getfn ? _getfn(_arg) : Tp());
  ------------------
  |  Branch (140:17): [True: 8, False: 0]
  ------------------
  141|      8|    }
_ZN4bvar13PassiveStatusImE11expose_implERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESC_NS_13DisplayFilterE:
  172|      4|                    DisplayFilter display_filter) override {
  173|      4|        const int rc = Variable::expose_impl(prefix, name, display_filter);
  174|      4|        if (ADDITIVE &&
  ------------------
  |  Branch (174:13): [True: 4, Folded]
  ------------------
  175|      4|            rc == 0 &&
  ------------------
  |  Branch (175:13): [True: 4, False: 0]
  ------------------
  176|      4|            _series_sampler == nullptr &&
  ------------------
  |  Branch (176:13): [True: 4, False: 0]
  ------------------
  177|      4|            FLAGS_save_series) {
  ------------------
  |  Branch (177:13): [True: 4, False: 0]
  ------------------
  178|      4|            _series_sampler = new SeriesSampler(this);
  179|      4|            _series_sampler->schedule();
  180|      4|        }
  181|      4|        return rc;
  182|      4|    }
_ZN4bvar13PassiveStatusImE13SeriesSamplerC2EPS1_:
   58|      4|            : _owner(owner), _vector_names(nullptr), _series(Op()) {}
_ZN4bvar13PassiveStatusImE13SeriesSampler11take_sampleEv:
   62|      8|        void take_sample() override { _series.append(_owner->get_value()); }
_ZN4bvar13PassiveStatusIiEC2ERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEPFiPvESD_:
   81|      2|        : _getfn(getfn)
   82|      2|        , _arg(arg)
   83|      2|        , _sampler(nullptr)
   84|      2|        , _series_sampler(nullptr) {
   85|      2|        expose(name);
   86|      2|    }
_ZNK4bvar13PassiveStatusIiE9get_valueEv:
  139|      4|    Tp get_value() const {
  140|      4|        return (_getfn ? _getfn(_arg) : Tp());
  ------------------
  |  Branch (140:17): [True: 4, False: 0]
  ------------------
  141|      4|    }
_ZN4bvar13PassiveStatusIiE11expose_implERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESC_NS_13DisplayFilterE:
  172|      2|                    DisplayFilter display_filter) override {
  173|      2|        const int rc = Variable::expose_impl(prefix, name, display_filter);
  174|      2|        if (ADDITIVE &&
  ------------------
  |  Branch (174:13): [True: 2, Folded]
  ------------------
  175|      2|            rc == 0 &&
  ------------------
  |  Branch (175:13): [True: 2, False: 0]
  ------------------
  176|      2|            _series_sampler == nullptr &&
  ------------------
  |  Branch (176:13): [True: 2, False: 0]
  ------------------
  177|      2|            FLAGS_save_series) {
  ------------------
  |  Branch (177:13): [True: 2, False: 0]
  ------------------
  178|      2|            _series_sampler = new SeriesSampler(this);
  179|      2|            _series_sampler->schedule();
  180|      2|        }
  181|      2|        return rc;
  182|      2|    }
_ZN4bvar13PassiveStatusIiE13SeriesSamplerC2EPS1_:
   58|      2|            : _owner(owner), _vector_names(nullptr), _series(Op()) {}
_ZN4bvar13PassiveStatusIiE13SeriesSampler11take_sampleEv:
   62|      4|        void take_sample() override { _series.append(_owner->get_value()); }
_ZN4bvar13PassiveStatusImEC2ERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEPFmPvESD_:
   81|      4|        : _getfn(getfn)
   82|      4|        , _arg(arg)
   83|      4|        , _sampler(nullptr)
   84|      4|        , _series_sampler(nullptr) {
   85|      4|        expose(name);
   86|      4|    }

_ZN4bvar7ReducerIPNS_6detail7SamplerENS1_14CombineSamplerENS1_6VoidOpEEC2ERKS3_RKS4_RKS5_:
  204|      2|        : _combiner(std::make_shared<combiner_type>(identity, identity, op))
  205|      2|        , _sampler(nullptr) , _series_sampler(nullptr) , _inv_op(inv_op) {}
_ZN4bvar7ReducerIPNS_6detail7SamplerENS1_14CombineSamplerENS1_6VoidOpEE5resetEv:
  238|      4|    T reset() { return _combiner->reset_all_agents(); }
_ZN4bvar7ReducerIPNS_6detail7SamplerENS1_14CombineSamplerENS1_6VoidOpEElsERKS3_:
  302|      8|    typename butil::add_cr_non_integral<T>::type value) {
  303|       |    // It's wait-free for most time
  304|      8|    agent_type* agent = _combiner->get_or_create_tls_agent();
  305|      8|    if (__builtin_expect(!agent, 0)) {
  ------------------
  |  Branch (305:9): [True: 0, False: 8]
  ------------------
  306|      0|        LOG(FATAL) << "Fail to create agent";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  307|      0|        return *this;
  308|      0|    }
  309|      8|    agent->element.modify(_combiner->op(), value);
  310|      8|    return *this;
  311|      8|}

_ZN4bvar8Variable11expose_implERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESB_NS_13DisplayFilterE:
  131|      8|                          DisplayFilter display_filter) {
  132|      8|    if (name.empty()) {
  ------------------
  |  Branch (132:9): [True: 0, False: 8]
  ------------------
  133|      0|        LOG(ERROR) << "Parameter[name] is empty";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  134|      0|        return -1;
  135|      0|    }
  136|       |    // NOTE: It's impossible to atomically erase from a submap and insert into
  137|       |    // another submap without a global lock. When the to-be-exposed name
  138|       |    // already exists, there's a chance that we can't insert back previous
  139|       |    // name. But it should be fine generally because users are unlikely to
  140|       |    // expose a variable more than once and calls to expose() are unlikely
  141|       |    // to contend heavily.
  142|       |
  143|       |    // remove previous pointer from the map if needed.
  144|      8|    hide();
  145|       |
  146|       |    // Build the name.
  147|      8|    _name.clear();
  148|      8|    _name.reserve((prefix.size() + name.size()) * 5 / 4);
  149|      8|    if (!prefix.empty()) {
  ------------------
  |  Branch (149:9): [True: 0, False: 8]
  ------------------
  150|      0|        to_underscored_name(&_name, prefix);
  151|      0|        if (!_name.empty() && butil::back_char(_name) != '_') {
  ------------------
  |  Branch (151:13): [True: 0, False: 0]
  |  Branch (151:31): [True: 0, False: 0]
  ------------------
  152|      0|            _name.push_back('_');
  153|      0|        }
  154|      0|    }
  155|      8|    to_underscored_name(&_name, name);
  156|       |    
  157|      8|    VarMapWithLock& m = get_var_map(_name);
  158|      8|    {
  159|      8|        BAIDU_SCOPED_LOCK(m.mutex);
  ------------------
  |  |   47|      8|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      8|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      8|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      8|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  160|      8|        VarEntry* entry = m.seek(_name);
  161|      8|        if (entry == nullptr) {
  ------------------
  |  Branch (161:13): [True: 8, False: 0]
  ------------------
  162|      8|            entry = &m[_name];
  163|      8|            entry->var = this;
  164|      8|            entry->display_filter = display_filter;
  165|      8|            return 0;
  166|      8|        }
  167|      8|    }
  168|      0|    RELEASE_ASSERT_VERBOSE(!FLAGS_bvar_abort_on_same_name,
  ------------------
  |  |  489|      0|    do {                                                                            \
  |  |  490|      0|        if (!(condition)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (490:13): [True: 0, False: 0]
  |  |  ------------------
  |  |  491|      0|            ASSERT_LOG("Assert failure: " #condition ". " #fmt, ## __VA_ARGS__);    \
  |  |  ------------------
  |  |  |  |  469|      0|    do {                                                                \
  |  |  |  |  470|      0|        std::string log = butil::string_printf(fmt, ## __VA_ARGS__);    \
  |  |  |  |  471|      0|        LOG(FATAL) << log;                                              \
  |  |  |  |  ------------------
  |  |  |  |  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  472|      0|    } while (false)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  492|      0|            ::abort();                                                              \
  |  |  493|      0|        }                                                                           \
  |  |  494|      0|    } while (false)
  |  |  ------------------
  |  |  |  Branch (494:14): [Folded, False: 0]
  |  |  ------------------
  ------------------
  169|      0|                           "Abort due to name conflict");
  170|      0|    if (!s_bvar_may_abort) {
  ------------------
  |  Branch (170:9): [True: 0, False: 0]
  ------------------
  171|       |        // Mark name conflict occurs, If this conflict happens before
  172|       |        // initialization of bvar_abort_on_same_name, the validator will
  173|       |        // abort the program if needed.
  174|      0|        s_bvar_may_abort = true;
  175|      0|    }
  176|       |        
  177|      0|    LOG(ERROR) << "Already exposed `" << _name << "' whose value is `"
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  178|      0|               << describe_exposed(_name) << '\'';
  179|      0|    _name.clear();
  180|      0|    return -1;
  181|      0|}
_ZN4bvar8Variable4hideEv:
  187|      8|bool Variable::hide() {
  188|      8|    if (_name.empty()) {
  ------------------
  |  Branch (188:9): [True: 8, False: 0]
  ------------------
  189|      8|        return false;
  190|      8|    }
  191|      0|    VarMapWithLock& m = get_var_map(_name);
  192|      0|    BAIDU_SCOPED_LOCK(m.mutex);
  ------------------
  |  |   47|      0|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|      0|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|      0|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|      0|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  193|      0|    VarEntry* entry = m.seek(_name);
  194|      0|    if (entry) {
  ------------------
  |  Branch (194:9): [True: 0, False: 0]
  ------------------
  195|      0|        CHECK_EQ(1UL, m.erase(_name));
  ------------------
  |  |  692|      0|#define CHECK_EQ(val1, val2) BAIDU_CHECK_OP(EQ, ==, val1, val2)
  |  |  ------------------
  |  |  |  |  630|      0|    if (std::string* _result =                                          \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (630:22): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  631|      0|        ::logging::Check##name##Impl((val1), (val2),                    \
  |  |  |  |  632|      0|                                     #val1 " " #op " " #val2))          \
  |  |  |  |  633|      0|        ::logging::LogMessage(__FILE__, __LINE__, __func__, _result).stream().SetCheck()
  |  |  ------------------
  ------------------
  196|      0|    } else {
  197|      0|        CHECK(false) << "`" << _name << "' must exist";
  ------------------
  |  |  617|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(FATAL).SetCheck(), !(condition))     \
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  618|      0|    << "Check failed: " #condition ". "
  ------------------
  198|      0|    }
  199|      0|    _name.clear();
  200|      0|    return true;
  201|      8|}
_ZN4bvar19to_underscored_nameEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKN5butil16BasicStringPieceIS5_EE:
  942|      8|void to_underscored_name(std::string* name, const butil::StringPiece& src) {
  943|      8|    name->reserve(name->size() + src.size() + 8/*just guess*/);
  944|    170|    for (const char* p = src.data(); p != src.data() + src.size(); ++p) {
  ------------------
  |  Branch (944:38): [True: 162, False: 8]
  ------------------
  945|    162|        if (isalpha(*p)) {
  ------------------
  |  Branch (945:13): [True: 146, False: 16]
  ------------------
  946|    146|            if (*p < 'a') { // upper cases
  ------------------
  |  Branch (946:17): [True: 0, False: 146]
  ------------------
  947|      0|                if (p != src.data() && !isupper(p[-1]) &&
  ------------------
  |  Branch (947:21): [True: 0, False: 0]
  |  Branch (947:40): [True: 0, False: 0]
  ------------------
  948|      0|                    butil::back_char(*name) != '_') {
  ------------------
  |  Branch (948:21): [True: 0, False: 0]
  ------------------
  949|      0|                    name->push_back('_');
  950|      0|                }
  951|      0|                name->push_back(*p - 'A' + 'a');
  952|    146|            } else {
  953|    146|                name->push_back(*p);
  954|    146|            }
  955|    146|        } else if (isdigit(*p)) {
  ------------------
  |  Branch (955:20): [True: 0, False: 16]
  ------------------
  956|      0|            name->push_back(*p);
  957|     16|        } else if (name->empty() || butil::back_char(*name) != '_') {
  ------------------
  |  Branch (957:20): [True: 0, False: 16]
  |  Branch (957:37): [True: 16, False: 0]
  ------------------
  958|     16|            name->push_back('_');
  959|     16|        }
  960|    162|    }
  961|      8|}
_ZN4bvar11get_var_mapERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE:
  119|      8|inline VarMapWithLock& get_var_map(const std::string& name) {
  120|      8|    VarMapWithLock& m = get_var_maps()[sub_map_index(name)];
  121|      8|    return m;
  122|      8|}
_ZN4bvar13sub_map_indexERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE:
  102|      8|inline size_t sub_map_index(const std::string& str) {
  103|      8|    if (str.empty()) {
  ------------------
  |  Branch (103:9): [True: 0, False: 8]
  ------------------
  104|      0|        return 0;
  105|      0|    }
  106|      8|    size_t h = 0;
  107|       |    // we're assume that str is ended with '\0', which may not be in general
  108|    170|    for (const char* p  = str.c_str(); *p; ++p) {
  ------------------
  |  Branch (108:40): [True: 162, False: 8]
  ------------------
  109|    162|        h = h * 5 + *p;
  110|    162|    }
  111|      8|    return h & (SUB_MAP_COUNT - 1);
  112|      8|}
_ZN4bvar12get_var_mapsEv:
  114|      8|inline VarMapWithLock* get_var_maps() {
  115|      8|    pthread_once(&s_var_maps_once, init_var_maps);
  116|      8|    return s_var_maps;
  117|      8|}
variable.cpp:_ZN4bvarL13init_var_mapsEv:
   96|      2|static void init_var_maps() {
   97|       |    // It's probably slow to initialize all sub maps, but rpc often expose 
   98|       |    // variables before user. So this should not be an issue to users.
   99|      2|    s_var_maps = new VarMapWithLock[SUB_MAP_COUNT];
  100|      2|}
_ZN4bvar14VarMapWithLockC2Ev:
   78|     64|    VarMapWithLock() {
   79|     64|        if (init(1024) != 0) {
  ------------------
  |  Branch (79:13): [True: 0, False: 64]
  ------------------
   80|      0|            LOG(WARNING) << "Fail to init VarMap";
  ------------------
  |  |  485|      0|    BAIDU_LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
  |  |  ------------------
  |  |  |  |  472|      0|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   81|      0|        }
   82|       |
   83|     64|        pthread_mutexattr_t attr;
   84|     64|        pthread_mutexattr_init(&attr);
   85|     64|        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
   86|     64|        pthread_mutex_init(&mutex, &attr);
   87|     64|        pthread_mutexattr_destroy(&attr);
   88|     64|    }
_ZN4bvar8VarEntryC2Ev:
   67|      8|    VarEntry() : var(nullptr), display_filter(DISPLAY_ON_ALL) {}

_ZN4bvar8VariableC2Ev:
  120|     10|    Variable() {}
_ZN4bvar8Variable6exposeERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS_13DisplayFilterE:
  150|      8|               DisplayFilter display_filter = DISPLAY_ON_ALL) {
  151|      8|        return expose_impl(butil::StringPiece(), name, display_filter);
  152|      8|    }

LLVMFuzzerTestOneInput:
   26|    105|{
   27|    105|    if (size < kMinInputLength || size > kMaxInputLength){
  ------------------
  |  |   21|    210|#define kMinInputLength 5
  ------------------
                  if (size < kMinInputLength || size > kMaxInputLength){
  ------------------
  |  |   22|    105|#define kMaxInputLength 1024
  ------------------
  |  Branch (27:9): [True: 0, False: 105]
  |  Branch (27:35): [True: 21, False: 84]
  ------------------
   28|     21|        return 1;
   29|     21|    }
   30|       |
   31|     84|    std::string input(reinterpret_cast<const char*>(data), size);
   32|     84|    butil::IOBuf buf;
   33|     84|    buf.append(input);
   34|     84|    {
   35|     84|        butil::Arena arena;
   36|     84|        brpc::RedisCommandParser parser;
   37|     84|        std::vector<butil::StringPiece> command_out;
   38|     84|        parser.Consume(buf, &command_out, &arena);
   39|     84|    }
   40|     84|    {
   41|     84|        butil::Arena arena;
   42|     84|        brpc::RedisReply r2(&arena);
   43|     84|        r2.ConsumePartialIOBuf(buf);
   44|     84|    }
   45|       |
   46|     84|    return 0;
   47|    105|}

