mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-06 23:54:03 +00:00
!7984 dfx: pgo trace
Merge pull request !7984 from Lasting/dfx/pgo/trace
This commit is contained in:
commit
ace52a525f
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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_
|
||||
|
34
ecmascript/ohos/aot_tools.h
Normal file
34
ecmascript/ohos/aot_tools.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 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
|
@ -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,
|
||||
|
@ -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;
|
||||
|
184
ecmascript/pgo_profiler/pgo_trace.h
Normal file
184
ecmascript/pgo_profiler/pgo_trace.h
Normal 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
|
Loading…
Reference in New Issue
Block a user