_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:
  369|     53|    : _parsing_array(false)
  370|     53|    , _length(0)
  371|     53|    , _index(0) {}
_ZN4brpc18RedisCommandParser7ConsumeERN5butil5IOBufEPSt6vectorINS1_16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESaISC_EEPNS1_5ArenaE:
  379|     53|                                       butil::Arena* arena) {
  380|     53|    ParseError err = PARSE_OK;
  381|    253|    do {
  382|    253|        RedisCommandConsumeState state = ConsumeImpl(buf, arena, &err);
  383|    253|        if (state == CONSUME_STATE_CONTINUE) {
  ------------------
  |  Branch (383:13): [True: 200, False: 53]
  ------------------
  384|    200|            continue;
  385|    200|        } else if (state == CONSUME_STATE_DONE) {
  ------------------
  |  Branch (385:20): [True: 12, False: 41]
  ------------------
  386|     12|            break;
  387|     41|        } else {
  388|     41|            return err;
  389|     41|        }
  390|    253|    } while (true);
  ------------------
  |  Branch (390:14): [True: 200, Folded]
  ------------------
  391|       |    
  392|     12|    args->swap(_args);
  393|     12|    Reset();
  394|     12|    return PARSE_OK;
  395|     53|}
_ZN4brpc18RedisCommandParser11ConsumeImplERN5butil5IOBufEPNS1_5ArenaEPNS_10ParseErrorE:
  399|    253|                                                         ParseError* err) {
  400|    253|    const auto pfc = static_cast<const char *>(buf.fetch1());
  401|    253|    if (pfc == NULL) {
  ------------------
  |  Branch (401:9): [True: 1, False: 252]
  ------------------
  402|      1|        *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  403|      1|        return CONSUME_STATE_ERROR;
  404|      1|    }
  405|       |    // '*' stands for array "*<size>\r\n<sub-reply1><sub-reply2>..."
  406|    252|    if (!_parsing_array && *pfc != '*') {
  ------------------
  |  Branch (406:9): [True: 53, False: 199]
  |  Branch (406:28): [True: 24, False: 29]
  ------------------
  407|     24|        if (!std::isalpha(static_cast<unsigned char>(*pfc))) {
  ------------------
  |  Branch (407:13): [True: 12, False: 12]
  ------------------
  408|     12|            *err = PARSE_ERROR_TRY_OTHERS;
  409|     12|            return CONSUME_STATE_ERROR;
  410|     12|        }
  411|     12|        const size_t buf_size = buf.size();
  412|     12|        const auto copy_str = static_cast<char *>(arena->allocate(buf_size + 1));
  413|     12|        buf.copy_to(copy_str, buf_size);
  414|     12|        if (*copy_str == ' ') {
  ------------------
  |  Branch (414:13): [True: 0, False: 12]
  ------------------
  415|      0|            *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  416|      0|            return CONSUME_STATE_ERROR;
  417|      0|        }
  418|     12|        copy_str[buf_size] = '\0';
  419|     12|        const size_t crlf_pos = butil::StringPiece(copy_str, buf_size).find("\r\n");
  420|     12|        if (crlf_pos == butil::StringPiece::npos) {  // not enough data
  ------------------
  |  Branch (420:13): [True: 0, False: 12]
  ------------------
  421|      0|            *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  422|      0|            return CONSUME_STATE_ERROR;
  423|      0|        }
  424|     12|        size_t offset = 0;
  425|    375|        while (offset < crlf_pos && copy_str[offset] != ' ') {
  ------------------
  |  Branch (425:16): [True: 374, False: 1]
  |  Branch (425:37): [True: 363, False: 11]
  ------------------
  426|    363|            ++offset;
  427|    363|        }
  428|     12|        const auto first_arg = static_cast<char*>(arena->allocate(offset));
  429|     12|        memcpy(first_arg, copy_str, offset);
  430|    375|        for (size_t i = 0; i < offset; ++i) {
  ------------------
  |  Branch (430:28): [True: 363, False: 12]
  ------------------
  431|    363|            first_arg[i] = tolower(first_arg[i]);
  432|    363|        }
  433|     12|        _args.push_back(butil::StringPiece(first_arg, offset));
  434|     12|        if (offset == crlf_pos) {
  ------------------
  |  Branch (434:13): [True: 1, False: 11]
  ------------------
  435|       |            // only one argument, directly return
  436|      1|            buf.pop_front(crlf_pos + 2);
  437|      1|            return CONSUME_STATE_DONE;
  438|      1|        }
  439|     11|        size_t arg_start_pos = ++offset;
  440|       |
  441|  8.27k|        for (; offset < crlf_pos; ++offset) {
  ------------------
  |  Branch (441:16): [True: 8.26k, False: 11]
  ------------------
  442|  8.26k|            if (copy_str[offset] != ' ') {
  ------------------
  |  Branch (442:17): [True: 7.10k, False: 1.16k]
  ------------------
  443|  7.10k|                continue;
  444|  7.10k|            }
  445|  1.16k|            const auto arg_length = offset - arg_start_pos;
  446|  1.16k|            const auto arg = static_cast<char *>(arena->allocate(arg_length));
  447|  1.16k|            memcpy(arg, copy_str + arg_start_pos, arg_length);
  448|  1.16k|            _args.push_back(butil::StringPiece(arg, arg_length));
  449|  1.16k|            arg_start_pos = ++offset;
  450|  1.16k|        }
  451|       |
  452|     11|        if (arg_start_pos < crlf_pos) {
  ------------------
  |  Branch (452:13): [True: 7, False: 4]
  ------------------
  453|       |            // process the last argument
  454|      7|            const auto arg_length = crlf_pos - arg_start_pos;
  455|      7|            const auto arg = static_cast<char *>(arena->allocate(arg_length));
  456|      7|            memcpy(arg, copy_str + arg_start_pos, arg_length);
  457|      7|            _args.push_back(butil::StringPiece(arg, arg_length));
  458|      7|        }
  459|       |
  460|     11|        buf.pop_front(crlf_pos + 2);
  461|     11|        return CONSUME_STATE_DONE;
  462|     12|    }
  463|       |    // '$' stands for bulk string "$<length>\r\n<string>\r\n"
  464|    228|    if (_parsing_array && *pfc != '$') {
  ------------------
  |  Branch (464:9): [True: 199, False: 29]
  |  Branch (464:27): [True: 22, False: 177]
  ------------------
  465|     22|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  466|     22|        return CONSUME_STATE_ERROR;
  467|     22|    }
  468|    206|    char intbuf[32];  // enough for fc + 64-bit decimal + \r\n
  469|    206|    const size_t ncopied = buf.copy_to(intbuf, sizeof(intbuf) - 1);
  470|    206|    intbuf[ncopied] = '\0';
  471|    206|    const size_t crlf_pos = butil::StringPiece(intbuf, ncopied).find("\r\n");
  472|    206|    if (crlf_pos == butil::StringPiece::npos) {  // not enough data
  ------------------
  |  Branch (472:9): [True: 0, False: 206]
  ------------------
  473|      0|        *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  474|      0|        return CONSUME_STATE_ERROR;
  475|      0|    }
  476|    206|    char* endptr = NULL;
  477|    206|    int64_t value = strtoll(intbuf + 1/*skip fc*/, &endptr, 10);
  478|    206|    if (endptr != intbuf + crlf_pos) {
  ------------------
  |  Branch (478:9): [True: 0, False: 206]
  ------------------
  479|      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]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  480|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  481|      0|        return CONSUME_STATE_ERROR;
  482|      0|    }
  483|    206|    if (value < 0) {
  ------------------
  |  Branch (483:9): [True: 0, False: 206]
  ------------------
  484|      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]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  485|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  486|      0|        return CONSUME_STATE_ERROR;
  487|      0|    }
  488|    206|    if (!_parsing_array) {
  ------------------
  |  Branch (488:9): [True: 29, False: 177]
  ------------------
  489|     29|        if (value > (int64_t)(FLAGS_redis_max_allocation_size / sizeof(butil::StringPiece))) {
  ------------------
  |  Branch (489:13): [True: 1, False: 28]
  ------------------
  490|      1|            LOG(ERROR) << "command array size exceeds limit! 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]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  491|      1|                       << (FLAGS_redis_max_allocation_size / sizeof(butil::StringPiece))
  492|      1|                       << ", actually=" << value;
  493|      1|            *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  494|      1|            return CONSUME_STATE_ERROR;
  495|      1|        }
  496|     28|        buf.pop_front(crlf_pos + 2/*CRLF*/);
  497|     28|        _parsing_array = true;
  498|     28|        _length = value;
  499|     28|        _index = 0;
  500|     28|        _args.resize(value);
  501|     28|        return CONSUME_STATE_CONTINUE;
  502|     29|    }
  503|    177|    CHECK(_index < _length) << "a complete command has been parsed. "
  ------------------
  |  |  617|    177|    BAIDU_LAZY_STREAM(LOG_STREAM(FATAL).SetCheck(), !(condition))     \
  |  |  ------------------
  |  |  |  |  472|    177|    !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (472:5): [True: 173, False: 4]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  618|      8|    << "Check failed: " #condition ". "
  ------------------
  504|      4|                               "impl of RedisCommandParser::Parse is buggy";
  505|    177|    const int64_t len = value;  // `value' is length of the string
  506|    177|    if (len < 0) {
  ------------------
  |  Branch (506:9): [True: 0, False: 177]
  ------------------
  507|      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]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  508|      0|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  509|      0|        return CONSUME_STATE_ERROR;
  510|      0|    }
  511|    177|    if (len > FLAGS_redis_max_allocation_size) {
  ------------------
  |  Branch (511:9): [True: 2, False: 175]
  ------------------
  512|      2|        LOG(ERROR) << "command string 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]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  513|      2|                   << FLAGS_redis_max_allocation_size << ", actually=" << len;
  514|      2|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  515|      2|        return CONSUME_STATE_ERROR;
  516|      2|    }
  517|    175|    if (buf.size() < crlf_pos + 2 + (size_t)len + 2/*CRLF*/) {
  ------------------
  |  Branch (517:9): [True: 2, False: 173]
  ------------------
  518|      2|        *err = PARSE_ERROR_NOT_ENOUGH_DATA;
  519|      2|        return CONSUME_STATE_ERROR;
  520|      2|    }
  521|    173|    buf.pop_front(crlf_pos + 2/*CRLF*/);
  522|    173|    char* d = (char*)arena->allocate((len/8 + 1) * 8);
  523|    173|    buf.cutn(d, len);
  524|    173|    d[len] = '\0';
  525|    173|    _args[_index].set(d, len);
  526|    173|    if (_index == 0) {
  ------------------
  |  Branch (526:9): [True: 2, False: 171]
  ------------------
  527|       |        // convert it to lowercase when it is command name
  528|      2|        for (int i = 0; i < len; ++i) {
  ------------------
  |  Branch (528:25): [True: 0, False: 2]
  ------------------
  529|      0|            d[i] = ::tolower(d[i]);
  530|      0|        }
  531|      2|    }
  532|    173|    char crlf[2];
  533|    173|    buf.cutn(crlf, sizeof(crlf));
  534|    173|    if (crlf[0] != '\r' || crlf[1] != '\n') {
  ------------------
  |  Branch (534:9): [True: 0, False: 173]
  |  Branch (534:28): [True: 1, False: 172]
  ------------------
  535|      1|        LOG(ERROR) << "string in command is not ended with CRLF";
  ------------------
  |  |  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]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  536|      1|        *err = PARSE_ERROR_ABSOLUTELY_WRONG;
  537|      1|        return CONSUME_STATE_ERROR;
  538|      1|    }
  539|    172|    if (++_index == _length) {
  ------------------
  |  Branch (539:9): [True: 0, False: 172]
  ------------------
  540|      0|        return CONSUME_STATE_DONE;
  541|      0|    }
  542|    172|    return CONSUME_STATE_CONTINUE;
  543|    172|}
_ZN4brpc18RedisCommandParser5ResetEv:
  545|     12|void RedisCommandParser::Reset() {
  546|     12|    _parsing_array = false;
  547|     12|    _length = 0;
  548|     12|    _index = 0;
  549|     12|    _args.clear();
  550|     12|}

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

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

bthread_self:
  384|     29|bthread_t bthread_self(void) {
  385|     29|    bthread::TaskGroup* g = bthread::tls_task_group;
  386|       |    // note: return 0 for main tasks now, which include main thread and
  387|       |    // all work threads. So that we can identify main tasks from logs
  388|       |    // more easily. This is probably questionable in the future.
  389|     29|    if (g != NULL && !g->is_current_main_task()/*note*/) {
  ------------------
  |  Branch (389:9): [True: 0, False: 29]
  |  Branch (389:22): [True: 0, False: 0]
  ------------------
  390|      0|        return g->current_tid();
  391|      0|    }
  392|     29|    return INVALID_BTHREAD;
  393|     29|}

_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:
  572|      1|                        const void* dtor_args) {
  573|      1|    uint32_t index = 0;
  574|      1|    {
  575|      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
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  576|      1|        if (bthread::nfreekey > 0) {
  ------------------
  |  Branch (576:13): [True: 0, False: 1]
  ------------------
  577|      0|            index = bthread::s_free_keys[--bthread::nfreekey];
  578|      1|        } else if (bthread::nkey < bthread::KEYS_MAX) {
  ------------------
  |  Branch (578:20): [True: 1, False: 0]
  ------------------
  579|      1|            index = bthread::nkey++;
  580|      1|        } else {
  581|      0|            return EAGAIN;  // what pthread_key_create returns in this case.
  582|      0|        }
  583|      1|    }
  584|      1|    bthread::s_key_info[index].dtor = dtor;
  585|      1|    bthread::s_key_info[index].dtor_args = dtor_args;
  586|      1|    key->index = index;
  587|      1|    key->version = bthread::s_key_info[index].version;
  588|      1|    if (key->version == 0) {
  ------------------
  |  Branch (588:9): [True: 1, False: 0]
  ------------------
  589|      1|        ++bthread::s_key_info[index].version;
  590|      1|        ++key->version;
  591|      1|    }
  592|      1|    return 0;
  593|      1|}
bthread_key_create:
  595|      1|int bthread_key_create(bthread_key_t* key, void (*dtor)(void*)) {
  596|      1|    if (dtor == NULL) {
  ------------------
  |  Branch (596:9): [True: 0, False: 1]
  ------------------
  597|      0|        return bthread_key_create2(key, NULL, NULL);
  598|      1|    } else {
  599|      1|        return bthread_key_create2(key, bthread::arg_as_dtor, (const void*)dtor);
  600|      1|    }
  601|      1|}
bthread_setspecific:
  626|      1|int bthread_setspecific(bthread_key_t key, void* data) {
  627|      1|    bthread::KeyTable* kt = bthread::tls_bls.keytable;
  628|      1|    if (NULL == kt) {
  ------------------
  |  Branch (628:9): [True: 1, False: 0]
  ------------------
  629|      1|        kt = new (std::nothrow) bthread::KeyTable;
  630|      1|        if (NULL == kt) {
  ------------------
  |  Branch (630:13): [True: 0, False: 1]
  ------------------
  631|      0|            return ENOMEM;
  632|      0|        }
  633|      1|        bthread::tls_bls.keytable = kt;
  634|      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()
  ------------------
  635|      1|        if (g) {
  ------------------
  |  Branch (635:13): [True: 0, False: 1]
  ------------------
  636|      0|            g->current_task()->local_storage.keytable = kt;
  637|      1|        } else {
  638|       |            // Only cleanup keytable created by pthread.
  639|       |            // keytable created by bthread will be deleted
  640|       |            // in `return_keytable' or `bthread_keytable_pool_destroy'.
  641|      1|            if (!bthread::tls_ever_created_keytable) {
  ------------------
  |  Branch (641:17): [True: 1, False: 0]
  ------------------
  642|      1|                bthread::tls_ever_created_keytable = true;
  643|      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()
  |  |  ------------------
  ------------------
  644|      1|            }
  645|      1|        }
  646|      1|    }
  647|      1|    return kt->set_data(key, data);
  648|      1|}
bthread_getspecific:
  650|     29|void* bthread_getspecific(bthread_key_t key) {
  651|     29|    bthread::KeyTable* kt = bthread::tls_bls.keytable;
  652|     29|    if (kt) {
  ------------------
  |  Branch (652:9): [True: 28, False: 1]
  ------------------
  653|     28|        return kt->get_data(key);
  654|     28|    }
  655|      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()
  ------------------
  656|      1|    if (g) {
  ------------------
  |  Branch (656:9): [True: 0, False: 1]
  ------------------
  657|      0|        bthread::TaskMeta* const task = g->current_task();
  658|      0|        kt = bthread::borrow_keytable(task->attr.keytable_pool);
  659|      0|        if (kt) {
  ------------------
  |  Branch (659:13): [True: 0, False: 0]
  ------------------
  660|      0|            g->current_task()->local_storage.keytable = kt;
  661|      0|            bthread::tls_bls.keytable = kt;
  662|      0|            return kt->get_data(key);
  663|      0|        }
  664|      0|    }
  665|      1|    return NULL;
  666|      1|}
key.cpp:_ZN7bthreadL13get_key_countEPv:
  417|     15|static int get_key_count(void*) {
  418|     15|    BAIDU_SCOPED_LOCK(bthread::s_key_mutex);
  ------------------
  |  |   47|     15|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|     15|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|     15|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|     15|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  419|     15|    return (int)nkey - (int)nfreekey;
  420|     15|}
key.cpp:_ZN7bthreadL18get_keytable_countEPv:
  421|     15|static size_t get_keytable_count(void*) {
  422|     15|    return nkeytable.load(butil::memory_order_relaxed);
  423|     15|}
key.cpp:_ZN7bthreadL19get_keytable_memoryEPv:
  424|     15|static size_t get_keytable_memory(void*) {
  425|     15|    const size_t n = nkeytable.load(butil::memory_order_relaxed);
  426|     15|    const size_t nsub = nsubkeytable.load(butil::memory_order_relaxed);
  427|     15|    return n * sizeof(KeyTable) + nsub * sizeof(SubKeyTable);
  428|     15|}
_ZN7bthread8KeyTableC2Ev:
  155|      1|    KeyTable() : next(NULL) {
  156|      1|        memset(_subs, 0, sizeof(_subs));
  157|      1|        nkeytable.fetch_add(1, butil::memory_order_relaxed);
  158|      1|    }
_ZN7bthread8KeyTable8set_dataE13bthread_key_tPv:
  197|      1|    inline int set_data(bthread_key_t key, void* data) {
  198|      1|        const uint32_t subidx = key.index / KEY_2NDLEVEL_SIZE;
  199|      1|        if (subidx < KEY_1STLEVEL_SIZE &&
  ------------------
  |  Branch (199:13): [True: 1, False: 0]
  ------------------
  200|      1|            key.version == s_key_info[key.index].version) {
  ------------------
  |  Branch (200:13): [True: 1, False: 0]
  ------------------
  201|      1|            SubKeyTable* sub_kt = _subs[subidx];
  202|      1|            if (sub_kt == NULL) {
  ------------------
  |  Branch (202:17): [True: 1, False: 0]
  ------------------
  203|      1|                sub_kt = new (std::nothrow) SubKeyTable;
  204|      1|                if (NULL == sub_kt) {
  ------------------
  |  Branch (204:21): [True: 0, False: 1]
  ------------------
  205|      0|                    return ENOMEM;
  206|      0|                }
  207|      1|                _subs[subidx] = sub_kt;
  208|      1|            }
  209|      1|            sub_kt->set_data(key.index - subidx * KEY_2NDLEVEL_SIZE,
  210|      1|                             key.version, data);
  211|      1|            return 0;
  212|      1|        }
  213|      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 ". "
  ------------------
  214|       |        return EINVAL;
  215|      1|    }
_ZN7bthread11SubKeyTableC2Ev:
   95|      1|    SubKeyTable() {
   96|      1|        memset(_data, 0, sizeof(_data));
   97|      1|        nsubkeytable.fetch_add(1, butil::memory_order_relaxed);
   98|      1|    }
_ZN7bthread11SubKeyTable8set_dataEjjPv:
  138|      1|    inline void set_data(uint32_t index, uint32_t version, void* data) {
  139|      1|        _data[index].version = version;
  140|      1|        _data[index].ptr = data;
  141|      1|    }
_ZNK7bthread8KeyTable8get_dataE13bthread_key_t:
  185|     28|    inline void* get_data(bthread_key_t key) const {
  186|     28|        const uint32_t subidx = key.index / KEY_2NDLEVEL_SIZE;
  187|     28|        if (subidx < KEY_1STLEVEL_SIZE) {
  ------------------
  |  Branch (187:13): [True: 28, False: 0]
  ------------------
  188|     28|            const SubKeyTable* sub_kt = _subs[subidx];
  189|     28|            if (sub_kt) {
  ------------------
  |  Branch (189:17): [True: 28, False: 0]
  ------------------
  190|     28|                return sub_kt->get_data(
  191|     28|                    key.index - subidx * KEY_2NDLEVEL_SIZE, key.version);
  192|     28|            }
  193|     28|        }
  194|      0|        return NULL;
  195|     28|    }
_ZNK7bthread11SubKeyTable8get_dataEjj:
  132|     28|    inline void* get_data(uint32_t index, uint32_t version) const {
  133|     28|        if (_data[index].version == version) {
  ------------------
  |  Branch (133:13): [True: 28, False: 0]
  ------------------
  134|     28|            return _data[index].ptr;
  135|     28|        }
  136|      0|        return NULL;
  137|     28|    }

_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:
 1299|    193|                       const pthread_mutexattr_t* __restrict mutexattr) {
 1300|    193|    INIT_MUTEX_OWNER_MAP_ENTRY(mutex, mutexattr);
  ------------------
  |  |  787|    193|#define INIT_MUTEX_OWNER_MAP_ENTRY(mutex, mutexattr) ((void)0)
  ------------------
 1301|    193|    return bthread::sys_pthread_mutex_init(mutex, mutexattr);
 1302|    193|}
pthread_mutex_lock:
 1309|    365|int pthread_mutex_lock(pthread_mutex_t* mutex) {
 1310|    365|    return bthread::pthread_mutex_lock_impl(mutex);
 1311|    365|}
pthread_mutex_unlock:
 1324|    365|int pthread_mutex_unlock(pthread_mutex_t* mutex) {
 1325|    365|    return bthread::pthread_mutex_unlock_impl(mutex);
 1326|    365|}
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|}
_ZN7bthread23pthread_mutex_lock_implEP15pthread_mutex_t:
  973|    365|BUTIL_FORCE_INLINE int pthread_mutex_lock_impl(pthread_mutex_t* mutex) {
  974|       |    return internal::pthread_mutex_lock_impl(mutex, NULL);
  975|    365|}
_ZN7bthread8internal23pthread_mutex_lock_implI15pthread_mutex_tEEiPT_PK8timespec:
  870|    365|BUTIL_FORCE_INLINE int pthread_mutex_lock_impl(Mutex* mutex, const struct timespec* abstime) {
  871|       |    // Don't change behavior of lock when profiler is off.
  872|    365|    if (!g_cp ||
  ------------------
  |  Branch (872:9): [True: 365, False: 0]
  ------------------
  873|       |        // collecting code including backtrace() and submit() may call
  874|       |        // pthread_mutex_lock and cause deadlock. Don't sample.
  875|    365|        tls_inside_lock) {
  ------------------
  |  Branch (875:9): [True: 0, False: 0]
  ------------------
  876|    365|        return pthread_mutex_lock_internal(mutex, abstime);
  877|    365|    }
  878|       |    // Don't slow down non-contended locks.
  879|      0|    int rc = pthread_mutex_trylock_internal(mutex);
  880|      0|    if (rc != EBUSY) {
  ------------------
  |  Branch (880:9): [True: 0, False: 0]
  ------------------
  881|      0|        return rc;
  882|      0|    }
  883|       |    // Ask bvar::Collector if this (contended) locking should be sampled
  884|      0|    const size_t sampling_range = bvar::is_collectable(&g_cp_sl);
  885|       |
  886|      0|    bthread_contention_site_t* csite = NULL;
  887|      0|#ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS
  888|      0|    TLSPthreadContentionSites& fast_alt = tls_csites;
  889|      0|    if (fast_alt.cp_version != g_cp_version) {
  ------------------
  |  Branch (889:9): [True: 0, False: 0]
  ------------------
  890|      0|        fast_alt.cp_version = g_cp_version;
  891|      0|        fast_alt.count = 0;
  892|      0|    }
  893|      0|    if (fast_alt.count < TLS_MAX_COUNT) {
  ------------------
  |  Branch (893:9): [True: 0, False: 0]
  ------------------
  894|      0|        MutexAndContentionSite& entry = fast_alt.list[fast_alt.count++];
  895|      0|        entry.mutex = mutex;
  896|      0|        csite = &entry.csite;
  897|      0|        if (!bvar::is_sampling_range_valid(sampling_range)) {
  ------------------
  |  Branch (897:13): [True: 0, False: 0]
  ------------------
  898|      0|            make_contention_site_invalid(&entry.csite);
  899|      0|            return pthread_mutex_lock_internal(mutex, abstime);
  900|      0|        }
  901|      0|    }
  902|      0|#endif
  903|      0|    if (!bvar::is_sampling_range_valid(sampling_range)) {  // don't sample
  ------------------
  |  Branch (903:9): [True: 0, False: 0]
  ------------------
  904|      0|        return pthread_mutex_lock_internal(mutex, abstime);
  905|      0|    }
  906|       |    // Lock and monitor the waiting time.
  907|      0|    const int64_t start_ns = butil::cpuwide_time_ns();
  908|      0|    rc = pthread_mutex_lock_internal(mutex, abstime);
  909|      0|    if (!rc) { // Inside lock
  ------------------
  |  Branch (909:9): [True: 0, False: 0]
  ------------------
  910|      0|        if (!csite) {
  ------------------
  |  Branch (910:13): [True: 0, False: 0]
  ------------------
  911|      0|            csite = add_pthread_contention_site(mutex);
  912|      0|            if (csite == NULL) {
  ------------------
  |  Branch (912:17): [True: 0, False: 0]
  ------------------
  913|      0|                return rc;
  914|      0|            }
  915|      0|        }
  916|      0|        csite->duration_ns = butil::cpuwide_time_ns() - start_ns;
  917|      0|        csite->sampling_range = sampling_range;
  918|      0|    } // else rare
  919|      0|    return rc;
  920|      0|}
_ZN7bthread8internal27pthread_mutex_lock_internalEP15pthread_mutex_tPK8timespec:
  798|    365|                                                   const struct timespec* abstime) {
  799|    365|    int rc = 0;
  800|    365|    if (NULL == abstime) {
  ------------------
  |  Branch (800:9): [True: 365, False: 0]
  ------------------
  801|    365|        FIND_SYS_PTHREAD_MUTEX_OWNER_MAP_ENTRY(mutex);
  ------------------
  |  |  789|    365|#define FIND_SYS_PTHREAD_MUTEX_OWNER_MAP_ENTRY(mutex) ((void)0)
  ------------------
  802|    365|        SYS_PTHREAD_MUTEX_CHECK_OWNER;
  ------------------
  |  |  790|    365|#define SYS_PTHREAD_MUTEX_CHECK_OWNER ((void)0)
  ------------------
  803|    365|        rc = sys_pthread_mutex_lock(mutex);
  804|    365|        if (0 == rc) {
  ------------------
  |  Branch (804:13): [True: 365, False: 0]
  ------------------
  805|    365|            SYS_PTHREAD_MUTEX_SET_OWNER;
  ------------------
  |  |  791|    365|#define SYS_PTHREAD_MUTEX_SET_OWNER ((void)0)
  ------------------
  806|    365|        }
  807|    365|    } else {
  808|      0|        rc = sys_pthread_mutex_timedlock(mutex, abstime);
  809|      0|        if (0 == rc) {
  ------------------
  |  Branch (809:13): [True: 0, False: 0]
  ------------------
  810|      0|            FIND_SYS_PTHREAD_MUTEX_OWNER_MAP_ENTRY(mutex);
  ------------------
  |  |  789|      0|#define FIND_SYS_PTHREAD_MUTEX_OWNER_MAP_ENTRY(mutex) ((void)0)
  ------------------
  811|      0|            SYS_PTHREAD_MUTEX_SET_OWNER;
  ------------------
  |  |  791|      0|#define SYS_PTHREAD_MUTEX_SET_OWNER ((void)0)
  ------------------
  812|      0|        }
  813|      0|    }
  814|    365|    if (0 == rc) {
  ------------------
  |  Branch (814:9): [True: 365, False: 0]
  ------------------
  815|    365|        ADD_TLS_PTHREAD_LOCK_COUNT;
  ------------------
  |  |  554|    365|#define ADD_TLS_PTHREAD_LOCK_COUNT ((void)0)
  ------------------
  816|    365|    }
  817|    365|    return rc;
  818|    365|}
