!7984 dfx: pgo trace

Merge pull request !7984 from Lasting/dfx/pgo/trace
This commit is contained in:
openharmony_ci 2024-07-10 06:06:36 +00:00 committed by Gitee
commit ace52a525f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 323 additions and 53 deletions

View File

@ -79,6 +79,7 @@
#include "ecmascript/object_factory.h"
#include "ecmascript/patch/quick_fix_manager.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#include "ecmascript/pgo_profiler/pgo_trace.h"
#include "ecmascript/regexp/regexp_parser_cache.h"
#include "ecmascript/runtime.h"
#include "ecmascript/runtime_call_id.h"
@ -94,6 +95,7 @@
#include "ecmascript/ohos/aot_crash_info.h"
#include "ecmascript/ohos/enable_aot_list_helper.h"
#include "ecmascript/ohos/jit_tools.h"
#include "ecmascript/ohos/aot_tools.h"
#if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
#include "parameters.h"
@ -217,6 +219,7 @@ void EcmaVM::PostFork()
DaemonThread::GetInstance()->StartRunning();
heap_->EnableParallelGC();
std::string bundleName = PGOProfilerManager::GetInstance()->GetBundleName();
pgo::PGOTrace::GetInstance()->SetEnable(ohos::AotTools::GetPgoTraceEnable());
#ifdef AOT_ESCAPE_ENABLE
AotCrashInfo::GetInstance().SetOptionPGOProfiler(&options_, bundleName);
#endif
@ -271,6 +274,7 @@ void EcmaVM::InitializePGOProfiler()
if (pgoProfiler_ == nullptr) {
pgoProfiler_ = PGOProfilerManager::GetInstance()->Build(this, isEnablePGOProfiler);
}
pgo::PGOTrace::GetInstance()->SetEnable(options_.GetPGOTrace() || ohos::AotTools::GetPgoTraceEnable());
thread_->SetPGOProfilerEnable(isEnablePGOProfiler);
}

View File

