14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_PGO_PROFILER_PGO_UTILS_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_PGO_PROFILER_PGO_UTILS_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <list> 204514f5e3Sopenharmony_ci#include <string> 214514f5e3Sopenharmony_ci 224514f5e3Sopenharmony_ci#include "ecmascript/common.h" 234514f5e3Sopenharmony_ci#include "ecmascript/log.h" 244514f5e3Sopenharmony_ci#include "ecmascript/log_wrapper.h" 254514f5e3Sopenharmony_ci#include "ecmascript/platform/mutex.h" 264514f5e3Sopenharmony_ci#include "libpandafile/file.h" 274514f5e3Sopenharmony_ci#include "mem/mem.h" 284514f5e3Sopenharmony_ci 294514f5e3Sopenharmony_cinamespace panda::ecmascript::pgo { 304514f5e3Sopenharmony_cistatic constexpr Alignment ALIGN_SIZE = Alignment::LOG_ALIGN_4; 314514f5e3Sopenharmony_ciusing PGOMethodId = panda_file::File::EntityId; 324514f5e3Sopenharmony_ciusing ApEntityId = uint32_t; 334514f5e3Sopenharmony_ci 344514f5e3Sopenharmony_ciclass DumpUtils { 354514f5e3Sopenharmony_cipublic: 364514f5e3Sopenharmony_ci static const std::string ELEMENT_SEPARATOR; 374514f5e3Sopenharmony_ci static const std::string BLOCK_SEPARATOR; 384514f5e3Sopenharmony_ci static const std::string TYPE_SEPARATOR; 394514f5e3Sopenharmony_ci static const std::string BLOCK_START; 404514f5e3Sopenharmony_ci static const std::string ARRAY_START; 414514f5e3Sopenharmony_ci static const std::string ARRAY_END; 424514f5e3Sopenharmony_ci static const std::string NEW_LINE; 434514f5e3Sopenharmony_ci static const std::string SPACE; 444514f5e3Sopenharmony_ci static const std::string BLOCK_AND_ARRAY_START; 454514f5e3Sopenharmony_ci static const std::string VERSION_HEADER; 464514f5e3Sopenharmony_ci static const std::string PANDA_FILE_INFO_HEADER; 474514f5e3Sopenharmony_ci static const uint32_t HEX_FORMAT_WIDTH_FOR_32BITS; 484514f5e3Sopenharmony_ci}; 494514f5e3Sopenharmony_ci 504514f5e3Sopenharmony_ciclass DumpJsonUtils { 514514f5e3Sopenharmony_cipublic: 524514f5e3Sopenharmony_ci static inline const std::string ABC_FILE_POOL = "abcFilePool"; 534514f5e3Sopenharmony_ci static inline const std::string ABC_FILE = "abcFile"; 544514f5e3Sopenharmony_ci static inline const std::string RECORD_DETAIL = "recordDetail"; 554514f5e3Sopenharmony_ci static inline const std::string MODULE_NAME = "moduleName"; 564514f5e3Sopenharmony_ci static inline const std::string FUNCTION = "function"; 574514f5e3Sopenharmony_ci static inline const std::string FUNCTION_NAME = "functionName"; 584514f5e3Sopenharmony_ci static inline const std::string TYPE = "type"; 594514f5e3Sopenharmony_ci static inline const std::string TYPE_OFFSET = "typeOffset"; 604514f5e3Sopenharmony_ci static inline const std::string TYPE_NAME = "typeName"; 614514f5e3Sopenharmony_ci static inline const std::string IS_ROOT = "isRoot"; 624514f5e3Sopenharmony_ci static inline const std::string KIND = "kind"; 634514f5e3Sopenharmony_ci static inline const std::string ABC_ID = "abcId"; 644514f5e3Sopenharmony_ci static inline const std::string ID = "id"; 654514f5e3Sopenharmony_ci}; 664514f5e3Sopenharmony_ci 674514f5e3Sopenharmony_ciclass ApNameUtils { 684514f5e3Sopenharmony_cipublic: 694514f5e3Sopenharmony_ci static const std::string AP_SUFFIX; 704514f5e3Sopenharmony_ci static const std::string RUNTIME_AP_PREFIX; 714514f5e3Sopenharmony_ci static const std::string MERGED_AP_PREFIX; 724514f5e3Sopenharmony_ci static const std::string DEFAULT_AP_NAME; 734514f5e3Sopenharmony_ci static std::string PUBLIC_API GetRuntimeApName(const std::string &ohosModuleName); 744514f5e3Sopenharmony_ci static std::string PUBLIC_API GetMergedApName(const std::string &ohosModuleName); 754514f5e3Sopenharmony_ci static std::string PUBLIC_API GetOhosPkgApName(const std::string &ohosModuleName); 764514f5e3Sopenharmony_ci 774514f5e3Sopenharmony_ciprivate: 784514f5e3Sopenharmony_ci static std::string GetBriefApName(const std::string &ohosModuleName); 794514f5e3Sopenharmony_ci}; 804514f5e3Sopenharmony_ci 814514f5e3Sopenharmony_ciclass ConcurrentGuardValues { 824514f5e3Sopenharmony_cipublic: 834514f5e3Sopenharmony_ci mutable std::atomic_int last_tid {0}; 844514f5e3Sopenharmony_ci mutable std::atomic_int count {0}; 854514f5e3Sopenharmony_ci static const int MAX_LOG_COUNT = 30; 864514f5e3Sopenharmony_ci 874514f5e3Sopenharmony_ci void AddLog(std::string str) 884514f5e3Sopenharmony_ci { 894514f5e3Sopenharmony_ci LockHolder lock(mutex_); 904514f5e3Sopenharmony_ci if (log_.size() >= MAX_LOG_COUNT) { 914514f5e3Sopenharmony_ci log_.pop_front(); 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci log_.push_back(str + ", tid: " + std::to_string(Gettid())); 944514f5e3Sopenharmony_ci } 954514f5e3Sopenharmony_ci 964514f5e3Sopenharmony_ci void AddLogWithDebugLog(std::string str) 974514f5e3Sopenharmony_ci { 984514f5e3Sopenharmony_ci AddLog(str); 994514f5e3Sopenharmony_ci LOG_ECMA(DEBUG) << str; 1004514f5e3Sopenharmony_ci } 1014514f5e3Sopenharmony_ci 1024514f5e3Sopenharmony_ci void ClearLog() 1034514f5e3Sopenharmony_ci { 1044514f5e3Sopenharmony_ci LockHolder lock(mutex_); 1054514f5e3Sopenharmony_ci log_.clear(); 1064514f5e3Sopenharmony_ci } 1074514f5e3Sopenharmony_ci 1084514f5e3Sopenharmony_ci void PrintLog() 1094514f5e3Sopenharmony_ci { 1104514f5e3Sopenharmony_ci LockHolder lock(mutex_); 1114514f5e3Sopenharmony_ci std::ostringstream os; 1124514f5e3Sopenharmony_ci os << "concurrent guard logs: " << std::endl; 1134514f5e3Sopenharmony_ci for (auto& str: log_) { 1144514f5e3Sopenharmony_ci os << str << std::endl; 1154514f5e3Sopenharmony_ci } 1164514f5e3Sopenharmony_ci LOG_ECMA(INFO) << os.str(); 1174514f5e3Sopenharmony_ci } 1184514f5e3Sopenharmony_ci 1194514f5e3Sopenharmony_ci int Gettid() 1204514f5e3Sopenharmony_ci { 1214514f5e3Sopenharmony_ci return os::thread::GetCurrentThreadId(); 1224514f5e3Sopenharmony_ci } 1234514f5e3Sopenharmony_ci 1244514f5e3Sopenharmony_ciprivate: 1254514f5e3Sopenharmony_ci std::list<std::string> log_; 1264514f5e3Sopenharmony_ci Mutex mutex_; 1274514f5e3Sopenharmony_ci}; 1284514f5e3Sopenharmony_ci 1294514f5e3Sopenharmony_ciclass ConcurrentGuard { 1304514f5e3Sopenharmony_ciprivate: 1314514f5e3Sopenharmony_ci std::string operation_; 1324514f5e3Sopenharmony_ci 1334514f5e3Sopenharmony_cipublic: 1344514f5e3Sopenharmony_ci ConcurrentGuard(ConcurrentGuardValues& v, std::string operation = ""): operation_(operation), v_(v) 1354514f5e3Sopenharmony_ci { 1364514f5e3Sopenharmony_ci v_.AddLogWithDebugLog("[ConcurrentGuard] " + operation_ + " start"); 1374514f5e3Sopenharmony_ci auto tid = v_.Gettid(); 1384514f5e3Sopenharmony_ci auto except = 0; 1394514f5e3Sopenharmony_ci // Support reenter 1404514f5e3Sopenharmony_ci if (!v_.count.compare_exchange_strong(except, 1) && v_.last_tid != tid) { 1414514f5e3Sopenharmony_ci v_.PrintLog(); 1424514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "[ConcurrentGuard] total thead count should be 0, but get " << except 1434514f5e3Sopenharmony_ci << ", current tid: " << tid << ", last tid: " << v_.last_tid; 1444514f5e3Sopenharmony_ci } 1454514f5e3Sopenharmony_ci v_.last_tid = tid; 1464514f5e3Sopenharmony_ci } 1474514f5e3Sopenharmony_ci ~ConcurrentGuard() 1484514f5e3Sopenharmony_ci { 1494514f5e3Sopenharmony_ci auto tid = v_.Gettid(); 1504514f5e3Sopenharmony_ci auto except = 1; 1514514f5e3Sopenharmony_ci // Support reenter 1524514f5e3Sopenharmony_ci if (!v_.count.compare_exchange_strong(except, 0) && v_.last_tid != tid) { 1534514f5e3Sopenharmony_ci v_.PrintLog(); 1544514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "[ConcurrentGuard] total thead count should be 1, but get " << except 1554514f5e3Sopenharmony_ci << ", current tid: " << tid << ", last tid: " << v_.last_tid; 1564514f5e3Sopenharmony_ci } 1574514f5e3Sopenharmony_ci v_.AddLogWithDebugLog("[ConcurrentGuard] " + operation_ + " end"); 1584514f5e3Sopenharmony_ci }; 1594514f5e3Sopenharmony_ci 1604514f5e3Sopenharmony_ciprivate: 1614514f5e3Sopenharmony_ci ConcurrentGuardValues& v_; 1624514f5e3Sopenharmony_ci}; 1634514f5e3Sopenharmony_ci} // namespace panda::ecmascript::pgo 1644514f5e3Sopenharmony_ci#endif // ECMASCRIPT_PGO_PROFILER_PGO_UTILS_H 165