_ZN7bthread25pthread_mutex_unlock_implEP15pthread_mutex_t:
  988|    365|BUTIL_FORCE_INLINE int pthread_mutex_unlock_impl(pthread_mutex_t* mutex) {
  989|    365|    return internal::pthread_mutex_unlock_impl(mutex);
  990|    365|}
_ZN7bthread8internal25pthread_mutex_unlock_implI15pthread_mutex_tEEiPT_:
  928|    365|BUTIL_FORCE_INLINE int pthread_mutex_unlock_impl(Mutex* mutex) {
  929|       |    // Don't change behavior of unlock when profiler is off.
  930|    365|    if (!g_cp || tls_inside_lock) {
  ------------------
  |  Branch (930:9): [True: 365, False: 0]
  |  Branch (930:18): [True: 0, False: 0]
  ------------------
  931|       |        // This branch brings an issue that an entry created by
  932|       |        // add_pthread_contention_site may not be cleared. Thus we add a
  933|       |        // 16-bit rolling version in the entry to find out such entry.
  934|    365|        return pthread_mutex_unlock_internal(mutex);
  935|    365|    }
  936|      0|    int64_t unlock_start_ns = 0;
  937|      0|    bool miss_in_tls = true;
  938|      0|    bthread_contention_site_t saved_csite = {0,0};
  939|      0|#ifndef DONT_SPEEDUP_PTHREAD_CONTENTION_PROFILER_WITH_TLS
  940|      0|    TLSPthreadContentionSites& fast_alt = tls_csites;
  941|      0|    for (int i = fast_alt.count - 1; i >= 0; --i) {
  ------------------
  |  Branch (941:38): [True: 0, False: 0]
  ------------------
  942|      0|        if (fast_alt.list[i].mutex == mutex) {
  ------------------
  |  Branch (942:13): [True: 0, False: 0]
  ------------------
  943|      0|            if (is_contention_site_valid(fast_alt.list[i].csite)) {
  ------------------
  |  Branch (943:17): [True: 0, False: 0]
  ------------------
  944|      0|                saved_csite = fast_alt.list[i].csite;
  945|      0|                unlock_start_ns = butil::cpuwide_time_ns();
  946|      0|            }
  947|      0|            fast_alt.list[i] = fast_alt.list[--fast_alt.count];
  948|      0|            miss_in_tls = false;
  949|      0|            break;
  950|      0|        }
  951|      0|    }
  952|      0|#endif
  953|       |    // Check the map to see if the lock is sampled. Notice that we're still
  954|       |    // inside critical section.
  955|      0|    if (miss_in_tls) {
  ------------------
  |  Branch (955:9): [True: 0, False: 0]
  ------------------
  956|      0|        if (remove_pthread_contention_site(mutex, &saved_csite)) {
  ------------------
  |  Branch (956:13): [True: 0, False: 0]
  ------------------
  957|      0|            unlock_start_ns = butil::cpuwide_time_ns();
  958|      0|        }
  959|      0|    }
  960|      0|    const int rc = pthread_mutex_unlock_internal(mutex);
  961|       |    // [Outside lock]
  962|      0|    if (unlock_start_ns) {
  ------------------
  |  Branch (962:9): [True: 0, False: 0]
  ------------------
  963|      0|        const int64_t unlock_end_ns = butil::cpuwide_time_ns();
  964|      0|        saved_csite.duration_ns += unlock_end_ns - unlock_start_ns;
  965|      0|        submit_contention(saved_csite, unlock_end_ns);
  966|      0|    }
  967|      0|    return rc;
  968|    365|}
_ZN7bthread8internal29pthread_mutex_unlock_internalEP15pthread_mutex_t:
  843|    365|BUTIL_FORCE_INLINE int pthread_mutex_unlock_internal(pthread_mutex_t* mutex) {
  844|    365|    SYS_PTHREAD_MUTEX_RESET_OWNER(mutex);
  ------------------
  |  |  792|    365|#define SYS_PTHREAD_MUTEX_RESET_OWNER(mutex) ((void)0)
  ------------------
  845|    365|    SUB_TLS_PTHREAD_LOCK_COUNT;
  ------------------
  |  |  555|    365|#define SUB_TLS_PTHREAD_LOCK_COUNT ((void)0)
  ------------------
  846|    365|    return sys_pthread_mutex_unlock(mutex);
  847|    365|}

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

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

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

_ZN5butil6atomicIiEC2Ei:
  235|      7|    atomic(T v) : ::std::atomic<T>(v) {}
_ZN5butil13static_atomicImE9fetch_addEmSt12memory_order:
  304|     14|    T fetch_add(T v, memory_order o) { return ref().fetch_add(v, o); }
_ZN5butil13static_atomicImE3refEv:
  316|     69|    atomic<T>& ref() {
  317|       |        // Suppress strict-alias warnings.
  318|     69|        atomic<T>* p = reinterpret_cast<atomic<T>*>(&val);
  319|     69|        return *p;
  320|     69|    }
_ZN5butil13static_atomicImE9fetch_subEmSt12memory_order:
  305|     10|    T fetch_sub(T v, memory_order o) { return ref().fetch_sub(v, o); }
_ZN5butil13static_atomicImE4loadESt12memory_order:
  293|     45|    T load(memory_order o) { return ref().load(o); }
_ZN5butil13static_atomicIlE3refEv:
  316|     15|    atomic<T>& ref() {
  317|       |        // Suppress strict-alias warnings.
  318|     15|        atomic<T>* p = reinterpret_cast<atomic<T>*>(&val);
  319|     15|        return *p;
  320|     15|    }
_ZN5butil13static_atomicIlE4loadESt12memory_order:
  293|     15|    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: 0, False: 2]
  ------------------
   68|      0|    family += (eax >> 20) & 0xff;
   69|      0|    model += ((eax >> 16) & 0xf) << 4;
   70|      0|  }
   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: 0, False: 2]
  ------------------
   78|      0|      family == 15 &&
  ------------------
  |  Branch (78:7): [True: 0, False: 0]
  ------------------
   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|     66|inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
  207|     66|  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|     66|  ATOMICOPS_COMPILER_BARRIER();
  ------------------
  |  |   24|     66|#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
  ------------------
  211|     66|  return value;
  212|     66|}
_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|     29|        ScopedPtr() : _data(NULL), _index(0), _w(NULL) {}
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE9ScopedPtrD2Ev:
   98|     29|        ~ScopedPtr() {
   99|     29|            if (_w) {
  ------------------
  |  Branch (99:17): [True: 29, False: 0]
  ------------------
  100|     29|                if (AllowBthreadSuspended) {
  ------------------
  |  Branch (100:21): [Folded, False: 29]
  ------------------
  101|      0|                    _w->EndRead(_index);
  102|     29|                } else {
  103|     29|                    _w->EndRead();
  104|     29|                }
  105|     29|            }
  106|     29|        }
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE7Wrapper7EndReadEv:
  340|     29|    inline void EndRead() {
  341|     29|        pthread_mutex_unlock(&_mutex);
  342|     29|    }
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE4ReadEPNS5_9ScopedPtrE:
  476|     29|    typename DoublyBufferedData<T, TLS, AllowBthreadSuspended>::ScopedPtr* ptr) {
  477|     29|    WrapperSharedPtr w = GetWrapper();
  478|     29|    if (BAIDU_UNLIKELY(w == NULL)) {
  ------------------
  |  |  272|     29|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 29]
  |  |  ------------------
  ------------------
  479|      0|        return -1;
  480|      0|    }
  481|       |
  482|     29|    if (AllowBthreadSuspended) {
  ------------------
  |  Branch (482:9): [Folded, False: 29]
  ------------------
  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|     29|    } else {
  492|     29|        w->BeginRead();
  493|     29|        ptr->_data = UnsafeRead();
  494|     29|    }
  495|     29|    ptr->_w.swap(w);
  496|     29|    return 0;
  497|     29|}
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE10GetWrapperEv:
  404|     29|DoublyBufferedData<T, TLS, AllowBthreadSuspended>::GetWrapper() {
  405|     29|    WrapperSharedPtr w = WrapperTLSGroup::get_or_create_tls_data(_wrapper_key);
  406|     29|    if (NULL == w) {
  ------------------
  |  Branch (406:9): [True: 0, False: 29]
  ------------------
  407|      0|        return NULL;
  408|      0|    }
  409|     29|    if (w->_control == this) {
  ------------------
  |  Branch (409:9): [True: 28, False: 1]
  ------------------
  410|     28|        return w;
  411|     28|    }
  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|     29|    static WrapperSharedPtr get_or_create_tls_data(WrapperTLSId id) {
  238|     29|        if (BAIDU_UNLIKELY(id < 0)) {
  ------------------
  |  |  272|     29|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 29]
  |  |  ------------------
  ------------------
  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|     29|        if (_s_tls_blocks == NULL) {
  ------------------
  |  Branch (242:13): [True: 1, False: 28]
  ------------------
  243|      1|            _s_tls_blocks = new std::vector<ThreadBlock*>;
  244|      1|            butil::thread_atexit(_destroy_tls_blocks);
  245|      1|        }
  246|     29|        const size_t block_id = (size_t)id / ELEMENTS_PER_BLOCK;
  247|     29|        if (block_id >= _s_tls_blocks->size()) {
  ------------------
  |  Branch (247:13): [True: 1, False: 28]
  ------------------
  248|       |            // The 32ul avoid pointless small resizes.
  249|      1|            _s_tls_blocks->resize(std::max(block_id + 1, 32ul));
  250|      1|        }
  251|     29|        ThreadBlock* tb = (*_s_tls_blocks)[block_id];
  252|     29|        if (tb == NULL) {
  ------------------
  |  Branch (252:13): [True: 1, False: 28]
  ------------------
  253|      1|            tb = new ThreadBlock;
  254|      1|            (*_s_tls_blocks)[block_id] = tb;
  255|      1|        }
  256|     29|        return tb->at(id - block_id * ELEMENTS_PER_BLOCK);
  257|     29|    }
_ZN5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE15WrapperTLSGroup11ThreadBlock2atEm:
  204|     29|        WrapperSharedPtr at(size_t offset) {
  205|     29|            if (NULL == _data[offset]) {
  ------------------
  |  Branch (205:17): [True: 1, False: 28]
  ------------------
  206|      1|                _data[offset] = std::make_shared<Wrapper>();
  207|      1|            }
  208|     29|            return _data[offset];
  209|     29|        };
_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|     29|    inline void BeginRead() {
  332|     29|        pthread_mutex_lock(&_mutex);
  333|     29|    }
_ZNK5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE10UnsafeReadEv:
  149|     29|    const T* UnsafeRead() const {
  150|     29|        return _data + _index.load(butil::memory_order_acquire);
  151|     29|    }
_ZNK5butil18DoublyBufferedDataIPN7logging7LogSinkENS_4VoidELb0EE9ScopedPtrdeEv:
  108|     29|        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|     15|  LinkNode<T>* head() const {
  180|     15|    return root_.next();
  181|     15|  }
_ZNK5butil10LinkedListIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE3endEv:
  187|     30|  const LinkNode<T>* end() const {
  188|     30|    return &root_;
  189|     30|  }
_ZN5butil8LinkNodeIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE5valueEv:
  150|     15|  T* value() {
  151|     15|    return static_cast<T*>(this);
  152|     15|  }
_ZNK5butil8LinkNodeIN4bvar6detail13AgentCombinerIPNS2_7SamplerES5_NS2_14CombineSamplerEE5AgentEE4nextEv:
  141|     30|  LinkNode<T>* next() const {
  142|     30|    return next_;
  143|     30|  }
_ZN5butil8LinkNodeIN4bvar6detail7SamplerEEC2Ev:
   88|     10|  LinkNode() : previous_(this), next_(this) {}
_ZNK5butil8LinkNodeIN4bvar6detail7SamplerEE4nextEv:
  141|     75|  LinkNode<T>* next() const {
  142|     75|    return next_;
  143|     75|  }
_ZN5butil8LinkNodeIN4bvar6detail7SamplerEE5valueEv:
  150|     60|  T* value() {
  151|     60|    return static_cast<T*>(this);
  152|     60|  }
_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|  }

_ZN5butil9nullopt_tC2ENS_8internal20optional_forbidden_tE:
   59|     12|    explicit nullopt_t(internal::optional_forbidden_t) noexcept {}
_ZN5butil8optionalINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoEEC2EOSG_:
  198|     64|    optional(T&& value) : _engaged(true) {
  199|     64|        _storage.Init(std::move(value));
  200|     64|    }
_ZNK5butil8optionalINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoEE9has_valueEv:
  309|     64|    bool has_value() const { return _engaged; }
_ZN5butil8optionalINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoEEptEv:
  300|    192|    T* operator->() {
  301|    192|        return _storage.get();
  302|    192|    }
_ZN5butil8optionalINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoEED2Ev:
  233|     64|    ~optional() {
  234|     64|        reset();
  235|     64|    }
_ZN5butil8optionalINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoEE5resetEv:
  377|     64|    void reset() {
  378|     64|        if (_engaged) {
  ------------------
  |  Branch (378:13): [True: 64, False: 0]
  ------------------
  379|     64|            _storage.Destroy();
  380|     64|            _engaged = false;
  381|     64|        }
  382|     64|    }

_ZN5butil5debug10StackTraceC2EPKPKvm:
   17|      4|StackTrace::StackTrace(const void* const* trace, size_t count) {
   18|      4|  count = std::min(count, arraysize(trace_));
  ------------------
  |  |  122|      4|#define arraysize(array) (sizeof(::butil::ArraySizeHelper(array)))
  ------------------
   19|      4|  if (count)
  ------------------
  |  Branch (19:7): [True: 4, False: 0]
  ------------------
   20|      4|    memcpy(trace_, trace, count * sizeof(trace_[0]));
   21|      4|  count_ = count;
   22|      4|}
_ZNK5butil5debug10StackTrace9AddressesEPm:
   24|      4|const void *const *StackTrace::Addresses(size_t* count) const {
   25|      4|  *count = count_;
   26|      4|  if (count_)
  ------------------
  |  Branch (26:7): [True: 4, False: 0]
  ------------------
   27|      4|    return trace_;
   28|      0|  return NULL;
   29|      4|}

_ZN5butil5debug10StackTraceC2Eb:
  766|      6|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|      6|  if (GetStackTrace) {
  ------------------
  |  Branch (770:7): [True: 0, False: 6]
  ------------------
  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|      6|  } else {
  773|      6|#if !defined(__UCLIBC__)
  774|       |    // Though the backtrace API man page does not list any possible negative
  775|       |    // return values, we take no chance.
  776|      6|    count_ = butil::saturated_cast<size_t>(backtrace(trace_, arraysize(trace_)));
  ------------------
  |  |  122|      6|#define arraysize(array) (sizeof(::butil::ArraySizeHelper(array)))
  ------------------
  777|      6|    if (exclude_self && count_ > 1) {
  ------------------
  |  Branch (777:9): [True: 0, False: 6]
  |  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|      6|  }
  786|      6|}
_ZNK5butil5debug10StackTrace14OutputToStreamEPSo:
  817|      4|void StackTrace::OutputToStream(std::ostream* os) const {
  818|      4|  StreamBacktraceOutputHandler handler(os);
  819|      4|  ProcessBacktrace(trace_, count_, &handler);
  820|      4|}
_ZN5butil5debug8internal6itoa_rElPcmim:
  831|     80|char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) {
  832|       |  // Make sure we can write at least one NUL byte.
  833|     80|  size_t n = 1;
  834|     80|  if (n > sz)
  ------------------
  |  Branch (834:7): [True: 0, False: 80]
  ------------------
  835|      0|    return NULL;
  836|       |
  837|     80|  if (base < 2 || base > 16) {
  ------------------
  |  Branch (837:7): [True: 0, False: 80]
  |  Branch (837:19): [True: 0, False: 80]
  ------------------
  838|      0|    buf[0] = '\000';
  839|      0|    return NULL;
  840|      0|  }
  841|       |
  842|     80|  char *start = buf;
  843|       |
  844|     80|  uintptr_t j = i;
  845|       |
  846|       |  // Handle negative numbers (only for base 10).
  847|     80|  if (i < 0 && base == 10) {
  ------------------
  |  Branch (847:7): [True: 0, False: 80]
  |  Branch (847:16): [True: 0, False: 0]
  ------------------
  848|      0|    j = -i;
  849|       |
  850|       |    // Make sure we can write the '-' character.
  851|      0|    if (++n > sz) {
  ------------------
  |  Branch (851:9): [True: 0, False: 0]
  ------------------
  852|      0|      buf[0] = '\000';
  853|      0|      return NULL;
  854|      0|    }
  855|      0|    *start++ = '-';
  856|      0|  }
  857|       |
  858|       |  // Loop until we have converted the entire number. Output at least one
  859|       |  // character (i.e. '0').
  860|     80|  char *ptr = start;
  861|    520|  do {
  862|       |    // Make sure there is still enough space left in our output buffer.
  863|    520|    if (++n > sz) {
  ------------------
  |  Branch (863:9): [True: 0, False: 520]
  ------------------
  864|      0|      buf[0] = '\000';
  865|      0|      return NULL;
  866|      0|    }
  867|       |
  868|       |    // Output the next digit.
  869|    520|    *ptr++ = "0123456789abcdef"[j % base];
  870|    520|    j /= base;
  871|       |
  872|    520|    if (padding > 0)
  ------------------
  |  Branch (872:9): [True: 520, False: 0]
  ------------------
  873|    520|      padding--;
  874|    520|  } while (j > 0 || padding > 0);
  ------------------
  |  Branch (874:12): [True: 440, False: 80]
  |  Branch (874:21): [True: 0, False: 80]
  ------------------
  875|       |
  876|       |  // Terminate the output with a NUL character.
  877|     80|  *ptr = '\000';
  878|       |
  879|       |  // Conversion to ASCII actually resulted in the digits being in reverse
  880|       |  // order. We can't easily generate them in forward order, as we can't tell
  881|       |  // the number of characters needed until we are done converting.
  882|       |  // So, now, we reverse the string (except for the possible "-" sign).
  883|    320|  while (--ptr > start) {
  ------------------
  |  Branch (883:10): [True: 240, False: 80]
  ------------------
  884|    240|    char ch = *ptr;
  885|    240|    *ptr = *start;
  886|    240|    *start++ = ch;
  887|    240|  }
  888|     80|  return buf;
  889|     80|}
stack_trace_posix.cc:_ZN5butil5debug12_GLOBAL__N_122BacktraceOutputHandlerD2Ev:
  124|      4|  virtual ~BacktraceOutputHandler() {}
stack_trace_posix.cc:_ZN5butil5debug12_GLOBAL__N_116ProcessBacktraceEPKPvmPNS1_22BacktraceOutputHandlerE:
  151|      4|                      BacktraceOutputHandler* handler) {
  152|       |  // NOTE: This code MUST be async-signal safe (it's used by in-process
  153|       |  // stack dumping signal handler). NO malloc or stdio is allowed here.
  154|       |
  155|      4|#if defined(USE_SYMBOLIZE)
  156|     44|  for (size_t i = 0; i < size; ++i) {
  ------------------
  |  Branch (156:22): [True: 40, False: 4]
  ------------------
  157|     40|    OutputFrameId(i, handler);
  158|     40|    handler->HandleOutput(" ");
  159|     40|    OutputPointer(trace[i], handler);
  160|     40|    handler->HandleOutput(" ");
  161|       |
  162|     40|    char buf[1024] = { '\0' };
  163|       |
  164|       |    // Subtract by one as return address of function may be in the next
  165|       |    // function when a function is annotated as noreturn.
  166|     40|    void* address = static_cast<char*>(trace[i]) - 1;
  167|     40|    if (google::Symbolize(address, buf, sizeof(buf)))
  ------------------
  |  Branch (167:9): [True: 32, False: 8]
  ------------------
  168|     32|      handler->HandleOutput(buf);
  169|      8|    else
  170|      8|      handler->HandleOutput("<unknown>");
  171|       |
  172|     40|    handler->HandleOutput("\n");
  173|     40|  }
  174|       |#elif !defined(__UCLIBC__)
  175|       |  bool printed = false;
  176|       |
  177|       |  // Below part is async-signal unsafe (uses malloc), so execute it only
  178|       |  // when we are not executing the signal handler.
  179|       |  if (in_signal_handler == 0) {
  180|       |    scoped_ptr<char*, FreeDeleter>
  181|       |        trace_symbols(backtrace_symbols(trace, size));
  182|       |    if (trace_symbols.get()) {
  183|       |      for (size_t i = 0; i < size; ++i) {
  184|       |        std::string trace_symbol = trace_symbols.get()[i];
  185|       |        DemangleSymbols(&trace_symbol);
  186|       |        handler->HandleOutput(trace_symbol.c_str());
  187|       |        handler->HandleOutput("\n");
  188|       |      }
  189|       |
  190|       |      printed = true;
  191|       |    }
  192|       |  }
  193|       |
  194|       |  if (!printed) {
  195|       |    for (size_t i = 0; i < size; ++i) {
  196|       |      handler->HandleOutput(" [");
  197|       |      OutputPointer(trace[i], handler);
  198|       |      handler->HandleOutput("]\n");
  199|       |    }
  200|       |  }
  201|       |#endif  // defined(USE_SYMBOLIZE)
  202|      4|}
stack_trace_posix.cc:_ZN5butil5debug12_GLOBAL__N_113OutputFrameIdElPNS1_22BacktraceOutputHandlerE:
  138|     40|void OutputFrameId(intptr_t frame_id, BacktraceOutputHandler* handler) {
  139|       |  // Max unsigned 64-bit number in decimal has 20 digits (18446744073709551615).
  140|       |  // Hence, 30 digits should be more than enough to represent it in decimal
  141|       |  // (including the null-terminator).
  142|     40|  char buf[30] = { '\0' };
  143|     40|  handler->HandleOutput("#");
  144|     40|  internal::itoa_r(frame_id, buf, sizeof(buf), 10, 1);
  145|     40|  handler->HandleOutput(buf);
  146|     40|}
stack_trace_posix.cc:_ZN5butil5debug12_GLOBAL__N_113OutputPointerEPvPNS1_22BacktraceOutputHandlerE:
  127|     40|void OutputPointer(void* pointer, BacktraceOutputHandler* handler) {
  128|       |  // This should be more than enough to store a 64-bit number in hex:
  129|       |  // 16 hex digits + 1 for null-terminator.
  130|     40|  char buf[17] = { '\0' };
  131|     40|  handler->HandleOutput("0x");
  132|     40|  internal::itoa_r(reinterpret_cast<intptr_t>(pointer),
  133|     40|                   buf, sizeof(buf), 16, 12);
  134|     40|  handler->HandleOutput(buf);
  135|     40|}
stack_trace_posix.cc:_ZN5butil5debug12_GLOBAL__N_128StreamBacktraceOutputHandlerC2EPSo:
  419|      4|  explicit StreamBacktraceOutputHandler(std::ostream* os) : os_(os) {
  420|      4|  }
stack_trace_posix.cc:_ZN5butil5debug12_GLOBAL__N_128StreamBacktraceOutputHandler12HandleOutputEPKc:
  422|    320|  virtual void HandleOutput(const char* output) OVERRIDE {
  423|    320|    (*os_) << output;
  424|    320|  }

_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:
  455|      1|void IOBuf::_push_or_move_back_ref_to_smallview(const BlockRef& r) {
  456|      1|    BlockRef* const refs = _sv.refs;
  457|      1|    if (NULL == refs[0].block) {
  ------------------
  |  Branch (457:9): [True: 1, False: 0]
  ------------------
  458|      1|        refs[0] = r;
  459|      1|        if (!MOVE) {
  ------------------
  |  Branch (459:13): [Folded, False: 1]
  ------------------
  460|      0|            r.block->inc_ref();
  461|      0|        }
  462|      1|        return;
  463|      1|    }
  464|      0|    if (NULL == refs[1].block) {
  ------------------
  |  Branch (464:9): [True: 0, False: 0]
  ------------------
  465|      0|        if (refs[0].block == r.block &&
  ------------------
  |  Branch (465:13): [True: 0, False: 0]
  ------------------
  466|      0|            refs[0].offset + refs[0].length == r.offset) { // Merge ref
  ------------------
  |  Branch (466:13): [True: 0, False: 0]
  ------------------
  467|      0|            refs[0].length += r.length;
  468|      0|            if (MOVE) {
  ------------------
  |  Branch (468:17): [True: 0, Folded]
  ------------------
  469|      0|                r.block->dec_ref();
  470|      0|            }
  471|      0|            return;
  472|      0|        }
  473|      0|        refs[1] = r;
  474|      0|        if (!MOVE) {
  ------------------
  |  Branch (474:13): [Folded, False: 0]
  ------------------
  475|      0|            r.block->inc_ref();
  476|      0|        }
  477|      0|        return;
  478|      0|    }
  479|      0|    if (refs[1].block == r.block &&
  ------------------
  |  Branch (479:9): [True: 0, False: 0]
  ------------------
  480|      0|        refs[1].offset + refs[1].length == r.offset) { // Merge ref
  ------------------
  |  Branch (480:9): [True: 0, False: 0]
  ------------------
  481|      0|        refs[1].length += r.length;
  482|      0|        if (MOVE) {
  ------------------
  |  Branch (482:13): [True: 0, Folded]
  ------------------
  483|      0|            r.block->dec_ref();
  484|      0|        }
  485|      0|        return;
  486|      0|    }
  487|       |    // Convert to BigView
  488|      0|    BlockRef* new_refs = iobuf::acquire_blockref_array();
  489|      0|    new_refs[0] = refs[0];
  490|      0|    new_refs[1] = refs[1];
  491|      0|    new_refs[2] = r;
  492|      0|    const size_t new_nbytes = refs[0].length + refs[1].length + r.length;
  493|      0|    if (!MOVE) {
  ------------------
  |  Branch (493:9): [Folded, False: 0]
  ------------------
  494|      0|        r.block->inc_ref();
  495|      0|    }
  496|      0|    _bv.magic = -1;
  497|      0|    _bv.start = 0;
  498|      0|    _bv.refs = new_refs;
  499|      0|    _bv.nref = 3;
  500|      0|    _bv.cap_mask = INITIAL_CAP - 1;
  501|      0|    _bv.nbytes = new_nbytes;
  502|      0|}