@ -65,6 +65,7 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
"--compiler-log-snapshot: Enable to print snapshot information. Default: 'false'\n"
"--compiler-log-time: Enable to print pass compiler time. Default: 'false'\n"
"--enable-ark-tools: Enable ark tools to debug. Default: 'false'\n"
"--pgo-trace: Enable pgo trace for JS runtime. Default: 'false'\n"
"--compiler-trace-bc: Enable tracing bytecode for aot runtime. Default: 'false'\n"
"--compiler-trace-deopt: Enable tracing deopt for aot runtime. Default: 'false'\n"
"--compiler-trace-inline: Enable tracing inline function for aot runtime. Default: 'false'\n"
@ -203,6 +204,7 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
{"compiler-log-time", required_argument, nullptr, OPTION_COMPILER_LOG_TIME},
{"compiler-type-threshold", required_argument, nullptr, OPTION_COMPILER_TYPE_THRESHOLD},
{"enable-ark-tools", required_argument, nullptr, OPTION_ENABLE_ARK_TOOLS},
{"pgo-trace", required_argument, nullptr, OPTION_PGO_TRACE},
{"compiler-trace-bc", required_argument, nullptr, OPTION_COMPILER_TRACE_BC},
{"compiler-trace-deopt", required_argument, nullptr, OPTION_COMPILER_TRACE_DEOPT},
{"compiler-trace-inline", required_argument, nullptr, OPTION_COMPILER_TRACE_INLINE},
@ -418,6 +420,14 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
return false;
}
break;
case OPTION_PGO_TRACE:
ret = ParseBoolParam(&argBool);
if (ret) {
SetPGOTrace(argBool);
} else {
return false;
}
break;
case OPTION_COMPILER_TRACE_BC:
ret = ParseBoolParam(&argBool);
if (ret) {

View File

@ -28,20 +28,20 @@
namespace panda::ecmascript {
using arg_list_t = std::vector<std::string>;
enum ArkProperties {
DEFAULT = -1, // default value 000'0000'0001'0000'0101'1100 -> 0x105c
DEFAULT = -1, // default value 000'0000'0001'0000'0101'1100 -> 0x105c
OPTIONAL_LOG = 1,
GC_STATS_PRINT = 1 << 1,
PARALLEL_GC = 1 << 2, // default enable
CONCURRENT_MARK = 1 << 3, // default enable
CONCURRENT_SWEEP = 1 << 4, // default enable
PARALLEL_GC = 1 << 2, // default enable
CONCURRENT_MARK = 1 << 3, // default enable
CONCURRENT_SWEEP = 1 << 4, // default enable
THREAD_CHECK = 1 << 5,
ENABLE_ARKTOOLS = 1 << 6, // default enable
ENABLE_ARKTOOLS = 1 << 6, // default enable
ENABLE_SNAPSHOT_SERIALIZE = 1 << 7,
ENABLE_SNAPSHOT_DESERIALIZE = 1 << 8,
EXCEPTION_BACKTRACE = 1 << 9,
GLOBAL_OBJECT_LEAK_CHECK = 1 << 10,
GLOBAL_PRIMITIVE_LEAK_CHECK = 1 << 11,
ENABLE_IDLE_GC = 1 << 12, // default enable
ENABLE_IDLE_GC = 1 << 12, // default enable
CPU_PROFILER_COLD_START_MAIN_THREAD = 1 << 13,
ENABLE_CPU_PROFILER_VM_TAG = 1 << 14,
ENABLE_GC_TRACER = 1 << 15,
@ -197,6 +197,7 @@ enum CommandValues {
OPTION_COMPILER_ENABLE_JIT_FAST_COMPILE,
OPTION_COMPILER_BASELINE_PGO,
OPTION_ASYNC_LOAD_ABC,
OPTION_PGO_TRACE,
};
static_assert(OPTION_SPLIT_ONE == 64);
@ -207,16 +208,16 @@ public:
DEFAULT_COPY_SEMANTIC(JSRuntimeOptions);
DEFAULT_MOVE_SEMANTIC(JSRuntimeOptions);
bool ParseCommand(const int argc, const char **argv);
bool ParseCommand(const int argc, const char** argv);
bool SetDefaultValue(char* argv);
bool EnableArkTools() const
{
return (enableArkTools_) ||
((static_cast<uint32_t>(arkProperties_) & ArkProperties::ENABLE_ARKTOOLS) != 0);
return (enableArkTools_) || ((static_cast<uint32_t>(arkProperties_) & ArkProperties::ENABLE_ARKTOOLS) != 0);
}
void SetEnableArkTools(bool value) {
void SetEnableArkTools(bool value)
{
enableArkTools_ = value;
}
@ -255,7 +256,7 @@ public:
compilerPkgInfo_ = std::move(pkgJsonInfo);
}
const std::string &GetCompilerPkgJsonInfo() const
const std::string& GetCompilerPkgJsonInfo() const
{
return compilerPkgInfo_;
}
@ -265,7 +266,7 @@ public:
compilerExternalPkgInfo_ = std::move(pkgJsonInfo);
}
const std::string &GetCompilerExternalPkgJsonInfo() const
const std::string& GetCompilerExternalPkgJsonInfo() const
{
return compilerExternalPkgInfo_;
}
@ -419,7 +420,7 @@ public:
if (configProperty != "") {
std::string key;
std::string value;
for (char c : configProperty) {
for (char c: configProperty) {
if (isdigit(c)) {
value += c;
} else {
@ -440,7 +441,7 @@ public:
int GetDefaultProperties()
{
return ArkProperties::PARALLEL_GC | ArkProperties::CONCURRENT_MARK | ArkProperties::CONCURRENT_SWEEP |
ArkProperties::ENABLE_ARKTOOLS | ArkProperties::ENABLE_IDLE_GC;
ArkProperties::ENABLE_ARKTOOLS | ArkProperties::ENABLE_IDLE_GC;
}
int GetArkProperties()
@ -663,9 +664,8 @@ public:
std::string strEnd = strAsmOpcodeDisableRange.substr(pos + 1);
int start = strStart.empty() ? 0 : std::stoi(strStart);
int end = strEnd.empty() ? kungfu::BYTECODE_STUB_END_ID : std::stoi(strEnd);
if (start >= 0 && start < kungfu::BytecodeStubCSigns::NUM_OF_ALL_NORMAL_STUBS &&
end >= 0 && end < kungfu::BytecodeStubCSigns::NUM_OF_ALL_NORMAL_STUBS &&
start <= end) {
if (start >= 0 && start < kungfu::BytecodeStubCSigns::NUM_OF_ALL_NORMAL_STUBS && end >= 0 &&
end < kungfu::BytecodeStubCSigns::NUM_OF_ALL_NORMAL_STUBS && start <= end) {
asmInterParsedOption_.handleStart = start;
asmInterParsedOption_.handleEnd = end;
}
@ -689,8 +689,7 @@ public:
bool WasSetCompilerLogOption() const
{
return WasOptionSet(OPTION_COMPILER_LOG_OPT) &&
GetCompilerLogOption().find("none") == std::string::npos;
return WasOptionSet(OPTION_COMPILER_LOG_OPT) && GetCompilerLogOption().find("none") == std::string::npos;
}
std::string GetMethodsListForLog() const
@ -705,9 +704,8 @@ public:
bool WasSetMethodsListForLog() const
{
return WasOptionSet(OPTION_COMPILER_LOG_METHODS) &&
GetCompilerLogOption().find("none") == std::string::npos &&
GetCompilerLogOption().find("all") == std::string::npos;
return WasOptionSet(OPTION_COMPILER_LOG_METHODS) && GetCompilerLogOption().find("none") == std::string::npos &&
GetCompilerLogOption().find("all") == std::string::npos;
}
void SetCompilerLogSnapshot(bool value)
@ -1140,7 +1138,6 @@ public:
return enableValueNumbering_;
}
void SetEnableJIT(bool value)
{
enableFastJIT_ = value;
@ -1406,6 +1403,16 @@ public:
compilerSkipMethods_ = std::move(value);
}
void SetPGOTrace(bool value)
{
pgoTrace_ = value;
}
bool GetPGOTrace() const
{
return pgoTrace_;
}
void SetTraceInline(bool value)
{
traceInline_ = value;
@ -1668,13 +1675,13 @@ public:
return testAssert_;
}
void SetCompilerMethodsRange(arg_list_t *argListStr)
void SetCompilerMethodsRange(arg_list_t* argListStr)
{
compileMethodsRange_.first = std::stoull((*argListStr)[0]);
compileMethodsRange_.second = std::stoull((*argListStr)[1]);
}
const std::pair<uint32_t, uint32_t> &GetCompilerMethodsRange() const
const std::pair<uint32_t, uint32_t>& GetCompilerMethodsRange() const
{
return compileMethodsRange_;
}
@ -1684,7 +1691,7 @@ public:
compileCodegenOption_ = std::move(argListStr);
}
const arg_list_t &GetCompilerCodegenOptions() const
const arg_list_t& GetCompilerCodegenOptions() const
{
return compileCodegenOption_;
}
@ -1823,9 +1830,9 @@ public:
static constexpr int32_t MAX_APP_COMPILE_METHOD_SIZE = 1_KB;
private:
static constexpr int32_t DEFAULT_OPT_LEVEL = 3; // 3: default opt level
static constexpr int32_t DEFAULT_OPT_LEVEL = 3; // 3: default opt level
static bool StartsWith(const std::string &haystack, const std::string &needle)
static bool StartsWith(const std::string& haystack, const std::string& needle)
{
return std::equal(needle.begin(), needle.end(), haystack.begin());
}
@ -1849,11 +1856,11 @@ private:
}
bool ParseBoolParam(bool* argBool);
bool ParseDoubleParam(const std::string &option, double* argDouble);
bool ParseIntParam(const std::string &option, int* argInt);
bool ParseUint32Param(const std::string &option, uint32_t *argUInt32);
bool ParseUint64Param(const std::string &option, uint64_t *argUInt64);
void ParseListArgParam(const std::string &option, arg_list_t *argListStr, std::string delimiter);
bool ParseDoubleParam(const std::string& option, double* argDouble);
bool ParseIntParam(const std::string& option, int* argInt);
bool ParseUint32Param(const std::string& option, uint32_t* argUInt32);
bool ParseUint64Param(const std::string& option, uint64_t* argUInt64);
void ParseListArgParam(const std::string& option, arg_list_t* argListStr, std::string delimiter);
bool enableArkTools_ {true};
std::string stubFile_ {"stub.an"};
@ -1914,16 +1921,16 @@ private:
bool enableNewValueNumbering_ {true};
bool enableOptInlining_ {true};
bool enableOptPGOType_ {true};
bool enableFastJIT_{false};
bool enableAPPJIT_{false};
bool enableFastJIT_ {false};
bool enableAPPJIT_ {false};
bool isEnableJitDfxDump_ {false};
bool enableOSR_{false};
bool enableOSR_ {false};
uint16_t jitHotnessThreshold_ {2};
uint8_t jitCallThreshold_ {0};
uint16_t osrHotnessThreshold_ {2};
bool forceJitCompileMain_{false};
bool enableBaselineJIT_{false};
uint16_t baselineJitHotnessThreshold_{1};
bool forceJitCompileMain_ {false};
bool enableBaselineJIT_ {false};
uint16_t baselineJitHotnessThreshold_ {1};
bool forceBaselineCompileMain_ {false};
bool enableOptTrackField_ {true};
uint32_t compilerModuleMethods_ {100};
@ -1948,10 +1955,11 @@ private:
bool verifyVTable_ {false};
std::string compilerSelectMethods_ {""};
std::string compilerSkipMethods_ {""};
bool pgoTrace_ {false};
bool traceInline_ {false};
bool traceJIT_{false};
bool traceValueNumbering_{false};
bool traceInstructionCombine_{false};
bool traceJIT_ {false};
bool traceValueNumbering_ {false};
bool traceInstructionCombine_ {false};
bool compilerPipelineHostAOT_ {false};
size_t maxInlineBytecodes_ {45};
std::string targetCompilerMode_ {""};
@ -1982,11 +1990,11 @@ private:
bool enableMemoryAnalysis_ {true};
bool checkPgoVersion_ {false};
bool enableJitFastCompile_ {false};
bool enableJitFrame_{false};
bool disableCodeSign_{false};
bool enableBaselinePgo_{false};
bool enableJitFrame_ {false};
bool disableCodeSign_ {false};
bool enableBaselinePgo_ {false};
bool asyncLoadAbc_ {true};
};
} // namespace panda::ecmascript
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JS_RUNTIME_OPTIONS_H_
#endif // ECMASCRIPT_JS_RUNTIME_OPTIONS_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 ECMASCRIPT_AOT_TOOLS_H
#define ECMASCRIPT_AOT_TOOLS_H
#if defined(OHOS_GET_PARAMETER)
#include "base/startup/init/interfaces/innerkits/include/syspara/parameters.h"
#endif
namespace panda::ecmascript::ohos {
class AotTools {
public:
static bool GetPgoTraceEnable()
{
#if defined(OHOS_GET_PARAMETER)
return OHOS::system::GetBoolParameter("ark.pgo.trace.enable", false);
#endif
return false;
}
};
}
#endif // ECMASCRIPT_AOT_TOOLS_H

View File

@ -27,16 +27,17 @@
#include "ecmascript/jit/jit_profiler.h"
#include "ecmascript/js_function.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/jspandafile/js_pandafile.h"
#include "ecmascript/jspandafile/js_pandafile_manager.h"
#include "ecmascript/log_wrapper.h"
#include "ecmascript/module/js_module_source_text.h"
#include "ecmascript/pgo_profiler/pgo_context.h"
#include "ecmascript/pgo_profiler/pgo_profiler_info.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#include "ecmascript/pgo_profiler/pgo_trace.h"
#include "ecmascript/pgo_profiler/pgo_utils.h"
#include "ecmascript/pgo_profiler/types/pgo_profile_type.h"
#include "ecmascript/pgo_profiler/types/pgo_type_generator.h"
#include "ecmascript/pgo_profiler/pgo_utils.h"
#include "ecmascript/module/js_module_source_text.h"
#include "ecmascript/jspandafile/js_pandafile.h"
#include "macros.h"
namespace panda::ecmascript::pgo {
@ -587,6 +588,9 @@ void PGOProfiler::HandlePGOPreDump()
ProfileType recordType = GetRecordProfileType(abcId, recordName);
recordInfos_->AddMethod(recordType, Method::Cast(methodValue), SampleMode::HOTNESS_MODE);
ProfileBytecode(abcId, recordName, funcValue);
if (PGOTrace::GetInstance()->IsEnable()) {
PGOTrace::GetInstance()->TryGetMethodData(methodValue, false);
}
});
}
@ -639,6 +643,9 @@ void PGOProfiler::HandlePGODumpByDumpThread(bool force)
}
ProfileBytecode(abcId, recordName, value);
current = PopFromProfileQueue();
if (PGOTrace::GetInstance()->IsEnable()) {
PGOTrace::GetInstance()->TryGetMethodData(methodValue, true);
}
}
ASSERT(GetState() != State::STOP);
if (IsGCWaitingWithLock()) {
@ -656,7 +663,13 @@ void PGOProfiler::MergeProfilerAndDispatchAsyncSaveTask(bool force)
auto mergeMinInterval = std::chrono::milliseconds(minIntervalOption * MS_PRE_SECOND);
if ((methodCount_ >= MERGED_EVERY_COUNT && interval > mergeMinInterval) || (force && methodCount_ > 0)) {
LOG_ECMA(DEBUG) << "Sample: post task to save profiler";
PGOProfilerManager::GetInstance()->Merge(this);
{
ClockScope start;
PGOProfilerManager::GetInstance()->Merge(this);
if (PGOTrace::GetInstance()->IsEnable()) {
PGOTrace::GetInstance()->SetMergeTime(start.TotalSpentTime());
}
}
if (!force) {
PGOProfilerManager::GetInstance()->AsyncSave();
}
@ -684,6 +697,7 @@ PGOProfiler::WorkNode* PGOProfiler::PopFromProfileQueue()
void PGOProfiler::ProfileBytecode(ApEntityId abcId, const CString &recordName, JSTaggedValue funcValue)
{
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PGOProfiler::ProfileBytecode");
ClockScope start;
JSFunction *function = JSFunction::Cast(funcValue);
if (function->IsSendableOrConcurrentFunction()) {
return;
@ -910,6 +924,10 @@ void PGOProfiler::ProfileBytecode(ApEntityId abcId, const CString &recordName, J
}
bcIns = bcIns.GetNext();
}
if (PGOTrace::GetInstance()->IsEnable()) {
auto methodData = PGOTrace::GetInstance()->TryGetMethodData(function->GetMethod());
methodData->SetProfileBytecodeTime(start.TotalSpentTime());
}
}
void PGOProfiler::DumpICByName(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,

View File

@ -21,12 +21,13 @@
#include <sys/stat.h>
#include "ecmascript/log_wrapper.h"
#include "ecmascript/ohos/enable_aot_list_helper.h"
#include "ecmascript/mem/c_string.h"
#include "ecmascript/ohos/enable_aot_list_helper.h"
#include "ecmascript/pgo_profiler/ap_file/pgo_file_info.h"
#include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
#include "ecmascript/pgo_profiler/pgo_profiler_encoder.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#include "ecmascript/pgo_profiler/pgo_trace.h"
#include "ecmascript/pgo_profiler/pgo_utils.h"
#include "ecmascript/platform/file.h"
#include "ecmascript/platform/mutex.h"
@ -179,6 +180,7 @@ void PGOProfilerEncoder::MergeWithExistProfile(PGOProfilerEncoder &runtimeEncode
bool PGOProfilerEncoder::SaveAndRename(const SaveTask *task)
{
ClockScope start;
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
static const char *tempSuffix = ".tmp";
auto tmpOutPath = realOutPath_ + "." + std::to_string(getpid()) + tempSuffix;
@ -218,6 +220,10 @@ bool PGOProfilerEncoder::SaveAndRename(const SaveTask *task)
return false;
}
RequestAot();
if (PGOTrace::GetInstance()->IsEnable()) {
PGOTrace::GetInstance()->SetSaveTime(start.TotalSpentTime());
PGOTrace::GetInstance()->Print();
}
return true;
}
@ -243,7 +249,13 @@ bool PGOProfilerEncoder::InternalSave(const SaveTask *task)
PGOProfilerEncoder encoder(realOutPath_, hotnessThreshold_, mode_);
encoder.InitializeData();
PGOProfilerDecoder decoder(realOutPath_, hotnessThreshold_);
encoder.MergeWithExistProfile(*this, decoder, task);
{
ClockScope start;
encoder.MergeWithExistProfile(*this, decoder, task);
if (PGOTrace::GetInstance()->IsEnable()) {
PGOTrace::GetInstance()->SetMergeWithExistProfileTime(start.TotalSpentTime());
}
}
auto saveAndRenameResult = encoder.SaveAndRename(task);
encoder.Destroy();
return saveAndRenameResult;

View File

@ -0,0 +1,184 @@
/*
* 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_PGO_PROFILER_PGO_TRACE_H
#define ECMASCRIPT_PGO_PROFILER_PGO_TRACE_H
#include <iomanip>
#include <memory>
#include <numeric>
#include <unordered_map>
#include "ecmascript/method.h"
namespace panda::ecmascript::pgo {
class PGOTrace {
public:
static constexpr int NAME_WIDTH = 40;
static constexpr int WIDTH = 20;
static constexpr int COLUMN_WIDTH = NAME_WIDTH + WIDTH * 6;
static constexpr const char* TITLE_TEXT = " PGO Trace ";
static constexpr const float MIN_PRINT_TIME = 10.0;
static constexpr const int MIN_PRINT_COUNT = 10;
static constexpr const int PRECISION = 3;
static constexpr const int TOTAL_COLUMN = 6;
static constexpr const int PROFILE_BYTECODE_TIME_COLUMN = 2;
static std::string Title()
{
int halfWidth = (COLUMN_WIDTH - std::strlen(TITLE_TEXT)) / 2 + 1;
return std::string(halfWidth, '=') + TITLE_TEXT + std::string(halfWidth, '=');
}
static std::string Separator()
{
return std::string(Title().length(), '=');
}
static std::shared_ptr<PGOTrace> GetInstance()
{
static auto trace = std::make_shared<PGOTrace>();
return trace;
}
void SetEnable(bool enable)
{
LOG_ECMA(DEBUG) << "PGO Trace enable: " << enable;
enable_ = enable;
}
bool IsEnable() const
{
return enable_;
}
class MethodData {
public:
MethodData(JSTaggedValue value, bool hotness)
{
Method* method = Method::Cast(value);
name_ = method->GetMethodName();
id_ = method->GetMethodId();
codesize_ = method->GetCodeSize();
hotness_ = hotness;
}
EntityId GetId() const
{
return id_;
}
void SetProfileBytecodeTime(float time)
{
profileBytecodeTime_.push_back(time);
}
void Print() const
{
float totalTime = std::accumulate(profileBytecodeTime_.begin(), profileBytecodeTime_.end(), 0.0);
float count = profileBytecodeTime_.size();
#if defined(PANDA_TARGET_OHOS) && !defined(STANDALONE_MODE)
if (totalTime < MIN_PRINT_TIME && count < MIN_PRINT_COUNT) {
return;
}
#endif
if (count <= 0) {
return;
}
float avgProfileBytecodeTime = totalTime / count;
LOG_TRACE(INFO) << std::left << std::setw(NAME_WIDTH) << name_ << std::right << std::setw(WIDTH) << id_
<< std::setw(WIDTH) << codesize_ << std::setw(WIDTH) << hotness_ << std::setw(WIDTH)
<< count << std::fixed << std::setprecision(PRECISION) << std::setw(WIDTH)
<< avgProfileBytecodeTime << std::setw(WIDTH) << totalTime;
}
void SetHotness(bool hotness)
{
hotness_ = hotness;
}
private:
const char* name_;
EntityId id_;
uint32_t codesize_;
std::list<float> profileBytecodeTime_;
bool hotness_;
};
MethodData* GetMethodData(EntityId id)
{
auto iter = methods.find(id);
if (iter == methods.end()) {
return nullptr;
}
return &(iter->second);
}
MethodData* TryGetMethodData(JSTaggedValue value, bool hotness = false)
{
MethodData method(value, hotness);
auto data = GetMethodData(method.GetId());
if (data) {
data->SetHotness(hotness);
return data;
} else {
auto res = methods.emplace(method.GetId(), method);
return &(res.first->second);
}
}
void Print() const
{
LOG_TRACE(INFO) << "only print methods which (total time > 10 ms || count > 10) on ohos device";
LOG_TRACE(INFO) << Title();
LOG_TRACE(INFO) << std::setw(NAME_WIDTH + WIDTH * (TOTAL_COLUMN - PROFILE_BYTECODE_TIME_COLUMN)) << ""
<< std::right << std::setw(WIDTH * PROFILE_BYTECODE_TIME_COLUMN) << "Profile Bytecode Time(ms)";
LOG_TRACE(INFO) << std::left << std::setw(NAME_WIDTH) << "Name" << std::right << std::setw(WIDTH) << "Id"
<< std::setw(WIDTH) << "CodeSize" << std::setw(WIDTH) << "Hotness" << std::setw(WIDTH)
<< "Count" << std::setw(WIDTH) << "Avg(ms)" << std::setw(WIDTH) << "Total(ms)";
for (auto& [id, method]: methods) {
method.Print();
}
LOG_TRACE(INFO) << Separator();
LOG_TRACE(INFO) << std::left << std::setw(NAME_WIDTH) << "MergeBeforeSave(ms) " << mergeTime_;
LOG_TRACE(INFO) << std::left << std::setw(NAME_WIDTH) << "MergeWithExistAP(ms) " << mergeWithExistProfileTime_;
LOG_TRACE(INFO) << std::left << std::setw(NAME_WIDTH) << "SaveAndRename(ms) " << saveTime_;
LOG_TRACE(INFO) << Separator();
}
void SetMergeTime(float time)
{
mergeTime_ = time;
}
void SetSaveTime(float time)
{
saveTime_ = time;
}
void SetMergeWithExistProfileTime(float time)
{
mergeWithExistProfileTime_ = time;
}
private:
std::unordered_map<EntityId, MethodData> methods;
float mergeTime_;
float mergeWithExistProfileTime_;
float saveTime_;
bool enable_ {false};
};
} // namespace panda::ecmascript::pgo
#endif // ECMASCRIPT_PGO_PROFILER_PGO_TRACE_H