!7417 change AOT escape code macros

Merge pull request !7417 from herongpeng/aot_escape_marcros

Change-Id: I596cc858805899b3c1db64af34edd1afd98bc2c8
This commit is contained in:
openharmony_ci 2024-05-18 02:07:27 +00:00 committed by h30044958
commit 6771b034cd
13 changed files with 430 additions and 269 deletions

View File

@ -28,6 +28,7 @@
#include "ecmascript/log.h"
#include "ecmascript/log_wrapper.h"
#include "ecmascript/napi/include/jsnapi.h"
#include "ecmascript/ohos/enable_aot_list_helper.h"
#include "ecmascript/ohos/ohos_pkg_args.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/platform/os.h"
@ -220,6 +221,7 @@ int Main(const int argc, const char **argv)
if (runtimeOptions.IsTargetCompilerMode()) {
compilerStats.PrintCompilerStatsLog();
}
ohos::EnableAotListHelper::GetInstance()->AddEnableListCount(cPreprocessor.GetMainPkgArgs()->GetPgoDir());
}
LOG_COMPILER(INFO) << (ret ? "ts aot compile success" : "ts aot compile failed");

View File

@ -24,6 +24,7 @@
#include "ecmascript/jspandafile/program_object.h"
#include "ecmascript/mem/heap-inl.h"
#include "ecmascript/message_string.h"
#include "ecmascript/ohos/aot_runtime_info.h"
#include "ecmascript/platform/os.h"
#if defined(PANDA_TARGET_OHOS)
#include "ecmascript/extractortool/src/extractor.h"
@ -34,10 +35,6 @@
namespace panda::ecmascript {
[[maybe_unused]] static bool g_needCheck = true;
const int USEC_PER_SEC = 1000 * 1000;
const int NSEC_PER_USEC = 1000;
std::unordered_map<EntityId, std::string> JsStackInfo::nameMap;
std::string JsStackInfo::BuildMethodTrace(Method *method, uint32_t pcOffset, bool enableStackSourceFile)
@ -147,60 +144,22 @@ std::string JsStackInfo::BuildJsStackTrace(JSThread *thread, bool needNative)
return data;
}
uint64_t GetMicrosecondsTimeStamp()
{
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return time.tv_sec * USEC_PER_SEC + time.tv_nsec / NSEC_PER_USEC;
}
void JsStackInfo::BuildCrashInfo(bool isJsCrash, uintptr_t pc)
{
if (JsStackInfo::loader != nullptr && !JsStackInfo::loader->IsEnableAOT() &&
JsStackInfo::options != nullptr && !JsStackInfo::options->IsEnableJIT()) {
return;
}
std::string realOutPath;
std::string sanboxPath = panda::os::file::File::GetExtendedFilePath(ohos::AotCrashInfo::GetSandBoxPath());
if (!ecmascript::RealPath(sanboxPath, realOutPath, false)) {
return;
}
uint64_t timestamp = GetMicrosecondsTimeStamp();
ohos::AotCrashInfo aotCrashInfo;
std::string soBuildId = aotCrashInfo.GetRuntimeBuildId();
if (soBuildId == "") {
LOG_ECMA(ERROR) << "can't get so buildId";
return;
}
realOutPath = realOutPath + "/" + ohos::AotCrashInfo::GetCrashFileName();
std::ifstream ifile(realOutPath.c_str());
std::vector<std::string> lines;
if (ifile.is_open()) {
std::string iline;
while (ifile >> iline) {
std::string buildId = ohos::AotCrashInfo::GetBuildId(iline);
if (buildId != soBuildId) {
continue;
}
lines.emplace_back(iline);
}
ifile.close();
}
ohos::CrashType type;
ohos::RuntimeInfoType type;
if (isJsCrash) {
type = ohos::CrashType::JS;
type = ohos::RuntimeInfoType::JS;
} else if (pc != 0 && JsStackInfo::loader != nullptr && JsStackInfo::loader->InsideAOT(pc)) {
type = ohos::CrashType::AOT;
type = ohos::RuntimeInfoType::AOT;
} else {
type = ohos::CrashType::OTHERS;
type = ohos::RuntimeInfoType::OTHERS;
}
std::string buildLine = ohos::AotCrashInfo::BuildAotCrashInfo(soBuildId, std::to_string(timestamp), type);
lines.emplace_back(buildLine);
std::ofstream file(realOutPath.c_str(), std::ofstream::out);
for (const std::string& line : lines) {
file << line << "\n";
}
file.close();
ohos::AotRuntimeInfo aotRuntimeInfo;
aotRuntimeInfo.BuildCrashRuntimeInfo(ohos::AotRuntimeInfo::GetRuntimeInfoTypeStr(type));
}
std::vector<struct JsFrameInfo> JsStackInfo::BuildJsStackInfo(JSThread *thread, bool currentStack)