_ZN5butil5IOBuf35_push_or_move_back_ref_to_smallviewILb0EEEvRKNS0_8BlockRefE:
  455|    679|void IOBuf::_push_or_move_back_ref_to_smallview(const BlockRef& r) {
  456|    679|    BlockRef* const refs = _sv.refs;
  457|    679|    if (NULL == refs[0].block) {
  ------------------
  |  Branch (457:9): [True: 673, False: 6]
  ------------------
  458|    673|        refs[0] = r;
  459|    673|        if (!MOVE) {
  ------------------
  |  Branch (459:13): [True: 673, Folded]
  ------------------
  460|    673|            r.block->inc_ref();
  461|    673|        }
  462|    673|        return;
  463|    673|    }
  464|      6|    if (NULL == refs[1].block) {
  ------------------
  |  Branch (464:9): [True: 6, False: 0]
  ------------------
  465|      6|        if (refs[0].block == r.block &&
  ------------------
  |  Branch (465:13): [True: 0, False: 6]
  ------------------
  466|      0|            refs[0].offset + refs[0].length == r.offset) { // Merge ref
  ------------------
  |  Branch (466:13): [True: 0, False: 0]
  ------------------
  467|      0|            refs[0].length += r.length;
  468|      0|            if (MOVE) {
  ------------------
  |  Branch (468:17): [Folded, False: 0]
  ------------------
  469|      0|                r.block->dec_ref();
  470|      0|            }
  471|      0|            return;
  472|      0|        }
  473|      6|        refs[1] = r;
  474|      6|        if (!MOVE) {
  ------------------
  |  Branch (474:13): [True: 6, Folded]
  ------------------
  475|      6|            r.block->inc_ref();
  476|      6|        }
  477|      6|        return;
  478|      6|    }
  479|      0|    if (refs[1].block == r.block &&
  ------------------
  |  Branch (479:9): [True: 0, False: 0]
  ------------------
  480|      0|        refs[1].offset + refs[1].length == r.offset) { // Merge ref
  ------------------
  |  Branch (480:9): [True: 0, False: 0]
  ------------------
  481|      0|        refs[1].length += r.length;
  482|      0|        if (MOVE) {
  ------------------
  |  Branch (482:13): [Folded, False: 0]
  ------------------
  483|      0|            r.block->dec_ref();
  484|      0|        }
  485|      0|        return;
  486|      0|    }
  487|       |    // Convert to BigView
  488|      0|    BlockRef* new_refs = iobuf::acquire_blockref_array();
  489|      0|    new_refs[0] = refs[0];
  490|      0|    new_refs[1] = refs[1];
  491|      0|    new_refs[2] = r;
  492|      0|    const size_t new_nbytes = refs[0].length + refs[1].length + r.length;
  493|      0|    if (!MOVE) {
  ------------------
  |  Branch (493:9): [True: 0, Folded]
  ------------------
  494|      0|        r.block->inc_ref();
  495|      0|    }
  496|      0|    _bv.magic = -1;
  497|      0|    _bv.start = 0;
  498|      0|    _bv.refs = new_refs;
  499|      0|    _bv.nref = 3;
  500|      0|    _bv.cap_mask = INITIAL_CAP - 1;
  501|      0|    _bv.nbytes = new_nbytes;
  502|      0|}
_ZN5butil5IOBuf25_pop_or_moveout_front_refILb1EEEiv:
  551|      1|int IOBuf::_pop_or_moveout_front_ref() {
  552|      1|    if (_small()) {
  ------------------
  |  Branch (552:9): [True: 1, False: 0]
  ------------------
  553|      1|        if (_sv.refs[0].block != NULL) {
  ------------------
  |  Branch (553:13): [True: 1, False: 0]
  ------------------
  554|      1|            if (!MOVEOUT) {
  ------------------
  |  Branch (554:17): [Folded, False: 1]
  ------------------
  555|      0|                _sv.refs[0].block->dec_ref();
  556|      0|            }
  557|      1|            _sv.refs[0] = _sv.refs[1];
  558|      1|            reset_block_ref(_sv.refs[1]);
  559|      1|            return 0;
  560|      1|        }
  561|      0|        return -1;
  562|      1|    } else {
  563|       |        // _bv.nref must be greater than 2
  564|      0|        const uint32_t start = _bv.start;
  565|      0|        if (!MOVEOUT) {
  ------------------
  |  Branch (565:13): [Folded, False: 0]
  ------------------
  566|      0|            _bv.refs[start].block->dec_ref();
  567|      0|        }
  568|      0|        if (--_bv.nref > 2) {
  ------------------
  |  Branch (568:13): [True: 0, False: 0]
  ------------------
  569|      0|            _bv.start = (start + 1) & _bv.cap_mask;
  570|      0|            _bv.nbytes -= _bv.refs[start].length;
  571|      0|        } else {  // count==2, fall back to SmallView
  572|      0|            BlockRef* const saved_refs = _bv.refs;
  573|      0|            const uint32_t saved_cap_mask = _bv.cap_mask;
  574|      0|            _sv.refs[0] = saved_refs[(start + 1) & saved_cap_mask];
  575|      0|            _sv.refs[1] = saved_refs[(start + 2) & saved_cap_mask];
  576|      0|            iobuf::release_blockref_array(saved_refs, saved_cap_mask + 1);
  577|      0|        }
  578|      0|        return 0;
  579|      0|    }
  580|      1|}
_ZN5butil5IOBuf25_pop_or_moveout_front_refILb0EEEiv:
  551|      5|int IOBuf::_pop_or_moveout_front_ref() {
  552|      5|    if (_small()) {
  ------------------
  |  Branch (552:9): [True: 5, False: 0]
  ------------------
  553|      5|        if (_sv.refs[0].block != NULL) {
  ------------------
  |  Branch (553:13): [True: 5, False: 0]
  ------------------
  554|      5|            if (!MOVEOUT) {
  ------------------
  |  Branch (554:17): [True: 5, Folded]
  ------------------
  555|      5|                _sv.refs[0].block->dec_ref();
  556|      5|            }
  557|      5|            _sv.refs[0] = _sv.refs[1];
  558|      5|            reset_block_ref(_sv.refs[1]);
  559|      5|            return 0;
  560|      5|        }
  561|      0|        return -1;
  562|      5|    } else {
  563|       |        // _bv.nref must be greater than 2
  564|      0|        const uint32_t start = _bv.start;
  565|      0|        if (!MOVEOUT) {
  ------------------
  |  Branch (565:13): [True: 0, Folded]
  ------------------
  566|      0|            _bv.refs[start].block->dec_ref();
  567|      0|        }
  568|      0|        if (--_bv.nref > 2) {
  ------------------
  |  Branch (568:13): [True: 0, False: 0]
  ------------------
  569|      0|            _bv.start = (start + 1) & _bv.cap_mask;
  570|      0|            _bv.nbytes -= _bv.refs[start].length;
  571|      0|        } else {  // count==2, fall back to SmallView
  572|      0|            BlockRef* const saved_refs = _bv.refs;
  573|      0|            const uint32_t saved_cap_mask = _bv.cap_mask;
  574|      0|            _sv.refs[0] = saved_refs[(start + 1) & saved_cap_mask];
  575|      0|            _sv.refs[1] = saved_refs[(start + 2) & saved_cap_mask];
  576|      0|            iobuf::release_blockref_array(saved_refs, saved_cap_mask + 1);
  577|      0|        }
  578|      0|        return 0;
  579|      0|    }
  580|      5|}
_ZN5butil5iobuf2cpEPvPKvm:
  162|  2.68k|void* cp(void *__restrict dest, const void *__restrict src, size_t n) {
  163|       |    // memcpy in gcc 4.8 seems to be faster enough.
  164|  2.68k|    return memcpy(dest, src, n);
  165|  2.68k|}
_ZN5butil5iobuf12inc_g_nblockEv:
  186|      6|void inc_g_nblock() {
  187|      6|    g_nblock.fetch_add(1, butil::memory_order_relaxed);
  188|      6|}
_ZN5butil5iobuf12dec_g_nblockEv:
  189|      5|void dec_g_nblock() {
  190|      5|    g_nblock.fetch_sub(1, butil::memory_order_relaxed);
  191|      5|}
_ZN5butil5iobuf14inc_g_blockmemEv:
  193|      6|void inc_g_blockmem() {
  194|      6|    g_blockmem.fetch_add(1, butil::memory_order_relaxed);
  195|      6|}
_ZN5butil5iobuf14dec_g_blockmemEv:
  196|      5|void dec_g_blockmem() {
  197|      5|    g_blockmem.fetch_sub(1, butil::memory_order_relaxed);
  198|      5|}
_ZN5butil5iobuf15share_tls_blockEv:
  292|     58|IOBuf::Block* share_tls_block() {
  293|     58|    TLSData& tls_data = g_tls_data;
  294|     58|    IOBuf::Block* const b = tls_data.block_head;
  295|     58|    if (b != NULL && !b->full()) {
  ------------------
  |  Branch (295:9): [True: 57, False: 1]
  |  Branch (295:22): [True: 52, False: 5]
  ------------------
  296|     52|        return b;
  297|     52|    }
  298|      6|    IOBuf::Block* new_block = NULL;
  299|      6|    if (b) {
  ------------------
  |  Branch (299:9): [True: 5, False: 1]
  ------------------
  300|      5|        new_block = b;
  301|     10|        while (new_block && new_block->full()) {
  ------------------
  |  Branch (301:16): [True: 5, False: 5]
  |  Branch (301:29): [True: 5, False: 0]
  ------------------
  302|      5|            IOBuf::Block* const saved_next = new_block->u.portal_next;
  303|      5|            new_block->dec_ref();
  304|      5|            --tls_data.num_blocks;
  305|      5|            new_block = saved_next;
  306|      5|        }
  307|      5|    } else if (!tls_data.registered) {
  ------------------
  |  Branch (307:16): [True: 1, False: 0]
  ------------------
  308|      1|        tls_data.registered = true;
  309|       |        // Only register atexit at the first time
  310|      1|        butil::thread_atexit(remove_tls_block_chain);
  311|      1|    }
  312|      6|    if (!new_block) {
  ------------------
  |  Branch (312:9): [True: 6, False: 0]
  ------------------
  313|      6|        new_block = create_block(); // may be NULL
  314|      6|        if (new_block) {
  ------------------
  |  Branch (314:13): [True: 6, False: 0]
  ------------------
  315|      6|            ++tls_data.num_blocks;
  316|      6|        }
  317|      6|    }
  318|      6|    tls_data.block_head = new_block;
  319|      6|    return new_block;
  320|     58|}
_ZN5butil5IOBuf5clearEv:
  615|    686|void IOBuf::clear() {
  616|    686|    if (_small()) {
  ------------------
  |  Branch (616:9): [True: 686, False: 0]
  ------------------
  617|    686|        if (_sv.refs[0].block != NULL) {
  ------------------
  |  Branch (617:13): [True: 671, False: 15]
  ------------------
  618|    671|            _sv.refs[0].block->dec_ref();
  619|    671|            reset_block_ref(_sv.refs[0]);
  620|       |                        
  621|    671|            if (_sv.refs[1].block != NULL) {
  ------------------
  |  Branch (621:17): [True: 3, False: 668]
  ------------------
  622|      3|                _sv.refs[1].block->dec_ref();
  623|      3|                reset_block_ref(_sv.refs[1]);
  624|      3|            }
  625|    671|        }
  626|    686|    } else {
  627|      0|        for (uint32_t i = 0; i < _bv.nref; ++i) { 
  ------------------
  |  Branch (627:30): [True: 0, False: 0]
  ------------------
  628|      0|            _bv.ref_at(i).block->dec_ref();
  629|      0|        }
  630|      0|        iobuf::release_blockref_array(_bv.refs, _bv.capacity());
  631|      0|        new (this) IOBuf;
  632|      0|    }
  633|    686|}
_ZN5butil5IOBuf9pop_frontEm:
  635|  2.77k|size_t IOBuf::pop_front(size_t n) {
  636|  2.77k|    const size_t len = length();
  637|  2.77k|    if (n >= len) {
  ------------------
  |  Branch (637:9): [True: 10, False: 2.76k]
  ------------------
  638|     10|        clear();
  639|     10|        return len;
  640|     10|    }
  641|  2.76k|    const size_t saved_n = n;
  642|  2.77k|    while (n) {  // length() == 0 does not enter
  ------------------
  |  Branch (642:12): [True: 2.77k, False: 0]
  ------------------
  643|  2.77k|        IOBuf::BlockRef &r = _front_ref();
  644|  2.77k|        if (r.length > n) {
  ------------------
  |  Branch (644:13): [True: 2.76k, False: 2]
  ------------------
  645|  2.76k|            r.offset += n;
  646|  2.76k|            r.length -= n;
  647|  2.76k|            if (!_small()) {
  ------------------
  |  Branch (647:17): [True: 0, False: 2.76k]
  ------------------
  648|      0|                _bv.nbytes -= n;
  649|      0|            }
  650|  2.76k|            return saved_n;
  651|  2.76k|        }
  652|      2|        n -= r.length;
  653|      2|        _pop_front_ref();
  654|      2|    }
  655|      0|    return saved_n;
  656|  2.76k|}
_ZN5butil5IOBuf4cutnEPS0_m:
  698|    621|size_t IOBuf::cutn(IOBuf* out, size_t n) {
  699|    621|    const size_t len = length();
  700|    621|    if (n > len) {
  ------------------
  |  Branch (700:9): [True: 0, False: 621]
  ------------------
  701|      0|        n = len;
  702|      0|    }
  703|    621|    const size_t saved_n = n;
  704|    622|    while (n) {   // length() == 0 does not enter
  ------------------
  |  Branch (704:12): [True: 622, False: 0]
  ------------------
  705|    622|        IOBuf::BlockRef &r = _front_ref();
  706|    622|        if (r.length <= n) {
  ------------------
  |  Branch (706:13): [True: 1, False: 621]
  ------------------
  707|      1|            n -= r.length;
  708|      1|            out->_move_back_ref(r);
  709|      1|            _moveout_front_ref();
  710|    621|        } else {
  711|    621|            const IOBuf::BlockRef cr = { r.offset, (uint32_t)n, r.block };
  712|    621|            out->_push_back_ref(cr);
  713|       |            
  714|    621|            r.offset += n;
  715|    621|            r.length -= n;
  716|    621|            if (!_small()) {
  ------------------
  |  Branch (716:17): [True: 0, False: 621]
  ------------------
  717|      0|                _bv.nbytes -= n;
  718|      0|            }
  719|    621|            return saved_n;
  720|    621|        }
  721|    622|    }
  722|      0|    return saved_n;
  723|    621|}
_ZN5butil5IOBuf4cutnEPvm:
  725|    446|size_t IOBuf::cutn(void* out, size_t n) {
  726|    446|    const size_t len = length();
  727|    446|    if (n > len) {
  ------------------
  |  Branch (727:9): [True: 0, False: 446]
  ------------------
  728|      0|        n = len;
  729|      0|    }
  730|    446|    const size_t saved_n = n;
  731|    449|    while (n) {   // length() == 0 does not enter
  ------------------
  |  Branch (731:12): [True: 302, False: 147]
  ------------------
  732|    302|        IOBuf::BlockRef &r = _front_ref();
  733|    302|        if (r.length <= n) {
  ------------------
  |  Branch (733:13): [True: 3, False: 299]
  ------------------
  734|      3|            iobuf::cp(out, r.block->data + r.offset, r.length);
  735|      3|            out = (char*)out + r.length;
  736|      3|            n -= r.length;
  737|      3|            _pop_front_ref();
  738|    299|        } else {
  739|    299|            iobuf::cp(out, r.block->data + r.offset, n);
  740|    299|            out = (char*)out + n;
  741|    299|            r.offset += n;
  742|    299|            r.length -= n;
  743|    299|            if (!_small()) {
  ------------------
  |  Branch (743:17): [True: 0, False: 299]
  ------------------
  744|      0|                _bv.nbytes -= n;
  745|      0|            }
  746|    299|            return saved_n;
  747|    299|        }
  748|    302|    }
  749|    147|    return saved_n;
  750|    446|}
_ZN5butil5IOBuf13_cut_by_delimEPS0_PKcm:
  785|    623|int IOBuf::_cut_by_delim(IOBuf* out, char const* dbegin, size_t ndelim) {
  786|    623|    typedef unsigned long SigType;
  787|    623|    const size_t NMAX = sizeof(SigType);
  788|       |    
  789|    623|    if (ndelim > NMAX || ndelim > length()) {
  ------------------
  |  Branch (789:9): [True: 0, False: 623]
  |  Branch (789:26): [True: 0, False: 623]
  ------------------
  790|      0|        return -1;
  791|      0|    }
  792|       |    
  793|    623|    SigType dsig = 0;
  794|  1.86k|    for (size_t i = 0; i < ndelim; ++i) {
  ------------------
  |  Branch (794:24): [True: 1.24k, False: 623]
  ------------------
  795|  1.24k|        dsig = (dsig << CHAR_BIT) | static_cast<SigType>(dbegin[i]);
  796|  1.24k|    }
  797|       |    
  798|    623|    const SigType SIGMASK =
  799|    623|        (ndelim == NMAX ? (SigType)-1 : (((SigType)1 << (ndelim * CHAR_BIT)) - 1));
  ------------------
  |  Branch (799:10): [True: 0, False: 623]
  ------------------
  800|       |
  801|    623|    const size_t nref = _ref_num();
  802|    623|    SigType sig = 0;
  803|    623|    size_t n = 0;
  804|       |
  805|    626|    for (size_t i = 0; i < nref; ++i) {
  ------------------
  |  Branch (805:24): [True: 624, False: 2]
  ------------------
  806|    624|        IOBuf::BlockRef const& r = _ref_at(i);
  807|    624|        char const* const s = r.block->data + r.offset;
  808|       |        
  809|  11.0k|        for (uint32_t j = 0; j < r.length; ++j, ++n) {
  ------------------
  |  Branch (809:30): [True: 11.0k, False: 3]
  ------------------
  810|  11.0k|            sig = ((sig << CHAR_BIT) | static_cast<SigType>(s[j])) & SIGMASK;
  811|  11.0k|            if (sig == dsig) {
  ------------------
  |  Branch (811:17): [True: 621, False: 10.4k]
  ------------------
  812|       |                // There's no way cutn/pop_front fails
  813|    621|                cutn(out, n + 1 - ndelim);
  814|    621|                pop_front(ndelim);
  815|    621|                return 0;
  816|    621|            }
  817|  11.0k|        }
  818|    624|    }
  819|       |
  820|      2|    return -1;
  821|    623|}
_ZN5butil5IOBuf6appendEPKvm:
 1071|     53|int IOBuf::append(void const* data, size_t count) {
 1072|     53|    if (BAIDU_UNLIKELY(!data)) {
  ------------------
  |  |  272|     53|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 53]
  |  |  ------------------
  ------------------
 1073|      0|        return -1;
 1074|      0|    }
 1075|     53|    if (count == 1) {
  ------------------
  |  Branch (1075:9): [True: 0, False: 53]
  ------------------
 1076|      0|        return push_back(*((char const*)data));
 1077|      0|    }
 1078|     53|    size_t total_nc = 0;
 1079|    111|    while (total_nc < count) {  // excluded count == 0
  ------------------
  |  Branch (1079:12): [True: 58, False: 53]
  ------------------
 1080|     58|        IOBuf::Block* b = iobuf::share_tls_block();
 1081|     58|        if (BAIDU_UNLIKELY(!b)) {
  ------------------
  |  |  272|     58|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 58]
  |  |  ------------------
  ------------------
 1082|      0|            return -1;
 1083|      0|        }
 1084|     58|        const size_t nc = std::min(count - total_nc, b->left_space());
 1085|     58|        iobuf::cp(b->data + b->size, (char*)data + total_nc, nc);
 1086|       |        
 1087|     58|        const IOBuf::BlockRef r = { (uint32_t)b->size, (uint32_t)nc, b };
 1088|     58|        _push_back_ref(r);
 1089|     58|        b->size += nc;
 1090|     58|        total_nc += nc;
 1091|     58|    }
 1092|     53|    return 0;
 1093|     53|}
_ZNK5butil5IOBuf7copy_toEPvmm:
 1295|  2.80k|size_t IOBuf::copy_to(void* d, size_t n, size_t pos) const {
 1296|  2.80k|    const size_t nref = _ref_num();
 1297|       |    // Skip `pos' bytes. `offset' is the starting position in starting BlockRef.
 1298|  2.80k|    size_t offset = pos;
 1299|  2.80k|    size_t i = 0;
 1300|  3.30k|    for (; offset != 0 && i < nref; ++i) {
  ------------------
  |  Branch (1300:12): [True: 621, False: 2.68k]
  |  Branch (1300:27): [True: 621, False: 0]
  ------------------
 1301|    621|        IOBuf::BlockRef const& r = _ref_at(i);
 1302|    621|        if (offset < (size_t)r.length) {
  ------------------
  |  Branch (1302:13): [True: 122, False: 499]
  ------------------
 1303|    122|            break;
 1304|    122|        }
 1305|    499|        offset -= r.length;
 1306|    499|    }
 1307|  2.80k|    size_t m = n;
 1308|  5.12k|    for (; m != 0 && i < nref; ++i) {
  ------------------
  |  Branch (1308:12): [True: 2.99k, False: 2.13k]
  |  Branch (1308:22): [True: 2.32k, False: 669]
  ------------------
 1309|  2.32k|        IOBuf::BlockRef const& r = _ref_at(i);
 1310|  2.32k|        const size_t nc = std::min(m, (size_t)r.length - offset);
 1311|  2.32k|        iobuf::cp(d, r.block->data + r.offset + offset, nc);
 1312|  2.32k|        offset = 0;
 1313|  2.32k|        d = (char*)d + nc;
 1314|  2.32k|        m -= nc;
 1315|  2.32k|    }
 1316|       |    // If nref == 0, here returns 0 correctly
 1317|  2.80k|    return n - m;
 1318|  2.80k|}
_ZNK5butil5IOBuf12copy_to_cstrEPcmm:
 1346|    621|size_t IOBuf::copy_to_cstr(char* s, size_t n, size_t pos) const {
 1347|    621|    const size_t nc = copy_to(s, n, pos);
 1348|    621|    s[nc] = '\0';
 1349|    621|    return nc;
 1350|    621|}
_ZNK5butil5IOBuf6fetch1Ev:
 1376|  2.85k|const void* IOBuf::fetch1() const {
 1377|  2.85k|    if (!empty()) {
  ------------------
  |  Branch (1377:9): [True: 2.84k, False: 10]
  ------------------
 1378|  2.84k|        const IOBuf::BlockRef& r0 = _front_ref();
 1379|  2.84k|        return r0.block->data + r0.offset;
 1380|  2.84k|    }
 1381|     10|    return NULL;
 1382|  2.85k|}

_ZN5butil5IOBufD2Ev:
  119|    676|    ~IOBuf() { clear(); }
_ZNK5butil5IOBuf4sizeEv:
  350|    863|    size_t size() const { return length(); }
_ZN5butil5IOBuf14_pop_front_refEv:
  393|      5|    int _pop_front_ref() { return _pop_or_moveout_front_ref<false>(); }
_ZN5butil5IOBuf18_moveout_front_refEv:
  397|      1|    int _moveout_front_ref() { return _pop_or_moveout_front_ref<true>(); }

_ZN5butil5IOBufC2Ev:
   77|    678|inline IOBuf::IOBuf() {
   78|    678|    reset_block_ref(_sv.refs[0]);
   79|    678|    reset_block_ref(_sv.refs[1]);
   80|    678|}
_ZN5butil15reset_block_refERNS_5IOBuf8BlockRefE:
   71|  2.03k|inline void reset_block_ref(IOBuf::BlockRef& ref) {
   72|  2.03k|    ref.offset = 0;
   73|  2.03k|    ref.length = 0;
   74|       |    ref.block = NULL;
   75|  2.03k|}
_ZN5butil5IOBuf6appendERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE:
  130|     53|inline int IOBuf::append(const std::string& s) {
  131|     53|    return append(s.data(), s.length());
  132|     53|}
_ZN5butil5IOBuf5BlockC2EPcj:
  481|      6|        : nshared(1)
  482|      6|        , flags(0)
  483|      6|        , abi_check(0)
  484|      6|        , size(0)
  485|      6|        , cap(data_size)
  486|      6|        , u({NULL})
  487|      6|        , data(data_in) {
  488|      6|        iobuf::inc_g_nblock();
  489|      6|        iobuf::inc_g_blockmem();
  490|      6|        if (is_samplable()) {
  ------------------
  |  Branch (490:13): [True: 0, False: 6]
  ------------------
  491|      0|            SubmitIOBufSample(this, 1);
  492|      0|        }
  493|      6|    }
_ZN5butil5IOBuf5Block9check_abiEv:
  516|  1.36k|    inline void check_abi() {
  517|  1.36k|#ifndef NDEBUG
  518|  1.36k|    if (abi_check != 0) {
  ------------------
  |  Branch (518:9): [True: 0, False: 1.36k]
  ------------------
  519|      0|        LOG(FATAL) << "Your program seems to wrongly contain two "
  ------------------
  |  |  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]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  520|      0|            "ABI-incompatible implementations of IOBuf";
  521|      0|    }
  522|  1.36k|#endif
  523|  1.36k|}
_ZN5butil5IOBuf5Block7inc_refEv:
  525|    679|    void inc_ref() {
  526|    679|        check_abi();
  527|    679|        nshared.fetch_add(1, butil::memory_order_relaxed);
  528|    679|        if (sampled()) {
  ------------------
  |  Branch (528:13): [True: 0, False: 679]
  ------------------
  529|      0|            SubmitIOBufSample(this, 1);
  530|      0|        }
  531|    679|    }
_ZN5butil5IOBuf5Block7dec_refEv:
  533|    684|    void dec_ref() {
  534|    684|        check_abi();
  535|    684|        if (sampled()) {
  ------------------
  |  Branch (535:13): [True: 0, False: 684]
  ------------------
  536|      0|            SubmitIOBufSample(this, -1);
  537|      0|        }
  538|    684|        if (nshared.fetch_sub(1, butil::memory_order_release) == 1) {
  ------------------
  |  Branch (538:13): [True: 5, False: 679]
  ------------------
  539|      5|            butil::atomic_thread_fence(butil::memory_order_acquire);
  540|      5|            if (!is_user_data()) {
  ------------------
  |  Branch (540:17): [True: 5, False: 0]
  ------------------
  541|      5|                iobuf::dec_g_nblock();
  542|      5|                iobuf::dec_g_blockmem();
  543|      5|                this->~Block();
  544|      5|                iobuf::blockmem_deallocate(this);
  545|      5|            } 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|      5|        }
  553|    684|    }
_ZNK5butil5IOBuf5Block4fullEv:
  559|     62|    bool full() const { return size >= cap; }
_ZNK5butil5IOBuf5Block10left_spaceEv:
  560|     58|    size_t left_space() const { return cap - size; }
_ZN5butil5IOBuf5Block12is_samplableEv:
  563|      6|    bool is_samplable() {
  564|      6|        if (IsIOBufProfilerSamplable()) {
  ------------------
  |  Branch (564:13): [True: 0, False: 6]
  ------------------
  565|      0|            flags |= IOBUF_BLOCK_FLAGS_SAMPLED;
  566|      0|            return true;
  567|      0|        }
  568|      6|        return false;
  569|      6|    }
_ZNK5butil5IOBuf5Block7sampledEv:
  571|  1.36k|    bool sampled() const {
  572|  1.36k|        return flags & IOBUF_BLOCK_FLAGS_SAMPLED;
  573|  1.36k|    }
_ZNK5butil5IOBuf5Block12is_user_dataEv:
  575|      5|    bool is_user_data() const {
  576|      5|        return flags & IOBUF_BLOCK_FLAGS_USER_DATA;
  577|      5|    }
_ZN5butil5IOBuf9cut_untilEPS0_PKc:
  109|    623|inline int IOBuf::cut_until(IOBuf* out, char const* delim) {
  110|    623|    if (*delim) {
  ------------------
  |  Branch (110:9): [True: 623, False: 0]
  ------------------
  111|    623|        if (!*(delim+1)) {
  ------------------
  |  Branch (111:13): [True: 0, False: 623]
  ------------------
  112|      0|            return _cut_by_char(out, *delim);
  113|    623|        } else {
  114|    623|            return _cut_by_delim(out, delim, strlen(delim));
  115|    623|        }
  116|    623|    }
  117|      0|    return -1;
  118|    623|}
_ZNK5butil5IOBuf5emptyEv:
  140|  2.85k|inline bool IOBuf::empty() const {
  141|  2.85k|    return _small() ? !_sv.refs[0].block : !_bv.nbytes;
  ------------------
  |  Branch (141:12): [True: 2.85k, False: 0]
  ------------------
  142|  2.85k|}
_ZNK5butil5IOBuf6lengthEv:
  144|  5.33k|inline size_t IOBuf::length() const {
  145|  5.33k|    return _small() ?
  ------------------
  |  Branch (145:12): [True: 5.33k, False: 0]
  ------------------
  146|  5.33k|        (_sv.refs[0].length + _sv.refs[1].length) : _bv.nbytes;
  147|  5.33k|}
_ZNK5butil5IOBuf6_smallEv:
  149|  26.7k|inline bool IOBuf::_small() const {
  150|  26.7k|    return _bv.magic >= 0;
  151|  26.7k|}
