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:
yp9522 2024-06-19 16:44:32 +08:00
parent 3fc00939c4
commit 0198dd8364
17 changed files with 684 additions and 8 deletions

View File

@ -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 = [

View File

@ -49,7 +49,8 @@
"samgr",
"common_event_service",
"power_manager",
"ffrt"
"ffrt",
"cJSON"
],
"third_party": [
]

View File

@ -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;

View File

@ -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();

View File

@ -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

View File

@ -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_;

View File

@ -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
{

View File

@ -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();

View File

@ -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_;

View File

@ -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;

View File

@ -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();

View File

@ -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();

View 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"
}

View 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

View 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

View 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;
}

View 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