View File

@ -19,7 +19,6 @@
#include <csignal>
#include "ecmascript/compiler/aot_file/aot_file_manager.h"
#include "ecmascript/extractortool/src/source_map.h"
#include "ecmascript/ohos/aot_crash_info.h"
#include "ecmascript/js_thread.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/dfx/dump_code/jit_dump_elf.h"
@ -165,7 +164,6 @@ public:
static std::unordered_map<EntityId, std::string> nameMap;
};
void CrashCallback(char *buf, size_t len, void *ucontext);
uint64_t GetMicrosecondsTimeStamp();
} // namespace panda::ecmascript
#endif // ECMASCRIPT_DFX_STACKINFO_JS_STACKINFO_H
extern "C" int step_ark_managed_native_frame(

View File

@ -231,8 +231,13 @@ void EcmaVM::PostFork()
} else if (ohos::EnableAotListHelper::GetInstance()->IsEnableList(bundleName)) {
options_.SetEnablePGOProfiler(true);
}
if (ohos::EnableAotListHelper::GetInstance()->IsAotCompileSuccessOnce()) {
options_.SetEnablePGOProfiler(false);
LOG_ECMA(INFO) << "Aot has compile success once.";
}
if (JSNApi::IsAotEscape()) {
options_.SetEnablePGOProfiler(false);
LOG_ECMA(INFO) << "Aot has escaped.";
}
ResetPGOProfiler();

View File

@ -93,6 +93,7 @@
#include "ecmascript/js_weak_container.h"
#include "ecmascript/ohos/aot_crash_info.h"
#include "ecmascript/ohos/framework_helper.h"
#include "ecmascript/ohos/aot_runtime_info.h"
#ifdef ARK_SUPPORT_INTL
#include "ecmascript/js_bigint.h"
#include "ecmascript/js_collator.h"
@ -199,7 +200,6 @@ using JsDebuggerManager = ecmascript::tooling::JsDebuggerManager;
using FrameIterator = ecmascript::FrameIterator;
using Concurrent = ecmascript::Concurrent;
using CrashInfo = ecmascript::ohos::AotCrashInfo;
using CrashType = ecmascript::ohos::CrashType;
namespace {
// NOLINTNEXTLINE(fuchsia-statically-constructed-objects)
@ -4268,51 +4268,26 @@ bool JSNApi::KeyIsNumber(const char* utf8)
return true;
}
std::map<CrashType, int> CollectCrashSum()
{
std::map<CrashType, int> escapeMap;
std::string realOutPath;
std::string arkProfilePath = CrashInfo::GetSandBoxPath();
std::string sanboxPath = panda::os::file::File::GetExtendedFilePath(arkProfilePath);
if (!ecmascript::RealPath(sanboxPath, realOutPath, false)) {
return escapeMap;
}
realOutPath = realOutPath + "/" + CrashInfo::GetCrashFileName();
CrashInfo aotCrashInfo;
std::string soBuildId = aotCrashInfo.GetRuntimeBuildId();
std::ifstream ifile(realOutPath.c_str());
if (ifile.is_open()) {
std::string iline;
while (ifile >> iline) {
std::string buildId = CrashInfo::GetBuildId(iline);
CrashType type = CrashInfo::GetCrashType(iline);
if (buildId == soBuildId) {
escapeMap[type]++;
}
}
ifile.close();
}
return escapeMap;
}
bool JSNApi::IsAotEscape()
{
if (CrashInfo::GetAotEscapeDisable()) {
return false;
}
auto escapeMap = CollectCrashSum();
return escapeMap[CrashType::AOT] >= CrashInfo::GetAotCrashCount() ||
escapeMap[CrashType::OTHERS] >= CrashInfo::GetOthersCrashCount() ||
escapeMap[CrashType::JS] >= CrashInfo::GetJsCrashCount();
ecmascript::ohos::AotRuntimeInfo aotRuntimeInfo;
auto escapeMap = aotRuntimeInfo.CollectCrashSum();
return escapeMap[ecmascript::ohos::RuntimeInfoType::AOT] >= CrashInfo::GetAotCrashCount() ||
escapeMap[ecmascript::ohos::RuntimeInfoType::OTHERS] >= CrashInfo::GetOthersCrashCount() ||
escapeMap[ecmascript::ohos::RuntimeInfoType::JS] >= CrashInfo::GetJsCrashCount();
}
bool JSNApi::IsJitEscape()
{
auto escapeMap = CollectCrashSum();
return escapeMap[CrashType::JIT] >= CrashInfo::GetJitCrashCount() ||
escapeMap[CrashType::AOT] >= CrashInfo::GetAotCrashCount() ||
escapeMap[CrashType::OTHERS] >= CrashInfo::GetOthersCrashCount() ||
escapeMap[CrashType::JS] >= CrashInfo::GetJsCrashCount();
ecmascript::ohos::AotRuntimeInfo aotRuntimeInfo;
auto escapeMap = aotRuntimeInfo.CollectCrashSum();
return escapeMap[ecmascript::ohos::RuntimeInfoType::JIT] >= CrashInfo::GetJitCrashCount() ||
escapeMap[ecmascript::ohos::RuntimeInfoType::AOT] >= CrashInfo::GetAotCrashCount() ||
escapeMap[ecmascript::ohos::RuntimeInfoType::OTHERS] >= CrashInfo::GetOthersCrashCount() ||
escapeMap[ecmascript::ohos::RuntimeInfoType::JS] >= CrashInfo::GetJsCrashCount();
}
bool JSNApi::IsSerializationTimeoutCheckEnabled(const EcmaVM *vm)