_ZNK5butil5IOBuf8_ref_numEv:
  153|  3.42k|inline size_t IOBuf::_ref_num() const {
  154|  3.42k|    return _small()
  ------------------
  |  Branch (154:12): [True: 3.42k, False: 0]
  ------------------
  155|  3.42k|        ? (!!_sv.refs[0].block + !!_sv.refs[1].block) : _bv.nref;
  156|  3.42k|}
_ZN5butil5IOBuf10_front_refEv:
  158|  3.69k|inline IOBuf::BlockRef& IOBuf::_front_ref() {
  159|  3.69k|    return _small() ? _sv.refs[0] : _bv.refs[_bv.start];
  ------------------
  |  Branch (159:12): [True: 3.69k, False: 0]
  ------------------
  160|  3.69k|}
_ZNK5butil5IOBuf10_front_refEv:
  162|  2.84k|inline const IOBuf::BlockRef& IOBuf::_front_ref() const {
  163|  2.84k|    return _small() ? _sv.refs[0] : _bv.refs[_bv.start];
  ------------------
  |  Branch (163:12): [True: 2.84k, False: 0]
  ------------------
  164|  2.84k|}
_ZN5butil5IOBuf7_ref_atEm:
  174|    624|inline IOBuf::BlockRef& IOBuf::_ref_at(size_t i) {
  175|    624|    return _small() ? _sv.refs[i] : _bv.ref_at(i);
  ------------------
  |  Branch (175:12): [True: 624, False: 0]
  ------------------
  176|    624|}
_ZNK5butil5IOBuf7_ref_atEm:
  178|  2.94k|inline const IOBuf::BlockRef& IOBuf::_ref_at(size_t i) const {
  179|  2.94k|    return _small() ? _sv.refs[i] : _bv.ref_at(i);
  ------------------
  |  Branch (179:12): [True: 2.94k, False: 0]
  ------------------
  180|  2.94k|}
_ZN5butil5IOBuf14_push_back_refERKNS0_8BlockRefE:
  199|    679|inline void IOBuf::_push_back_ref(const BlockRef& r) {
  200|    679|    if (_small()) {
  ------------------
  |  Branch (200:9): [True: 679, False: 0]
  ------------------
  201|    679|        return _push_or_move_back_ref_to_smallview<false>(r);
  202|    679|    } else {
  203|      0|        return _push_or_move_back_ref_to_bigview<false>(r);
  204|      0|    }
  205|    679|}
_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|}
_ZN5butil5iobuf12create_blockEm:
  629|      6|inline IOBuf::Block* create_block(const size_t block_size) {
  630|      6|    if (block_size > 0xFFFFFFFFULL) {
  ------------------
  |  Branch (630:9): [True: 0, False: 6]
  ------------------
  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|      6|    char* mem = (char*)iobuf::blockmem_allocate(block_size);
  635|      6|    if (mem == NULL) {
  ------------------
  |  Branch (635:9): [True: 0, False: 6]
  ------------------
  636|      0|        return NULL;
  637|      0|    }
  638|      6|    return new (mem) IOBuf::Block(mem + sizeof(IOBuf::Block),
  639|      6|                                  block_size - sizeof(IOBuf::Block));
  640|      6|}
_ZN5butil5iobuf12create_blockEv:
  642|      6|inline IOBuf::Block* create_block() {
  643|      6|    return create_block(IOBuf::DEFAULT_BLOCK_SIZE);
  644|      6|}

_ZN5butil22IsIOBufProfilerEnabledEv:
   70|      6|bool IsIOBufProfilerEnabled() {
   71|      6|    pthread_once(&g_iobuf_profiler_info_once, InitGlobalIOBufProfilerInfo);
   72|      6|    return g_iobuf_profiler_enabled;
   73|      6|}
_ZN5butil24IsIOBufProfilerSamplableEv:
   75|      6|bool IsIOBufProfilerSamplable() {
   76|      6|    if (!IsIOBufProfilerEnabled()) {
  ------------------
  |  Branch (76:9): [True: 6, False: 0]
  ------------------
   77|      6|        return false;
   78|      6|    }
   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:
  459|     29|TimeVal GetTimestamp() {
  460|     29|#if defined(OS_LINUX) || defined(OS_MACOSX)
  461|     29|    timeval tv;
  462|     29|    gettimeofday(&tv, NULL);
  463|     29|    return tv;
  464|       |#else
  465|       |    return { time(NULL) };
  466|       |#endif
  467|     29|}
_ZN7logging15LogInfoToLogStrEiN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEiS8_S8_:
  562|     29|                            butil::StringPiece content) {
  563|       |    // There's a copy here to concatenate prefix and content. Since
  564|       |    // DefaultLogSink is hardly used right now, the copy is irrelevant.
  565|       |    // A LogSink focused on performance should also be able to handle
  566|       |    // non-continuous inputs which is a must to maximize performance.
  567|     29|    std::ostringstream os;
  568|     29|    PrintLog(os, severity, file.data(), line, func.data(), content);
  569|     29|    os << '\n';
  570|     29|    return os.str();
  571|     29|}
_ZN7logging14GetMinLogLevelEv:
  818|     25|int GetMinLogLevel() {
  819|     25|    return FLAGS_minloglevel;
  820|     25|}
_ZN7logging14PrintLogPrefixERSoiN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEiS9_7timeval:
  846|     29|                    butil::StringPiece func, TimeVal tv) {
  847|     29|    PrintLogSeverity(os, severity);
  848|     29|    time_t t = tv.tv_sec;
  849|     29|    struct tm local_tm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL};
  850|       |#if _MSC_VER >= 1400
  851|       |    localtime_s(&local_tm, &t);
  852|       |#else
  853|     29|    localtime_r(&t, &local_tm);
  854|     29|#endif
  855|     29|    const char prev_fill = os.fill('0');
  856|     29|    if (FLAGS_log_year) {
  ------------------
  |  Branch (856:9): [True: 0, False: 29]
  ------------------
  857|      0|        os << std::setw(4) << local_tm.tm_year + 1900;
  858|      0|    }
  859|     29|    os << std::setw(2) << local_tm.tm_mon + 1
  860|     29|       << std::setw(2) << local_tm.tm_mday << ' '
  861|     29|       << std::setw(2) << local_tm.tm_hour << ':'
  862|     29|       << std::setw(2) << local_tm.tm_min << ':'
  863|     29|       << std::setw(2) << local_tm.tm_sec;
  864|     29|#if defined(OS_LINUX) || defined(OS_MACOSX)
  865|     29|    os << '.' << std::setw(6) << tv.tv_usec;
  866|     29|#endif
  867|     29|    if (FLAGS_log_pid) {
  ------------------
  |  Branch (867:9): [True: 0, False: 29]
  ------------------
  868|      0|        os << ' ' << std::setfill(' ') << std::setw(5) << CurrentProcessId();
  869|      0|    }
  870|     29|    os << ' ' << std::setfill(' ') << std::setw(5)
  871|     29|       << butil::PlatformThread::CurrentId() << std::setfill('0');
  872|     29|    if (FLAGS_log_bid && bthread_self) {
  ------------------
  |  Branch (872:9): [True: 29, False: 0]
  |  Branch (872:26): [True: 29, False: 0]
  ------------------
  873|     29|        os << ' ' << std::setfill(' ') << std::setw(5) << bthread_self();
  874|     29|    }
  875|     29|    if (FLAGS_log_hostname) {
  ------------------
  |  Branch (875:9): [True: 0, False: 29]
  ------------------
  876|      0|        butil::StringPiece hostname(butil::my_hostname());
  877|      0|        if (hostname.ends_with(".baidu.com")) { // make it shorter
  ------------------
  |  Branch (877:13): [True: 0, False: 0]
  ------------------
  878|      0|            hostname.remove_suffix(10);
  879|      0|        }
  880|      0|        os << ' ' << hostname;
  881|      0|    }
  882|     29|    os << ' ' << file << ':' << line;
  883|     29|    if (!func.empty()) {
  ------------------
  |  Branch (883:9): [True: 29, False: 0]
  ------------------
  884|     29|        os << " " << func;
  885|     29|    }
  886|     29|    os << "] ";
  887|       |
  888|     29|    os.fill(prev_fill);
  889|     29|}
_ZN7logging8PrintLogERSoiPKciS2_RKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE:
  976|     29|              const char* func, const butil::StringPiece& content) {
  977|     29|    if (!FLAGS_log_as_json) {
  ------------------
  |  Branch (977:9): [True: 29, False: 0]
  ------------------
  978|     29|        PrintLogPrefix(os, severity, file, line, func, GetTimestamp());
  979|     29|        OutputLog(os, content);
  980|     29|    } else {
  981|      0|        os << '{';
  982|      0|        PrintLogPrefixAsJSON(os, severity, file, func, line, GetTimestamp());
  983|      0|        bool pair_quote = false;
  984|      0|        if (content.empty() || content[0] != '"') {
  ------------------
  |  Branch (984:13): [True: 0, False: 0]
  |  Branch (984:32): [True: 0, False: 0]
  ------------------
  985|       |            // not a json, add a 'M' field
  986|      0|            os << ",\"M\":\"";
  987|      0|            pair_quote = true;
  988|      0|        } else {
  989|      0|            os << ',';
  990|      0|        }
  991|      0|        OutputLog(os, content);
  992|      0|        if (pair_quote) {
  ------------------
  |  Branch (992:13): [True: 0, False: 0]
  ------------------
  993|      0|            os << '"';
  994|      0|        } else if (!content.empty() && content[content.size() -1 ] != '"') {
  ------------------
  |  Branch (994:20): [True: 0, False: 0]
  |  Branch (994:40): [True: 0, False: 0]
  ------------------
  995|       |            // Controller may write `"M":"...` which misses the last quote
  996|      0|            os << '"';
  997|      0|        }
  998|      0|        os << '}';
  999|      0|    }
 1000|     29|}
_ZN7logging21DoublyBufferedLogSink11GetInstanceEv:
 1018|     29|DoublyBufferedLogSink* DoublyBufferedLogSink::GetInstance() {
 1019|     29|    return Singleton<DoublyBufferedLogSink,
 1020|     29|                     LeakySingletonTraits<DoublyBufferedLogSink> >::get();
 1021|     29|}
_ZN7logging18CharArrayStreamBuf8overflowEi:
 1131|      9|int CharArrayStreamBuf::overflow(int ch) {
 1132|      9|    if (ch == std::streambuf::traits_type::eof()) {
  ------------------
  |  Branch (1132:9): [True: 0, False: 9]
  ------------------
 1133|      0|        return ch;
 1134|      0|    }
 1135|      9|    size_t new_size = std::max(_size * 3 / 2, (size_t)64);
 1136|      9|    char* new_data = (char*)malloc(new_size);
 1137|      9|    if (BAIDU_UNLIKELY(new_data == NULL)) {
  ------------------
  |  |  272|      9|#    define BAIDU_UNLIKELY(expr) (__builtin_expect((bool)(expr), false))
  |  |  ------------------
  |  |  |  Branch (272:34): [True: 0, False: 9]
  |  |  ------------------
  ------------------
 1138|      0|        setp(NULL, NULL);
 1139|      0|        return std::streambuf::traits_type::eof();
 1140|      0|    }
 1141|      9|    memcpy(new_data, _data, _size);
 1142|      9|    free(_data);
 1143|      9|    _data = new_data;
 1144|      9|    const size_t old_size = _size;
 1145|      9|    _size = new_size;
 1146|      9|    setp(_data, _data + new_size);
 1147|      9|    pbump(old_size);
 1148|       |    // if size == 1, this function will call overflow again.
 1149|      9|    return sputc(ch);
 1150|      9|}
_ZN7logging18CharArrayStreamBuf4syncEv:
 1152|      4|int CharArrayStreamBuf::sync() {
 1153|       |    // data are already there.
 1154|      4|    return 0;
 1155|      4|}
_ZN7logging18CharArrayStreamBuf5resetEv:
 1157|     29|void CharArrayStreamBuf::reset() {
 1158|     29|    setp(_data, _data + _size);
 1159|     29|}
_ZN7logging9LogStream11SetPositionEPKciS2_i:
 1171|     29|                                  LogSeverity severity) {
 1172|     29|    _file = file;
 1173|     29|    _line = line;
 1174|     29|    _func = func;
 1175|     29|    _severity = severity;
 1176|     29|    return *this;
 1177|     29|}
_ZN7logging9LogStream17FlushWithoutResetEv:
 1345|     29|void LogStream::FlushWithoutReset() {
 1346|     29|    if (empty()) {
  ------------------
  |  Branch (1346:9): [True: 0, False: 29]
  ------------------
 1347|       |        // Nothing to flush.
 1348|      0|        return;
 1349|      0|    }
 1350|       |
 1351|     29|#if !defined(OS_NACL) && !defined(__UCLIBC__)
 1352|     29|    if ((FLAGS_print_stack_on_check && _is_check && _severity == BLOG_FATAL) || _backtrace) {
  ------------------
  |  Branch (1352:10): [True: 29, False: 0]
  |  Branch (1352:40): [True: 4, False: 25]
  |  Branch (1352:53): [True: 4, False: 0]
  |  Branch (1352:81): [True: 0, False: 25]
  ------------------
 1353|       |        // Include a stack trace on a fatal.
 1354|      4|        butil::debug::StackTrace trace;
 1355|      4|        size_t count = 0;
 1356|      4|        const void* const* addrs = trace.Addresses(&count);
 1357|       |
 1358|      4|        *this << std::endl;  // Newline to separate from log message.
 1359|      4|        if (count > 3) {
  ------------------
  |  Branch (1359:13): [True: 4, False: 0]
  ------------------
 1360|       |            // Remove top 3 frames which are useless to users.
 1361|       |            // #2 may be ~LogStream
 1362|       |            //   #0 0x00000059ccae butil::debug::StackTrace::StackTrace()
 1363|       |            //   #1 0x0000005947c7 logging::LogStream::FlushWithoutReset()
 1364|       |            //   #2 0x000000594b88 logging::LogMessage::~LogMessage()
 1365|      4|            butil::debug::StackTrace trace_stripped(addrs + 3, count - 3);
 1366|      4|            trace_stripped.OutputToStream(this);
 1367|      4|        } else {
 1368|      0|            trace.OutputToStream(this);
 1369|      0|        }
 1370|      4|    }
 1371|     29|#endif
 1372|       |    // End the data with zero because sink is likely to assume this.
 1373|     29|    *this << std::ends;
 1374|       |    // Move back one step because we don't want to count the zero.
 1375|     29|    pbump(-1); 
 1376|       |
 1377|       |    // Give any logsink first dibs on the message.
 1378|       |#ifdef BAIDU_INTERNAL
 1379|       |    // If the logsink fails and it's not comlog, try comlog. stderr on last try.
 1380|       |    bool tried_comlog = false;
 1381|       |#endif
 1382|     29|    bool tried_default = false;
 1383|     29|    {
 1384|     29|        DoublyBufferedLogSink::ScopedPtr ptr;
 1385|     29|        if (DoublyBufferedLogSink::GetInstance()->Read(&ptr) == 0 &&
  ------------------
  |  Branch (1385:13): [True: 29, False: 0]
  ------------------
 1386|     29|            (*ptr) != NULL) {
  ------------------
  |  Branch (1386:13): [True: 0, False: 29]
  ------------------
 1387|      0|            bool result = (*ptr)->OnLogMessage(
 1388|      0|                _severity, _file, _line, _func, content());
 1389|      0|            if (result) {
  ------------------
  |  Branch (1389:17): [True: 0, False: 0]
  ------------------
 1390|      0|                goto FINISH_LOGGING;
 1391|      0|            }
 1392|       |#ifdef BAIDU_INTERNAL
 1393|       |            tried_comlog = (*ptr == ComlogSink::GetInstance());
 1394|       |#endif
 1395|      0|            tried_default = (*ptr == DefaultLogSink::GetInstance());
 1396|      0|        }
 1397|     29|    }
 1398|       |
 1399|       |#ifdef BAIDU_INTERNAL
 1400|       |    if (!tried_comlog) {
 1401|       |        if (ComlogSink::GetInstance()->OnLogMessage(
 1402|       |                _severity, _file, _line, _func, content())) {
 1403|       |            goto FINISH_LOGGING;
 1404|       |        }
 1405|       |    }
 1406|       |#endif
 1407|     29|    if (!tried_default) {
  ------------------
  |  Branch (1407:9): [True: 29, False: 0]
  ------------------
 1408|     29|        DefaultLogSink::GetInstance()->OnLogMessage(
 1409|     29|            _severity, _file, _line, _func, content());
 1410|     29|    }
 1411|       |
 1412|     29|FINISH_LOGGING:
 1413|     29|    if (FLAGS_crash_on_fatal_log && _severity == BLOG_FATAL) {
  ------------------
  |  Branch (1413:9): [True: 0, False: 29]
  |  Branch (1413:37): [True: 0, False: 0]
  ------------------
 1414|       |        // Ensure the first characters of the string are on the stack so they
 1415|       |        // are contained in minidumps for diagnostic purposes.
 1416|      0|        butil::StringPiece str = content();
 1417|      0|        char str_stack[1024];
 1418|      0|        str.copy(str_stack, arraysize(str_stack));
  ------------------
  |  |  122|      0|#define arraysize(array) (sizeof(::butil::ArraySizeHelper(array)))
  ------------------
 1419|      0|        butil::debug::Alias(str_stack);
 1420|       |
 1421|      0|        if (log_assert_handler) {
  ------------------
  |  Branch (1421:13): [True: 0, False: 0]
  ------------------
 1422|       |            // Make a copy of the string for the handler out of paranoia.
 1423|      0|            log_assert_handler(str.as_string());
 1424|      0|        } else {
 1425|       |            // Don't use the string with the newline, get a fresh version to send to
 1426|       |            // the debug message process. We also don't display assertions to the
 1427|       |            // user in release mode. The enduser can't do anything with this
 1428|       |            // information, and displaying message boxes when the application is
 1429|       |            // hosed can cause additional problems.
 1430|      0|#ifndef NDEBUG
 1431|      0|            DisplayDebugMessageInDialog(str.as_string());
 1432|      0|#endif
 1433|       |            // Crash the process to generate a dump.
 1434|      0|            butil::debug::BreakDebugger();
 1435|      0|        }
 1436|      0|    }
 1437|     29|}
_ZN7logging10LogMessageC2EPKciS2_i:
 1443|     29|                       const char* func, LogSeverity severity) {
 1444|     29|    _stream = CreateLogStream(file, line, func, severity);
 1445|     29|}
_ZN7logging10LogMessageD2Ev:
 1468|     29|LogMessage::~LogMessage() {
 1469|     29|    DestroyLogStream(_stream);
 1470|     29|}
_ZN7logging22GetLastSystemErrorCodeEv:
 1479|     29|SystemErrorCode GetLastSystemErrorCode() {
 1480|       |#if defined(OS_WIN)
 1481|       |    return ::GetLastError();
 1482|       |#elif defined(OS_POSIX)
 1483|     29|    return errno;
 1484|       |#else
 1485|       |#error Not implemented
 1486|       |#endif
 1487|     29|}
_ZN7logging22SetLastSystemErrorCodeEi:
 1489|     29|void SetLastSystemErrorCode(SystemErrorCode err) {
 1490|       |#if defined(OS_WIN)
 1491|       |    ::SetLastError(err);
 1492|       |#elif defined(OS_POSIX)
 1493|     29|    errno = err;
 1494|       |#else
 1495|       |#error Not implemented
 1496|       |#endif
 1497|     29|}
logging.cc:_ZN7loggingL16PrintLogSeverityERSoi:
  833|     29|static void PrintLogSeverity(std::ostream& os, int severity) {
  834|     29|    if (severity < 0) {
  ------------------
  |  Branch (834:9): [True: 0, False: 29]
  ------------------
  835|       |        // Add extra space to separate from following datetime.
  836|      0|        os << 'V' << -severity << ' ';
  837|     29|    } else if (severity < LOG_NUM_SEVERITIES) {
  ------------------
  |  Branch (837:16): [True: 29, False: 0]
  ------------------
  838|     29|        os << log_severity_names[severity][0];
  839|     29|    } else {
  840|      0|        os << 'U';
  841|      0|    }
  842|     29|}
_ZN7logging9OutputLogERSoRKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE:
  967|     29|inline void OutputLog(std::ostream& os, const butil::StringPiece& s) {
  968|     29|    if (FLAGS_escape_log) {
  ------------------
  |  Branch (968:9): [True: 0, False: 29]
  ------------------
  969|      0|        EscapeJson(os, s);
  970|     29|    } else {
  971|     29|        os.write(s.data(), s.length());
  972|     29|    }
  973|     29|}
_ZN7logging14DefaultLogSink11GetInstanceEv:
 1289|     29|    static DefaultLogSink* GetInstance() {
 1290|     29|        return Singleton<DefaultLogSink,
 1291|     29|                         LeakySingletonTraits<DefaultLogSink> >::get();
 1292|     29|    }
_ZN7logging14DefaultLogSinkC2Ev:
 1340|      1|    DefaultLogSink() = default;
_ZN7logging14DefaultLogSink12OnLogMessageEiPKciS2_RKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE:
 1301|     29|                      const butil::StringPiece& content) override {
 1302|     29|        std::string log;
 1303|     29|        if ((logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0 ||
  ------------------
  |  Branch (1303:13): [True: 29, False: 0]
  ------------------
 1304|     29|            severity >= kAlwaysPrintErrorLevel) {
  ------------------
  |  Branch (1304:13): [True: 0, False: 0]
  ------------------
 1305|     29|            log = LogInfoToLogStr(severity, file, line, func, content);
 1306|       |            // When we're only outputting to a log file, above a certain log level, we
 1307|       |            // should still output to stderr so that we can better detect and diagnose
 1308|       |            // problems with unit tests, especially on the buildbots.
 1309|     29|            fwrite(log.data(), log.size(), 1, stderr);
 1310|     29|            fflush(stderr);
 1311|     29|        }
 1312|       |        // write to log file
 1313|     29|        if ((logging_destination & LOG_TO_FILE) != 0) {
  ------------------
  |  Branch (1313:13): [True: 0, False: 29]
  ------------------
 1314|      0|            if ((FLAGS_crash_on_fatal_log && severity == BLOG_FATAL) ||
  ------------------
  |  Branch (1314:18): [True: 0, False: 0]
  |  Branch (1314:46): [True: 0, False: 0]
  ------------------
 1315|      0|                !FLAGS_async_log) {
  ------------------
  |  Branch (1315:17): [True: 0, False: 0]
  ------------------
 1316|      0|                if (log.empty()) {
  ------------------
  |  Branch (1316:21): [True: 0, False: 0]
  ------------------
 1317|      0|                    log = LogInfoToLogStr(severity, file, line, func, content);
 1318|      0|                }
 1319|      0|                Log2File(log);
 1320|      0|            } else {
 1321|      0|                LogInfo info;
 1322|      0|                if (log.empty()) {
  ------------------
  |  Branch (1322:21): [True: 0, False: 0]
  ------------------
 1323|      0|                    info.severity = severity;
 1324|      0|                    info.timestamp = GetTimestamp();
 1325|      0|                    info.file = file;
 1326|      0|                    info.func = func;
 1327|      0|                    info.line = line;
 1328|      0|                    info.content = content.as_string();
 1329|      0|                    info.raw = true;
 1330|      0|                } else {
 1331|      0|                    info.content = std::move(log);
 1332|      0|                    info.raw = false;
 1333|      0|                }
 1334|      0|                AsyncLogger::GetInstance()->Log(std::move(info));
 1335|      0|            }
 1336|      0|        }
 1337|     29|        return true;
 1338|     29|    }
_ZN7logging15CreateLogStreamEPKciS1_i:
 1235|     29|                                  LogSeverity severity) {
 1236|     29|    int slot = 0;
 1237|     29|    if (severity >= 0) {
  ------------------
  |  Branch (1237:9): [True: 29, False: 0]
  ------------------
 1238|     29|        DCHECK_LT(severity, LOG_NUM_SEVERITIES);
  ------------------
  |  |  887|     29|#define DCHECK_LT(val1, val2) BAIDU_DCHECK_OP(LT, < , val1, val2)
  |  |  ------------------
  |  |  |  |  856|     29|    if (DCHECK_IS_ON())                                                   \
  |  |  |  |  ------------------
  |  |  |  |  |  |  702|     29|#define DCHECK_IS_ON() 1
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (702:24): [True: 29, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  857|     29|        if (std::string* _result =                                      \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (857:26): [True: 0, False: 29]
  |  |  |  |  ------------------
  |  |  |  |  858|     29|            ::logging::Check##name##Impl((val1), (val2),                \
  |  |  |  |  859|     29|                                         #val1 " " #op " " #val2))      \
  |  |  |  |  860|     29|            ::logging::LogMessage(                                      \
  |  |  |  |  861|      0|                __FILE__, __LINE__, __func__,                           \
  |  |  |  |  862|      0|                ::logging::BLOG_DCHECK,                                 \
  |  |  |  |  863|      0|                _result).stream()
  |  |  ------------------
  ------------------
 1239|     29|        slot = severity + 1;
 1240|     29|    } // else vlog
 1241|     29|    LogStream** stream_array = get_or_new_tls_stream_array();
 1242|     29|    LogStream* stream = stream_array[slot];
 1243|     29|    if (stream == NULL) {
  ------------------
  |  Branch (1243:9): [True: 2, False: 27]
  ------------------
 1244|      2|        stream = new LogStream;
 1245|      2|        stream_array[slot] = stream;
 1246|      2|    }
 1247|     29|    if (stream->empty()) {
  ------------------
  |  Branch (1247:9): [True: 29, False: 0]
  ------------------
 1248|     29|        stream->SetPosition(file, line, func, severity);
 1249|     29|    }
 1250|     29|    return stream;
 1251|     29|}
logging.cc:_ZN7loggingL27get_or_new_tls_stream_arrayEv:
 1218|     29|static LogStream** get_or_new_tls_stream_array() {
 1219|     29|    LogStream** a = get_tls_stream_array();
 1220|     29|    if (a == NULL) {
  ------------------
  |  Branch (1220:9): [True: 1, False: 28]
  ------------------
 1221|      1|        a = new LogStream*[LOG_NUM_SEVERITIES + 1];
 1222|      1|        memset(a, 0, sizeof(LogStream*) * (LOG_NUM_SEVERITIES + 1));
 1223|      1|        if (is_bthread_linked()) {
  ------------------
  |  Branch (1223:13): [True: 1, False: 0]
  ------------------
 1224|      1|            bthread_setspecific(stream_bkey, a);
 1225|      1|        } else {
 1226|      0|            pthread_setspecific(stream_pkey, a);
 1227|      0|        }
 1228|      1|    }
 1229|     29|    return a;
 1230|     29|}
logging.cc:_ZN7loggingL20get_tls_stream_arrayEv:
 1209|     29|static LogStream** get_tls_stream_array() {
 1210|     29|    pthread_once(&create_stream_key_once, create_stream_key_or_die);
 1211|     29|    if (is_bthread_linked()) {
  ------------------
  |  Branch (1211:9): [True: 29, False: 0]
  ------------------
 1212|     29|        return (LogStream**)bthread_getspecific(stream_bkey);
 1213|     29|    } else {
 1214|      0|        return (LogStream**)pthread_getspecific(stream_pkey);
 1215|      0|    }
 1216|     29|}
logging.cc:_ZN7loggingL24create_stream_key_or_dieEv:
 1194|      1|static void create_stream_key_or_die() {
 1195|      1|    if (is_bthread_linked()) {
  ------------------
  |  Branch (1195:9): [True: 1, False: 0]
  ------------------
 1196|      1|        int rc = bthread_key_create(&stream_bkey, destroy_tls_streams);
 1197|      1|        if (rc) {
  ------------------
  |  Branch (1197:13): [True: 0, False: 1]
  ------------------
 1198|      0|            fprintf(stderr, "Fail to bthread_key_create");
 1199|      0|            exit(1);
 1200|      0|        }
 1201|      1|    } else {
 1202|      0|        int rc = pthread_key_create(&stream_pkey, destroy_tls_streams);
 1203|      0|        if (rc) {
  ------------------
  |  Branch (1203:13): [True: 0, False: 0]
  ------------------
 1204|       |            fprintf(stderr, "Fail to pthread_key_create");
 1205|      0|            exit(1);
 1206|      0|        }
 1207|      0|    }
 1208|      1|}
_ZN7logging17is_bthread_linkedEv:
 1183|     31|inline bool is_bthread_linked() { return bthread_key_create != NULL; }
_ZN7logging16DestroyLogStreamEPNS_9LogStreamE:
 1259|     29|inline void DestroyLogStream(LogStream* stream) {
 1260|     29|    if (stream != NULL) {
  ------------------
  |  Branch (1260:9): [True: 29, False: 0]
  ------------------
 1261|     29|        stream->Flush();
 1262|     29|    }
 1263|     29|}
_ZN7logging21DoublyBufferedLogSinkC2Ev:
 1011|      1|    DoublyBufferedLogSink() {}

_ZN7logging7LogSinkC2Ev:
  322|      1|    LogSink() {}
_ZN7logging18CharArrayStreamBufC2Ev:
  908|      2|    explicit CharArrayStreamBuf() : _data(NULL), _size(0) {}
_ZN7logging9LogStreamlsEPFRSoS1_E:
  939|     33|    inline LogStream& operator<<(std::ostream& (*m)(std::ostream&)) {
  940|     33|        m(*(std::ostream*)this);
  941|     33|        return *this;
  942|     33|    }
_ZN7logging9LogStream8SetCheckEv:
  961|      4|    LogStream& SetCheck() {
  962|      4|        _is_check = true;
  963|      4|        return *this;
  964|      4|    }
_ZNK7logging9LogStream5emptyEv:
  971|     58|    bool empty() const { return pbase() == pptr(); }
_ZNK7logging9LogStream7contentB5cxx11Ev:
  974|     29|    { return butil::StringPiece(pbase(), pptr() - pbase()); }
_ZN7logging9LogStream5FlushEv:
  990|     29|    inline void Flush() {
  991|     29|        const bool res = _noflush;
  992|     29|        _noflush = false;
  993|     29|        if (!res) {
  ------------------
  |  Branch (993:13): [True: 29, False: 0]
  ------------------
  994|       |            // Save and restore thread-local error code after Flush().
  995|     29|            const SystemErrorCode err = GetLastSystemErrorCode();
  996|     29|            FlushWithoutReset();
  997|     29|            reset();
  998|     29|            clear();
  999|     29|            SetLastSystemErrorCode(err);
 1000|     29|            _is_check = false;
 1001|     29|            _backtrace = false;
 1002|     29|        }
 1003|     29|    }
_ZN7logging10LogMessage6streamEv:
 1044|     29|    LogStream& stream() { return *_stream; }
_ZN7logging17LogMessageVoidifyC2Ev:
 1065|     29|    LogMessageVoidify() { }
_ZN7logging17LogMessageVoidifyanERSo:
 1068|     29|    void operator&(std::ostream&) { }
_ZN7logging9LogStreamlsIA12_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|    }
_ZN7logging9LogStreamlsImEERS0_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|    }
_ZN7logging9LogStreamlsIA33_cEERS0_RKT_:
  944|      4|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      4|        *(std::ostream*)this << t;
  946|      4|        return *this;
  947|      4|    }
