148f512ceSopenharmony_ci/*
248f512ceSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
448f512ceSopenharmony_ci * you may not use this file except in compliance with the License.
548f512ceSopenharmony_ci * You may obtain a copy of the License at
648f512ceSopenharmony_ci *
748f512ceSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
848f512ceSopenharmony_ci *
948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and
1348f512ceSopenharmony_ci * limitations under the License.
1448f512ceSopenharmony_ci */
1548f512ceSopenharmony_ci
1648f512ceSopenharmony_ci#ifndef REPORT_JSON_FILE_H
1748f512ceSopenharmony_ci#define REPORT_JSON_FILE_H
1848f512ceSopenharmony_ci
1948f512ceSopenharmony_ci#include <algorithm>
2048f512ceSopenharmony_ci#include <cstdio>
2148f512ceSopenharmony_ci#include <cstdlib>
2248f512ceSopenharmony_ci#include <functional>
2348f512ceSopenharmony_ci#include <map>
2448f512ceSopenharmony_ci
2548f512ceSopenharmony_ci#include "debug_logger.h"
2648f512ceSopenharmony_ci#include "perf_file_reader.h"
2748f512ceSopenharmony_ci#include "utilities.h"
2848f512ceSopenharmony_ci#include "virtual_runtime.h"
2948f512ceSopenharmony_ci
3048f512ceSopenharmony_cinamespace OHOS {
3148f512ceSopenharmony_cinamespace Developtools {
3248f512ceSopenharmony_cinamespace HiPerf {
3348f512ceSopenharmony_ciusing jsonStringMap = std::map<std::string, std::string>;
3448f512ceSopenharmony_ciusing jsonStringVector = std::vector<std::string>;
3548f512ceSopenharmony_ciusing jsonIntVector = std::vector<int>;
3648f512ceSopenharmony_ci
3748f512ceSopenharmony_citemplate<class T>
3848f512ceSopenharmony_civoid OutputJsonKey(FILE *output, const T &value)
3948f512ceSopenharmony_ci{
4048f512ceSopenharmony_ci    if constexpr (std::is_same<T, std::string>::value) {
4148f512ceSopenharmony_ci        if (value.empty()) {
4248f512ceSopenharmony_ci            // for key vector [] mode, not key is needed
4348f512ceSopenharmony_ci            return;
4448f512ceSopenharmony_ci        }
4548f512ceSopenharmony_ci        fprintf(output, "\"%s\":", value.c_str());
4648f512ceSopenharmony_ci    } else if constexpr (std::is_same<T, std::string_view>::value) {
4748f512ceSopenharmony_ci        if (value.empty()) {
4848f512ceSopenharmony_ci            // for key vector [] mode, not key is needed
4948f512ceSopenharmony_ci            return;
5048f512ceSopenharmony_ci        }
5148f512ceSopenharmony_ci        fprintf(output, "\"%s\":", value.data());
5248f512ceSopenharmony_ci    } else if constexpr (std::is_same<typename std::decay<T>::type, char *>::value) {
5348f512ceSopenharmony_ci        if (value[0] == '\0') {
5448f512ceSopenharmony_ci            // same as value.empty()
5548f512ceSopenharmony_ci            return;
5648f512ceSopenharmony_ci        }
5748f512ceSopenharmony_ci        fprintf(output, "\"%s\":", value);
5848f512ceSopenharmony_ci    } else {
5948f512ceSopenharmony_ci        fprintf(output, "\"%s\":", std::to_string(value).c_str());
6048f512ceSopenharmony_ci    }
6148f512ceSopenharmony_ci}
6248f512ceSopenharmony_citemplate<class T>
6348f512ceSopenharmony_civoid OutputJsonValue(FILE *output, const T &value, bool first = true)
6448f512ceSopenharmony_ci{
6548f512ceSopenharmony_ci    if (!first) {
6648f512ceSopenharmony_ci        fprintf(output, ",");
6748f512ceSopenharmony_ci    }
6848f512ceSopenharmony_ci    if constexpr (std::is_same<T, std::string>::value) {
6948f512ceSopenharmony_ci        fprintf(output, "\"%s\"", value.c_str());
7048f512ceSopenharmony_ci    } else if constexpr (std::is_same<T, std::string_view>::value) {
7148f512ceSopenharmony_ci        fprintf(output, "\"%s\"", value.data());
7248f512ceSopenharmony_ci    } else if constexpr (std::is_same<T, int>::value) {
7348f512ceSopenharmony_ci        fprintf(output, "%s", std::to_string(value).c_str());
7448f512ceSopenharmony_ci    } else if constexpr (std::is_same<T, uint64_t>::value) {
7548f512ceSopenharmony_ci        fprintf(output, "%s", std::to_string(value).c_str());
7648f512ceSopenharmony_ci    } else if constexpr (std::is_same<T, bool>::value) {
7748f512ceSopenharmony_ci        fprintf(output, "%s", std::to_string(value).c_str());
7848f512ceSopenharmony_ci    } else if constexpr (std::is_same<T, size_t>::value) {
7948f512ceSopenharmony_ci        fprintf(output, "%s", std::to_string(value).c_str());
8048f512ceSopenharmony_ci    } else if constexpr (std::is_same<typename std::decay<T>::type, char *>::value) {
8148f512ceSopenharmony_ci        fprintf(output, "\"%s\"", value);
8248f512ceSopenharmony_ci    } else {
8348f512ceSopenharmony_ci        value.OutputJson(output);
8448f512ceSopenharmony_ci    }
8548f512ceSopenharmony_ci}
8648f512ceSopenharmony_ci
8748f512ceSopenharmony_ci/*
8848f512ceSopenharmony_ci    k:"v"
8948f512ceSopenharmony_ci    k:1
9048f512ceSopenharmony_ci*/
9148f512ceSopenharmony_citemplate<class K, class T>
9248f512ceSopenharmony_civoid OutputJsonPair(FILE *output, const K &key, const T &value, bool first = false)
9348f512ceSopenharmony_ci{
9448f512ceSopenharmony_ci    if (!first) {
9548f512ceSopenharmony_ci        if (fprintf(output, ",") < 0) {
9648f512ceSopenharmony_ci            return;
9748f512ceSopenharmony_ci        }
9848f512ceSopenharmony_ci    }
9948f512ceSopenharmony_ci    // for id, symbol
10048f512ceSopenharmony_ci    OutputJsonKey(output, key);
10148f512ceSopenharmony_ci    // ReportFuncMapItem funcName.
10248f512ceSopenharmony_ci    OutputJsonValue(output, value);
10348f512ceSopenharmony_ci}
10448f512ceSopenharmony_ci
10548f512ceSopenharmony_ci/*
10648f512ceSopenharmony_ci    k:[v1,v2,v3]
10748f512ceSopenharmony_ci*/
10848f512ceSopenharmony_citemplate<class T>
10948f512ceSopenharmony_civoid OutputJsonVectorList(FILE *output, const std::string &key, const std::vector<T> &value,
11048f512ceSopenharmony_ci                          bool first = false)
11148f512ceSopenharmony_ci{
11248f512ceSopenharmony_ci    if (!first) {
11348f512ceSopenharmony_ci        if (fprintf(output, ",") < 0) {
11448f512ceSopenharmony_ci            return;
11548f512ceSopenharmony_ci        }
11648f512ceSopenharmony_ci    }
11748f512ceSopenharmony_ci    if (fprintf(output, "\"%s\":[", key.c_str()) != -1) {
11848f512ceSopenharmony_ci        auto it = value.begin();
11948f512ceSopenharmony_ci        while (it != value.end()) {
12048f512ceSopenharmony_ci            OutputJsonValue(output, *it, it == value.begin());
12148f512ceSopenharmony_ci            it++;
12248f512ceSopenharmony_ci        }
12348f512ceSopenharmony_ci        if (fprintf(output, "]") < 0) {
12448f512ceSopenharmony_ci            return;
12548f512ceSopenharmony_ci        }
12648f512ceSopenharmony_ci    }
12748f512ceSopenharmony_ci}
12848f512ceSopenharmony_ci
12948f512ceSopenharmony_ci/*
13048f512ceSopenharmony_ci    k:[v1,v2,v3]
13148f512ceSopenharmony_ci*/
13248f512ceSopenharmony_citemplate<class K, class V>
13348f512ceSopenharmony_civoid OutputJsonMapList(FILE *output, const std::string &key, const std::map<K, V> &value,
13448f512ceSopenharmony_ci                       bool first = false)
13548f512ceSopenharmony_ci{
13648f512ceSopenharmony_ci    if (!first) {
13748f512ceSopenharmony_ci        if (fprintf(output, ",") < 0) {
13848f512ceSopenharmony_ci            return;
13948f512ceSopenharmony_ci        }
14048f512ceSopenharmony_ci    }
14148f512ceSopenharmony_ci    if (fprintf(output, "\"%s\":[", key.c_str()) != -1) {
14248f512ceSopenharmony_ci        auto it = value.begin();
14348f512ceSopenharmony_ci        while (it != value.end()) {
14448f512ceSopenharmony_ci            OutputJsonValue(output, it->second, it == value.begin());
14548f512ceSopenharmony_ci            it++;
14648f512ceSopenharmony_ci        }
14748f512ceSopenharmony_ci        if (fprintf(output, "]") < 0) {
14848f512ceSopenharmony_ci            return;
14948f512ceSopenharmony_ci        }
15048f512ceSopenharmony_ci    }
15148f512ceSopenharmony_ci}
15248f512ceSopenharmony_ci
15348f512ceSopenharmony_ci/*
15448f512ceSopenharmony_ci    k:{k1:v1,k2:v2,k3:v3}
15548f512ceSopenharmony_ci*/
15648f512ceSopenharmony_citemplate<class K, class V>
15748f512ceSopenharmony_civoid OutputJsonMap(FILE *output, const std::string &key, const std::map<K, V> &value,
15848f512ceSopenharmony_ci                   bool first = false)
15948f512ceSopenharmony_ci{
16048f512ceSopenharmony_ci    if (!first) {
16148f512ceSopenharmony_ci        if (fprintf(output, ",") < 0) {
16248f512ceSopenharmony_ci            return;
16348f512ceSopenharmony_ci        }
16448f512ceSopenharmony_ci    }
16548f512ceSopenharmony_ci    if (fprintf(output, "\"%s\":{", key.c_str()) != -1) {
16648f512ceSopenharmony_ci        auto it = value.begin();
16748f512ceSopenharmony_ci        while (it != value.end()) {
16848f512ceSopenharmony_ci            OutputJsonPair(output, it->first, it->second, it == value.begin());
16948f512ceSopenharmony_ci            it++;
17048f512ceSopenharmony_ci        }
17148f512ceSopenharmony_ci        if (fprintf(output, "}") < 0) {
17248f512ceSopenharmony_ci            return;
17348f512ceSopenharmony_ci        }
17448f512ceSopenharmony_ci    }
17548f512ceSopenharmony_ci}
17648f512ceSopenharmony_ci
17748f512ceSopenharmony_citemplate<class K, class V>
17848f512ceSopenharmony_ciV &GetOrCreateMapItem(std::map<K, V> &map, const K &key)
17948f512ceSopenharmony_ci{
18048f512ceSopenharmony_ci    if (map.count(key) == 0) {
18148f512ceSopenharmony_ci        map.emplace(key, (key));
18248f512ceSopenharmony_ci    }
18348f512ceSopenharmony_ci    return map.at(key);
18448f512ceSopenharmony_ci}
18548f512ceSopenharmony_ci
18648f512ceSopenharmony_cistruct ReportFuncMapItem {
18748f512ceSopenharmony_ci    int libId_ = -1;
18848f512ceSopenharmony_ci    std::string funcName_;
18948f512ceSopenharmony_ci    int reportFuncId_ = -1;
19048f512ceSopenharmony_ci    void OutputJson(FILE *output) const
19148f512ceSopenharmony_ci    {
19248f512ceSopenharmony_ci        if (fprintf(output, "{") < 0) {
19348f512ceSopenharmony_ci            return;
19448f512ceSopenharmony_ci        }
19548f512ceSopenharmony_ci        OutputJsonPair(output, "file", libId_, true);
19648f512ceSopenharmony_ci        OutputJsonPair(output, "symbol", funcName_);
19748f512ceSopenharmony_ci        if (fprintf(output, "}") < 0) {
19848f512ceSopenharmony_ci            return;
19948f512ceSopenharmony_ci        }
20048f512ceSopenharmony_ci    }
20148f512ceSopenharmony_ci    ReportFuncMapItem(int libId, std::string &funcName, int reportFuncId)
20248f512ceSopenharmony_ci        : libId_(libId), funcName_(funcName), reportFuncId_(reportFuncId) {}
20348f512ceSopenharmony_ci};
20448f512ceSopenharmony_ci
20548f512ceSopenharmony_cistruct ReportFuncItem {
20648f512ceSopenharmony_ci    int functionId_ = -1;
20748f512ceSopenharmony_ci    int functionInLibId_ = -1;
20848f512ceSopenharmony_ci    uint64_t sampleCount_ = 0;
20948f512ceSopenharmony_ci    uint64_t eventCount_ = 0;
21048f512ceSopenharmony_ci    uint64_t subTreeEventCount_ = 0;
21148f512ceSopenharmony_ci    explicit ReportFuncItem(int functionId) : functionId_(functionId) {}
21248f512ceSopenharmony_ci    void OutputJson(FILE *output) const
21348f512ceSopenharmony_ci    {
21448f512ceSopenharmony_ci        if (fprintf(output, "{") < 0) {
21548f512ceSopenharmony_ci            return;
21648f512ceSopenharmony_ci        }
21748f512ceSopenharmony_ci        OutputJsonPair(output, "symbol", functionId_, true);
21848f512ceSopenharmony_ci        OutputJsonVectorList(output, "counts",
21948f512ceSopenharmony_ci                             std::vector<uint64_t> {sampleCount_, eventCount_, subTreeEventCount_});
22048f512ceSopenharmony_ci        if (fprintf(output, "}") < 0) {
22148f512ceSopenharmony_ci            return;
22248f512ceSopenharmony_ci        }
22348f512ceSopenharmony_ci    }
22448f512ceSopenharmony_ci};
22548f512ceSopenharmony_ci
22648f512ceSopenharmony_cistruct ReportCallNodeItem {
22748f512ceSopenharmony_ci    uint64_t selfEventCount_ = 0;
22848f512ceSopenharmony_ci    uint64_t subTreeEventCount_ = 0;
22948f512ceSopenharmony_ci    int functionId_ = -1;
23048f512ceSopenharmony_ci    int nodeIndex_ = -1;
23148f512ceSopenharmony_ci    bool reverseCaller_ = false;
23248f512ceSopenharmony_ci    std::string_view funcName_ = "";
23348f512ceSopenharmony_ci    std::string debug_ = "";
23448f512ceSopenharmony_ci    std::map<int, ReportCallNodeItem> childrenMap;
23548f512ceSopenharmony_ci
23648f512ceSopenharmony_ci    void OutputJson(FILE *output) const
23748f512ceSopenharmony_ci    {
23848f512ceSopenharmony_ci        if (fprintf(output, "{") < 0) {
23948f512ceSopenharmony_ci            return;
24048f512ceSopenharmony_ci        }
24148f512ceSopenharmony_ci        OutputJsonPair(output, "selfEvents", selfEventCount_, true);
24248f512ceSopenharmony_ci        OutputJsonPair(output, "subEvents", subTreeEventCount_);
24348f512ceSopenharmony_ci        OutputJsonPair(output, "symbol", functionId_);
24448f512ceSopenharmony_ci        if (!funcName_.empty()) { // for debug
24548f512ceSopenharmony_ci            OutputJsonPair(output, "funcName", funcName_);
24648f512ceSopenharmony_ci            OutputJsonPair(output, "nodeIndex", nodeIndex_);
24748f512ceSopenharmony_ci            OutputJsonPair(output, "reversed", reverseCaller_);
24848f512ceSopenharmony_ci        }
24948f512ceSopenharmony_ci        OutputJsonMapList(output, "callStack", childrenMap);
25048f512ceSopenharmony_ci        if (fprintf(output, "}") < 0) {
25148f512ceSopenharmony_ci            return;
25248f512ceSopenharmony_ci        }
25348f512ceSopenharmony_ci    }
25448f512ceSopenharmony_ci
25548f512ceSopenharmony_ci    uint64_t UpdateChildrenEventCount()
25648f512ceSopenharmony_ci    {
25748f512ceSopenharmony_ci        subTreeEventCount_ = selfEventCount_;
25848f512ceSopenharmony_ci        for (auto &pair : childrenMap) {
25948f512ceSopenharmony_ci            subTreeEventCount_ += pair.second.UpdateChildrenEventCount();
26048f512ceSopenharmony_ci            if (!funcName_.empty()) {
26148f512ceSopenharmony_ci            }
26248f512ceSopenharmony_ci        }
26348f512ceSopenharmony_ci        return subTreeEventCount_;
26448f512ceSopenharmony_ci    }
26548f512ceSopenharmony_ci
26648f512ceSopenharmony_ci    static bool FindByFunctionId(ReportCallNodeItem &a, int functionId)
26748f512ceSopenharmony_ci    {
26848f512ceSopenharmony_ci        return (a.functionId_ == functionId);
26948f512ceSopenharmony_ci    }
27048f512ceSopenharmony_ci
27148f512ceSopenharmony_ci    explicit ReportCallNodeItem(int functionId) : functionId_(functionId) {}
27248f512ceSopenharmony_ci};
27348f512ceSopenharmony_ci
27448f512ceSopenharmony_cistruct ReportLibItem {
27548f512ceSopenharmony_ci    int libId_ = 0;
27648f512ceSopenharmony_ci    uint64_t eventCount_ = 0;
27748f512ceSopenharmony_ci    std::map<int, ReportFuncItem> funcs_;
27848f512ceSopenharmony_ci    void OutputJson(FILE *output) const
27948f512ceSopenharmony_ci    {
28048f512ceSopenharmony_ci        if (fprintf(output, "{") < 0) {
28148f512ceSopenharmony_ci            return;
28248f512ceSopenharmony_ci        }
28348f512ceSopenharmony_ci        OutputJsonPair(output, "fileId", libId_, true);
28448f512ceSopenharmony_ci        OutputJsonPair(output, "eventCount", eventCount_);
28548f512ceSopenharmony_ci        OutputJsonMapList(output, "functions", funcs_);
28648f512ceSopenharmony_ci        if (fprintf(output, "}") < 0) {
28748f512ceSopenharmony_ci            return;
28848f512ceSopenharmony_ci        }
28948f512ceSopenharmony_ci    }
29048f512ceSopenharmony_ci};
29148f512ceSopenharmony_ci
29248f512ceSopenharmony_cistruct ReportThreadItem {
29348f512ceSopenharmony_ci    pid_t tid_ = 0;
29448f512ceSopenharmony_ci    uint64_t eventCount_ = 0;
29548f512ceSopenharmony_ci    uint64_t sampleCount_ = 0;
29648f512ceSopenharmony_ci    std::map<int, ReportLibItem> libs_;
29748f512ceSopenharmony_ci    ReportCallNodeItem callNode;
29848f512ceSopenharmony_ci    ReportCallNodeItem callNodeReverse;
29948f512ceSopenharmony_ci    void OutputJson(FILE *output) const
30048f512ceSopenharmony_ci    {
30148f512ceSopenharmony_ci        if (fprintf(output, "{") < 0) {
30248f512ceSopenharmony_ci            return;
30348f512ceSopenharmony_ci        }
30448f512ceSopenharmony_ci        OutputJsonPair(output, "tid", tid_, true);
30548f512ceSopenharmony_ci        OutputJsonPair(output, "eventCount", eventCount_);
30648f512ceSopenharmony_ci        OutputJsonPair(output, "sampleCount", sampleCount_);
30748f512ceSopenharmony_ci        OutputJsonMapList(output, "libs", libs_);
30848f512ceSopenharmony_ci        OutputJsonPair(output, "CallOrder", callNode);
30948f512ceSopenharmony_ci        OutputJsonPair(output, "CalledOrder", callNodeReverse);
31048f512ceSopenharmony_ci        if (fprintf(output, "}") < 0) {
31148f512ceSopenharmony_ci            return;
31248f512ceSopenharmony_ci        }
31348f512ceSopenharmony_ci    }
31448f512ceSopenharmony_ci    ReportThreadItem(pid_t id) : tid_(id), callNode(-1), callNodeReverse(-1) {}
31548f512ceSopenharmony_ci};
31648f512ceSopenharmony_ci
31748f512ceSopenharmony_cistruct ReportProcessItem {
31848f512ceSopenharmony_ci    pid_t pid_ = 0;
31948f512ceSopenharmony_ci    uint64_t eventCount_ = 0;
32048f512ceSopenharmony_ci    std::map<pid_t, ReportThreadItem> threads_;
32148f512ceSopenharmony_ci    void OutputJson(FILE *output) const
32248f512ceSopenharmony_ci    {
32348f512ceSopenharmony_ci        if (fprintf(output, "{") < 0) {
32448f512ceSopenharmony_ci            return;
32548f512ceSopenharmony_ci        }
32648f512ceSopenharmony_ci        OutputJsonPair(output, "pid", pid_, true);
32748f512ceSopenharmony_ci        OutputJsonPair(output, "eventCount", eventCount_);
32848f512ceSopenharmony_ci        OutputJsonMapList(output, "threads", threads_);
32948f512ceSopenharmony_ci        if (fprintf(output, "}") < 0) {
33048f512ceSopenharmony_ci            return;
33148f512ceSopenharmony_ci        }
33248f512ceSopenharmony_ci    }
33348f512ceSopenharmony_ci    explicit ReportProcessItem(pid_t pid) : pid_(pid) {}
33448f512ceSopenharmony_ci};
33548f512ceSopenharmony_ci
33648f512ceSopenharmony_cistruct ReportConfigItem {
33748f512ceSopenharmony_ci    int index_;
33848f512ceSopenharmony_ci    std::string eventName_;
33948f512ceSopenharmony_ci    uint64_t eventCount_ = 0;
34048f512ceSopenharmony_ci    std::map<pid_t, ReportProcessItem> processes_;
34148f512ceSopenharmony_ci    void OutputJson(FILE *output) const
34248f512ceSopenharmony_ci    {
34348f512ceSopenharmony_ci        if (fprintf(output, "{") < 0) {
34448f512ceSopenharmony_ci            return;
34548f512ceSopenharmony_ci        }
34648f512ceSopenharmony_ci        OutputJsonPair(output, "eventConfigName", eventName_, true);
34748f512ceSopenharmony_ci        OutputJsonPair(output, "eventCount", eventCount_);
34848f512ceSopenharmony_ci        OutputJsonMapList(output, "processes", processes_);
34948f512ceSopenharmony_ci        if (fprintf(output, "}") < 0) {
35048f512ceSopenharmony_ci            return;
35148f512ceSopenharmony_ci        }
35248f512ceSopenharmony_ci    }
35348f512ceSopenharmony_ci    ReportConfigItem(int index, std::string eventName) : index_(index), eventName_(eventName) {}
35448f512ceSopenharmony_ci};
35548f512ceSopenharmony_ci
35648f512ceSopenharmony_cistatic constexpr const int keyLibId = 0;
35748f512ceSopenharmony_cistatic constexpr const int keyfuncName = 1;
35848f512ceSopenharmony_ci
35948f512ceSopenharmony_ciclass ReportJsonFile {
36048f512ceSopenharmony_cipublic:
36148f512ceSopenharmony_ci    int nodeIndex_ = 0; // debug only
36248f512ceSopenharmony_ci    static bool debug_;
36348f512ceSopenharmony_ci    FILE *output_ = nullptr;
36448f512ceSopenharmony_ci    ReportJsonFile(const std::unique_ptr<PerfFileReader> &recordFileReader,
36548f512ceSopenharmony_ci                   const VirtualRuntime &virtualRuntime)
36648f512ceSopenharmony_ci        : recordFileReader_(recordFileReader), virtualRuntime_(virtualRuntime)
36748f512ceSopenharmony_ci    {
36848f512ceSopenharmony_ci    }
36948f512ceSopenharmony_ci
37048f512ceSopenharmony_ci    void UpdateReportSample(uint64_t configid, pid_t pid, pid_t tid, uint64_t eventCount);
37148f512ceSopenharmony_ci    void UpdateReportCallStack(uint64_t id, pid_t pid, pid_t tid, uint64_t eventCount,
37248f512ceSopenharmony_ci                               std::vector<DfxFrame> &frames);
37348f512ceSopenharmony_ci    void UpdateCallNodeEventCount();
37448f512ceSopenharmony_ci    void ProcessSymbolsFiles(const std::vector<std::unique_ptr<SymbolsFile>> &symbolsFiles);
37548f512ceSopenharmony_ci
37648f512ceSopenharmony_ci    // json
37748f512ceSopenharmony_ci    bool OutputJson(FILE *output = nullptr);
37848f512ceSopenharmony_ci
37948f512ceSopenharmony_ci    std::map<std::vector<uint64_t>, ReportConfigItem> reportConfigItems_;
38048f512ceSopenharmony_ci
38148f512ceSopenharmony_ciprivate:
38248f512ceSopenharmony_ci    const std::unique_ptr<PerfFileReader> &recordFileReader_;
38348f512ceSopenharmony_ci    const VirtualRuntime &virtualRuntime_;
38448f512ceSopenharmony_ci    std::vector<std::string_view> libList_;
38548f512ceSopenharmony_ci    int functionId_ = 0;
38648f512ceSopenharmony_ci    std::map<int, std::map<std::string, ReportFuncMapItem>> functionMap_;
38748f512ceSopenharmony_ci    void AddNewFunction(int libId, std::string name);
38848f512ceSopenharmony_ci    void OutputJsonFunctionMap(FILE *output);
38948f512ceSopenharmony_ci
39048f512ceSopenharmony_ci    ReportConfigItem &GetConfig(uint64_t id);
39148f512ceSopenharmony_ci    std::string GetConfigName(uint64_t id);
39248f512ceSopenharmony_ci    uint32_t GetConfigIndex(uint64_t id);
39348f512ceSopenharmony_ci
39448f512ceSopenharmony_ci    int GetFunctionID(int libId, const std::string &function);
39548f512ceSopenharmony_ci    int GetLibID(std::string_view filepath);
39648f512ceSopenharmony_ci
39748f512ceSopenharmony_ci    void OutputJsonFeatureString();
39848f512ceSopenharmony_ci    void OutputJsonRuntimeInfo();
39948f512ceSopenharmony_ci
40048f512ceSopenharmony_ci    void AddReportCallStack(uint64_t eventCount, ReportCallNodeItem &callNode,
40148f512ceSopenharmony_ci                            const std::vector<DfxFrame> &frames);
40248f512ceSopenharmony_ci    void AddReportCallStackReverse(uint64_t eventCount, ReportCallNodeItem &callNode,
40348f512ceSopenharmony_ci                                   const std::vector<DfxFrame> &frames);
40448f512ceSopenharmony_ci    uint64_t sampleCount_ = 0;
40548f512ceSopenharmony_ci
40648f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, UpdateReportSample);
40748f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, UpdateReportCallStack);
40848f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, UpdateCallNodeEventCount);
40948f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, ProcessSymbolsFiles);
41048f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, GetFunctionID);
41148f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, GetLibID);
41248f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, GetConfigIndex);
41348f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, GetConfigName);
41448f512ceSopenharmony_ci    FRIEND_TEST(ReportJsonFileTest, GetConfig);
41548f512ceSopenharmony_ci    friend class ReportJsonFileTest;
41648f512ceSopenharmony_ci};
41748f512ceSopenharmony_ci} // namespace HiPerf
41848f512ceSopenharmony_ci} // namespace Developtools
41948f512ceSopenharmony_ci} // namespace OHOS
42048f512ceSopenharmony_ci#endif // REPORT_JSON_FILE_H
421