View File

@ -16,36 +16,20 @@
#ifndef ECMASCRIPT_COMPILER_OHOS_AOT_CRASH_INFO_H
#define ECMASCRIPT_COMPILER_OHOS_AOT_CRASH_INFO_H
#include "ohos_constants.h"
#include "ecmascript/base/string_helper.h"
#if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
#ifdef AOT_ESCAPE_ENABLE
#include "parameters.h"
#endif
namespace panda::ecmascript::ohos {
#define CRASH_TYPE(V) \
V(AOT) \
V(OTHERS) \
V(NONE) \
V(JIT) \
V(JS) \
enum class CrashType {
AOT,
JIT,
OTHERS,
NONE,
JS,
};
class AotCrashInfo {
constexpr static const char *const SANDBOX_ARK_PROFILE_PATH = "/data/storage/ark-profile";
constexpr static const char *const CRASH_FILE_NAME = "aot_crash.log";
constexpr static const char *const RUNTIME_SO_PATH = "/system/lib64/platformsdk/libark_jsruntime.so";
constexpr static const char *const SPLIT_STR = "|";
constexpr static const char *const AOT_ESCAPE_DISABLE = "ark.aot.escape.disable";
constexpr static int AOT_CRASH_COUNT = 1;
constexpr static int OTHERS_CRASH_COUNT = 3;
constexpr static int CRASH_LOG_SIZE = 3;
constexpr static int NT_GNU_BUILD_ID = 3;
constexpr static int JIT_CRASH_COUNT = 1;
constexpr static int JS_CRASH_COUNT = 3;
public:
@ -53,26 +37,9 @@ public:
explicit AotCrashInfo() = default;
virtual ~AotCrashInfo() = default;
static CrashType GetCrashType(std::string crashInfo)
{
std::vector<std::string> splitCrashInfo = base::StringHelper::SplitString(crashInfo, SPLIT_STR);
if (splitCrashInfo.size() == CRASH_LOG_SIZE) {
if (splitCrashInfo[CRASH_LOG_SIZE - 1] == GetCrashTypeStr(CrashType::AOT)) {
return CrashType::AOT;
} else if (splitCrashInfo[CRASH_LOG_SIZE - 1] == GetCrashTypeStr(CrashType::JIT)) {
return CrashType::JIT;
} else if (splitCrashInfo[CRASH_LOG_SIZE - 1] == GetCrashTypeStr(CrashType::JS)) {
return CrashType::JS;
} else if (splitCrashInfo[CRASH_LOG_SIZE - 1] == GetCrashTypeStr(CrashType::OTHERS)) {
return CrashType::OTHERS;
}
}
return CrashType::NONE;
}
static bool GetAotEscapeDisable()
{
#if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
#ifdef AOT_ESCAPE_ENABLE
return OHOS::system::GetBoolParameter(AOT_ESCAPE_DISABLE, false);
#endif
return false;
@ -80,7 +47,7 @@ public:
static std::string GetSandBoxPath()
{
return SANDBOX_ARK_PROFILE_PATH;
return OhosConstants::SANDBOX_ARK_PROFILE_PATH;
}
static std::string GetCrashFileName()
@ -107,150 +74,6 @@ public:
{
return OTHERS_CRASH_COUNT;
}
static std::string GetCrashTypeStr(CrashType type)
{
const std::map<CrashType, const char *> strMap = {
#define CRASH_TYPE_MAP(name) { CrashType::name, #name },
CRASH_TYPE(CRASH_TYPE_MAP)
#undef CRASH_TYPE_MAP
};
if (strMap.count(type) > 0) {
return strMap.at(type);
}
return "";
}
static CrashType GetCrashTypeByStr(std::string crashType)
{
const std::map<std::string, CrashType> strMap = {
#define CRASH_TYPE_MAP(name) { #name, CrashType::name },
CRASH_TYPE(CRASH_TYPE_MAP)
#undef CRASH_TYPE_MAP
};
if (strMap.count(crashType) > 0) {
return strMap.at(crashType);
}
return CrashType::NONE;
}
static std::string BuildAotCrashInfo(std::string buildId, std::string timestamp, CrashType type)
{
return buildId + SPLIT_STR + timestamp + SPLIT_STR + GetCrashTypeStr(type);
}
static std::string GetBuildId(std::string crashInfo)
{
std::vector<std::string> splitCrashInfo = base::StringHelper::SplitString(crashInfo, SPLIT_STR);
if (splitCrashInfo.size() == CRASH_LOG_SIZE) {
return splitCrashInfo[0];
}
return "";
}
std::string GetRuntimeBuildId()
{
std::string realPath;
if (!FileExist(RUNTIME_SO_PATH)) {
return "";
}
std::string soPath = panda::os::file::File::GetExtendedFilePath(RUNTIME_SO_PATH);
if (!ecmascript::RealPath(soPath, realPath, false)) {
return "";
}
if (!FileExist(realPath.c_str())) {
return "";
}
fileMap = ecmascript::FileMap(realPath.c_str(), FILE_RDONLY, PAGE_PROT_READ);
if (fileMap.GetOriginAddr() == nullptr) {
return "";
}
ecmascript::PagePreRead(fileMap.GetOriginAddr(), fileMap.GetSize());
return ParseELFSectionsForBuildId();
}
private:
std::string GetReadableBuildId(std::string &buildIdHex)
{
if (buildIdHex.empty()) {
return "";
}
static const char HEXTABLE[] = "0123456789abcdef";
static const int HEXLENGTH = 16;
static const int HEX_EXPAND_PARAM = 2;
const size_t len = buildIdHex.length();
std::string buildId(len * HEX_EXPAND_PARAM, '\0');
for (size_t i = 0; i < len; i++) {
unsigned int n = buildIdHex[i];
buildId[i * HEX_EXPAND_PARAM] = HEXTABLE[(n >> 4) % HEXLENGTH]; // 4 : higher 4 bit of uint8
buildId[i * HEX_EXPAND_PARAM + 1] = HEXTABLE[n % HEXLENGTH];
}
return buildId;
}
uint64_t AlignValues(uint64_t val, uint64_t align)
{
return (val + AlignBytes(align)) & AlignMask(align);
}
uint64_t AlignMask(uint64_t align)
{
return ~(static_cast<uint64_t>((align) - 1));
}
uint64_t AlignBytes(uint64_t align)
{
return (align) - 1;
}
std::string ParseELFSectionsForBuildId()
{
llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMap.GetOriginAddr());
char *addr = reinterpret_cast<char *>(ehdr);
llvm::ELF::Elf64_Shdr *shdr = reinterpret_cast<llvm::ELF::Elf64_Shdr *>(addr + ehdr->e_shoff);
ASSERT(ehdr->e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
llvm::ELF::Elf64_Shdr strdr = shdr[ehdr->e_shstrndx];
int secId = -1;
std::string sectionName = ".note.gnu.build-id";
for (size_t i = 0; i < ehdr->e_shnum; i++) {
llvm::ELF::Elf64_Word shName = shdr[i].sh_name;
char *curShName = reinterpret_cast<char *>(addr) + shName + strdr.sh_offset;
if (sectionName.compare(curShName) == 0) {
secId = static_cast<int>(i);
break;
}
}
if (secId == -1) {
return "";
}
llvm::ELF::Elf64_Shdr secShdr = shdr[secId];
uint64_t buildIdOffset = secShdr.sh_offset;
uint64_t buildIdSize = secShdr.sh_size;
llvm::ELF::Elf64_Nhdr *nhdr = reinterpret_cast<llvm::ELF::Elf64_Nhdr *>(addr + buildIdOffset);
char *curShNameForNhdr = reinterpret_cast<char *>(addr + buildIdOffset + sizeof(*nhdr));
if (buildIdSize - sizeof(*nhdr) < nhdr->n_namesz) {
return "";
}
std::string curShNameStr = curShNameForNhdr;
if (curShNameStr.back() == '\0') {
curShNameStr.resize(curShNameStr.size() - 1);
}
if (curShNameStr != "GNU" || nhdr->n_type != NT_GNU_BUILD_ID) {
return "";
}
if (buildIdSize - sizeof(*nhdr) - AlignValues(nhdr->n_namesz, 4) < nhdr->n_descsz || nhdr->n_descsz == 0) {
return "";
}
char *curShNameValueForNhdr = reinterpret_cast<char *>(addr + buildIdOffset + sizeof(*nhdr)
+ AlignValues(nhdr->n_namesz, 4));
std::string curShNameValueForNhdrStr = curShNameValueForNhdr;
return GetReadableBuildId(curShNameValueForNhdrStr);
}
ecmascript::MemMap fileMap;
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_COMPILER_OHOS_AOT_CRASH_INFO_H

View File

@ -0,0 +1,330 @@
/*
* 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 ECMASCRIPT_COMPILER_OHOS_RUNTIME_BUILD_INFO_H
#define ECMASCRIPT_COMPILER_OHOS_RUNTIME_BUILD_INFO_H
#include <sys/time.h>
#include "ecmascript/platform/directory.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/platform/map.h"
#include "ecmascript/ohos/aot_crash_info.h"
#include "libpandafile/file.h"
#include "llvm/BinaryFormat/ELF.h"
#include "ohos_constants.h"
namespace panda::ecmascript::ohos {
#define RUNTIME_INFO_TYPE(V) \
V(AOT) \
V(OTHERS) \
V(NONE) \
V(JIT) \
V(JS) \
V(AOT_BUILD) \
enum class RuntimeInfoType {
AOT,
JIT,
OTHERS,
NONE,
JS,
AOT_BUILD,
};
class AotRuntimeInfo {
public:
constexpr static const int USEC_PER_SEC = 1000 * 1000;
constexpr static const int NSEC_PER_USEC = 1000;
constexpr static const int NT_GNU_BUILD_ID = 3;
constexpr static const int CRASH_INFO_SIZE = 3;
uint64_t GetMicrosecondsTimeStamp() const
{
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return time.tv_sec * USEC_PER_SEC + time.tv_nsec / NSEC_PER_USEC;
}
std::string BuildSingleInfo(const std::string &buildId, const std::string &timestamp, const std::string &type) const
{
return buildId + OhosConstants::SPLIT_STR + timestamp + OhosConstants::SPLIT_STR + type;
}
std::vector<std::string> GetCrashRuntimeInfoList(const std::string &soBuildId) const
{
std::string realOutPath = GetCrashSandBoxRealPath();
std::vector<std::string> list;
if (realOutPath == "") {
LOG_ECMA(INFO) << "Get crash sanbox path fail.";
return list;
}
list = GetRuntimeInfoByPath(realOutPath, soBuildId);
return list;
}
void BuildCompileRuntimeInfo(const std::string &type, const std::string &pgoPath)
{
std::string soBuildId = GetRuntimeBuildId();
if (soBuildId == "") {
LOG_ECMA(INFO) << "can't get so buildId.";
return;
}
std::string realOutPath;
std::string runtimePgoRealPath = pgoPath + OhosConstants::PATH_SEPARATOR + OhosConstants::AOT_RUNTIME_INFO_NAME;
if (!ecmascript::RealPath(runtimePgoRealPath, realOutPath, false)) {
LOG_ECMA(INFO) << "Build compile pgo path fail.";
return;
}
std::vector<std::string> lines = GetRuntimeInfoByPath(realOutPath, soBuildId);
uint64_t timestamp = GetMicrosecondsTimeStamp();
std::string buildLine = BuildSingleInfo(soBuildId, std::to_string(timestamp), type);
lines.emplace_back(buildLine);
SetRuntimeInfo(realOutPath, lines);
}
void BuildCrashRuntimeInfo(const std::string &type)
{
std::string soBuildId = GetRuntimeBuildId();
if (soBuildId == "") {
LOG_ECMA(INFO) << "can't get so buildId.";
return;
}
std::vector<std::string> lines = GetCrashRuntimeInfoList(soBuildId);
uint64_t timestamp = GetMicrosecondsTimeStamp();
std::string buildLine = BuildSingleInfo(soBuildId, std::to_string(timestamp), type);
lines.emplace_back(buildLine);
std::string realOutPath = GetCrashSandBoxRealPath();
if (realOutPath == "") {
LOG_ECMA(INFO) << "Get crash sanbox path fail.";
return;
}
SetRuntimeInfo(realOutPath, lines);
}
int GetCompileCountByType(RuntimeInfoType type)
{
std::map<RuntimeInfoType, int> escapeMap = CollectCrashSum();
if (escapeMap.count(type) == 0) {
return 0;
}
return escapeMap[type];
}
std::map<RuntimeInfoType, int> CollectCrashSum()
{
std::map<RuntimeInfoType, int> escapeMap;
std::string soBuildId = GetRuntimeBuildId();
if (soBuildId == "") {
LOG_ECMA(INFO) << "can't get so buildId.";
return escapeMap;
}
std::vector<std::string> lines = GetCrashRuntimeInfoList(soBuildId);
for (const std::string &line: lines) {
std::string type = GetType(line);
RuntimeInfoType runtimeInfoType = GetRuntimeInfoTypeByStr(type);
escapeMap[runtimeInfoType]++;
}
return escapeMap;
}
std::string GetRuntimeBuildId()
{
std::string realPath;
if (!FileExist(OhosConstants::RUNTIME_SO_PATH)) {
return "";
}
std::string soPath = panda::os::file::File::GetExtendedFilePath(OhosConstants::RUNTIME_SO_PATH);
if (!ecmascript::RealPath(soPath, realPath, false)) {
return "";
}
if (!FileExist(realPath.c_str())) {
return "";
}
fileMap = ecmascript::FileMap(realPath.c_str(), FILE_RDONLY, PAGE_PROT_READ);
if (fileMap.GetOriginAddr() == nullptr) {
return "";
}
ecmascript::PagePreRead(fileMap.GetOriginAddr(), fileMap.GetSize());
return ParseELFSectionsForBuildId();
}
static std::string GetRuntimeInfoTypeStr(RuntimeInfoType type)
{
const std::map<RuntimeInfoType, const char *> strMap = {
#define RUNTIME_INFO_TYPE_MAP(name) { RuntimeInfoType::name, #name },
RUNTIME_INFO_TYPE(RUNTIME_INFO_TYPE_MAP)
#undef RUNTIME_INFO_TYPE_MAP
};
if (strMap.count(type) > 0) {
return strMap.at(type);
}
return "";
}
static RuntimeInfoType GetRuntimeInfoTypeByStr(std::string type)
{
const std::map<std::string, RuntimeInfoType> strMap = {
#define RUNTIME_INFO_TYPE_MAP(name) { #name, RuntimeInfoType::name },
RUNTIME_INFO_TYPE(RUNTIME_INFO_TYPE_MAP)
#undef RUNTIME_INFO_TYPE_MAP
};
if (strMap.count(type) > 0) {
return strMap.at(type);
}
return RuntimeInfoType::NONE;
}
private:
void SetRuntimeInfo(const std::string &realOutPath, std::vector<std::string> lines) const
{
std::ofstream file(realOutPath.c_str(), std::ofstream::out);
for (const std::string &line: lines) {
file << line << "\n";
}
file.close();
}
std::vector<std::string> GetRuntimeInfoByPath(const std::string &realOutPath, const std::string &soBuildId) const
{
std::ifstream ifile(realOutPath.c_str());
std::vector<std::string> lines;
if (ifile.is_open()) {
std::string iline;
while (ifile >> iline) {
std::string buildId = GetBuildId(iline);
if (buildId != soBuildId) {
continue;
}
lines.emplace_back(iline);
}
ifile.close();
}
return lines;
}
std::string GetBuildId(std::string crashInfo) const
{
std::vector<std::string> splitCrashInfo = base::StringHelper::SplitString(crashInfo, OhosConstants::SPLIT_STR);
if (splitCrashInfo.size() == CRASH_INFO_SIZE) {
return splitCrashInfo[0];
}
return "";
}
std::string GetType(std::string crashInfo) const
{
std::vector<std::string> splitCrashInfo = base::StringHelper::SplitString(crashInfo, OhosConstants::SPLIT_STR);
if (splitCrashInfo.size() == CRASH_INFO_SIZE) {
return splitCrashInfo[2];
}
return "";
}
std::string GetCrashSandBoxRealPath() const
{
std::string realOutPath;
std::string arkProfilePath = AotCrashInfo::GetSandBoxPath();
std::string sanboxPath = panda::os::file::File::GetExtendedFilePath(arkProfilePath);
if (!ecmascript::RealPath(sanboxPath, realOutPath, false)) {
return "";
}
realOutPath = realOutPath + OhosConstants::PATH_SEPARATOR + OhosConstants::AOT_RUNTIME_INFO_NAME;
return realOutPath;
}
std::string ParseELFSectionsForBuildId() const
{
llvm::ELF::Elf64_Ehdr *ehdr = reinterpret_cast<llvm::ELF::Elf64_Ehdr *>(fileMap.GetOriginAddr());
char *addr = reinterpret_cast<char *>(ehdr);
llvm::ELF::Elf64_Shdr *shdr = reinterpret_cast<llvm::ELF::Elf64_Shdr *>(addr + ehdr->e_shoff);
ASSERT(ehdr->e_shstrndx != static_cast<llvm::ELF::Elf64_Half>(-1));
llvm::ELF::Elf64_Shdr strdr = shdr[ehdr->e_shstrndx];
int secId = -1;
std::string sectionName = ".note.gnu.build-id";
for (size_t i = 0; i < ehdr->e_shnum; i++) {
llvm::ELF::Elf64_Word shName = shdr[i].sh_name;
char *curShName = reinterpret_cast<char *>(addr) + shName + strdr.sh_offset;
if (sectionName.compare(curShName) == 0) {
secId = static_cast<int>(i);
break;
}
}
if (secId == -1) {
return "";
}
llvm::ELF::Elf64_Shdr secShdr = shdr[secId];
uint64_t buildIdOffset = secShdr.sh_offset;
uint64_t buildIdSize = secShdr.sh_size;
llvm::ELF::Elf64_Nhdr *nhdr = reinterpret_cast<llvm::ELF::Elf64_Nhdr *>(addr + buildIdOffset);
char *curShNameForNhdr = reinterpret_cast<char *>(addr + buildIdOffset + sizeof(*nhdr));
if (buildIdSize - sizeof(*nhdr) < nhdr->n_namesz) {
return "";
}
std::string curShNameStr = curShNameForNhdr;
if (curShNameStr.back() == '\0') {
curShNameStr.resize(curShNameStr.size() - 1);
}
if (curShNameStr != "GNU" || nhdr->n_type != NT_GNU_BUILD_ID) {
return "";
}
if ((buildIdSize - sizeof(*nhdr) - AlignValues(nhdr->n_namesz, 4) < nhdr->n_descsz) || nhdr->n_descsz == 0) {
return "";
}
char *curShNameValueForNhdr = reinterpret_cast<char *>(addr + buildIdOffset + sizeof(*nhdr) +
AlignValues(nhdr->n_namesz, 4));
std::string curShNameValueForNhdrStr = curShNameValueForNhdr;
return GetReadableBuildId(curShNameValueForNhdrStr);
}
std::string GetReadableBuildId(std::string &buildIdHex) const
{
if (buildIdHex.empty()) {
return "";
}
static const char HEXTABLE[] = "0123456789abcdef";
static const int HEXLENGTH = 16;
static const int HEX_EXPAND_PARAM = 2;
const size_t len = buildIdHex.length();
std::string buildId(len * HEX_EXPAND_PARAM, '\0');
for (size_t i = 0; i < len; i++) {
unsigned int n = buildIdHex[i];
buildId[i * HEX_EXPAND_PARAM] = HEXTABLE[(n >> 4) % HEXLENGTH]; // 4 : higher 4 bit of uint8
buildId[i * HEX_EXPAND_PARAM + 1] = HEXTABLE[n % HEXLENGTH];
}
return buildId;
}
uint64_t AlignValues(uint64_t val, uint64_t align) const
{
return (val + AlignBytes(align)) & AlignMask(align);
}
uint64_t AlignMask(uint64_t align) const
{
return ~(static_cast<uint64_t>((align) - 1));
}
uint64_t AlignBytes(uint64_t align) const
{
return (align) - 1;
}
ecmascript::MemMap fileMap;
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_COMPILER_OHOS_RUNTIME_BUILD_INFO_H

View File

@ -12,6 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.P
*/
#include "ecmascript/ohos/enable_aot_list_helper.h"
namespace panda::ecmascript::ohos {

View File

@ -22,11 +22,19 @@
#include <string>
#include <vector>
#include "ohos_constants.h"
#include "ecmascript/base/string_helper.h"
#include "ecmascript/log_wrapper.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/ohos/aot_runtime_info.h"
#include "macros.h"
#ifdef AOT_ESCAPE_ENABLE
#include "parameters.h"
#endif
namespace panda::ecmascript::ohos {
class EnableAotListHelper {
constexpr static const char *const AOT_BUILD_COUNT_DISABLE = "ark.aot.build.count.disable";
public:
static std::shared_ptr<EnableAotListHelper> GetInstance()
{
@ -102,9 +110,38 @@ public:
jitEnableList_.clear();
}
static bool GetAotBuildCountDisable()
{
#ifdef AOT_ESCAPE_ENABLE
return OHOS::system::GetBoolParameter(AOT_BUILD_COUNT_DISABLE, false);
#endif
return false;
}
void AddEnableListCount(const std::string &pgoPath) const
{
ohos::AotRuntimeInfo aotRuntimeInfo;
aotRuntimeInfo.BuildCompileRuntimeInfo(
ohos::AotRuntimeInfo::GetRuntimeInfoTypeStr(ohos::RuntimeInfoType::AOT_BUILD), pgoPath);
}
bool IsAotCompileSuccessOnce() const
{
if (GetAotBuildCountDisable()) {
return false;
}
ohos::AotRuntimeInfo aotRuntimeInfo;
int count = aotRuntimeInfo.GetCompileCountByType(ohos::RuntimeInfoType::AOT_BUILD);
if (count > 0) {
return true;
}
return false;
}
private:
NO_COPY_SEMANTIC(EnableAotListHelper);
NO_MOVE_SEMANTIC(EnableAotListHelper);
static void Trim(std::string &data)
{
if (data.empty()) {

View File

@ -0,0 +1,29 @@
/*
* 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 ECMASCRIPT_COMPILER_OHOS_CONSTANTS_H
#define ECMASCRIPT_COMPILER_OHOS_CONSTANTS_H
namespace panda::ecmascript::ohos {
namespace OhosConstants {
constexpr const char* SANDBOX_ARK_PROFILE_PATH = "/data/storage/ark-profile";
constexpr const char* ARM64 = "arm64";
constexpr const char* RUNTIME_SO_PATH = "/system/lib64/platformsdk/libark_jsruntime.so";
constexpr const char* PATH_SEPARATOR = "/";
constexpr const char* AOT_RUNTIME_INFO_NAME = "aot_runtime_info.log";
constexpr const char* SPLIT_STR = "|";
} // namespace OhosConstants
} // namespace panda::ecmascript::ohos
#endif // ECMASCRIPT_COMPILER_OHOS_CONSTANTS_H

View File

@ -86,7 +86,7 @@ void PUBLIC_API PageUnmap(MemMap it);
MemMap PUBLIC_API MachineCodePageMap(size_t size, int prot = PAGE_PROT_NONE, size_t alignment = 0);
void PUBLIC_API MachineCodePageUnmap(MemMap it);
void PageRelease(void *mem, size_t size);
void PagePreRead(void *mem, size_t size);
void PUBLIC_API PagePreRead(void *mem, size_t size);
void PageTag(void *mem, size_t size, PageTagType type, const std::string &spaceName = EMPTY_STRING,
const uint32_t threadId = 0);
void PageClearTag(void *mem, size_t size);

View File

@ -228,6 +228,7 @@ template("libark_jsruntime_common_set") {
defines += [
"GET_PARAMETER_FOR_JIT",
"JIT_ESCAPE_ENABLE",
"AOT_ESCAPE_ENABLE",
]
}

View File

@ -269,6 +269,7 @@
panda::ecmascript::PageSize*;
panda::ecmascript::PageUnmap*;
panda::ecmascript::PageSize*;
panda::ecmascript::PagePreRead*;
panda::ecmascript::pgo::PGOProfiler::GetMethodAbcId*;
panda::ecmascript::RealPath*;
panda::ecmascript::SetDirModeAsDefault*;