_ZN7logging9LogStreamlsIA25_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|    }
_ZN7logging9LogStreamlsIPcEERS0_RKT_:
  944|      6|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      6|        *(std::ostream*)this << t;
  946|      6|        return *this;
  947|      6|    }
_ZN7logging9LogStreamlsIlEERS0_RKT_:
  944|      9|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      9|        *(std::ostream*)this << t;
  946|      9|        return *this;
  947|      9|    }
_ZN7logging9LogStreamlsIiEERS0_RKT_:
  944|     12|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|     12|        *(std::ostream*)this << t;
  946|     12|        return *this;
  947|     12|    }
_ZN7logging9LogStreamlsIA35_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|      6|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      6|        *(std::ostream*)this << t;
  946|      6|        return *this;
  947|      6|    }
_ZN7logging9LogStreamlsIA39_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|    }
_ZN7logging9LogStreamlsIA49_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|    }
_ZN7logging9LogStreamlsIA41_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|    }
_ZN7logging9LogStreamlsIcEERS0_RKT_:
  944|      6|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      6|        *(std::ostream*)this << t;
  946|      6|        return *this;
  947|      6|    }
_ZN7logging9LogStreamlsIA79_cEERS0_RKT_:
  944|      4|    template <typename T> inline LogStream& operator<<(T const& t) {
  945|      4|        *(std::ostream*)this << t;
  946|      4|        return *this;
  947|      4|    }
_ZN7logging9LogStreamlsIA46_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|    }
_ZN7logging9LogStreamC1Ev:
  926|      2|        : std::ostream(this), _file("-"), _line(0), _func("-")
  927|      2|        , _severity(0) , _noflush(false), _is_check(false), _backtrace(false) {
  928|      2|    }

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

_ZN5butil17ManualConstructorINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoEE4InitIJSG_EEEvDpOT_:
   62|     64|    void Init(Args&&... args) {
   63|     64|        new (_space.void_data()) Type(std::forward<Args>(args)...);
   64|     64|    }
_ZN5butil17ManualConstructorINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoEE3getEv:
   47|    256|    Type* get() {
   48|    256|        return _space.template data_as<Type>();
   49|    256|    }
_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|    }
_ZN5butil17ManualConstructorINS_7FlatMapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEN4bvar8VarEntryENS_13DefaultHasherIS7_EENS_14DefaultEqualToIS7_EELb0ENS_11PtAllocatorELb0EE14NewBucketsInfoEE7DestroyEv:
   66|     64|     void Destroy() { get()->~Type(); }

_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:
  244|     29|  static Type* get() {
  245|       |    // The load has acquire memory ordering as the thread which reads the
  246|       |    // instance_ pointer must acquire visibility over the singleton data.
  247|     29|    butil::subtle::AtomicWord value = butil::subtle::Acquire_Load(&instance_);
  248|     29|    if (value != 0 && value != butil::internal::kBeingCreatedMarker) {
  ------------------
  |  Branch (248:9): [True: 28, False: 1]
  |  Branch (248:23): [True: 28, False: 0]
  ------------------
  249|       |      // See the corresponding HAPPENS_BEFORE below.
  250|     28|      ANNOTATE_HAPPENS_AFTER(&instance_);
  251|     28|      return reinterpret_cast<Type*>(value);
  252|     28|    }
  253|       |
  254|       |    // Object isn't created yet, maybe we will get to create it, let's try...
  255|      1|    if (butil::subtle::Acquire_CompareAndSwap(
  ------------------
  |  Branch (255:9): [True: 1, False: 0]
  ------------------
  256|      1|          &instance_, 0, butil::internal::kBeingCreatedMarker) == 0) {
  257|       |      // instance_ was NULL and is now kBeingCreatedMarker.  Only one thread
  258|       |      // will ever get here.  Threads might be spinning on us, and they will
  259|       |      // stop right after we do this store.
  260|      1|      Type* newval = Traits::New();
  261|       |
  262|       |      // This annotation helps race detectors recognize correct lock-less
  263|       |      // synchronization between different threads calling get().
  264|       |      // See the corresponding HAPPENS_AFTER below and above.
  265|      1|      ANNOTATE_HAPPENS_BEFORE(&instance_);
  266|       |      // Releases the visibility over instance_ to the readers.
  267|      1|      butil::subtle::Release_Store(
  268|      1|          &instance_, reinterpret_cast<butil::subtle::AtomicWord>(newval));
  269|       |
  270|      1|      if (newval != NULL) {
  ------------------
  |  Branch (270:11): [True: 1, False: 0]
  ------------------
  271|      1|        if (Traits::kRegisterAtExit) {
  ------------------
  |  Branch (271:13): [Folded, False: 1]
  ------------------
  272|      0|          butil::AtExitManager::RegisterCallback(OnExit, NULL);
  273|      1|        } else {
  274|       |          // Instruct LeakSanitizer to ignore the designated memory leak.
  275|      1|          ANNOTATE_LEAKING_OBJECT_PTR(newval);
  ------------------
  |  |   51|      1|#define ANNOTATE_LEAKING_OBJECT_PTR(X) ((void)(X))
  ------------------
  276|      1|        }
  277|      1|      }
  278|       |
  279|      1|      return newval;
  280|      1|    }
  281|       |
  282|       |    // We hit a race. Wait for the other thread to complete it.
  283|      0|    value = butil::internal::WaitForInstance(&instance_);
  284|       |
  285|       |    // See the corresponding HAPPENS_BEFORE above.
  286|      0|    ANNOTATE_HAPPENS_AFTER(&instance_);
  287|      0|    return reinterpret_cast<Type*>(value);
  288|      1|  }
_ZN22DefaultSingletonTraitsIN7logging14DefaultLogSinkEE3NewEv:
   52|      1|  static Type* New() {
   53|       |    // The parenthesis is very important here; it forces POD type
   54|       |    // initialization.
   55|      1|    return new Type();
   56|      1|  }
_ZN9SingletonIN7logging21DoublyBufferedLogSinkE20LeakySingletonTraitsIS1_ES1_E3getEv:
  244|     29|  static Type* get() {
  245|       |    // The load has acquire memory ordering as the thread which reads the
  246|       |    // instance_ pointer must acquire visibility over the singleton data.
  247|     29|    butil::subtle::AtomicWord value = butil::subtle::Acquire_Load(&instance_);
  248|     29|    if (value != 0 && value != butil::internal::kBeingCreatedMarker) {
  ------------------
  |  Branch (248:9): [True: 28, False: 1]
  |  Branch (248:23): [True: 28, False: 0]
  ------------------
  249|       |      // See the corresponding HAPPENS_BEFORE below.
  250|     28|      ANNOTATE_HAPPENS_AFTER(&instance_);
  251|     28|      return reinterpret_cast<Type*>(value);
  252|     28|    }
  253|       |
  254|       |    // Object isn't created yet, maybe we will get to create it, let's try...
  255|      1|    if (butil::subtle::Acquire_CompareAndSwap(
  ------------------
  |  Branch (255:9): [True: 1, False: 0]
  ------------------
  256|      1|          &instance_, 0, butil::internal::kBeingCreatedMarker) == 0) {
  257|       |      // instance_ was NULL and is now kBeingCreatedMarker.  Only one thread
  258|       |      // will ever get here.  Threads might be spinning on us, and they will
  259|       |      // stop right after we do this store.
  260|      1|      Type* newval = Traits::New();
  261|       |
  262|       |      // This annotation helps race detectors recognize correct lock-less
  263|       |      // synchronization between different threads calling get().
  264|       |      // See the corresponding HAPPENS_AFTER below and above.
  265|      1|      ANNOTATE_HAPPENS_BEFORE(&instance_);
  266|       |      // Releases the visibility over instance_ to the readers.
  267|      1|      butil::subtle::Release_Store(
  268|      1|          &instance_, reinterpret_cast<butil::subtle::AtomicWord>(newval));
  269|       |
  270|      1|      if (newval != NULL) {
  ------------------
  |  Branch (270:11): [True: 1, False: 0]
  ------------------
  271|      1|        if (Traits::kRegisterAtExit) {
  ------------------
  |  Branch (271:13): [Folded, False: 1]
  ------------------
  272|      0|          butil::AtExitManager::RegisterCallback(OnExit, NULL);
  273|      1|        } else {
  274|       |          // Instruct LeakSanitizer to ignore the designated memory leak.
  275|      1|          ANNOTATE_LEAKING_OBJECT_PTR(newval);
  ------------------
  |  |   51|      1|#define ANNOTATE_LEAKING_OBJECT_PTR(X) ((void)(X))
  ------------------
  276|      1|        }
  277|      1|      }
  278|       |
  279|      1|      return newval;
  280|      1|    }
  281|       |
  282|       |    // We hit a race. Wait for the other thread to complete it.
  283|      0|    value = butil::internal::WaitForInstance(&instance_);
  284|       |
  285|       |    // See the corresponding HAPPENS_BEFORE above.
  286|      0|    ANNOTATE_HAPPENS_AFTER(&instance_);
  287|      0|    return reinterpret_cast<Type*>(value);
  288|      1|  }
_ZN22DefaultSingletonTraitsIN7logging21DoublyBufferedLogSinkEE3NewEv:
   52|      1|  static Type* New() {
   53|       |    // The parenthesis is very important here; it forces POD type
   54|       |    // initialization.
   55|      1|    return new Type();
   56|      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|      6|inline Dst saturated_cast(Src value) {
   37|       |  // Optimization for floating point values, which already saturate.
   38|      6|  if (std::numeric_limits<Dst>::is_iec559)
  ------------------
  |  Branch (38:7): [Folded, False: 6]
  ------------------
   39|      0|    return static_cast<Dst>(value);
   40|       |
   41|      6|  switch (internal::DstRangeRelationToSrcRange<Dst>(value)) {
  ------------------
  |  Branch (41:11): [True: 6, False: 0]
  ------------------
   42|      6|    case internal::RANGE_VALID:
  ------------------
  |  Branch (42:5): [True: 6, False: 0]
  ------------------
   43|      6|      return static_cast<Dst>(value);
   44|       |
   45|      0|    case internal::RANGE_UNDERFLOW:
  ------------------
  |  Branch (45:5): [True: 0, False: 6]
  ------------------
   46|      0|      return std::numeric_limits<Dst>::min();
   47|       |
   48|      0|    case internal::RANGE_OVERFLOW:
  ------------------
  |  Branch (48:5): [True: 0, False: 6]
  ------------------
   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: 6]
  ------------------
   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|      6|  }
   56|       |
   57|      0|  NOTREACHED();
  ------------------
  |  | 1224|      6|#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): [True: 0, Folded]
  |  |  |  |  |  |  |  Branch (472:7): [True: 0, Folded]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  |  |  847|      0|    << "Check failed: " #condition ". "
  |  |  ------------------
  ------------------
   58|      0|  return static_cast<Dst>(value);
   59|      6|}

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

_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|     90|    explicit lock_guard(pthread_mutex_t & mutex) : _pmutex(&mutex) {
  156|     90|#if !defined(NDEBUG)
  157|     90|        const int rc = pthread_mutex_lock(_pmutex);
  158|     90|        if (rc) {
  ------------------
  |  Branch (158:13): [True: 0, False: 90]
  ------------------
  159|      0|            LOG(FATAL) << "Fail to lock pthread_mutex_t=" << _pmutex << ", " << 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]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  160|      0|            _pmutex = NULL;
  161|      0|        }
  162|       |#else
  163|       |        pthread_mutex_lock(_pmutex);
  164|       |#endif  // NDEBUG
  165|     90|    }
_ZNSt10lock_guardI15pthread_mutex_tED2Ev:
  167|     90|    ~lock_guard() {
  168|     90|#ifndef NDEBUG
  169|     90|        if (_pmutex) {
  ------------------
  |  Branch (169:13): [True: 90, False: 0]
  ------------------
  170|     90|            pthread_mutex_unlock(_pmutex);
  171|     90|        }
  172|       |#else
  173|       |        pthread_mutex_unlock(_pmutex);
  174|       |#endif
  175|     90|    }

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

_ZN5butil9back_charERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE:
  468|     16|inline char back_char(const std::string& s) { return s[s.size() - 1]; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4dataEv:
  208|    323|  const value_type* data() const { return ptr_; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4sizeEv:
  209|  6.80k|  size_type size() const { return length_; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5beginEv:
  274|  6.54k|  const_iterator begin() const { return ptr_; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3endEv:
  275|  4.36k|  const_iterator end() const { return ptr_ + length_; }
_ZN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEC2EPKcm:
  196|  3.39k|      : ptr_(offset), length_(len) {}
_ZN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEC2Ev:
  184|  1.56M|  BasicStringPiece() : ptr_(NULL), length_(0) {}
_ZN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEC2EPKc:
  186|  2.30k|      : ptr_(str),
  187|  2.30k|        length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
  ------------------
  |  Branch (187:17): [True: 0, False: 2.30k]
  ------------------
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE6lengthEv:
  210|     29|  size_type length() const { return length_; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE5emptyEv:
  211|     45|  bool empty() const { return length_ == 0; }
_ZNK5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE4findERKS7_m:
  321|  2.18k|                 size_type pos = 0) const {
  322|  2.18k|    return internal::find(*this, s, pos);
  323|  2.18k|  }
_ZN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE3setEPKcm:
  222|    173|  void set(const value_type* data, size_type len) {
  223|    173|    ptr_ = data;
  224|    173|    length_ = len;
  225|    173|  }

_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|    102|    void lock() {
   71|       |#if defined(OS_WIN)
   72|       |        ::EnterCriticalSection(&_native_handle);
   73|       |#elif defined(OS_POSIX)
   74|       |        pthread_mutex_lock(&_native_handle);
   75|    102|#endif
   76|    102|    }
_ZN5butil5Mutex6unlockEv:
   80|    102|    void unlock() {
   81|       |#if defined(OS_WIN)
   82|       |        ::LeaveCriticalSection(&_native_handle);
   83|       |#elif defined(OS_POSIX)
   84|       |        pthread_mutex_unlock(&_native_handle);
   85|    102|#endif
   86|    102|    }
_ZN5butil4LockC2Ev:
  126|    106|    Lock() {}
_ZN5butil4Lock7AcquireEv:
  128|     42|    void Acquire() { lock(); }
_ZN5butil4Lock7ReleaseEv:
  129|     42|    void Release() { unlock(); }
_ZNK5butil4Lock14AssertAcquiredEv:
  131|     42|    void AssertAcquired() const {}
_ZN5butil8AutoLockC2ERNS_4LockE:
  139|     42|    explicit AutoLock(Lock& lock) : lock_(lock) {
  140|     42|        lock_.Acquire();
  141|     42|    }
_ZN5butil8AutoLockD2Ev:
  147|     42|    ~AutoLock() {
  148|     42|        lock_.AssertAcquired();
  149|     42|        lock_.Release();
  150|     42|    }

_ZN6google8DemangleEPKcPci:
 1298|     32|bool Demangle(const char *mangled, char *out, int out_size) {
 1299|     32|  State state;
 1300|     32|  InitState(&state, mangled, out, out_size);
 1301|     32|  return ParseTopLevelMangledName(&state) && !state.overflowed;
  ------------------
  |  Branch (1301:10): [True: 8, False: 24]
  |  Branch (1301:46): [True: 8, False: 0]
  ------------------
 1302|     32|}
demangle.cc:_ZN6googleL9InitStateEPNS_5StateEPKcPci:
  188|     32|                      char *out, int out_size) {
  189|     32|  state->mangled_cur = mangled;
  190|     32|  state->out_cur = out;
  191|     32|  state->out_begin = out;
  192|     32|  state->out_end = out + out_size;
  193|       |  state->prev_name  = NULL;
  194|     32|  state->prev_name_length = -1;
  195|     32|  state->nest_level = -1;
  196|     32|  state->append = true;
  197|     32|  state->overflowed = false;
  198|     32|}
demangle.cc:_ZN6googleL24ParseTopLevelMangledNameEPNS_5StateE:
 1277|     32|static bool ParseTopLevelMangledName(State *state) {
 1278|     32|  if (ParseMangledName(state)) {
  ------------------
  |  Branch (1278:7): [True: 8, False: 24]
  ------------------
 1279|      8|    if (state->mangled_cur[0] != '\0') {
  ------------------
  |  Branch (1279:9): [True: 0, False: 8]
  ------------------
 1280|       |      // Drop trailing function clone suffix, if any.
 1281|      0|      if (IsFunctionCloneSuffix(state->mangled_cur)) {
  ------------------
  |  Branch (1281:11): [True: 0, False: 0]
  ------------------
 1282|      0|        return true;
 1283|      0|      }
 1284|       |      // Append trailing version suffix if any.
 1285|       |      // ex. _Z3foo@@GLIBCXX_3.4
 1286|      0|      if (state->mangled_cur[0] == '@') {
  ------------------
  |  Branch (1286:11): [True: 0, False: 0]
  ------------------
 1287|      0|        MaybeAppend(state, state->mangled_cur);
 1288|      0|        return true;
 1289|      0|      }
 1290|      0|      return false;  // Unconsumed suffix.
 1291|      0|    }
 1292|      8|    return true;
 1293|      8|  }
 1294|     24|  return false;
 1295|     32|}
demangle.cc:_ZN6googleL16ParseMangledNameEPNS_5StateE:
  474|     32|static bool ParseMangledName(State *state) {
  475|     32|  return ParseTwoCharToken(state, "_Z") && ParseEncoding(state);
  ------------------
  |  Branch (475:10): [True: 8, False: 24]
  |  Branch (475:44): [True: 8, False: 0]
  ------------------
  476|     32|}
demangle.cc:_ZN6googleL17ParseTwoCharTokenEPNS_5StateEPKc:
  214|  1.61k|static bool ParseTwoCharToken(State *state, const char *two_char_token) {
  215|  1.61k|  if (state->mangled_cur[0] == two_char_token[0] &&
  ------------------
  |  Branch (215:7): [True: 156, False: 1.45k]
  ------------------
  216|    156|      state->mangled_cur[1] == two_char_token[1]) {
  ------------------
  |  Branch (216:7): [True: 48, False: 108]
  ------------------
  217|     48|    state->mangled_cur += 2;
  218|     48|    return true;
  219|     48|  }
  220|  1.56k|  return false;
  221|  1.61k|}
demangle.cc:_ZN6googleL13ParseEncodingEPNS_5StateE:
  481|      8|static bool ParseEncoding(State *state) {
  482|      8|  State copy = *state;
  483|      8|  if (ParseName(state) && ParseBareFunctionType(state)) {
  ------------------
  |  Branch (483:7): [True: 8, False: 0]
  |  Branch (483:27): [True: 8, False: 0]
  ------------------
  484|      8|    return true;
  485|      8|  }
  486|      0|  *state = copy;
  487|       |
  488|      0|  if (ParseName(state) || ParseSpecialName(state)) {
  ------------------
  |  Branch (488:7): [True: 0, False: 0]
  |  Branch (488:27): [True: 0, False: 0]
  ------------------
  489|      0|    return true;
  490|      0|  }
  491|      0|  return false;
  492|      0|}
demangle.cc:_ZN6googleL9ParseNameEPNS_5StateE:
  498|    132|static bool ParseName(State *state) {
  499|    132|  if (ParseNestedName(state) || ParseLocalName(state)) {
  ------------------
  |  Branch (499:7): [True: 60, False: 72]
  |  Branch (499:33): [True: 0, False: 72]
  ------------------
  500|     60|    return true;
  501|     60|  }
  502|       |
  503|     72|  State copy = *state;
  504|     72|  if (ParseUnscopedTemplateName(state) &&
  ------------------
  |  Branch (504:7): [True: 16, False: 56]
  ------------------
  505|     16|      ParseTemplateArgs(state)) {
  ------------------
  |  Branch (505:7): [True: 0, False: 16]
  ------------------
  506|      0|    return true;
  507|      0|  }
  508|     72|  *state = copy;
  509|       |
  510|       |  // Less greedy than <unscoped-template-name> <template-args>.
  511|     72|  if (ParseUnscopedName(state)) {
  ------------------
  |  Branch (511:7): [True: 0, False: 72]
  ------------------
  512|      0|    return true;
  513|      0|  }
  514|     72|  return false;
  515|     72|}
demangle.cc:_ZN6googleL15ParseNestedNameEPNS_5StateE:
  542|    132|static bool ParseNestedName(State *state) {
  543|    132|  State copy = *state;
  544|    132|  if (ParseOneCharToken(state, 'N') &&
  ------------------
  |  Branch (544:7): [True: 60, False: 72]
  ------------------
  545|     60|      EnterNestedName(state) &&
  ------------------
  |  Branch (545:7): [True: 60, False: 0]
  ------------------
  546|     60|      Optional(ParseCVQualifiers(state)) &&
  ------------------
  |  Branch (546:7): [True: 60, False: 0]
  ------------------
  547|     60|      ParsePrefix(state) &&
  ------------------
  |  Branch (547:7): [True: 60, False: 0]
  ------------------
  548|     60|      LeaveNestedName(state, copy.nest_level) &&
  ------------------
  |  Branch (548:7): [True: 60, False: 0]
  ------------------
  549|     60|      ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (549:7): [True: 60, False: 0]
  ------------------
  550|     60|    return true;
  551|     60|  }
  552|     72|  *state = copy;
  553|     72|  return false;
  554|    132|}
demangle.cc:_ZN6googleL17ParseOneCharTokenEPNS_5StateEc:
  203|  5.18k|static bool ParseOneCharToken(State *state, const char one_char_token) {
  204|  5.18k|  if (state->mangled_cur[0] == one_char_token) {
  ------------------
  |  Branch (204:7): [True: 332, False: 4.85k]
  ------------------
  205|    332|    ++state->mangled_cur;
  206|    332|    return true;
  207|    332|  }
  208|  4.85k|  return false;
  209|  5.18k|}
demangle.cc:_ZN6googleL15EnterNestedNameEPNS_5StateE:
  350|     60|static bool EnterNestedName(State *state) {
  351|     60|  state->nest_level = 0;
  352|     60|  return true;
  353|     60|}
demangle.cc:_ZN6googleL8OptionalEb:
  237|     60|static bool Optional(bool) {
  238|     60|  return true;
  239|     60|}
demangle.cc:_ZN6googleL17ParseCVQualifiersEPNS_5StateE:
  962|    296|static bool ParseCVQualifiers(State *state) {
  963|    296|  int num_cv_qualifiers = 0;
  964|    296|  num_cv_qualifiers += ParseOneCharToken(state, 'r');
  965|    296|  num_cv_qualifiers += ParseOneCharToken(state, 'V');
  966|    296|  num_cv_qualifiers += ParseOneCharToken(state, 'K');
  967|    296|  return num_cv_qualifiers > 0;
  968|    296|}
demangle.cc:_ZN6googleL11ParsePrefixEPNS_5StateE:
  567|    108|static bool ParsePrefix(State *state) {
  568|    108|  bool has_something = false;
  569|    236|  while (true) {
  ------------------
  |  Branch (569:10): [True: 236, Folded]
  ------------------
  570|    236|    MaybeAppendSeparator(state);
  571|    236|    if (ParseTemplateParam(state) ||
  ------------------
  |  Branch (571:9): [True: 0, False: 236]
  ------------------
  572|    236|        ParseSubstitution(state) ||
  ------------------
  |  Branch (572:9): [True: 60, False: 176]
  ------------------
  573|    176|        ParseUnscopedName(state)) {
  ------------------
  |  Branch (573:9): [True: 68, False: 108]
  ------------------
  574|    128|      has_something = true;
  575|    128|      MaybeIncreaseNestLevel(state);
  576|    128|      continue;
  577|    128|    }
  578|    108|    MaybeCancelLastSeparator(state);
  579|    108|    if (has_something && ParseTemplateArgs(state)) {
  ------------------
  |  Branch (579:9): [True: 68, False: 40]
  |  Branch (579:26): [True: 48, False: 20]
  ------------------
  580|     48|      return ParsePrefix(state);
  581|     60|    } else {
  582|     60|      break;
  583|     60|    }
  584|    108|  }
  585|     60|  return true;
  586|    108|}
demangle.cc:_ZN6googleL20MaybeAppendSeparatorEPNS_5StateE:
  381|    236|static void MaybeAppendSeparator(State *state) {
  382|    236|  if (state->nest_level >= 1) {
  ------------------
  |  Branch (382:7): [True: 176, False: 60]
  ------------------
  383|    176|    MaybeAppend(state, "::");
  384|    176|  }
  385|    236|}
demangle.cc:_ZN6googleL18ParseTemplateParamEPNS_5StateE:
 1051|    348|static bool ParseTemplateParam(State *state) {
 1052|    348|  if (ParseTwoCharToken(state, "T_")) {
  ------------------
  |  Branch (1052:7): [True: 0, False: 348]
  ------------------
 1053|      0|    MaybeAppend(state, "?");  // We don't support template substitutions.
 1054|      0|    return true;
 1055|      0|  }
 1056|       |
 1057|    348|  State copy = *state;
 1058|    348|  if (ParseOneCharToken(state, 'T') && ParseNumber(state, NULL) &&
  ------------------
  |  Branch (1058:7): [True: 0, False: 348]
  |  Branch (1058:40): [True: 0, False: 0]
  ------------------
 1059|      0|      ParseOneCharToken(state, '_')) {
  ------------------
  |  Branch (1059:7): [True: 0, False: 0]
  ------------------
 1060|      0|    MaybeAppend(state, "?");  // We don't support template substitutions.
 1061|      0|    return true;
 1062|      0|  }
 1063|    348|  *state = copy;
 1064|    348|  return false;
 1065|    348|}
demangle.cc:_ZN6googleL11ParseNumberEPNS_5StateEPi:
  628|    320|static bool ParseNumber(State *state, int *number_out) {
  629|    320|  int sign = 1;
  630|    320|  if (ParseOneCharToken(state, 'n')) {
  ------------------
  |  Branch (630:7): [True: 0, False: 320]
  ------------------
  631|      0|    sign = -1;
  632|      0|  }
  633|    320|  const char *p = state->mangled_cur;
  634|    320|  int number = 0;
  635|    420|  for (;*p != '\0'; ++p) {
  ------------------
  |  Branch (635:9): [True: 404, False: 16]
  ------------------
  636|    404|    if (IsDigit(*p)) {
  ------------------
  |  Branch (636:9): [True: 100, False: 304]
  ------------------
  637|    100|      number = number * 10 + (*p - '0');
  638|    304|    } else {
  639|    304|      break;
  640|    304|    }
  641|    404|  }
  642|    320|  if (p != state->mangled_cur) {  // Conversion succeeded.
  ------------------
  |  Branch (642:7): [True: 68, False: 252]
  ------------------
  643|     68|    state->mangled_cur = p;
  644|     68|    if (number_out != NULL) {
  ------------------
  |  Branch (644:9): [True: 68, False: 0]
  ------------------
  645|     68|      *number_out = number * sign;
  646|     68|    }
  647|     68|    return true;
  648|     68|  }
  649|    252|  return false;
  650|    320|}
demangle.cc:_ZN6googleL7IsDigitEc:
  290|    500|static bool IsDigit(char c) {
  291|    500|  return c >= '0' && c <= '9';
  ------------------
  |  Branch (291:10): [True: 500, False: 0]
  |  Branch (291:22): [True: 128, False: 372]
  ------------------
  292|    500|}
demangle.cc:_ZN6googleL17ParseSubstitutionEPNS_5StateE:
 1242|    436|static bool ParseSubstitution(State *state) {
 1243|    436|  if (ParseTwoCharToken(state, "S_")) {
  ------------------
  |  Branch (1243:7): [True: 40, False: 396]
  ------------------
 1244|     40|    MaybeAppend(state, "?");  // We don't support substitutions.
 1245|     40|    return true;
 1246|     40|  }
 1247|       |
 1248|    396|  State copy = *state;
 1249|    396|  if (ParseOneCharToken(state, 'S') && ParseSeqId(state) &&
  ------------------
  |  Branch (1249:7): [True: 52, False: 344]
  |  Branch (1249:40): [True: 44, False: 8]
  ------------------
 1250|     44|      ParseOneCharToken(state, '_')) {
  ------------------
  |  Branch (1250:7): [True: 44, False: 0]
  ------------------
 1251|     44|    MaybeAppend(state, "?");  // We don't support substitutions.
 1252|     44|    return true;
 1253|     44|  }
 1254|    352|  *state = copy;
 1255|       |
 1256|       |  // Expand abbreviations like "St" => "std".
 1257|    352|  if (ParseOneCharToken(state, 'S')) {
  ------------------
  |  Branch (1257:7): [True: 8, False: 344]
  ------------------
 1258|      8|    const AbbrevPair *p;
 1259|      8|    for (p = kSubstitutionList; p->abbrev != NULL; ++p) {
  ------------------
  |  Branch (1259:33): [True: 8, False: 0]
  ------------------
 1260|      8|      if (state->mangled_cur[0] == p->abbrev[1]) {
  ------------------
  |  Branch (1260:11): [True: 8, False: 0]
  ------------------
 1261|      8|        MaybeAppend(state, "std");
 1262|      8|        if (p->real_name[0] != '\0') {
  ------------------
  |  Branch (1262:13): [True: 0, False: 8]
  ------------------
 1263|      0|          MaybeAppend(state, "::");
 1264|      0|          MaybeAppend(state, p->real_name);
 1265|      0|        }
 1266|      8|        ++state->mangled_cur;
 1267|      8|        return true;
 1268|      8|      }
 1269|      8|    }
 1270|      8|  }
 1271|    344|  *state = copy;
 1272|    344|  return false;
 1273|    352|}
demangle.cc:_ZN6googleL10ParseSeqIdEPNS_5StateE:
  670|     52|static bool ParseSeqId(State *state) {
  671|     52|  const char *p = state->mangled_cur;
  672|     96|  for (;*p != '\0'; ++p) {
  ------------------
  |  Branch (672:9): [True: 96, False: 0]
  ------------------
  673|     96|    if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) {
  ------------------
  |  Branch (673:9): [True: 68, False: 28]
  |  Branch (673:27): [True: 68, False: 0]
  |  Branch (673:40): [True: 16, False: 52]
  ------------------
  674|     52|      break;
  675|     52|    }
  676|     96|  }
  677|     52|  if (p != state->mangled_cur) {  // Conversion succeeded.
  ------------------
  |  Branch (677:7): [True: 44, False: 8]
  ------------------
  678|     44|    state->mangled_cur = p;
  679|     44|    return true;
  680|     44|  }
  681|      8|  return false;
  682|     52|}
demangle.cc:_ZN6googleL22MaybeIncreaseNestLevelEPNS_5StateE:
  374|    128|static void MaybeIncreaseNestLevel(State *state) {
  375|    128|  if (state->nest_level > -1) {
  ------------------
  |  Branch (375:7): [True: 128, False: 0]
  ------------------
  376|    128|    ++state->nest_level;
  377|    128|  }
  378|    128|}
demangle.cc:_ZN6googleL24MaybeCancelLastSeparatorEPNS_5StateE:
  388|    108|static void MaybeCancelLastSeparator(State *state) {
  389|    108|  if (state->nest_level >= 1 && state->append &&
  ------------------
  |  Branch (389:7): [True: 108, False: 0]
  |  Branch (389:33): [True: 16, False: 92]
  ------------------
  390|     16|      state->out_begin <= state->out_cur - 2) {
  ------------------
  |  Branch (390:7): [True: 16, False: 0]
  ------------------
  391|     16|    state->out_cur -= 2;
  392|     16|    *state->out_cur = '\0';
  393|     16|  }
  394|    108|}
demangle.cc:_ZN6googleL15LeaveNestedNameEPNS_5StateEs:
  356|     60|static bool LeaveNestedName(State *state, short prev_value) {
  357|     60|  state->nest_level = prev_value;
  358|     60|  return true;
  359|     60|}
demangle.cc:_ZN6googleL14ParseLocalNameEPNS_5StateE:
 1212|     72|static bool ParseLocalName(State *state) {
 1213|     72|  State copy = *state;
 1214|     72|  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
  ------------------
  |  Branch (1214:7): [True: 0, False: 72]
  |  Branch (1214:40): [True: 0, False: 0]
  ------------------
 1215|      0|      ParseOneCharToken(state, 'E') && MaybeAppend(state, "::") &&
  ------------------
  |  Branch (1215:7): [True: 0, False: 0]
  |  Branch (1215:40): [True: 0, False: 0]
  ------------------
 1216|      0|      ParseName(state) && Optional(ParseDiscriminator(state))) {
  ------------------
  |  Branch (1216:7): [True: 0, False: 0]
  |  Branch (1216:27): [True: 0, False: 0]
  ------------------
 1217|      0|    return true;
 1218|      0|  }
 1219|     72|  *state = copy;
 1220|       |
 1221|     72|  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
  ------------------
  |  Branch (1221:7): [True: 0, False: 72]
  |  Branch (1221:40): [True: 0, False: 0]
  ------------------
 1222|      0|      ParseTwoCharToken(state, "Es") && Optional(ParseDiscriminator(state))) {
  ------------------
  |  Branch (1222:7): [True: 0, False: 0]
  |  Branch (1222:41): [True: 0, False: 0]
  ------------------
 1223|      0|    return true;
 1224|      0|  }
 1225|     72|  *state = copy;
 1226|     72|  return false;
 1227|     72|}
