mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
update ap_file_viewer code
Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IA716C Signed-off-by: yp9522 <yanpeng51@h-partners.com> Change-Id: Id8d0b90b1a909aba5d65f4cd457c4abb8bef0bd1 Signed-off-by: yp9522 <yanpeng51@h-partners.com> Signed-off-by: yanpeng <yanpeng51@h-partners.com> Signed-off-by: yp9522 <yanpeng51@h-partners.com>
This commit is contained in:
parent
3fc00939c4
commit
0198dd8364
13
BUILD.gn
13
BUILD.gn
@ -34,6 +34,15 @@ group("ark_js_packages") {
|
||||
}
|
||||
}
|
||||
|
||||
group("ap_viewer_all_host_tools_packages") {
|
||||
if (host_os != "mac" && target_os != "android") {
|
||||
deps = [
|
||||
"tools/ap_file_viewer/native:apViewer($build_root/toolchain/mingw:mingw_x86_64)",
|
||||
"tools/ap_file_viewer/native:apViewer(${host_toolchain})",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
group("ark_js_host_windows_tools_packages") {
|
||||
deps = []
|
||||
if (host_os != "mac" && target_os != "android") {
|
||||
@ -535,6 +544,9 @@ config("ark_jsruntime_common_config") {
|
||||
!defined(global_parts_info.security_code_crypto_metadata_process)) {
|
||||
code_encrypto_enable = false
|
||||
}
|
||||
if (is_mingw && ark_standalone_build) {
|
||||
code_encrypto_enable = false
|
||||
}
|
||||
if (code_encrypto_enable) {
|
||||
defines += [ "CODE_ENCRYPTION_ENABLE" ]
|
||||
}
|
||||
@ -546,6 +558,7 @@ config("ecma_test_config") {
|
||||
"./ecmascript/*",
|
||||
"./test/executiontest/*",
|
||||
"./test/fuzztest/*",
|
||||
"./tools/ap_file_viewer/*",
|
||||
]
|
||||
|
||||
configs = [
|
||||
|
@ -49,7 +49,8 @@
|
||||
"samgr",
|
||||
"common_event_service",
|
||||
"power_manager",
|
||||
"ffrt"
|
||||
"ffrt",
|
||||
"cJSON"
|
||||
],
|
||||
"third_party": [
|
||||
]
|
||||
|
@ -566,8 +566,8 @@ void TimSort::CopyArray(JSHandle<TaggedArray> &src, int srcPos,
|
||||
DISALLOW_GARBAGE_COLLECTION;
|
||||
ASSERT(srcPos >= 0);
|
||||
ASSERT(dstPos >= 0);
|
||||
ASSERT(srcPos <= src->GetLength() - length);
|
||||
ASSERT(dstPos <= dst->GetLength() - length);
|
||||
ASSERT(static_cast<int64_t>(srcPos) <= static_cast<int64_t>(src->GetLength() - length));
|
||||
ASSERT(static_cast<int64_t>(dstPos) <= static_cast<int64_t>(dst->GetLength() - length));
|
||||
|
||||
if (srcPos < dstPos) {
|
||||
int srcIdx = srcPos + length - 1;
|
||||
|
@ -1684,7 +1684,7 @@ std::string JSDateTimeFormat::ToTitleCaseTimezonePosition(const std::string &inp
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ASSERT(input.length() >= leftPosition);
|
||||
ASSERT(input.length() >= static_cast<size_t>(leftPosition));
|
||||
titleEntry.emplace_back(input.substr(leftPosition, input.length() - leftPosition));
|
||||
std::string result;
|
||||
size_t len = titleEntry.size();
|
||||
|
@ -199,4 +199,30 @@ void PGOMethodTypeSet::ProcessToText(std::string &text) const
|
||||
text += (DumpUtils::SPACE + DumpUtils::ARRAY_END);
|
||||
}
|
||||
}
|
||||
|
||||
void PGOMethodTypeSet::ProcessToJson(ProfileType::VariantVector &typeArray) const
|
||||
{
|
||||
for (auto typeInfoIter : scalarOpTypeInfos_) {
|
||||
if (typeInfoIter.GetType().IsNone()) {
|
||||
continue;
|
||||
}
|
||||
ProfileType::StringMap type;
|
||||
type.insert(std::make_pair(DumpJsonUtils::TYPE_OFFSET, std::to_string(typeInfoIter.GetOffset())));
|
||||
typeInfoIter.GetType().GetTypeJson(type);
|
||||
typeArray.push_back(type);
|
||||
}
|
||||
for (auto rwScalarOpTypeInfoIter : rwScalarOpTypeInfos_) {
|
||||
if (rwScalarOpTypeInfoIter.GetCount() == 0) {
|
||||
continue;
|
||||
}
|
||||
ProfileType::MapVector sameOffsetTypeArray;
|
||||
rwScalarOpTypeInfoIter.ProcessToJson(sameOffsetTypeArray);
|
||||
typeArray.push_back(sameOffsetTypeArray);
|
||||
}
|
||||
for (const auto &defTypeInfoIter : objDefOpTypeInfos_) {
|
||||
std::vector<ProfileType::StringMap> sameOffsetTypeArray;
|
||||
defTypeInfoIter.ProcessToJson(sameOffsetTypeArray);
|
||||
typeArray.push_back(sameOffsetTypeArray);
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript::pgo
|
||||
|
@ -103,6 +103,8 @@ public:
|
||||
bool ParseFromText(const std::string &typeString);
|
||||
void ProcessToText(std::string &text) const;
|
||||
|
||||
void ProcessToJson(ProfileType::VariantVector &typeArray) const;
|
||||
|
||||
NO_COPY_SEMANTIC(PGOMethodTypeSet);
|
||||
NO_MOVE_SEMANTIC(PGOMethodTypeSet);
|
||||
|
||||
@ -199,6 +201,15 @@ private:
|
||||
text += (DumpUtils::SPACE + DumpUtils::ARRAY_END);
|
||||
}
|
||||
|
||||
void ProcessToJson(ProfileType::MapVector &typeArray) const
|
||||
{
|
||||
for (uint32_t i = 0; i < type_.GetCount(); i++) {
|
||||
std::vector<ProfileType::StringMap> sameOffsetTypeArray;
|
||||
type_.GetObjectInfo(i).GetInfoJson(sameOffsetTypeArray, std::to_string(GetOffset()));
|
||||
typeArray.push_back(sameOffsetTypeArray);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
RWOpType type_;
|
||||
};
|
||||
@ -269,6 +280,11 @@ private:
|
||||
text += (DumpUtils::SPACE + DumpUtils::ARRAY_END);
|
||||
}
|
||||
|
||||
void ProcessToJson(std::vector<ProfileType::StringMap> &sameOffsetTypeArray) const
|
||||
{
|
||||
this->GetType().GetTypeJson(sameOffsetTypeArray, std::to_string(this->GetOffset()));
|
||||
}
|
||||
|
||||
PGODefineOpType GetType() const
|
||||
{
|
||||
return type_;
|
||||
|
@ -161,6 +161,15 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void ProcessToJson(std::vector<ProfileType::StringMap> &abcPoolArray)
|
||||
{
|
||||
for (auto &entry : pool_) {
|
||||
ProfileType::StringMap abcPool;
|
||||
abcPool.insert(std::make_pair(DumpJsonUtils::ABC_ID, std::to_string(entry.first)));
|
||||
abcPool.insert(std::make_pair(DumpJsonUtils::ABC_FILE, entry.second.GetData()));
|
||||
abcPoolArray.push_back(abcPool);
|
||||
}
|
||||
}
|
||||
uint32_t ParseFromBinary([[maybe_unused]] PGOContext &context, void **buffer,
|
||||
PGOProfilerHeader const *header) override
|
||||
{
|
||||
|
@ -149,6 +149,13 @@ void PGOMethodInfo::ProcessToText(std::string &text) const
|
||||
text += GetMethodName();
|
||||
}
|
||||
|
||||
void PGOMethodInfo::ProcessToJson(ProfileType::VariantMap &function) const
|
||||
{
|
||||
std::string methodName = GetMethodName();
|
||||
std::string functionName = methodName + "(" + std::to_string(GetMethodId().GetOffset()) + ")";
|
||||
function.insert(std::make_pair(DumpJsonUtils::FUNCTION_NAME, functionName));
|
||||
}
|
||||
|
||||
std::vector<std::string> PGOMethodInfo::ParseFromText(const std::string &infoString)
|
||||
{
|
||||
std::vector<std::string> infoStrings = StringHelper::SplitString(infoString, DumpUtils::ELEMENT_SEPARATOR);
|
||||
@ -473,6 +480,27 @@ void PGOMethodInfoMap::ProcessToText(uint32_t threshold, const CString &recordNa
|
||||
}
|
||||
}
|
||||
|
||||
void PGOMethodInfoMap::ProcessToJson(uint32_t threshold, ProfileType::jModuleType &jModule) const
|
||||
{
|
||||
std::vector<ProfileType::VariantMap> functionArray;
|
||||
for (auto methodInfoIter : methodInfos_) {
|
||||
auto methodInfo = methodInfoIter.second;
|
||||
if (methodInfo->IsFilter(threshold)) {
|
||||
continue;
|
||||
}
|
||||
ProfileType::VariantMap function;
|
||||
methodInfo->ProcessToJson(function);
|
||||
auto iter = methodTypeInfos_.find(methodInfo->GetMethodId());
|
||||
if (iter != methodTypeInfos_.end()) {
|
||||
ProfileType::VariantVector typeArray;
|
||||
iter->second->ProcessToJson(typeArray);
|
||||
function.insert(std::make_pair(DumpJsonUtils::TYPE, typeArray));
|
||||
}
|
||||
functionArray.push_back(function);
|
||||
}
|
||||
jModule.insert(std::make_pair(DumpJsonUtils::FUNCTION, functionArray));
|
||||
}
|
||||
|
||||
bool PGOMethodIdSet::ParseFromBinary(PGOContext &context, void **buffer)
|
||||
{
|
||||
PGOProfilerHeader *const header = context.GetHeader();
|
||||
|
@ -234,6 +234,8 @@ public:
|
||||
static std::vector<std::string> ParseFromText(const std::string &infoString);
|
||||
void ProcessToText(std::string &text) const;
|
||||
|
||||
void ProcessToJson(ProfileType::VariantMap &function) const;
|
||||
|
||||
NO_COPY_SEMANTIC(PGOMethodInfo);
|
||||
NO_MOVE_SEMANTIC(PGOMethodInfo);
|
||||
|
||||
@ -291,6 +293,8 @@ public:
|
||||
bool ParseFromText(Chunk *chunk, uint32_t threshold, const std::vector<std::string> &content);
|
||||
void ProcessToText(uint32_t threshold, const CString &recordName, std::ofstream &stream) const;
|
||||
|
||||
void ProcessToJson(uint32_t threshold, ProfileType::jModuleType &jModule) const;
|
||||
|
||||
const CMap<PGOMethodId, PGOMethodInfo *> &GetMethodInfos() const
|
||||
{
|
||||
return methodInfos_;
|
||||
|
@ -47,6 +47,23 @@ public:
|
||||
static const uint32_t HEX_FORMAT_WIDTH_FOR_32BITS;
|
||||
};
|
||||
|
||||
class DumpJsonUtils {
|
||||
public:
|
||||
static inline const std::string ABC_FILE_POOL = "abcFilePool";
|
||||
static inline const std::string ABC_FILE = "abcFile";
|
||||
static inline const std::string RECORD_DETAIL = "recordDetail";
|
||||
static inline const std::string MODULE_NAME = "moduleName";
|
||||
static inline const std::string FUNCTION = "function";
|
||||
static inline const std::string FUNCTION_NAME = "functionName";
|
||||
static inline const std::string TYPE = "type";
|
||||
static inline const std::string TYPE_OFFSET = "typeOffset";
|
||||
static inline const std::string TYPE_NAME = "typeName";
|
||||
static inline const std::string IS_ROOT = "isRoot";
|
||||
static inline const std::string KIND = "kind";
|
||||
static inline const std::string ABC_ID = "abcId";
|
||||
static inline const std::string ID = "id";
|
||||
};
|
||||
|
||||
class ApNameUtils {
|
||||
public:
|
||||
static const std::string AP_SUFFIX;
|
||||
|
@ -74,6 +74,12 @@ public:
|
||||
using IsRootBits = KindBits::NextFlag; // 50
|
||||
using EverOutOfBoundsBits = IsRootBits::NextFlag; // 51
|
||||
|
||||
using StringMap = std::multimap<std::string, std::string>;
|
||||
using MapVector = std::vector<std::vector<StringMap>>;
|
||||
using VariantVector = std::vector<std::variant<StringMap, MapVector, std::vector<StringMap>>>;
|
||||
using VariantMap = std::multimap<std::string, std::variant<std::string, VariantVector>>;
|
||||
using jModuleType = std::multimap<std::string, std::variant<std::string, std::vector<VariantMap>>>;
|
||||
|
||||
class BuiltinsId {
|
||||
public:
|
||||
static constexpr uint32_t BUILTINS_ID_NUM = 16;
|
||||
@ -98,6 +104,15 @@ public:
|
||||
return BuiltinsIdBits::Decode(id_);
|
||||
}
|
||||
|
||||
virtual std::string GetIdToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "(";
|
||||
ss << GetId();
|
||||
ss << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t id_ { 0 };
|
||||
};
|
||||
@ -134,6 +149,17 @@ public:
|
||||
{
|
||||
return NewElementsKindBits::Decode(id_);
|
||||
}
|
||||
|
||||
std::string GetIdToString() const override
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "(";
|
||||
ss << static_cast<uint32_t>(BuiltinsId::GetBuiltinsId()) << ", ";
|
||||
ss << static_cast<uint32_t>(GetElementsKind()) << ", ";
|
||||
ss << static_cast<uint32_t>(GetTransitionElementsKind());
|
||||
ss << ")";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
class BuiltinsTypedArrayId : public BuiltinsId {
|
||||
@ -155,6 +181,19 @@ public:
|
||||
{
|
||||
return OnHeapModeBits::Decode(id_);
|
||||
}
|
||||
|
||||
std::string GetIdToString() const override
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "(";
|
||||
ss << static_cast<uint32_t>(BuiltinsId::GetBuiltinsId()) << ", ";
|
||||
auto builtinsArrayId = BuiltinsArrayId(GetId());
|
||||
ss << static_cast<uint32_t>(builtinsArrayId.GetElementsKind()) << ", ";
|
||||
ss << static_cast<uint32_t>(builtinsArrayId.GetTransitionElementsKind()) << ", ";
|
||||
ss << static_cast<uint32_t>(GetOnHeapMode());
|
||||
ss << ")";
|
||||
return ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(KindBits::IsValid(Kind::TotalKinds));
|
||||
@ -367,6 +406,25 @@ public:
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
void GetTypeJson(StringMap &type) const
|
||||
{
|
||||
type.insert(std::make_pair(DumpJsonUtils::IS_ROOT, IsRootType() ? "true" : "false"));
|
||||
type.insert(std::make_pair(DumpJsonUtils::KIND, std::to_string(static_cast<double>(GetKind()))));
|
||||
type.insert(std::make_pair(DumpJsonUtils::ABC_ID, std::to_string(GetAbcId())));
|
||||
std::string strId;
|
||||
if (IsBuiltinsArray()) {
|
||||
auto arrayId = BuiltinsArrayId(GetId());
|
||||
strId = arrayId.GetIdToString();
|
||||
} else if (IsBuiltinsTypeArray()) {
|
||||
auto typedArrayId = BuiltinsTypedArrayId(GetId());
|
||||
strId = typedArrayId.GetIdToString();
|
||||
} else {
|
||||
auto builtinsId = BuiltinsId(GetId());
|
||||
strId = builtinsId.GetIdToString();
|
||||
}
|
||||
type.insert(std::make_pair(DumpJsonUtils::ID, strId));
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const ProfileType& type)
|
||||
{
|
||||
os << type.GetTypeString();
|
||||
|
@ -248,6 +248,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void GetTypeJson(ProfileType::StringMap &type) const
|
||||
{
|
||||
if (IsPrimitiveType()) {
|
||||
type.insert(std::make_pair(DumpJsonUtils::TYPE_NAME,
|
||||
std::to_string(static_cast<uint32_t>(std::get<Type>(type_)))));
|
||||
} else {
|
||||
type.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, "Type"));
|
||||
std::get<PGOProfileType>(type_).GetTypeJson(type);
|
||||
}
|
||||
if (IsScalarOpType()) {
|
||||
if (!ToString().empty()) {
|
||||
type.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ToString() const
|
||||
{
|
||||
if (IsPrimitiveType()) {
|
||||
@ -284,12 +300,10 @@ public:
|
||||
case Type::ANY:
|
||||
return "any";
|
||||
default:
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
return "";
|
||||
}
|
||||
|
||||
bool IsProfileType() const
|
||||
@ -587,6 +601,28 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddTypeJson(const char *typeName, const T& type, std::string typeOffset,
|
||||
std::vector<ProfileType::StringMap> &typeArray) const
|
||||
{
|
||||
ProfileType::StringMap typeJson;
|
||||
typeJson.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, typeName));
|
||||
typeJson.insert(std::make_pair(DumpJsonUtils::TYPE_OFFSET, typeOffset));
|
||||
type.GetTypeJson(typeJson);
|
||||
typeArray.push_back(typeJson);
|
||||
}
|
||||
|
||||
void GetInfoJson(std::vector<ProfileType::StringMap> &typeArray, std::string typeoffset) const
|
||||
{
|
||||
AddTypeJson("receiverRootType", receiverRootType_, typeoffset, typeArray);
|
||||
AddTypeJson("receiverType", receiverType_, typeoffset, typeArray);
|
||||
AddTypeJson("holdRootType", holdRootType_, typeoffset, typeArray);
|
||||
AddTypeJson("holdType", holdType_, typeoffset, typeArray);
|
||||
AddTypeJson("holdTraRootType", holdTraRootType_, typeoffset, typeArray);
|
||||
AddTypeJson("holdTraType", holdTraType_, typeoffset, typeArray);
|
||||
AddTypeJson("accessorMethodType", accessorMethod_, typeoffset, typeArray);
|
||||
}
|
||||
|
||||
PGOProfileType GetProfileType() const
|
||||
{
|
||||
return receiverType_;
|
||||
@ -817,6 +853,25 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddTypeJson(const char *typeName, const T& type, std::string typeOffset,
|
||||
std::vector<ProfileType::StringMap> &sameOffsetTypeArray) const
|
||||
{
|
||||
ProfileType::StringMap typeJson;
|
||||
typeJson.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, typeName));
|
||||
typeJson.insert(std::make_pair(DumpJsonUtils::TYPE_NAME, typeOffset));
|
||||
type.GetTypeJson(typeJson);
|
||||
sameOffsetTypeArray.push_back(typeJson);
|
||||
}
|
||||
|
||||
void GetTypeJson(std::vector<ProfileType::StringMap> &sameOffsetTypeArray,
|
||||
std::string typeOffset) const
|
||||
{
|
||||
AddTypeJson("localType", type_, typeOffset, sameOffsetTypeArray);
|
||||
AddTypeJson("ctorType", ctorPt_, typeOffset, sameOffsetTypeArray);
|
||||
AddTypeJson("protoType", protoPt_, typeOffset, sameOffsetTypeArray);
|
||||
}
|
||||
|
||||
bool IsNone() const
|
||||
{
|
||||
return type_.IsNone();
|
||||
|
81
tools/ap_file_viewer/native/BUILD.gn
Normal file
81
tools/ap_file_viewer/native/BUILD.gn
Normal file
@ -0,0 +1,81 @@
|
||||
# Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//arkcompiler/ets_runtime/js_runtime_config.gni")
|
||||
|
||||
ohos_shared_library("profDumpJson") {
|
||||
deps = [ ":profDumpJsonStatic" ]
|
||||
part_name = "ets_runtime"
|
||||
subsystem_name = "arkcompiler"
|
||||
}
|
||||
|
||||
ohos_static_library("profDumpJsonStatic") {
|
||||
if (is_ohos && is_standard_system && current_toolchain != host_toolchain &&
|
||||
!ark_standalone_build) {
|
||||
sanitize = {
|
||||
ubsan = true
|
||||
}
|
||||
}
|
||||
sources = [ "src/prof_dump_json.cpp" ]
|
||||
include_dirs = [ "include" ]
|
||||
cflags = [ "-g" ]
|
||||
if (is_mingw) {
|
||||
defines = [ "PROF_DUMP_JSON_WINDOWS" ]
|
||||
}
|
||||
deps = [
|
||||
"$js_root:libark_js_intl_set",
|
||||
"$js_root:libark_jsruntime_set",
|
||||
"$js_root/ecmascript/compiler:libark_mock_stub_set",
|
||||
]
|
||||
external_deps = [
|
||||
"cJSON:cjson_static",
|
||||
"runtime_core:arkfile_header_deps",
|
||||
"runtime_core:libarkbase_static",
|
||||
"runtime_core:libarkfile_static",
|
||||
"zlib:libz",
|
||||
]
|
||||
if (target_os == "ios") {
|
||||
deps += [
|
||||
"$ark_third_party_root/icu/icu4c:static_icui18n",
|
||||
"$ark_third_party_root/icu/icu4c:static_icuuc",
|
||||
]
|
||||
} else {
|
||||
external_deps += [
|
||||
"icu:shared_icui18n",
|
||||
"icu:shared_icuuc",
|
||||
]
|
||||
}
|
||||
part_name = "ets_runtime"
|
||||
subsystem_name = "arkcompiler"
|
||||
}
|
||||
|
||||
ohos_executable("apViewer") {
|
||||
sources = [ "src/main.cpp" ]
|
||||
include_dirs = [ "include" ]
|
||||
deps = [ ":profDumpJson" ]
|
||||
configs = [
|
||||
"$js_root:ark_jsruntime_common_config",
|
||||
"$js_root:ark_jsruntime_public_config",
|
||||
]
|
||||
external_deps = [
|
||||
"bounds_checking_function:libsec_shared",
|
||||
"cJSON:cjson_static",
|
||||
]
|
||||
|
||||
# hiviewdfx libraries
|
||||
external_deps += hiviewdfx_ext_deps
|
||||
deps += hiviewdfx_deps
|
||||
|
||||
part_name = "ets_runtime"
|
||||
subsystem_name = "arkcompiler"
|
||||
}
|
172
tools/ap_file_viewer/native/include/prof_convert_json.h
Normal file
172
tools/ap_file_viewer/native/include/prof_convert_json.h
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NATIVE_CONVERT_JSON_H
|
||||
#define NATIVE_CONVERT_JSON_H
|
||||
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
|
||||
#include "third_party/cJSON/cJSON.h"
|
||||
|
||||
namespace native {
|
||||
using namespace panda::ecmascript::pgo;
|
||||
class JsonConverter {
|
||||
public:
|
||||
cJSON* ConvertStr(const std::vector<ProfileType::StringMap>& data) const
|
||||
{
|
||||
return HandleMapVector(data);
|
||||
}
|
||||
|
||||
cJSON* Convert(const std::vector<ProfileType::jModuleType>& data) const
|
||||
{
|
||||
cJSON* jsonArray = cJSON_CreateArray();
|
||||
if (jsonArray == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& complexMap : data) {
|
||||
cJSON* jsonObject = cJSON_CreateObject();
|
||||
if (jsonObject == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& [key, value] : complexMap) {
|
||||
cJSON* jsonValue = HandleVariant(value);
|
||||
if (jsonValue == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
cJSON_AddItemToObject(jsonObject, key.c_str(), jsonValue);
|
||||
}
|
||||
cJSON_AddItemToArray(jsonArray, jsonObject);
|
||||
}
|
||||
return jsonArray;
|
||||
}
|
||||
|
||||
private:
|
||||
cJSON* HandleVariant(const std::variant<std::string, std::vector<ProfileType::VariantMap>>& value) const
|
||||
{
|
||||
if (std::holds_alternative<std::string>(value)) {
|
||||
return cJSON_CreateString(std::get<std::string>(value).c_str());
|
||||
} else if (std::holds_alternative<std::vector<ProfileType::VariantMap>>(value)) {
|
||||
return HandleVariantMap(std::get<std::vector<ProfileType::VariantMap>>(value));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cJSON* HandleVariantMap(const std::vector<ProfileType::VariantMap>& vaMap) const
|
||||
{
|
||||
cJSON* jsonArray = cJSON_CreateArray();
|
||||
if (jsonArray == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& nestedItem : vaMap) {
|
||||
cJSON* mapObject = cJSON_CreateObject();
|
||||
if (mapObject == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& [key, value] : nestedItem) {
|
||||
cJSON* jsonValue = HandleVariantNext(value);
|
||||
if (jsonValue == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
cJSON_AddItemToObject(mapObject, key.c_str(), jsonValue);
|
||||
}
|
||||
cJSON_AddItemToArray(jsonArray, mapObject);
|
||||
}
|
||||
return jsonArray;
|
||||
}
|
||||
|
||||
cJSON* HandleVariantNext(const std::variant<std::string, ProfileType::VariantVector>& value) const
|
||||
{
|
||||
if (std::holds_alternative<std::string>(value)) {
|
||||
return cJSON_CreateString(std::get<std::string>(value).c_str());
|
||||
} else if (std::holds_alternative<ProfileType::VariantVector>(value)) {
|
||||
return HandleVariantVector(std::get<ProfileType::VariantVector>(value));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cJSON* HandleVariantVector(const ProfileType::VariantVector& vec) const
|
||||
{
|
||||
cJSON* jsonArray = cJSON_CreateArray();
|
||||
if (jsonArray == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& nestedItem : vec) {
|
||||
if (std::holds_alternative<ProfileType::StringMap>(nestedItem)) {
|
||||
cJSON* mapObject = HandleStringMap(std::get<ProfileType::StringMap>(nestedItem));
|
||||
cJSON_AddItemToArray(jsonArray, mapObject);
|
||||
} else if (std::holds_alternative<ProfileType::MapVector>(nestedItem)) {
|
||||
cJSON* innerInnerArray = HandleNestedMapVector(std::get<ProfileType::MapVector>(nestedItem));
|
||||
cJSON_AddItemToArray(jsonArray, innerInnerArray);
|
||||
} else if (std::holds_alternative<std::vector<ProfileType::StringMap>>(nestedItem)) {
|
||||
cJSON* arrayOfMaps = HandleMapVector(std::get<std::vector<ProfileType::StringMap>>(nestedItem));
|
||||
cJSON_AddItemToArray(jsonArray, arrayOfMaps);
|
||||
}
|
||||
}
|
||||
return jsonArray;
|
||||
}
|
||||
|
||||
cJSON* HandleStringMap(const ProfileType::StringMap& stringMap) const
|
||||
{
|
||||
cJSON* mapObject = cJSON_CreateObject();
|
||||
if (mapObject == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& [mapKey, mapValue] : stringMap) {
|
||||
cJSON_AddStringToObject(mapObject, mapKey.c_str(), mapValue.c_str());
|
||||
}
|
||||
return mapObject;
|
||||
}
|
||||
|
||||
cJSON* HandleMapVector(const std::vector<ProfileType::StringMap>& vecMap) const
|
||||
{
|
||||
cJSON* arrayOfMaps = cJSON_CreateArray();
|
||||
if (arrayOfMaps == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& stringMap : vecMap) {
|
||||
cJSON* mapObject = HandleStringMap(stringMap);
|
||||
if (mapObject == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
cJSON_AddItemToArray(arrayOfMaps, mapObject);
|
||||
}
|
||||
return arrayOfMaps;
|
||||
}
|
||||
|
||||
cJSON* HandleNestedMapVector(const ProfileType::MapVector& vecVec) const
|
||||
{
|
||||
cJSON* innerInnerArray = cJSON_CreateArray();
|
||||
if (innerInnerArray == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& vec1 : vecVec) {
|
||||
cJSON* innerArray = cJSON_CreateArray();
|
||||
if (innerArray == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
for (const auto& stringMap : vec1) {
|
||||
cJSON* mapObject = HandleStringMap(stringMap);
|
||||
if (mapObject == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
cJSON_AddItemToArray(innerArray, mapObject);
|
||||
}
|
||||
cJSON_AddItemToArray(innerInnerArray, innerArray);
|
||||
}
|
||||
return innerInnerArray;
|
||||
}
|
||||
};
|
||||
} // namespace native
|
||||
#endif // NATIVE_CONVERT_JSON_H
|
34
tools/ap_file_viewer/native/include/prof_dump_json.h
Normal file
34
tools/ap_file_viewer/native/include/prof_dump_json.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef NATIVE_PROF_DUMP_JSON_H
|
||||
#define NATIVE_PROF_DUMP_JSON_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define PROF_DUMP_JSON_API DUMP_PUBLIC_API
|
||||
#ifndef PROF_DUMP_JSON_WINDOWS
|
||||
#define DUMP_PUBLIC_API __attribute__((visibility ("default")))
|
||||
#else
|
||||
#define DUMP_PUBLIC_API __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
namespace native {
|
||||
extern "C" {
|
||||
PROF_DUMP_JSON_API size_t ConvertApToJson(const char *path, const size_t pathSize);
|
||||
PROF_DUMP_JSON_API bool GetConvertResult(char *buffer, size_t length);
|
||||
}
|
||||
} // namespace native
|
||||
#endif // NATIVE_PROF_DUMP_JSON_H
|
76
tools/ap_file_viewer/native/src/main.cpp
Normal file
76
tools/ap_file_viewer/native/src/main.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
#include "ecmascript/platform/file.h"
|
||||
#include "prof_dump_json.h"
|
||||
#include "securec.h"
|
||||
|
||||
static constexpr size_t OUTPUT_FILE_ARG = 2;
|
||||
static constexpr size_t ARGS_NUMBER = 3;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != ARGS_NUMBER) {
|
||||
std::cout << "please use this tools like:" << std::endl;
|
||||
std::cout << " ./apViewer input.ap out.json" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
std::string input = argv[1];
|
||||
std::string output = argv[OUTPUT_FILE_ARG];
|
||||
size_t length = native::ConvertApToJson(input.c_str(), input.length());
|
||||
if (length == 0 || length >= SIZE_MAX) {
|
||||
LOG_NO_TAG(ERROR) << "ConvertApToJson returned zero or invalid length!";
|
||||
return 0;
|
||||
}
|
||||
char *buffer = (char *)malloc(length);
|
||||
if (buffer == nullptr) {
|
||||
LOG_NO_TAG(ERROR) << "malloc buffer failed";
|
||||
return 0;
|
||||
}
|
||||
if (memset_s(buffer, length, 0, length) != EOK) {
|
||||
LOG_NO_TAG(ERROR) << "clean malloc buffer failed";
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto result = native::GetConvertResult(buffer, length);
|
||||
if (result) {
|
||||
std::cout << "convert " << argv[1] << " to " << argv[OUTPUT_FILE_ARG] << " success!" << std::endl;
|
||||
} else {
|
||||
std::cout << "convert " << argv[1] << " to " << argv[OUTPUT_FILE_ARG] << " failed!" << std::endl;
|
||||
}
|
||||
|
||||
std::string realOutPath;
|
||||
if (!panda::ecmascript::RealPath(output, realOutPath, false)) {
|
||||
LOG_NO_TAG(ERROR) << "Can not load filepath " << output;
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
std::ofstream outFile(realOutPath);
|
||||
if (!outFile.is_open()) {
|
||||
LOG_NO_TAG(ERROR) << "open " << realOutPath << " failed!";
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
std::string strRet(buffer, length);
|
||||
outFile << strRet;
|
||||
outFile.close();
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
86
tools/ap_file_viewer/native/src/prof_dump_json.cpp
Normal file
86
tools/ap_file_viewer/native/src/prof_dump_json.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "prof_dump_json.h"
|
||||
#include "prof_convert_json.h"
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_utils.h"
|
||||
|
||||
namespace native {
|
||||
using namespace panda::ecmascript::pgo;
|
||||
static std::string g_result = "";
|
||||
|
||||
size_t ConvertApToJson(const char *path, const size_t pathSize)
|
||||
{
|
||||
std::string apFilePath(path, pathSize);
|
||||
PGOProfilerDecoder decoder(apFilePath, 1);
|
||||
if (!decoder.LoadFull()) {
|
||||
return 0;
|
||||
}
|
||||
// parse recordDetailInofo
|
||||
std::vector<ProfileType::jModuleType> modules;
|
||||
auto recordDetailInfos = decoder.GetRecordDetailInfosPtr();
|
||||
auto recordInfos = recordDetailInfos->GetRecordInfos();
|
||||
auto recordPool = recordDetailInfos->GetRecordPool();
|
||||
for (auto iter = recordInfos.begin(); iter != recordInfos.end(); iter++) {
|
||||
std::string moduleName(recordPool->GetName(iter->first));
|
||||
if (moduleName.empty()) {
|
||||
continue;
|
||||
}
|
||||
ProfileType::jModuleType oneModule;
|
||||
oneModule.insert(std::make_pair(DumpJsonUtils::MODULE_NAME, moduleName));
|
||||
iter->second->ProcessToJson(1, oneModule);
|
||||
modules.push_back(oneModule);
|
||||
}
|
||||
// parse abcFilePool
|
||||
cJSON *allMessage = cJSON_CreateObject();
|
||||
if (allMessage == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
JsonConverter convert;
|
||||
cJSON* recordDetailInofo = convert.Convert(modules);
|
||||
cJSON_AddItemToObject(allMessage, DumpJsonUtils::RECORD_DETAIL.c_str(), recordDetailInofo);
|
||||
|
||||
std::vector<ProfileType::StringMap> abcFilePoolMessage;
|
||||
decoder.GetAbcFilePool()->GetPool()->ProcessToJson(abcFilePoolMessage);
|
||||
cJSON* abcFilePool = convert.ConvertStr(abcFilePoolMessage);
|
||||
cJSON_AddItemToObject(allMessage, DumpJsonUtils::ABC_FILE_POOL.c_str(), abcFilePool);
|
||||
|
||||
char *data = cJSON_PrintUnformatted(allMessage);
|
||||
if (data == nullptr) {
|
||||
cJSON_Delete(allMessage);
|
||||
LOG_NO_TAG(ERROR) << "Failed to convert cJSON object to string";
|
||||
return 0;
|
||||
}
|
||||
g_result = std::string(data);
|
||||
cJSON_Delete(allMessage);
|
||||
cJSON_free(data);
|
||||
return g_result.length();
|
||||
}
|
||||
|
||||
bool GetConvertResult(char* buffer, size_t length)
|
||||
{
|
||||
if (!g_result.empty()) {
|
||||
if (memcpy_s(buffer, length, g_result.c_str(), g_result.length()) != EOK) {
|
||||
return false;
|
||||
}
|
||||
g_result.clear();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace native
|
Loading…
Reference in New Issue
Block a user