1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "dfx_instr_statistic.h"
17#include "dfx_define.h"
18#include "dfx_log.h"
19
20namespace OHOS {
21namespace HiviewDFX {
22namespace {
23#undef LOG_DOMAIN
24#undef LOG_TAG
25#define LOG_DOMAIN 0xD002D11
26#define LOG_TAG "DfxInstrStatistic"
27}
28
29DfxInstrStatistic &DfxInstrStatistic::GetInstance()
30{
31    static DfxInstrStatistic instance;
32    return instance;
33}
34
35void DfxInstrStatistic::SetCurrentStatLib(const std::string soName)
36{
37    soName_ = soName;
38    statisticInfo_.clear();
39}
40
41void DfxInstrStatistic::AddInstrStatistic(InstrStatisticType type, uint64_t val, uint64_t err)
42{
43    if (err != 0) {
44        DFXLOGE("type: %{public}u, val: %{public}" PRIx64 ", err: %{public}" PRIx64 "", type, val, err);
45    } else {
46        DFXLOGU("type: %{public}u, val: %{public}" PRIx64 "", type, val);
47    }
48    std::shared_ptr<std::vector<std::pair<uint64_t, uint64_t>>> stats;
49    auto iter = statisticInfo_.find(static_cast<uint32_t>(type));
50    if (iter != statisticInfo_.end()) {
51        stats = iter->second;
52    } else {
53        stats = std::make_shared<std::vector<std::pair<uint64_t, uint64_t>>>();
54        statisticInfo_[type] = stats;
55    }
56    if (stats != nullptr) {
57        stats->push_back(std::make_pair(val, err));
58    }
59}
60
61void DfxInstrStatistic::DumpInstrStatResult(std::vector<std::pair<uint32_t, uint32_t>> &result)
62{
63    auto iter = statisticInfo_.begin();
64    DFXLOGU("++++++Dump Instr Statistic for elf file: %{public}s", soName_.c_str());
65    while (iter != statisticInfo_.end()) {
66        InstrStatisticType type = static_cast<InstrStatisticType>(iter->first);
67        std::shared_ptr<std::vector<std::pair<uint64_t, uint64_t>>> stats = iter->second;
68        if (stats == nullptr) {
69            iter++;
70            continue;
71        }
72        switch (type) {
73            case InstructionEntriesArmExidx:
74            case InstructionEntriesEhFrame:
75            case InstructionEntriesDebugFrame:
76                DFXLOGU("\t [%{public}d]: Type: %{public}u, Count: %{public}" PRIu64 "", __LINE__,
77                    type, (uint64_t) stats->size());
78                for (size_t i = 0; i < stats->size(); ++i) {
79                    DFXLOGU("\t Value: %{public}" PRIx64 "", (uint64_t) stats->at(i).first);
80                    result.push_back(std::make_pair(type, static_cast<uint32_t>(stats->at(i).first)));
81                }
82                break;
83            default:
84                DFXLOGU("\t [%{public}d]: Type: %{public}u, Count: %{public}" PRIu64 "", __LINE__,
85                    type, (uint64_t) stats->size());
86                result.push_back(std::make_pair(type, static_cast<uint32_t>(stats->size())));
87                break;
88        }
89        iter++;
90    }
91    DFXLOGU("------Dump Instr Statistic End.");
92}
93} // namespace HiviewDFX
94} // namespace OHOS
95