demangle.cc:_ZN6googleL25ParseUnscopedTemplateNameEPNS_5StateE:
  536|     72|static bool ParseUnscopedTemplateName(State *state) {
  537|     72|  return ParseUnscopedName(state) || ParseSubstitution(state);
  ------------------
  |  Branch (537:10): [True: 0, False: 72]
  |  Branch (537:38): [True: 16, False: 56]
  ------------------
  538|     72|}
demangle.cc:_ZN6googleL17ParseTemplateArgsEPNS_5StateE:
 1076|     84|static bool ParseTemplateArgs(State *state) {
 1077|     84|  State copy = *state;
 1078|     84|  DisableAppend(state);
 1079|     84|  if (ParseOneCharToken(state, 'I') &&
  ------------------
  |  Branch (1079:7): [True: 48, False: 36]
  ------------------
 1080|     48|      OneOrMore(ParseTemplateArg, state) &&
  ------------------
  |  Branch (1080:7): [True: 48, False: 0]
  ------------------
 1081|     48|      ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (1081:7): [True: 48, False: 0]
  ------------------
 1082|     48|    RestoreAppend(state, copy.append);
 1083|     48|    MaybeAppend(state, "<>");
 1084|     48|    return true;
 1085|     48|  }
 1086|     36|  *state = copy;
 1087|     36|  return false;
 1088|     84|}
demangle.cc:_ZN6googleL13DisableAppendEPNS_5StateE:
  362|     92|static bool DisableAppend(State *state) {
  363|     92|  state->append = false;
  364|     92|  return true;
  365|     92|}
demangle.cc:_ZN6googleL9OneOrMoreEPFbPNS_5StateEES1_:
  243|     56|static bool OneOrMore(ParseFunc parse_func, State *state) {
  244|     56|  if (parse_func(state)) {
  ------------------
  |  Branch (244:7): [True: 56, False: 0]
  ------------------
  245|    140|    while (parse_func(state)) {
  ------------------
  |  Branch (245:12): [True: 84, False: 56]
  ------------------
  246|     84|    }
  247|     56|    return true;
  248|     56|  }
  249|      0|  return false;
  250|     56|}
demangle.cc:_ZN6googleL16ParseTemplateArgEPNS_5StateE:
 1094|    128|static bool ParseTemplateArg(State *state) {
 1095|    128|  State copy = *state;
 1096|    128|  if (ParseOneCharToken(state, 'I') &&
  ------------------
  |  Branch (1096:7): [True: 0, False: 128]
  ------------------
 1097|      0|      ZeroOrMore(ParseTemplateArg, state) &&
  ------------------
  |  Branch (1097:7): [True: 0, False: 0]
  ------------------
 1098|      0|      ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (1098:7): [True: 0, False: 0]
  ------------------
 1099|      0|    return true;
 1100|      0|  }
 1101|    128|  *state = copy;
 1102|       |
 1103|    128|  if (ParseType(state) ||
  ------------------
  |  Branch (1103:7): [True: 80, False: 48]
  ------------------
 1104|     80|      ParseExprPrimary(state)) {
  ------------------
  |  Branch (1104:7): [True: 0, False: 48]
  ------------------
 1105|     80|    return true;
 1106|     80|  }
 1107|     48|  *state = copy;
 1108|       |
 1109|     48|  if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
  ------------------
  |  Branch (1109:7): [True: 0, False: 48]
  |  Branch (1109:40): [True: 0, False: 0]
  ------------------
 1110|      0|      ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (1110:7): [True: 0, False: 0]
  ------------------
 1111|      0|    return true;
 1112|      0|  }
 1113|     48|  *state = copy;
 1114|     48|  return false;
 1115|     48|}
demangle.cc:_ZN6googleL9ParseTypeEPNS_5StateE:
  906|    236|static bool ParseType(State *state) {
  907|       |  // We should check CV-qualifers, and PRGC things first.
  908|    236|  State copy = *state;
  909|    236|  if (ParseCVQualifiers(state) && ParseType(state)) {
  ------------------
  |  Branch (909:7): [True: 8, False: 228]
  |  Branch (909:35): [True: 8, False: 0]
  ------------------
  910|      8|    return true;
  911|      8|  }
  912|    228|  *state = copy;
  913|       |
  914|    228|  if (ParseCharClass(state, "OPRCG") && ParseType(state)) {
  ------------------
  |  Branch (914:7): [True: 32, False: 196]
  |  Branch (914:41): [True: 32, False: 0]
  ------------------
  915|     32|    return true;
  916|     32|  }
  917|    196|  *state = copy;
  918|       |
  919|    196|  if (ParseTwoCharToken(state, "Dp") && ParseType(state)) {
  ------------------
  |  Branch (919:7): [True: 0, False: 196]
  |  Branch (919:41): [True: 0, False: 0]
  ------------------
  920|      0|    return true;
  921|      0|  }
  922|    196|  *state = copy;
  923|       |
  924|    196|  if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") &&
  ------------------
  |  Branch (924:7): [True: 0, False: 196]
  |  Branch (924:40): [True: 0, False: 0]
  ------------------
  925|      0|      ParseExpression(state) && ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (925:7): [True: 0, False: 0]
  |  Branch (925:33): [True: 0, False: 0]
  ------------------
  926|      0|    return true;
  927|      0|  }
  928|    196|  *state = copy;
  929|       |
  930|    196|  if (ParseOneCharToken(state, 'U') && ParseSourceName(state) &&
  ------------------
  |  Branch (930:7): [True: 0, False: 196]
  |  Branch (930:40): [True: 0, False: 0]
  ------------------
  931|      0|      ParseType(state)) {
  ------------------
  |  Branch (931:7): [True: 0, False: 0]
  ------------------
  932|      0|    return true;
  933|      0|  }
  934|    196|  *state = copy;
  935|       |
  936|    196|  if (ParseBuiltinType(state) ||
  ------------------
  |  Branch (936:7): [True: 72, False: 124]
  ------------------
  937|    124|      ParseFunctionType(state) ||
  ------------------
  |  Branch (937:7): [True: 0, False: 124]
  ------------------
  938|    124|      ParseClassEnumType(state) ||
  ------------------
  |  Branch (938:7): [True: 52, False: 72]
  ------------------
  939|     72|      ParseArrayType(state) ||
  ------------------
  |  Branch (939:7): [True: 0, False: 72]
  ------------------
  940|     72|      ParsePointerToMemberType(state) ||
  ------------------
  |  Branch (940:7): [True: 0, False: 72]
  ------------------
  941|    140|      ParseSubstitution(state)) {
  ------------------
  |  Branch (941:7): [True: 16, False: 56]
  ------------------
  942|    140|    return true;
  943|    140|  }
  944|       |
  945|     56|  if (ParseTemplateTemplateParam(state) &&
  ------------------
  |  Branch (945:7): [True: 0, False: 56]
  ------------------
  946|      0|      ParseTemplateArgs(state)) {
  ------------------
  |  Branch (946:7): [True: 0, False: 0]
  ------------------
  947|      0|    return true;
  948|      0|  }
  949|     56|  *state = copy;
  950|       |
  951|       |  // Less greedy than <template-template-param> <template-args>.
  952|     56|  if (ParseTemplateParam(state)) {
  ------------------
  |  Branch (952:7): [True: 0, False: 56]
  ------------------
  953|      0|    return true;
  954|      0|  }
  955|       |
  956|     56|  return false;
  957|     56|}
demangle.cc:_ZN6googleL14ParseCharClassEPNS_5StateEPKc:
  225|    228|static bool ParseCharClass(State *state, const char *char_class) {
  226|    228|  const char *p = char_class;
  227|  1.27k|  for (; *p != '\0'; ++p) {
  ------------------
  |  Branch (227:10): [True: 1.07k, False: 196]
  ------------------
  228|  1.07k|    if (state->mangled_cur[0] == *p) {
  ------------------
  |  Branch (228:9): [True: 32, False: 1.04k]
  ------------------
  229|     32|      ++state->mangled_cur;
  230|     32|      return true;
  231|     32|    }
  232|  1.07k|  }
  233|    196|  return false;
  234|    228|}
demangle.cc:_ZN6googleL15ParseSourceNameEPNS_5StateE:
  600|    320|static bool ParseSourceName(State *state) {
  601|    320|  State copy = *state;
  602|    320|  int length = -1;
  603|    320|  if (ParseNumber(state, &length) && ParseIdentifier(state, length)) {
  ------------------
  |  Branch (603:7): [True: 68, False: 252]
  |  Branch (603:38): [True: 68, False: 0]
  ------------------
  604|     68|    return true;
  605|     68|  }
  606|    252|  *state = copy;
  607|    252|  return false;
  608|    320|}
demangle.cc:_ZN6googleL15ParseIdentifierEPNS_5StateEi:
  685|     68|static bool ParseIdentifier(State *state, int length) {
  686|     68|  if (length == -1 ||
  ------------------
  |  Branch (686:7): [True: 0, False: 68]
  ------------------
  687|     68|      !AtLeastNumCharsRemaining(state->mangled_cur, length)) {
  ------------------
  |  Branch (687:7): [True: 0, False: 68]
  ------------------
  688|      0|    return false;
  689|      0|  }
  690|     68|  if (IdentifierIsAnonymousNamespace(state, length)) {
  ------------------
  |  Branch (690:7): [True: 0, False: 68]
  ------------------
  691|      0|    MaybeAppend(state, "(anonymous namespace)");
  692|     68|  } else {
  693|     68|    MaybeAppendWithLength(state, state->mangled_cur, length);
  694|     68|  }
  695|     68|  state->mangled_cur += length;
  696|     68|  return true;
  697|     68|}
demangle.cc:_ZN6googleL24AtLeastNumCharsRemainingEPKci:
  168|    388|static bool AtLeastNumCharsRemaining(const char *str, int n) {
  169|  1.66k|  for (int i = 0; i < n; ++i) {
  ------------------
  |  Branch (169:19): [True: 1.30k, False: 368]
  ------------------
  170|  1.30k|    if (str[i] == '\0') {
  ------------------
  |  Branch (170:9): [True: 20, False: 1.28k]
  ------------------
  171|     20|      return false;
  172|     20|    }
  173|  1.30k|  }
  174|    368|  return true;
  175|    388|}
demangle.cc:_ZN6googleL30IdentifierIsAnonymousNamespaceEPNS_5StateEi:
  398|     68|static bool IdentifierIsAnonymousNamespace(State *state, int length) {
  399|     68|  static const char anon_prefix[] = "_GLOBAL__N_";
  400|     68|  return (length > (int)sizeof(anon_prefix) - 1 &&  // Should be longer.
  ------------------
  |  Branch (400:11): [True: 16, False: 52]
  ------------------
  401|     16|          StrPrefix(state->mangled_cur, anon_prefix));
  ------------------
  |  Branch (401:11): [True: 0, False: 16]
  ------------------
  402|     68|}
demangle.cc:_ZN6googleL9StrPrefixEPKcS1_:
  178|     16|static bool StrPrefix(const char *str, const char *prefix) {
  179|     16|  size_t i = 0;
  180|     20|  while (str[i] != '\0' && prefix[i] != '\0' &&
  ------------------
  |  Branch (180:10): [True: 20, False: 0]
  |  Branch (180:28): [True: 20, False: 0]
  ------------------
  181|     20|         str[i] == prefix[i]) {
  ------------------
  |  Branch (181:10): [True: 4, False: 16]
  ------------------
  182|      4|    ++i;
  183|      4|  }
  184|     16|  return prefix[i] == '\0';  // Consumed everything in "prefix".
  185|     16|}
demangle.cc:_ZN6googleL21MaybeAppendWithLengthEPNS_5StateEPKci:
  323|    132|                                  const int length) {
  324|    132|  if (state->append && length > 0) {
  ------------------
  |  Branch (324:7): [True: 88, False: 44]
  |  Branch (324:24): [True: 88, False: 0]
  ------------------
  325|       |    // Append a space if the output buffer ends with '<' and "str"
  326|       |    // starts with '<' to avoid <<<.
  327|     88|    if (str[0] == '<' && state->out_begin < state->out_cur  &&
  ------------------
  |  Branch (327:9): [True: 8, False: 80]
  |  Branch (327:26): [True: 8, False: 0]
  ------------------
  328|      8|        state->out_cur[-1] == '<') {
  ------------------
  |  Branch (328:9): [True: 0, False: 8]
  ------------------
  329|      0|      Append(state, " ", 1);
  330|      0|    }
  331|       |    // Remember the last identifier name for ctors/dtors.
  332|     88|    if (IsAlpha(str[0]) || str[0] == '_') {
  ------------------
  |  Branch (332:9): [True: 16, False: 72]
  |  Branch (332:28): [True: 16, False: 56]
  ------------------
  333|     32|      state->prev_name = state->out_cur;
  334|     32|      state->prev_name_length = length;
  335|     32|    }
  336|     88|    Append(state, str, length);
  337|     88|  }
  338|    132|}
demangle.cc:_ZN6googleL6AppendEPNS_5StateEPKci:
  265|     88|static void Append(State *state, const char * const str, const int length) {
  266|     88|  int i;
  267|    444|  for (i = 0; i < length; ++i) {
  ------------------
  |  Branch (267:15): [True: 356, False: 88]
  ------------------
  268|    356|    if (state->out_cur + 1 < state->out_end) {  // +1 for '\0'
  ------------------
  |  Branch (268:9): [True: 356, False: 0]
  ------------------
  269|    356|      *state->out_cur = str[i];
  270|    356|      ++state->out_cur;
  271|    356|    } else {
  272|      0|      state->overflowed = true;
  273|      0|      break;
  274|      0|    }
  275|    356|  }
  276|     88|  if (!state->overflowed) {
  ------------------
  |  Branch (276:7): [True: 88, False: 0]
  ------------------
  277|     88|    *state->out_cur = '\0';  // Terminate it with '\0'
  278|     88|  }
  279|     88|}
demangle.cc:_ZN6googleL7IsAlphaEc:
  286|     88|static bool IsAlpha(char c) {
  287|     88|  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
  ------------------
  |  Branch (287:11): [True: 16, False: 72]
  |  Branch (287:23): [True: 16, False: 0]
  |  Branch (287:37): [True: 16, False: 56]
  |  Branch (287:49): [True: 0, False: 16]
  ------------------
  288|     88|}
demangle.cc:_ZN6googleL16ParseBuiltinTypeEPNS_5StateE:
  972|    196|static bool ParseBuiltinType(State *state) {
  973|    196|  const AbbrevPair *p;
  974|  2.93k|  for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) {
  ------------------
  |  Branch (974:30): [True: 2.81k, False: 124]
  ------------------
  975|  2.81k|    if (state->mangled_cur[0] == p->abbrev[0]) {
  ------------------
  |  Branch (975:9): [True: 72, False: 2.74k]
  ------------------
  976|     72|      MaybeAppend(state, p->real_name);
  977|     72|      ++state->mangled_cur;
  978|     72|      return true;
  979|     72|    }
  980|  2.81k|  }
  981|       |
  982|    124|  State copy = *state;
  983|    124|  if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) {
  ------------------
  |  Branch (983:7): [True: 0, False: 124]
  |  Branch (983:40): [True: 0, False: 0]
  ------------------
  984|      0|    return true;
  985|      0|  }
  986|    124|  *state = copy;
  987|    124|  return false;
  988|    124|}
demangle.cc:_ZN6googleL17ParseFunctionTypeEPNS_5StateE:
  991|    124|static bool ParseFunctionType(State *state) {
  992|    124|  State copy = *state;
  993|    124|  if (ParseOneCharToken(state, 'F') &&
  ------------------
  |  Branch (993:7): [True: 0, False: 124]
  ------------------
  994|      0|      Optional(ParseOneCharToken(state, 'Y')) &&
  ------------------
  |  Branch (994:7): [True: 0, False: 0]
  ------------------
  995|      0|      ParseBareFunctionType(state) && ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (995:7): [True: 0, False: 0]
  |  Branch (995:39): [True: 0, False: 0]
  ------------------
  996|      0|    return true;
  997|      0|  }
  998|    124|  *state = copy;
  999|    124|  return false;
 1000|    124|}
demangle.cc:_ZN6googleL18ParseClassEnumTypeEPNS_5StateE:
 1016|    124|static bool ParseClassEnumType(State *state) {
 1017|    124|  return ParseName(state);
 1018|    124|}
demangle.cc:_ZN6googleL14ParseArrayTypeEPNS_5StateE:
 1022|     72|static bool ParseArrayType(State *state) {
 1023|     72|  State copy = *state;
 1024|     72|  if (ParseOneCharToken(state, 'A') && ParseNumber(state, NULL) &&
  ------------------
  |  Branch (1024:7): [True: 0, False: 72]
  |  Branch (1024:40): [True: 0, False: 0]
  ------------------
 1025|      0|      ParseOneCharToken(state, '_') && ParseType(state)) {
  ------------------
  |  Branch (1025:7): [True: 0, False: 0]
  |  Branch (1025:40): [True: 0, False: 0]
  ------------------
 1026|      0|    return true;
 1027|      0|  }
 1028|     72|  *state = copy;
 1029|       |
 1030|     72|  if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) &&
  ------------------
  |  Branch (1030:7): [True: 0, False: 72]
  |  Branch (1030:40): [True: 0, False: 0]
  ------------------
 1031|      0|      ParseOneCharToken(state, '_') && ParseType(state)) {
  ------------------
  |  Branch (1031:7): [True: 0, False: 0]
  |  Branch (1031:40): [True: 0, False: 0]
  ------------------
 1032|      0|    return true;
 1033|      0|  }
 1034|     72|  *state = copy;
 1035|     72|  return false;
 1036|     72|}
demangle.cc:_ZN6googleL24ParsePointerToMemberTypeEPNS_5StateE:
 1039|     72|static bool ParsePointerToMemberType(State *state) {
 1040|     72|  State copy = *state;
 1041|     72|  if (ParseOneCharToken(state, 'M') && ParseType(state) &&
  ------------------
  |  Branch (1041:7): [True: 0, False: 72]
  |  Branch (1041:40): [True: 0, False: 0]
  ------------------
 1042|      0|      ParseType(state)) {
  ------------------
  |  Branch (1042:7): [True: 0, False: 0]
  ------------------
 1043|      0|    return true;
 1044|      0|  }
 1045|     72|  *state = copy;
 1046|     72|  return false;
 1047|     72|}
demangle.cc:_ZN6googleL26ParseTemplateTemplateParamEPNS_5StateE:
 1070|     56|static bool ParseTemplateTemplateParam(State *state) {
 1071|     56|  return (ParseTemplateParam(state) ||
  ------------------
  |  Branch (1071:11): [True: 0, False: 56]
  ------------------
 1072|     56|          ParseSubstitution(state));
  ------------------
  |  Branch (1072:11): [True: 0, False: 56]
  ------------------
 1073|     56|}
demangle.cc:_ZN6googleL16ParseExprPrimaryEPNS_5StateE:
 1178|     48|static bool ParseExprPrimary(State *state) {
 1179|     48|  State copy = *state;
 1180|     48|  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
  ------------------
  |  Branch (1180:7): [True: 0, False: 48]
  |  Branch (1180:40): [True: 0, False: 0]
  ------------------
 1181|      0|      ParseNumber(state, NULL) &&
  ------------------
  |  Branch (1181:7): [True: 0, False: 0]
  ------------------
 1182|      0|      ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (1182:7): [True: 0, False: 0]
  ------------------
 1183|      0|    return true;
 1184|      0|  }
 1185|     48|  *state = copy;
 1186|       |
 1187|     48|  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
  ------------------
  |  Branch (1187:7): [True: 0, False: 48]
  |  Branch (1187:40): [True: 0, False: 0]
  ------------------
 1188|      0|      ParseFloatNumber(state) &&
  ------------------
  |  Branch (1188:7): [True: 0, False: 0]
  ------------------
 1189|      0|      ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (1189:7): [True: 0, False: 0]
  ------------------
 1190|      0|    return true;
 1191|      0|  }
 1192|     48|  *state = copy;
 1193|       |
 1194|     48|  if (ParseOneCharToken(state, 'L') && ParseMangledName(state) &&
  ------------------
  |  Branch (1194:7): [True: 0, False: 48]
  |  Branch (1194:40): [True: 0, False: 0]
  ------------------
 1195|      0|      ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (1195:7): [True: 0, False: 0]
  ------------------
 1196|      0|    return true;
 1197|      0|  }
 1198|     48|  *state = copy;
 1199|       |
 1200|     48|  if (ParseTwoCharToken(state, "LZ") && ParseEncoding(state) &&
  ------------------
  |  Branch (1200:7): [True: 0, False: 48]
  |  Branch (1200:41): [True: 0, False: 0]
  ------------------
 1201|      0|      ParseOneCharToken(state, 'E')) {
  ------------------
  |  Branch (1201:7): [True: 0, False: 0]
  ------------------
 1202|      0|    return true;
 1203|      0|  }
 1204|     48|  *state = copy;
 1205|       |
 1206|     48|  return false;
 1207|     48|}
demangle.cc:_ZN6googleL17ParseOperatorNameEPNS_5StateE:
  702|    320|static bool ParseOperatorName(State *state) {
  703|    320|  if (!AtLeastNumCharsRemaining(state->mangled_cur, 2)) {
  ------------------
  |  Branch (703:7): [True: 20, False: 300]
  ------------------
  704|     20|    return false;
  705|     20|  }
  706|       |  // First check with "cv" (cast) case.
  707|    300|  State copy = *state;
  708|    300|  if (ParseTwoCharToken(state, "cv") &&
  ------------------
  |  Branch (708:7): [True: 0, False: 300]
  ------------------
  709|      0|      MaybeAppend(state, "operator ") &&
  ------------------
  |  Branch (709:7): [True: 0, False: 0]
  ------------------
  710|      0|      EnterNestedName(state) &&
  ------------------
  |  Branch (710:7): [True: 0, False: 0]
  ------------------
  711|      0|      ParseType(state) &&
  ------------------
  |  Branch (711:7): [True: 0, False: 0]
  ------------------
  712|      0|      LeaveNestedName(state, copy.nest_level)) {
  ------------------
  |  Branch (712:7): [True: 0, False: 0]
  ------------------
  713|      0|    return true;
  714|      0|  }
  715|    300|  *state = copy;
  716|       |
  717|       |  // Then vendor extended operators.
  718|    300|  if (ParseOneCharToken(state, 'v') && ParseCharClass(state, "0123456789") &&
  ------------------
  |  Branch (718:7): [True: 0, False: 300]
  |  Branch (718:40): [True: 0, False: 0]
  ------------------
  719|      0|      ParseSourceName(state)) {
  ------------------
  |  Branch (719:7): [True: 0, False: 0]
  ------------------
  720|      0|    return true;
  721|      0|  }
  722|    300|  *state = copy;
  723|       |
  724|       |  // Other operator names should start with a lower alphabet followed
  725|       |  // by a lower/upper alphabet.
  726|    300|  if (!(IsLower(state->mangled_cur[0]) &&
  ------------------
  |  Branch (726:9): [True: 0, False: 300]
  ------------------
  727|    300|        IsAlpha(state->mangled_cur[1]))) {
  ------------------
  |  Branch (727:9): [True: 0, False: 0]
  ------------------
  728|    300|    return false;
  729|    300|  }
  730|       |  // We may want to perform a binary search if we really need speed.
  731|      0|  const AbbrevPair *p;
  732|      0|  for (p = kOperatorList; p->abbrev != NULL; ++p) {
  ------------------
  |  Branch (732:27): [True: 0, False: 0]
  ------------------
  733|      0|    if (state->mangled_cur[0] == p->abbrev[0] &&
  ------------------
  |  Branch (733:9): [True: 0, False: 0]
  ------------------
  734|      0|        state->mangled_cur[1] == p->abbrev[1]) {
  ------------------
  |  Branch (734:9): [True: 0, False: 0]
  ------------------
  735|      0|      MaybeAppend(state, "operator");
  736|      0|      if (IsLower(*p->real_name)) {  // new, delete, etc.
  ------------------
  |  Branch (736:11): [True: 0, False: 0]
  ------------------
  737|      0|        MaybeAppend(state, " ");
  738|      0|      }
  739|      0|      MaybeAppend(state, p->real_name);
  740|      0|      state->mangled_cur += 2;
  741|      0|      return true;
  742|      0|    }
  743|      0|  }
  744|      0|  return false;
  745|      0|}
demangle.cc:_ZN6googleL7IsLowerEc:
  282|    300|static bool IsLower(char c) {
  283|    300|  return c >= 'a' && c <= 'z';
  ------------------
  |  Branch (283:10): [True: 0, False: 300]
  |  Branch (283:22): [True: 0, False: 0]
  ------------------
  284|    300|}
demangle.cc:_ZN6googleL20ParseUnqualifiedNameEPNS_5StateE:
  592|    320|static bool ParseUnqualifiedName(State *state) {
  593|    320|  return (ParseOperatorName(state) ||
  ------------------
  |  Branch (593:11): [True: 0, False: 320]
  ------------------
  594|    320|          ParseCtorDtorName(state) ||
  ------------------
  |  Branch (594:11): [True: 0, False: 320]
  ------------------
  595|    320|          ParseSourceName(state) ||
  ------------------
  |  Branch (595:11): [True: 68, False: 252]
  ------------------
  596|    252|          ParseLocalSourceName(state));
  ------------------
  |  Branch (596:11): [True: 0, False: 252]
  ------------------
  597|    320|}
demangle.cc:_ZN6googleL17ParseCtorDtorNameEPNS_5StateE:
  863|    320|static bool ParseCtorDtorName(State *state) {
  864|    320|  State copy = *state;
  865|    320|  if (ParseOneCharToken(state, 'C') &&
  ------------------
  |  Branch (865:7): [True: 0, False: 320]
  ------------------
  866|      0|      ParseCharClass(state, "123")) {
  ------------------
  |  Branch (866:7): [True: 0, False: 0]
  ------------------
  867|      0|    const char * const prev_name = state->prev_name;
  868|      0|    const int prev_name_length = state->prev_name_length;
  869|      0|    MaybeAppendWithLength(state, prev_name, prev_name_length);
  870|      0|    return true;
  871|      0|  }
  872|    320|  *state = copy;
  873|       |
  874|    320|  if (ParseOneCharToken(state, 'D') &&
  ------------------
  |  Branch (874:7): [True: 0, False: 320]
  ------------------
  875|      0|      ParseCharClass(state, "012")) {
  ------------------
  |  Branch (875:7): [True: 0, False: 0]
  ------------------
  876|      0|    const char * const prev_name = state->prev_name;
  877|      0|    const int prev_name_length = state->prev_name_length;
  878|      0|    MaybeAppend(state, "~");
  879|      0|    MaybeAppendWithLength(state, prev_name, prev_name_length);
  880|      0|    return true;
  881|      0|  }
  882|    320|  *state = copy;
  883|    320|  return false;
  884|    320|}
demangle.cc:_ZN6googleL20ParseLocalSourceNameEPNS_5StateE:
  615|    252|static bool ParseLocalSourceName(State *state) {
  616|    252|  State copy = *state;
  617|    252|  if (ParseOneCharToken(state, 'L') && ParseSourceName(state) &&
  ------------------
  |  Branch (617:7): [True: 0, False: 252]
  |  Branch (617:40): [True: 0, False: 0]
  ------------------
  618|      0|      Optional(ParseDiscriminator(state))) {
  ------------------
  |  Branch (618:7): [True: 0, False: 0]
  ------------------
  619|      0|    return true;
  620|      0|  }
  621|    252|  *state = copy;
  622|    252|  return false;
  623|    252|}
demangle.cc:_ZN6googleL13RestoreAppendEPNS_5StateEb:
  368|     56|static bool RestoreAppend(State *state, bool prev_value) {
  369|     56|  state->append = prev_value;
  370|     56|  return true;
  371|     56|}
demangle.cc:_ZN6googleL17ParseUnscopedNameEPNS_5StateE:
  519|    320|static bool ParseUnscopedName(State *state) {
  520|    320|  if (ParseUnqualifiedName(state)) {
  ------------------
  |  Branch (520:7): [True: 68, False: 252]
  ------------------
  521|     68|    return true;
  522|     68|  }
  523|       |
  524|    252|  State copy = *state;
  525|    252|  if (ParseTwoCharToken(state, "St") &&
  ------------------
  |  Branch (525:7): [True: 0, False: 252]
  ------------------
  526|      0|      MaybeAppend(state, "std::") &&
  ------------------
  |  Branch (526:7): [True: 0, False: 0]
  ------------------
  527|      0|      ParseUnqualifiedName(state)) {
  ------------------
  |  Branch (527:7): [True: 0, False: 0]
  ------------------
  528|      0|    return true;
  529|      0|  }
  530|    252|  *state = copy;
  531|    252|  return false;
  532|    252|}
demangle.cc:_ZN6googleL21ParseBareFunctionTypeEPNS_5StateE:
 1003|      8|static bool ParseBareFunctionType(State *state) {
 1004|      8|  State copy = *state;
 1005|      8|  DisableAppend(state);
 1006|      8|  if (OneOrMore(ParseType, state)) {
  ------------------
  |  Branch (1006:7): [True: 8, False: 0]
  ------------------
 1007|      8|    RestoreAppend(state, copy.append);
 1008|      8|    MaybeAppend(state, "()");
 1009|      8|    return true;
 1010|      8|  }
 1011|      0|  *state = copy;
 1012|      0|  return false;
 1013|      8|}
demangle.cc:_ZN6googleL11MaybeAppendEPNS_5StateEPKc:
  341|    396|static bool MaybeAppend(State *state, const char * const str) {
  342|    396|  if (state->append) {
  ------------------
  |  Branch (342:7): [True: 64, False: 332]
  ------------------
  343|     64|    int length = StrLen(str);
  344|     64|    MaybeAppendWithLength(state, str, length);
  345|     64|  }
  346|    396|  return true;
  347|    396|}
demangle.cc:_ZN6googleL6StrLenEPKc:
  158|     64|static size_t StrLen(const char *str) {
  159|     64|  size_t len = 0;
  160|    200|  while (*str != '\0') {
  ------------------
  |  Branch (160:10): [True: 136, False: 64]
  ------------------
  161|    136|    ++str;
  162|    136|    ++len;
  163|    136|  }
  164|     64|  return len;
  165|     64|}

_ZN6google16SafeAppendStringEPKcPci:
  708|     40|void SafeAppendString(const char* source, char* dest, int dest_size) {
  709|     40|  int dest_string_length = strlen(dest);
  710|     40|  SAFE_ASSERT(dest_string_length < dest_size);
  ------------------
  |  |   77|     40|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 40, False: 0]
  |  |  ------------------
  ------------------
  711|     40|  dest += dest_string_length;
  712|     40|  dest_size -= dest_string_length;
  713|     40|  strncpy(dest, source, dest_size);
  714|       |  // Making sure |dest| is always null-terminated.
  715|     40|  dest[dest_size - 1] = '\0';
  716|     40|}
_ZN6google9SymbolizeEPvPci:
  848|     40|bool BAIDU_WEAK Symbolize(void *pc, char *out, int out_size) {
  849|     40|  SAFE_ASSERT(out_size >= 0);
  ------------------
  |  |   77|     40|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 40, False: 0]
  |  |  ------------------
  ------------------
  850|       |  return SymbolizeAndDemangle(pc, out, out_size, NULL);
  851|     40|}
symbolize.cc:_ZN6googleL19ReadFromOffsetExactEiPvml:
  180|    120|                                const size_t count, const off_t offset) {
  181|    120|  ssize_t len = ReadFromOffset(fd, buf, count, offset);
  182|    120|  return len == (ssize_t)count;
  183|    120|}
symbolize.cc:_ZN6googleL14ReadFromOffsetEiPvml:
  167|  11.0k|                              const size_t count, const off_t offset) {
  168|  11.0k|  off_t off = lseek(fd, offset, SEEK_SET);
  169|  11.0k|  if (off == (off_t)-1) {
  ------------------
  |  Branch (169:7): [True: 0, False: 11.0k]
  ------------------
  170|      0|    return -1;
  171|      0|  }
  172|  11.0k|  return ReadPersistent(fd, buf, count);
  173|  11.0k|}
symbolize.cc:_ZN6googleL14ReadPersistentEiPvm:
  143|  11.0k|static ssize_t ReadPersistent(const int fd, void *buf, const size_t count) {
  144|  11.0k|  SAFE_ASSERT(fd >= 0);
  ------------------
  |  |   77|  11.0k|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 11.0k, False: 0]
  |  |  ------------------
  ------------------
  145|  11.0k|  SAFE_ASSERT(count <= (size_t)std::numeric_limits<ssize_t>::max());
  ------------------
  |  |   77|  11.0k|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 11.0k, False: 0]
  |  |  ------------------
  ------------------
  146|  11.0k|  char *buf0 = reinterpret_cast<char *>(buf);
  147|  11.0k|  ssize_t num_bytes = 0;
  148|  22.1k|  while ((size_t)num_bytes < count) {
  ------------------
  |  Branch (148:10): [True: 11.0k, False: 11.0k]
  ------------------
  149|  11.0k|    ssize_t len;
  150|  11.0k|    NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes));
  ------------------
  |  |  136|  11.0k|#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
  |  |  ------------------
  |  |  |  Branch (136:36): [True: 0, False: 11.0k]
  |  |  |  Branch (136:48): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  151|  11.0k|    if (len < 0) {  // There was an error other than EINTR.
  ------------------
  |  Branch (151:9): [True: 0, False: 11.0k]
  ------------------
  152|      0|      return -1;
  153|      0|    }
  154|  11.0k|    if (len == 0) {  // Reached EOF.
  ------------------
  |  Branch (154:9): [True: 0, False: 11.0k]
  ------------------
  155|      0|      break;
  156|      0|    }
  157|  11.0k|    num_bytes += len;
  158|  11.0k|  }
  159|  11.0k|  SAFE_ASSERT((size_t)num_bytes <= count);
  ------------------
  |  |   77|  11.0k|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 11.0k, False: 0]
  |  |  ------------------
  ------------------
  160|  11.0k|  return num_bytes;
  161|  11.0k|}
symbolize.cc:_ZN6googleL20SymbolizeAndDemangleEPvPciPm:
  737|     40|                                                    uint64_t *out_saddr) {
  738|     40|  uint64_t pc0 = reinterpret_cast<uintptr_t>(pc);
  739|     40|  uint64_t start_address = 0;
  740|     40|  uint64_t base_address = 0;
  741|     40|  int object_fd = -1;
  742|       |
  743|     40|  if ((NULL == out || out_size < 1) &&
  ------------------
  |  Branch (743:8): [True: 0, False: 40]
  |  Branch (743:23): [True: 0, False: 40]
  ------------------
  744|     40|      NULL == out_saddr) {
  ------------------
  |  Branch (744:7): [True: 0, False: 0]
  ------------------
  745|      0|    return false;
  746|      0|  }
  747|     40|  if (NULL != out) {
  ------------------
  |  Branch (747:7): [True: 40, False: 0]
  ------------------
  748|     40|    out[0] = '\0';
  749|     40|    SafeAppendString("(", out, out_size);
  750|     40|  }
  751|       |
  752|     40|  if (g_symbolize_open_object_file_callback) {
  ------------------
  |  Branch (752:7): [True: 0, False: 40]
  ------------------
  753|      0|    object_fd = g_symbolize_open_object_file_callback(pc0, start_address,
  754|      0|                                                      base_address, out + 1,
  755|      0|                                                      out_size - 1);
  756|     40|  } else {
  757|     40|    object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, start_address,
  758|     40|                                                             base_address,
  759|     40|                                                             out + 1,
  760|     40|                                                             out_size - 1);
  761|     40|  }
  762|       |
  763|       |  // Check whether a file name was returned.
  764|     40|  if (object_fd < 0) {
  ------------------
  |  Branch (764:7): [True: 0, False: 40]
  ------------------
  765|      0|    if (NULL != out && out[1] && NULL == out_saddr) {
  ------------------
  |  Branch (765:9): [True: 0, False: 0]
  |  Branch (765:24): [True: 0, False: 0]
  |  Branch (765:34): [True: 0, False: 0]
  ------------------
  766|       |      // The object file containing PC was determined successfully however the
  767|       |      // object file was not opened successfully.  This is still considered
  768|       |      // success because the object file name and offset are known and tools
  769|       |      // like asan_symbolize.py can be used for the symbolization.
  770|      0|      out[out_size - 1] = '\0';  // Making sure |out| is always null-terminated.
  771|      0|      SafeAppendString("+0x", out, out_size);
  772|      0|      SafeAppendHexNumber(pc0 - base_address, out, out_size);
  773|      0|      SafeAppendString(")", out, out_size);
  774|      0|      return true;
  775|      0|    }
  776|       |    // Failed to determine the object file containing PC.  Bail out.
  777|      0|    return false;
  778|      0|  }
  779|     40|  FileDescriptor wrapped_object_fd(object_fd);
  780|     40|  int elf_type = FileGetElfType(wrapped_object_fd.get());
  781|     40|  if (elf_type == -1) {
  ------------------
  |  Branch (781:7): [True: 0, False: 40]
  ------------------
  782|      0|    return false;
  783|      0|  }
  784|     40|  if (g_symbolize_callback) {
  ------------------
  |  Branch (784:7): [True: 0, False: 40]
  ------------------
  785|       |    // Run the call back if it's installed.
  786|       |    // Note: relocation (and much of the rest of this code) will be
  787|       |    // wrong for prelinked shared libraries and PIE executables.
  788|      0|    uint64_t relocation = (elf_type == ET_DYN) ? start_address : 0;
  ------------------
  |  Branch (788:27): [True: 0, False: 0]
  ------------------
  789|      0|    int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(),
  790|      0|                                                 pc, out, out_size,
  791|      0|                                                 relocation);
  792|      0|    if (num_bytes_written > 0) {
  ------------------
  |  Branch (792:9): [True: 0, False: 0]
  ------------------
  793|      0|      out += num_bytes_written;
  794|      0|      out_size -= num_bytes_written;
  795|      0|    }
  796|      0|  }
  797|     40|  if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0,
  ------------------
  |  Branch (797:7): [True: 8, False: 32]
  ------------------
  798|     40|                               out, out_size, out_saddr,
  799|     40|                               start_address)) {
  800|      8|    return false;
  801|      8|  }
  802|       |
  803|     32|  if (NULL != out) {
  ------------------
  |  Branch (803:7): [True: 32, False: 0]
  ------------------
  804|       |    // Symbolization succeeded.  Now we try to demangle the symbol.
  805|     32|    DemangleInplace(out, out_size);
  806|     32|  }
  807|     32|  return true;
  808|     40|}
symbolize.cc:_ZN6googleL44OpenObjectFileContainingPcAndGetStartAddressEmRmS0_Pci:
  520|     40|                                             int out_file_name_size) {
  521|     40|  int object_fd;
  522|       |
  523|       |  // Open /proc/self/maps.
  524|     40|  int maps_fd;
  525|     40|  NO_INTR(maps_fd = open("/proc/self/maps", O_RDONLY));
  ------------------
  |  |  136|     40|#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
  |  |  ------------------
  |  |  |  Branch (136:36): [True: 0, False: 40]
  |  |  |  Branch (136:48): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  526|     40|  FileDescriptor wrapped_maps_fd(maps_fd);
  527|     40|  if (wrapped_maps_fd.get() < 0) {
  ------------------
  |  Branch (527:7): [True: 0, False: 40]
  ------------------
  528|      0|    return -1;
  529|      0|  }
  530|       |
  531|       |  // Iterate over maps and look for the map containing the pc.  Then
  532|       |  // look into the symbol tables inside.
  533|     40|  char buf[1024];  // Big enough for line of sane /proc/self/maps
  534|     40|  int num_maps = 0;
  535|     40|  LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf));
  536|    192|  while (true) {
  ------------------
  |  Branch (536:10): [True: 192, Folded]
  ------------------
  537|    192|    num_maps++;
  538|    192|    const char *cursor;
  539|    192|    const char *eol;
  540|    192|    if (!reader.ReadLine(&cursor, &eol)) {  // EOF or malformed line.
  ------------------
  |  Branch (540:9): [True: 0, False: 192]
  ------------------
  541|      0|      return -1;
  542|      0|    }
  543|       |
  544|       |    // Start parsing line in /proc/self/maps.  Here is an example:
  545|       |    //
  546|       |    // 08048000-0804c000 r-xp 00000000 08:01 2142121    /bin/cat
  547|       |    //
  548|       |    // We want start address (08048000), end address (0804c000), flags
  549|       |    // (r-xp) and file name (/bin/cat).
  550|       |
  551|       |    // Read start address.
  552|    192|    cursor = GetHex(cursor, eol, &start_address);
  553|    192|    if (cursor == eol || *cursor != '-') {
  ------------------
  |  Branch (553:9): [True: 0, False: 192]
  |  Branch (553:26): [True: 0, False: 192]
  ------------------
  554|      0|      return -1;  // Malformed line.
  555|      0|    }
  556|    192|    ++cursor;  // Skip '-'.
  557|       |
  558|       |    // Read end address.
  559|    192|    uint64_t end_address;
  560|    192|    cursor = GetHex(cursor, eol, &end_address);
  561|    192|    if (cursor == eol || *cursor != ' ') {
  ------------------
  |  Branch (561:9): [True: 0, False: 192]
  |  Branch (561:26): [True: 0, False: 192]
  ------------------
  562|      0|      return -1;  // Malformed line.
  563|      0|    }
  564|    192|    ++cursor;  // Skip ' '.
  565|       |
  566|       |    // Check start and end addresses.
  567|    192|    if (!(start_address <= pc && pc < end_address)) {
  ------------------
  |  Branch (567:11): [True: 192, False: 0]
  |  Branch (567:34): [True: 40, False: 152]
  ------------------
  568|    152|      continue;  // We skip this map.  PC isn't in this map.
  569|    152|    }
  570|       |
  571|       |    // Read flags.  Skip flags until we encounter a space or eol.
  572|     40|    const char * const flags_start = cursor;
  573|    200|    while (cursor < eol && *cursor != ' ') {
  ------------------
  |  Branch (573:12): [True: 200, False: 0]
  |  Branch (573:28): [True: 160, False: 40]
  ------------------
  574|    160|      ++cursor;
  575|    160|    }
  576|       |    // We expect at least four letters for flags (ex. "r-xp").
  577|     40|    if (cursor == eol || cursor < flags_start + 4) {
  ------------------
  |  Branch (577:9): [True: 0, False: 40]
  |  Branch (577:26): [True: 0, False: 40]
  ------------------
  578|      0|      return -1;  // Malformed line.
  579|      0|    }
  580|       |
  581|       |    // Check flags.  We are only interested in "r-x" maps.
  582|     40|    if (memcmp(flags_start, "r-x", 3) != 0) {  // Not a "r-x" map.
  ------------------
  |  Branch (582:9): [True: 0, False: 40]
  ------------------
  583|      0|      continue;  // We skip this map.
  584|      0|    }
  585|     40|    ++cursor;  // Skip ' '.
  586|       |
  587|       |    // Read file offset.
  588|     40|    uint64_t file_offset;
  589|     40|    cursor = GetHex(cursor, eol, &file_offset);
  590|     40|    if (cursor == eol || *cursor != ' ') {
  ------------------
  |  Branch (590:9): [True: 0, False: 40]
  |  Branch (590:26): [True: 0, False: 40]
  ------------------
  591|      0|      return -1;  // Malformed line.
  592|      0|    }
  593|     40|    ++cursor;  // Skip ' '.
  594|       |
  595|       |    // Don't subtract 'start_address' from the first entry:
  596|       |    // * If a binary is compiled w/o -pie, then the first entry in
  597|       |    //   process maps is likely the binary itself (all dynamic libs
  598|       |    //   are mapped higher in address space). For such a binary,
  599|       |    //   instruction offset in binary coincides with the actual
  600|       |    //   instruction address in virtual memory (as code section
  601|       |    //   is mapped to a fixed memory range).
  602|       |    // * If a binary is compiled with -pie, all the modules are
  603|       |    //   mapped high at address space (in particular, higher than
  604|       |    //   shadow memory of the tool), so the module can't be the
  605|       |    //   first entry.
  606|     40|    base_address = ((num_maps == 1) ? 0U : start_address) - file_offset;
  ------------------
  |  Branch (606:21): [True: 0, False: 40]
  ------------------
  607|       |
  608|       |    // Skip to file name.  "cursor" now points to dev.  We need to
  609|       |    // skip at least two spaces for dev and inode.
  610|     40|    int num_spaces = 0;
  611|  1.36k|    while (cursor < eol) {
  ------------------
  |  Branch (611:12): [True: 1.36k, False: 0]
  ------------------
  612|  1.36k|      if (*cursor == ' ') {
  ------------------
  |  Branch (612:11): [True: 840, False: 520]
  ------------------
  613|    840|        ++num_spaces;
  614|    840|      } else if (num_spaces >= 2) {
  ------------------
  |  Branch (614:18): [True: 40, False: 480]
  ------------------
  615|       |        // The first non-space character after skipping two spaces
  616|       |        // is the beginning of the file name.
  617|     40|        break;
  618|     40|      }
  619|  1.32k|      ++cursor;
  620|  1.32k|    }
  621|     40|    if (cursor == eol) {
  ------------------
  |  Branch (621:9): [True: 0, False: 40]
  ------------------
  622|      0|      return -1;  // Malformed line.
  623|      0|    }
  624|       |
  625|       |    // Finally, "cursor" now points to file name of our interest.
  626|     40|    NO_INTR(object_fd = open(cursor, O_RDONLY));
  ------------------
  |  |  136|     40|#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
  |  |  ------------------
  |  |  |  Branch (136:36): [True: 0, False: 40]
  |  |  |  Branch (136:48): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  627|     40|    if (object_fd < 0) {
  ------------------
  |  Branch (627:9): [True: 0, False: 40]
  ------------------
  628|       |      // Failed to open object file.  Copy the object file name to
  629|       |      // |out_file_name|.
  630|      0|      strncpy(out_file_name, cursor, out_file_name_size);
  631|       |      // Making sure |out_file_name| is always null-terminated.
  632|      0|      out_file_name[out_file_name_size - 1] = '\0';
  633|      0|      return -1;
  634|      0|    }
  635|     40|    return object_fd;
  636|     40|  }
  637|     40|}
symbolize.cc:_ZN6google12_GLOBAL__N_110LineReaderC2EiPci:
  407|     40|  explicit LineReader(int fd, char *buf, int buf_len) : fd_(fd),
  408|     40|    buf_(buf), buf_len_(buf_len), bol_(buf), eol_(buf), eod_(buf) {
  409|     40|  }
symbolize.cc:_ZN6google12_GLOBAL__N_110LineReader8ReadLineEPPKcS4_:
  416|    192|  bool ReadLine(const char **bol, const char **eol) {
  417|    192|    if (BufferIsEmpty()) {  // First time.
  ------------------
  |  Branch (417:9): [True: 40, False: 152]
  ------------------
  418|     40|      const ssize_t num_bytes = ReadPersistent(fd_, buf_, buf_len_);
  419|     40|      if (num_bytes <= 0) {  // EOF or error.
  ------------------
  |  Branch (419:11): [True: 0, False: 40]
  ------------------
  420|      0|        return false;
  421|      0|      }
  422|     40|      eod_ = buf_ + num_bytes;
  423|     40|      bol_ = buf_;
  424|    152|    } else {
  425|    152|      bol_ = eol_ + 1;  // Advance to the next line in the buffer.
  426|    152|      SAFE_ASSERT(bol_ <= eod_);  // "bol_" can point to "eod_".
  ------------------
  |  |   77|    152|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 152, False: 0]
  |  |  ------------------
  ------------------
  427|    152|      if (!HasCompleteLine()) {
  ------------------
  |  Branch (427:11): [True: 8, False: 144]
  ------------------
  428|      8|        const int incomplete_line_length = eod_ - bol_;
  429|       |        // Move the trailing incomplete line to the beginning.
  430|      8|        memmove(buf_, bol_, incomplete_line_length);
  431|       |        // Read text from file and append it.
  432|      8|        char * const append_pos = buf_ + incomplete_line_length;
  433|      8|        const int capacity_left = buf_len_ - incomplete_line_length;
  434|      8|        const ssize_t num_bytes = ReadPersistent(fd_, append_pos,
  435|      8|                                                 capacity_left);
  436|      8|        if (num_bytes <= 0) {  // EOF or error.
  ------------------
  |  Branch (436:13): [True: 0, False: 8]
  ------------------
  437|      0|          return false;
  438|      0|        }
  439|      8|        eod_ = append_pos + num_bytes;
  440|      8|        bol_ = buf_;
  441|      8|      }
  442|    152|    }
  443|    192|    eol_ = FindLineFeed();
  444|    192|    if (eol_ == NULL) {  // '\n' not found.  Malformed line.
  ------------------
  |  Branch (444:9): [True: 0, False: 192]
  ------------------
  445|      0|      return false;
  446|      0|    }
  447|    192|    *eol_ = '\0';  // Replace '\n' with '\0'.
  448|       |
  449|    192|    *bol = bol_;
  450|    192|    *eol = eol_;
  451|    192|    return true;
  452|    192|  }
symbolize.cc:_ZN6google12_GLOBAL__N_110LineReader13BufferIsEmptyEv:
  472|    344|  bool BufferIsEmpty() {
  473|    344|    return buf_ == eod_;
  474|    344|  }
symbolize.cc:_ZN6google12_GLOBAL__N_110LineReader15HasCompleteLineEv:
  476|    152|  bool HasCompleteLine() {
  477|    152|    return !BufferIsEmpty() && FindLineFeed() != NULL;
  ------------------
  |  Branch (477:12): [True: 152, False: 0]
  |  Branch (477:32): [True: 144, False: 8]
  ------------------
  478|    152|  }
symbolize.cc:_ZN6google12_GLOBAL__N_110LineReader12FindLineFeedEv:
  468|    344|  char *FindLineFeed() {
  469|    344|    return reinterpret_cast<char *>(memchr(bol_, '\n', eod_ - bol_));
  470|    344|  }
symbolize.cc:_ZN6googleL6GetHexEPKcS1_Pm:
  491|    424|static char *GetHex(const char *start, const char *end, uint64_t *hex) {
  492|    424|  *hex = 0;
  493|    424|  const char *p;
  494|  5.35k|  for (p = start; p < end; ++p) {
  ------------------
  |  Branch (494:19): [True: 5.35k, False: 0]
  ------------------
  495|  5.35k|    int ch = *p;
  496|  5.35k|    if ((ch >= '0' && ch <= '9') ||
  ------------------
  |  Branch (496:10): [True: 4.92k, False: 424]
  |  Branch (496:23): [True: 3.33k, False: 1.59k]
  ------------------
  497|  4.92k|        (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) {
  ------------------
  |  Branch (497:10): [True: 1.59k, False: 424]
  |  Branch (497:23): [True: 0, False: 1.59k]
  |  Branch (497:38): [True: 1.59k, False: 424]
  |  Branch (497:51): [True: 1.59k, False: 0]
  ------------------
  498|  4.92k|      *hex = (*hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9);
  ------------------
  |  Branch (498:29): [True: 3.33k, False: 1.59k]
  ------------------
  499|  4.92k|    } else {  // Encountered the first non-hex character.
  500|    424|      break;
  501|    424|    }
  502|  5.35k|  }
  503|    424|  SAFE_ASSERT(p <= end);
  ------------------
  |  |   77|    424|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 424, False: 0]
  |  |  ------------------
  ------------------
  504|    424|  return const_cast<char *>(p);
  505|    424|}
symbolize.cc:_ZN6google12_GLOBAL__N_114FileDescriptorC2Ei:
  387|     80|  explicit FileDescriptor(int fd) : fd_(fd) {}
symbolize.cc:_ZN6googleL14FileGetElfTypeEi:
  186|     40|static int FileGetElfType(const int fd) {
  187|     40|  ElfW(Ehdr) elf_header;
  188|     40|  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
  ------------------
  |  Branch (188:7): [True: 0, False: 40]
  ------------------
  189|      0|    return -1;
  190|      0|  }
  191|     40|  if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) {
  ------------------
  |  Branch (191:7): [True: 0, False: 40]
  ------------------
  192|      0|    return -1;
  193|      0|  }
  194|     40|  return elf_header.e_type;
  195|     40|}
symbolize.cc:_ZN6google12_GLOBAL__N_114FileDescriptor3getEv:
  393|    160|  int get() { return fd_; }
symbolize.cc:_ZN6googleL23GetSymbolFromObjectFileEimPciPmm:
  339|     40|                                    uint64_t map_start_address) {
  340|       |  // Read the ELF header.
  341|     40|  ElfW(Ehdr) elf_header;
  342|     40|  if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
  ------------------
  |  Branch (342:7): [True: 0, False: 40]
  ------------------
  343|      0|    return false;
  344|      0|  }
  345|       |
  346|     40|  uint64_t symbol_offset = 0;
  347|     40|  if (elf_header.e_type == ET_DYN) {  // DSO needs offset adjustment.
  ------------------
  |  Branch (347:7): [True: 40, False: 0]
  ------------------
  348|     40|    symbol_offset = map_start_address;
  349|     40|  }
  350|       |
  351|     40|  ElfW(Shdr) symtab, strtab;
  352|       |
  353|       |  // Consult a regular symbol table first.
  354|     40|  if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
  ------------------
  |  Branch (354:7): [True: 32, False: 8]
  ------------------
  355|     40|                             SHT_SYMTAB, &symtab)) {
  356|     32|    if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
  ------------------
  |  Branch (356:9): [True: 0, False: 32]
  ------------------
  357|     32|                             symtab.sh_link * sizeof(symtab))) {
  358|      0|      return false;
  359|      0|    }
  360|     32|    if (FindSymbol(pc, fd, out, out_size, out_saddr,
  ------------------
  |  Branch (360:9): [True: 32, False: 0]
  ------------------
  361|     32|                   symbol_offset, &strtab, &symtab)) {
  362|     32|      return true;  // Found the symbol in a regular symbol table.
  363|     32|    }
  364|     32|  }
  365|       |
  366|       |  // If the symbol is not found, then consult a dynamic symbol table.
  367|      8|  if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
  ------------------
  |  Branch (367:7): [True: 8, False: 0]
  ------------------
  368|      8|                             SHT_DYNSYM, &symtab)) {
  369|      8|    if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
  ------------------
  |  Branch (369:9): [True: 0, False: 8]
  ------------------
  370|      8|                             symtab.sh_link * sizeof(symtab))) {
  371|      0|      return false;
  372|      0|    }
  373|      8|    if (FindSymbol(pc, fd, out, out_size, out_saddr,
  ------------------
  |  Branch (373:9): [True: 0, False: 8]
  ------------------
  374|      8|                   symbol_offset, &strtab, &symtab)) {
  375|      0|      return true;  // Found the symbol in a dynamic symbol table.
  376|      0|    }
  377|      8|  }
  378|       |
  379|      8|  return false;
  380|      8|}
symbolize.cc:_ZN6googleL22GetSectionHeaderByTypeEitljP10Elf64_Shdr:
  204|     48|                       ElfW(Word) type, ElfW(Shdr) *out) {
  205|       |  // Read at most 16 section headers at a time to save read calls.
  206|     48|  ElfW(Shdr) buf[16];
  207|    176|  for (int i = 0; i < sh_num;) {
  ------------------
  |  Branch (207:19): [True: 168, False: 8]
  ------------------
  208|    168|    const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]);
  209|    168|    const ssize_t num_bytes_to_read =
  210|    168|        ((ssize_t)sizeof(buf) > num_bytes_left) ? num_bytes_left : sizeof(buf);
  ------------------
  |  Branch (210:9): [True: 32, False: 136]
  ------------------
  211|    168|    const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read,
  212|    168|                                       sh_offset + i * sizeof(buf[0]));
  213|    168|    SAFE_ASSERT(len % sizeof(buf[0]) == 0);
  ------------------
  |  |   77|    168|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 168, False: 0]
  |  |  ------------------
  ------------------
  214|    168|    const ssize_t num_headers_in_buf = len / sizeof(buf[0]);
  215|    168|    SAFE_ASSERT((size_t)num_headers_in_buf <= sizeof(buf) / sizeof(buf[0]));
  ------------------
  |  |   77|    168|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 168, False: 0]
  |  |  ------------------
  ------------------
  216|  2.29k|    for (int j = 0; j < num_headers_in_buf; ++j) {
  ------------------
  |  Branch (216:21): [True: 2.16k, False: 128]
  ------------------
  217|  2.16k|      if (buf[j].sh_type == type) {
  ------------------
  |  Branch (217:11): [True: 40, False: 2.12k]
  ------------------
  218|     40|        *out = buf[j];
  219|     40|        return true;
  220|     40|      }
  221|  2.16k|    }
  222|    128|    i += num_headers_in_buf;
  223|    128|  }
  224|      8|  return false;
  225|     48|}
symbolize.cc:_ZN6googleL10FindSymbolEmiPciPmmPK10Elf64_ShdrS4_:
  283|     40|           const ElfW(Shdr) *strtab, const ElfW(Shdr) *symtab) {
  284|     40|  if (symtab == NULL) {
  ------------------
  |  Branch (284:7): [True: 0, False: 40]
  ------------------
  285|      0|    return false;
  286|      0|  }
  287|     40|  const int num_symbols = symtab->sh_size / symtab->sh_entsize;
  288|  10.7k|  for (int i = 0; i < num_symbols;) {
  ------------------
  |  Branch (288:19): [True: 10.7k, False: 8]
  ------------------
  289|  10.7k|    off_t offset = symtab->sh_offset + i * symtab->sh_entsize;
  290|       |
  291|       |    // If we are reading Elf64_Sym's, we want to limit this array to
  292|       |    // 32 elements (to keep stack consumption low), otherwise we can
  293|       |    // have a 64 element Elf32_Sym array.
  294|  10.7k|#if __WORDSIZE == 64
  295|  10.7k|#define NUM_SYMBOLS 32
  296|       |#else
  297|       |#define NUM_SYMBOLS 64
  298|       |#endif
  299|       |
  300|       |    // Read at most NUM_SYMBOLS symbols at once to save read() calls.
  301|  10.7k|    ElfW(Sym) buf[NUM_SYMBOLS];
  302|  10.7k|    const ssize_t len = ReadFromOffset(fd, &buf, sizeof(buf), offset);
  303|  10.7k|    SAFE_ASSERT(len % sizeof(buf[0]) == 0);
  ------------------
  |  |   77|  10.7k|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 10.7k, False: 0]
  |  |  ------------------
  ------------------
  304|  10.7k|    const ssize_t num_symbols_in_buf = len / sizeof(buf[0]);
  305|  10.7k|    SAFE_ASSERT((size_t)num_symbols_in_buf <= sizeof(buf)/sizeof(buf[0]));
  ------------------
  |  |   77|  10.7k|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 10.7k, False: 0]
  |  |  ------------------
  ------------------
  306|   352k|    for (int j = 0; j < num_symbols_in_buf; ++j) {
  ------------------
  |  Branch (306:21): [True: 342k, False: 10.6k]
  ------------------
  307|   342k|      const ElfW(Sym)& symbol = buf[j];
  308|   342k|      uint64_t start_address = symbol.st_value;
  309|   342k|      start_address += symbol_offset;
  310|   342k|      uint64_t end_address = start_address + symbol.st_size;
  311|   342k|      if (symbol.st_value != 0 &&  // Skip null value symbols.
  ------------------
  |  Branch (311:11): [True: 334k, False: 7.47k]
  ------------------
  312|   334k|          symbol.st_shndx != 0 &&  // Skip undefined symbols.
  ------------------
  |  Branch (312:11): [True: 334k, False: 0]
  ------------------
  313|   334k|          start_address <= pc && pc < end_address) {
  ------------------
  |  Branch (313:11): [True: 31.9k, False: 302k]
  |  Branch (313:34): [True: 32, False: 31.9k]
  ------------------
  314|     32|        if (NULL != out) {
  ------------------
  |  Branch (314:13): [True: 32, False: 0]
  ------------------
  315|     32|          ssize_t len1 = ReadFromOffset(
  316|     32|              fd, out, out_size, strtab->sh_offset + symbol.st_name);
  317|     32|          if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) {
  ------------------
  |  Branch (317:15): [True: 0, False: 32]
  |  Branch (317:28): [True: 0, False: 32]
  ------------------
  318|      0|            return false;
  319|      0|          }
  320|     32|        }
  321|     32|        if (NULL != out_saddr) {
  ------------------
  |  Branch (321:13): [True: 0, False: 32]
  ------------------
  322|      0|          *out_saddr = start_address;
  323|      0|        }
  324|     32|        return true;  // Obtained the symbol name.
  325|     32|      }
  326|   342k|    }
  327|  10.6k|    i += num_symbols_in_buf;
  328|  10.6k|  }
  329|      8|  return false;
  330|     40|}
symbolize.cc:_ZN6googleL15DemangleInplaceEPci:
   97|     32|static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size) {
   98|     32|  char demangled[256];  // Big enough for sane demangled symbols.
   99|     32|  if (Demangle(out, demangled, sizeof(demangled))) {
  ------------------
  |  Branch (99:7): [True: 8, False: 24]
  ------------------
  100|       |    // Demangling succeeded. Copy to out if the space allows.
  101|      8|    size_t len = strlen(demangled);
  102|      8|    if (len + 1 <= (size_t)out_size) {  // +1 for '\0'.
  ------------------
  |  Branch (102:9): [True: 8, False: 0]
  ------------------
  103|      8|      SAFE_ASSERT(len < sizeof(demangled));
  ------------------
  |  |   77|      8|#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
  |  |  ------------------
  |  |  |  Branch (77:28): [True: 8, False: 0]
  |  |  ------------------
  ------------------
  104|      8|      memmove(out, demangled, len + 1);
  105|      8|    }
  106|      8|  }
  107|     32|}
symbolize.cc:_ZN6google12_GLOBAL__N_114FileDescriptorD2Ev:
  388|     80|  ~FileDescriptor() {
  389|     80|    if (fd_ >= 0) {
  ------------------
  |  Branch (389:9): [True: 80, False: 0]
  ------------------
  390|       |      NO_INTR(close(fd_));
  ------------------
  |  |  136|     80|#define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
  |  |  ------------------
  |  |  |  Branch (136:36): [True: 0, False: 80]
  |  |  |  Branch (136:48): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  391|     80|    }
  392|     80|  }

_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|      2|  __attribute__((noinline, unused)) type get_##var_name(void) {                \
   36|      2|    asm volatile("");                                                          \
   37|      2|    return var_name;                                                           \
   38|      2|  }                                                                            \

_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, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   78|      2|#endif  //  !defined(OS_NACL)
   79|      2|}

_ZN5butil14PlatformThread9CurrentIdEv:
  145|     31|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|     31|  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|     31|}

_ZN5butil15gettimeofday_usEv:
  338|     43|inline int64_t gettimeofday_us() {
  339|     43|    timeval now;
  340|       |    gettimeofday(&now, NULL);
  341|     43|    return now.tv_sec * 1000000L + now.tv_usec;
  342|     43|}

_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 NULL;
  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 NULL;
  134|      0|        }
  135|      2|        if (_s_tls_blocks == NULL) {
  ------------------
  |  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 == NULL, 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 NULL;
  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 == NULL) {
  ------------------
  |  Branch (149:13): [True: 2, False: 0]
  ------------------
  150|      2|            ThreadBlock *new_block = new (std::nothrow) ThreadBlock;
  151|      2|            if (__builtin_expect(new_block == NULL, 0)) {
  ------------------
  |  Branch (151:17): [True: 0, False: 2]
  ------------------
  152|      0|                return NULL;
  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|     23|    const Op& op, T1& v1, const T2& v2) {
   29|     23|    return op(v1, v2);
   30|     23|}

_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|    }
_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|    }
_ZNK4bvar6detail13AgentCombinerIPNS0_7SamplerES3_NS0_14CombineSamplerEE2opEv:
  335|      8|    const BinaryOp& op() const { return _op; }
_ZN4bvar6detail13AgentCombinerIPNS0_7SamplerES3_NS0_14CombineSamplerEE16reset_all_agentsEv:
  261|     15|    ResultTp reset_all_agents() {
  262|     15|        ElementTp prev;
  263|     15|        butil::AutoLock guard(_lock);
  264|     15|        ResultTp tmp = _global_result;
  265|     15|        _global_result = _result_identity;
  266|     15|        for (butil::LinkNode<Agent>* node = _agents.head();
  267|     30|             node != _agents.end(); node = node->next()) {
  ------------------
  |  Branch (267:14): [True: 15, False: 15]
  ------------------
  268|     15|            node->value()->element.exchange(&prev, _element_identity);
  269|     15|            call_op_returning_void(_op, tmp, prev);
  270|     15|        }
  271|     15|        return tmp;
  272|     15|    }
_ZN4bvar6detail16ElementContainerIPNS0_7SamplerEvE8exchangeEPS3_RKS3_:
   86|     15|    void exchange(T* prev, const T& new_value) {
   87|     15|        butil::AutoLock guard(_lock);
   88|     15|        *prev = _value;
   89|     15|        _value = new_value;
   90|     15|    }
_ZN4bvar6detail13AgentCombinerIPNS0_7SamplerES3_NS0_14CombineSamplerEE23get_or_create_tls_agentEv:
  300|      8|    Agent* get_or_create_tls_agent() {
  301|      8|        Agent* agent = AgentGroup::get_tls_agent(_id);
  302|      8|        if (!agent) {
  ------------------
  |  Branch (302:13): [True: 2, False: 6]
  ------------------
  303|       |            // Create the agent
  304|      2|            agent = AgentGroup::get_or_create_tls_agent(_id);
  305|      2|            if (NULL == agent) {
  ------------------
  |  Branch (305:17): [True: 0, False: 2]
  ------------------
  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 NULL;
  308|      0|            }
  309|      2|        }
  310|      8|        if (!agent->combiner.expired()) {
  ------------------
  |  Branch (310:13): [True: 6, False: 2]
  ------------------
  311|      6|            return agent;
  312|      6|        }
  313|      2|        agent->reset(_element_identity, this->shared_from_this());
  314|       |        // TODO: Is uniqueness-checking necessary here?
  315|      2|        {
  316|      2|            butil::AutoLock guard(_lock);
  317|      2|            _agents.Append(agent);
  318|      2|        }
  319|      2|        return agent;
  320|      8|    }
_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 == NULL) {
  145|       |        s_cumulated_time_bvar =
  146|       |            new PassiveStatus<double>(get_cumulated_time, this);
  147|       |    }
  148|       |    if (s_sampling_thread_usage_bvar == NULL) {
  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|     17|    while (!_stop) {
  ------------------
  |  Branch (157:12): [True: 15, False: 2]
  ------------------
  158|     15|        int64_t abstime = butil::gettimeofday_us();
  159|     15|        Sampler* s = this->reset();
  160|     15|        if (s) {
  ------------------
  |  Branch (160:13): [True: 2, False: 13]
  ------------------
  161|      2|            s->InsertBeforeAsList(&root);
  162|      2|        }
  163|     75|        for (butil::LinkNode<Sampler>* p = root.next(); p != &root;) {
  ------------------
  |  Branch (163:57): [True: 60, False: 15]
  ------------------
  164|       |            // We may remove p from the list, save next first.
  165|     60|            butil::LinkNode<Sampler>* saved_next = p->next();
  166|     60|            Sampler* s = p->value();
  167|     60|            s->_mutex.lock();
  168|     60|            if (!s->_used) {
  ------------------
  |  Branch (168:17): [True: 0, False: 60]
  ------------------
  169|      0|                s->_mutex.unlock();
  170|      0|                p->RemoveFromList();
  171|      0|                delete s;
  172|     60|            } else {
  173|     60|                s->take_sample();
  174|     60|                s->_mutex.unlock();
  175|     60|            }
  176|     60|            p = saved_next;
  177|     60|        }
  178|     15|        bool slept = false;
  179|     15|        int64_t now = butil::gettimeofday_us();
  180|     15|        _cumulated_time_us += now - abstime;
  181|     15|        abstime += 1000000L;
  182|     30|        while (abstime > now) {
  ------------------
  |  Branch (182:16): [True: 15, False: 15]
  ------------------
  183|     15|            ::usleep(abstime - now);
  184|     15|            slept = true;
  185|     15|            now = butil::gettimeofday_us();
  186|     15|        }
  187|     15|        if (slept) {
  ------------------
  |  Branch (187:13): [True: 13, False: 2]
  ------------------
  188|     13|            consecutive_nosleep = 0;
  189|     13|        } 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|     15|    }
  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, NULL, 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(NULL, NULL, 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|       |        return NULL;
  115|      2|    }
_ZNK4bvar6detail14CombineSamplerclERPNS0_7SamplerES3_:
   36|     23|    void operator()(Sampler* & s1, Sampler* s2) const {
   37|     23|        if (s2 == NULL) {
  ------------------
  |  Branch (37:13): [True: 13, False: 10]
  ------------------
   38|     13|            return;
   39|     13|        }
   40|     10|        if (s1 == NULL) {
  ------------------
  |  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|       |        pthread_mutex_init(&_mutex, NULL);
  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|     15|    void append(const T& value) {
  115|     15|        BAIDU_SCOPED_LOCK(_mutex);
  ------------------
  |  |   47|     15|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|     15|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|     15|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|     15|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  116|     15|        return append_second(value, _op);
  117|     15|    }
_ZN4bvar6detail10SeriesBaseIlNS0_5AddToIlEEE13append_secondERKlRKS3_:
  161|     15|void SeriesBase<T, Op>::append_second(const T& value, const Op& op) {
  162|     15|    _data.second(_nsecond) = value;
  163|     15|    ++_nsecond;
  164|     15|    if (_nsecond >= 60) {
  ------------------
  |  Branch (164:9): [True: 0, False: 15]
  ------------------
  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|     15|}
_ZN4bvar6detail10SeriesBaseIlNS0_5AddToIlEEE4Data6secondEi:
  135|     15|        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|       |        pthread_mutex_init(&_mutex, NULL);
  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|     30|    void append(const T& value) {
  115|     30|        BAIDU_SCOPED_LOCK(_mutex);
  ------------------
  |  |   47|     30|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|     30|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|     30|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|     30|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  116|     30|        return append_second(value, _op);
  117|     30|    }
_ZN4bvar6detail10SeriesBaseImNS0_5AddToImEEE13append_secondERKmRKS3_:
  161|     30|void SeriesBase<T, Op>::append_second(const T& value, const Op& op) {
  162|     30|    _data.second(_nsecond) = value;
  163|     30|    ++_nsecond;
  164|     30|    if (_nsecond >= 60) {
  ------------------
  |  Branch (164:9): [True: 0, False: 30]
  ------------------
  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|     30|}
_ZN4bvar6detail10SeriesBaseImNS0_5AddToImEEE4Data6secondEi:
  135|     30|        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|       |        pthread_mutex_init(&_mutex, NULL);
  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|     15|    void append(const T& value) {
  115|     15|        BAIDU_SCOPED_LOCK(_mutex);
  ------------------
  |  |   47|     15|    decltype(::butil::detail::get_lock_guard<decltype(ref_of_lock)>()) \
  |  |   48|     15|    BAIDU_CONCAT(scoped_locker_dummy_at_line_, __LINE__)(ref_of_lock)
  |  |  ------------------
  |  |  |  |   88|     15|# define BAIDU_CONCAT(a, b) BAIDU_CONCAT_HELPER(a, b)
  |  |  |  |  ------------------
  |  |  |  |  |  |   89|     15|# define BAIDU_CONCAT_HELPER(a, b) a##b
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  116|     15|        return append_second(value, _op);
  117|     15|    }
_ZN4bvar6detail10SeriesBaseIiNS0_5AddToIiEEE13append_secondERKiRKS3_:
  161|     15|void SeriesBase<T, Op>::append_second(const T& value, const Op& op) {
  162|     15|    _data.second(_nsecond) = value;
  163|     15|    ++_nsecond;
  164|     15|    if (_nsecond >= 60) {
  ------------------
  |  Branch (164:9): [True: 0, False: 15]
  ------------------
  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|     15|}
_ZN4bvar6detail10SeriesBaseIiNS0_5AddToIiEEE4Data6secondEi:
  135|     15|        T& second(int index) { return _array[index]; }

_ZNK4bvar13PassiveStatusIlE9get_valueEv:
  139|     15|    Tp get_value() const {
  140|     15|        return (_getfn ? _getfn(_arg) : Tp());
  ------------------
  |  Branch (140:17): [True: 15, False: 0]
  ------------------
  141|     15|    }
_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 == NULL &&
  ------------------
  |  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(NULL), _series(Op()) {}
_ZN4bvar13PassiveStatusIlE13SeriesSampler11take_sampleEv:
   62|     15|        void take_sample() override { _series.append(_owner->get_value()); }
_ZN4bvar13PassiveStatusIlEC2ERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEPFlPvESD_:
   81|      2|        : _getfn(getfn)
   82|      2|        , _arg(arg)
   83|      2|        , _sampler(NULL)
   84|      2|        , _series_sampler(NULL) {
   85|      2|        expose(name);
   86|      2|    }
_ZNK4bvar13PassiveStatusImE9get_valueEv:
  139|     30|    Tp get_value() const {
  140|     30|        return (_getfn ? _getfn(_arg) : Tp());
  ------------------
  |  Branch (140:17): [True: 30, False: 0]
  ------------------
  141|     30|    }
_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 == NULL &&
  ------------------
  |  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(NULL), _series(Op()) {}
_ZN4bvar13PassiveStatusImE13SeriesSampler11take_sampleEv:
   62|     30|        void take_sample() override { _series.append(_owner->get_value()); }
_ZN4bvar13PassiveStatusIiEC2ERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEPFiPvESD_:
   81|      2|        : _getfn(getfn)
   82|      2|        , _arg(arg)
   83|      2|        , _sampler(NULL)
   84|      2|        , _series_sampler(NULL) {
   85|      2|        expose(name);
   86|      2|    }
_ZNK4bvar13PassiveStatusIiE9get_valueEv:
  139|     15|    Tp get_value() const {
  140|     15|        return (_getfn ? _getfn(_arg) : Tp());
  ------------------
  |  Branch (140:17): [True: 15, False: 0]
  ------------------
  141|     15|    }
_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 == NULL &&
  ------------------
  |  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(NULL), _series(Op()) {}
_ZN4bvar13PassiveStatusIiE13SeriesSampler11take_sampleEv:
   62|     15|        void take_sample() override { _series.append(_owner->get_value()); }
_ZN4bvar13PassiveStatusImEC2ERKN5butil16BasicStringPieceINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEPFmPvESD_:
   81|      4|        : _getfn(getfn)
   82|      4|        , _arg(arg)
   83|      4|        , _sampler(NULL)
   84|      4|        , _series_sampler(NULL) {
   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(NULL) , _series_sampler(NULL) , _inv_op(inv_op) {}
_ZN4bvar7ReducerIPNS_6detail7SamplerENS1_14CombineSamplerENS1_6VoidOpEE5resetEv:
  238|     15|    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 == NULL) {
  ------------------
  |  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(NULL), 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|     74|{
   27|     74|    if (size < kMinInputLength || size > kMaxInputLength){
  ------------------
  |  |   21|    148|#define kMinInputLength 5
  ------------------
                  if (size < kMinInputLength || size > kMaxInputLength){
  ------------------
  |  |   22|     74|#define kMaxInputLength 1024
  ------------------
  |  Branch (27:9): [True: 0, False: 74]
  |  Branch (27:35): [True: 21, False: 53]
  ------------------
   28|     21|        return 1;
   29|     21|    }
   30|       |
   31|     53|    std::string input(reinterpret_cast<const char*>(data), size);
   32|     53|    butil::IOBuf buf;
   33|     53|    buf.append(input);
   34|     53|    {
   35|     53|        butil::Arena arena;
   36|     53|        brpc::RedisCommandParser parser;
   37|     53|        std::vector<butil::StringPiece> command_out;
   38|     53|        parser.Consume(buf, &command_out, &arena);
   39|     53|    }
   40|     53|    {
   41|     53|        butil::Arena arena;
   42|     53|        brpc::RedisReply r2(&arena);
   43|     53|        r2.ConsumePartialIOBuf(buf);
   44|     53|    }
   45|       |
   46|     53|    return 0;
   47|     74|}

