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_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_PGO_PROFILER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <chrono> 204514f5e3Sopenharmony_ci#include <memory> 214514f5e3Sopenharmony_ci 224514f5e3Sopenharmony_ci#include "ecmascript/common.h" 234514f5e3Sopenharmony_ci#include "ecmascript/elements.h" 244514f5e3Sopenharmony_ci#include "ecmascript/global_index.h" 254514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value.h" 264514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/method_literal.h" 274514f5e3Sopenharmony_ci#include "ecmascript/mem/c_containers.h" 284514f5e3Sopenharmony_ci#include "ecmascript/mem/native_area_allocator.h" 294514f5e3Sopenharmony_ci#include "ecmascript/mem/region.h" 304514f5e3Sopenharmony_ci#include "ecmascript/mem/visitor.h" 314514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 324514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/types/pgo_type_generator.h" 334514f5e3Sopenharmony_ci#include "ecmascript/platform/mutex.h" 344514f5e3Sopenharmony_ci#include "ecmascript/taskpool/task.h" 354514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_utils.h" 364514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/types/pgo_profile_type.h" 374514f5e3Sopenharmony_ci#include "ecmascript/js_handle.h" 384514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_extra_profiler.h" 394514f5e3Sopenharmony_ci 404514f5e3Sopenharmony_cinamespace panda::ecmascript { 414514f5e3Sopenharmony_ciclass ProfileTypeInfo; 424514f5e3Sopenharmony_ciclass JSFunction; 434514f5e3Sopenharmony_ciclass GlobalIndex; 444514f5e3Sopenharmony_ciclass JITProfiler; 454514f5e3Sopenharmony_cinamespace pgo { 464514f5e3Sopenharmony_ciclass PGORecordDetailInfos; 474514f5e3Sopenharmony_ci 484514f5e3Sopenharmony_cienum class SampleMode : uint8_t { 494514f5e3Sopenharmony_ci HOTNESS_MODE, 504514f5e3Sopenharmony_ci CALL_MODE, 514514f5e3Sopenharmony_ci}; 524514f5e3Sopenharmony_ci 534514f5e3Sopenharmony_ciclass PGOProfiler { 544514f5e3Sopenharmony_cipublic: 554514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(PGOProfiler); 564514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(PGOProfiler); 574514f5e3Sopenharmony_ci 584514f5e3Sopenharmony_ci PGOProfiler(EcmaVM *vm, bool isEnable); 594514f5e3Sopenharmony_ci 604514f5e3Sopenharmony_ci virtual ~PGOProfiler(); 614514f5e3Sopenharmony_ci 624514f5e3Sopenharmony_ci void PUBLIC_API RecordProfileType(JSHClass *hclass, JSPandaFile *pandaFile, int32_t traceId); 634514f5e3Sopenharmony_ci 644514f5e3Sopenharmony_ci static ProfileType CreateRecordProfileType(ApEntityId abcId, ApEntityId classId); 654514f5e3Sopenharmony_ci void ProfileDefineClass(JSTaggedType ctor); 664514f5e3Sopenharmony_ci void ProfileProtoTransitionClass(JSHandle<JSFunction> func, 674514f5e3Sopenharmony_ci JSHandle<JSHClass> hclass, 684514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> proto); 694514f5e3Sopenharmony_ci void ProfileProtoTransitionPrototype(JSHandle<JSFunction> func, 704514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> prototype, 714514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> oldPrototype, 724514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> baseIhc); 734514f5e3Sopenharmony_ci void ProfileDefineGetterSetter(JSHClass *receverHClass, 744514f5e3Sopenharmony_ci JSHClass *holderHClass, 754514f5e3Sopenharmony_ci const JSHandle<JSTaggedValue> &func, 764514f5e3Sopenharmony_ci int32_t pcOffset); 774514f5e3Sopenharmony_ci void ProfileClassRootHClass(JSTaggedType ctor, JSTaggedType rootHcValue, 784514f5e3Sopenharmony_ci ProfileType::Kind kind = ProfileType::Kind::ClassId); 794514f5e3Sopenharmony_ci void UpdateRootProfileTypeSafe(JSHClass* oldHClass, JSHClass* newHClass); 804514f5e3Sopenharmony_ci 814514f5e3Sopenharmony_ci void InitJITProfiler(); 824514f5e3Sopenharmony_ci void SetSaveTimestamp(std::chrono::system_clock::time_point timestamp) 834514f5e3Sopenharmony_ci { 844514f5e3Sopenharmony_ci saveTimestamp_ = timestamp; 854514f5e3Sopenharmony_ci } 864514f5e3Sopenharmony_ci JITProfiler *GetJITProfile() 874514f5e3Sopenharmony_ci { 884514f5e3Sopenharmony_ci return jitProfiler_; 894514f5e3Sopenharmony_ci } 904514f5e3Sopenharmony_ci void PGOPreDump(JSTaggedType func); 914514f5e3Sopenharmony_ci void PGODump(JSTaggedType func); 924514f5e3Sopenharmony_ci 934514f5e3Sopenharmony_ci void SuspendByGC(); 944514f5e3Sopenharmony_ci void ResumeByGC(); 954514f5e3Sopenharmony_ci void WaitPGODumpFinish(); 964514f5e3Sopenharmony_ci 974514f5e3Sopenharmony_ci void HandlePGOPreDump(); 984514f5e3Sopenharmony_ci void HandlePGODumpByDumpThread(bool force); 994514f5e3Sopenharmony_ci 1004514f5e3Sopenharmony_ci void ProcessReferences(const WeakRootVisitor &visitor); 1014514f5e3Sopenharmony_ci void Iterate(const RootVisitor &visitor); 1024514f5e3Sopenharmony_ci 1034514f5e3Sopenharmony_ci void UpdateTrackArrayLength(JSTaggedValue trackInfoVal, uint32_t newSize); 1044514f5e3Sopenharmony_ci void UpdateTrackSpaceFlag(TaggedObject *object, RegionSpaceFlag spaceFlag); 1054514f5e3Sopenharmony_ci void UpdateTrackElementsKind(JSTaggedValue trackInfoVal, ElementsKind newKind); 1064514f5e3Sopenharmony_ci void UpdateTrackInfo(JSTaggedValue trackInfoVal); 1074514f5e3Sopenharmony_ci 1084514f5e3Sopenharmony_ci JSTaggedValue TryFindKeyInPrototypeChain(TaggedObject *currObj, JSHClass *currHC, JSTaggedValue key); 1094514f5e3Sopenharmony_ci 1104514f5e3Sopenharmony_ci void InsertSkipCtorMethodIdSafe(EntityId ctorMethodId) 1114514f5e3Sopenharmony_ci { 1124514f5e3Sopenharmony_ci LockHolder lock(skipCtorMethodIdMutex_); 1134514f5e3Sopenharmony_ci skipCtorMethodId_.insert(ctorMethodId.GetOffset()); 1144514f5e3Sopenharmony_ci } 1154514f5e3Sopenharmony_ci 1164514f5e3Sopenharmony_ciprivate: 1174514f5e3Sopenharmony_ci static constexpr uint32_t MERGED_EVERY_COUNT = 50; 1184514f5e3Sopenharmony_ci static constexpr uint32_t MS_PRE_SECOND = 1000; 1194514f5e3Sopenharmony_ci enum class BCType : uint8_t { 1204514f5e3Sopenharmony_ci STORE, 1214514f5e3Sopenharmony_ci LOAD, 1224514f5e3Sopenharmony_ci }; 1234514f5e3Sopenharmony_ci 1244514f5e3Sopenharmony_ci void ProfileBytecode(ApEntityId abcId, const CString& recordName, JSTaggedValue funcValue); 1254514f5e3Sopenharmony_ci 1264514f5e3Sopenharmony_ci enum class State : uint8_t { 1274514f5e3Sopenharmony_ci STOP, 1284514f5e3Sopenharmony_ci PAUSE, 1294514f5e3Sopenharmony_ci START, 1304514f5e3Sopenharmony_ci FORCE_SAVE, 1314514f5e3Sopenharmony_ci FORCE_SAVE_PAUSE, 1324514f5e3Sopenharmony_ci }; 1334514f5e3Sopenharmony_ci 1344514f5e3Sopenharmony_ci static std::string StateToString(State state) 1354514f5e3Sopenharmony_ci { 1364514f5e3Sopenharmony_ci switch (state) { 1374514f5e3Sopenharmony_ci case State::STOP: 1384514f5e3Sopenharmony_ci return "STOP"; 1394514f5e3Sopenharmony_ci case State::PAUSE: 1404514f5e3Sopenharmony_ci return "PAUSE"; 1414514f5e3Sopenharmony_ci case State::START: 1424514f5e3Sopenharmony_ci return "START"; 1434514f5e3Sopenharmony_ci case State::FORCE_SAVE: 1444514f5e3Sopenharmony_ci return "FORCE SAVE"; 1454514f5e3Sopenharmony_ci case State::FORCE_SAVE_PAUSE: 1464514f5e3Sopenharmony_ci return "FORCE SAVE PAUSE"; 1474514f5e3Sopenharmony_ci default: 1484514f5e3Sopenharmony_ci return "UNKNOWN"; 1494514f5e3Sopenharmony_ci } 1504514f5e3Sopenharmony_ci } 1514514f5e3Sopenharmony_ci 1524514f5e3Sopenharmony_ci State GetState(); 1534514f5e3Sopenharmony_ci void SetState(State state); 1544514f5e3Sopenharmony_ci void NotifyGC(std::string tag = ""); 1554514f5e3Sopenharmony_ci void NotifyAll(std::string tag = ""); 1564514f5e3Sopenharmony_ci void WaitingPGODump(); 1574514f5e3Sopenharmony_ci void StopPGODump(); 1584514f5e3Sopenharmony_ci void StartPGODump(); 1594514f5e3Sopenharmony_ci bool IsGCWaitingWithLock(); 1604514f5e3Sopenharmony_ci bool IsGCWaiting(); 1614514f5e3Sopenharmony_ci void DispatchPGODumpTask(); 1624514f5e3Sopenharmony_ci 1634514f5e3Sopenharmony_ci void DumpICByName(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, uint32_t slotId, 1644514f5e3Sopenharmony_ci ProfileTypeInfo *profileTypeInfo, BCType type); 1654514f5e3Sopenharmony_ci void DumpICByValue(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1664514f5e3Sopenharmony_ci uint32_t slotId, ProfileTypeInfo *profileTypeInfo, BCType type); 1674514f5e3Sopenharmony_ci 1684514f5e3Sopenharmony_ci void DumpICByNameWithPoly(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1694514f5e3Sopenharmony_ci JSTaggedValue cacheValue, BCType type); 1704514f5e3Sopenharmony_ci void DumpICByValueWithPoly(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1714514f5e3Sopenharmony_ci JSTaggedValue cacheValue, BCType type); 1724514f5e3Sopenharmony_ci 1734514f5e3Sopenharmony_ci bool DumpICByNameWithHandler(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1744514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue secondValue, BCType type); 1754514f5e3Sopenharmony_ci bool DumpICLoadByNameWithHandler(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1764514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue secondValue); 1774514f5e3Sopenharmony_ci void DumpICByValueWithHandler(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1784514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue secondValue, BCType type); 1794514f5e3Sopenharmony_ci 1804514f5e3Sopenharmony_ci void TryDumpProtoTransitionType(JSHClass *hclass); 1814514f5e3Sopenharmony_ci 1824514f5e3Sopenharmony_ci void DumpByForce(); 1834514f5e3Sopenharmony_ci 1844514f5e3Sopenharmony_ci void DumpOpType(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, uint32_t slotId, 1854514f5e3Sopenharmony_ci ProfileTypeInfo *profileTypeInfo); 1864514f5e3Sopenharmony_ci void DumpDefineClass(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1874514f5e3Sopenharmony_ci uint32_t slotId, ProfileTypeInfo *profileTypeInfo); 1884514f5e3Sopenharmony_ci bool FunctionKindVerify(const JSFunction *ctorFunction); 1894514f5e3Sopenharmony_ci void DumpCreateObject(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1904514f5e3Sopenharmony_ci uint32_t slotId, ProfileTypeInfo *profileTypeInfo, int32_t traceId); 1914514f5e3Sopenharmony_ci void DumpCall(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, uint32_t slotId, 1924514f5e3Sopenharmony_ci ProfileTypeInfo *profileTypeInfo); 1934514f5e3Sopenharmony_ci void DumpNewObjRange(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1944514f5e3Sopenharmony_ci uint32_t slotId, ProfileTypeInfo *profileTypeInfo); 1954514f5e3Sopenharmony_ci void DumpGetIterator(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1964514f5e3Sopenharmony_ci uint32_t slotId, ProfileTypeInfo *profileTypeInfo); 1974514f5e3Sopenharmony_ci void DumpInstanceof(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 1984514f5e3Sopenharmony_ci uint32_t slotId, ProfileTypeInfo *profileTypeInfo); 1994514f5e3Sopenharmony_ci 2004514f5e3Sopenharmony_ci void UpdateLayout(JSHClass *hclass); 2014514f5e3Sopenharmony_ci void UpdateTransitionLayout(JSHClass* parent, JSHClass* child); 2024514f5e3Sopenharmony_ci bool AddTransitionObjectInfo(ProfileType recordType, 2034514f5e3Sopenharmony_ci EntityId methodId, 2044514f5e3Sopenharmony_ci int32_t bcOffset, 2054514f5e3Sopenharmony_ci JSHClass* receiver, 2064514f5e3Sopenharmony_ci JSHClass* hold, 2074514f5e3Sopenharmony_ci JSHClass* holdTra, 2084514f5e3Sopenharmony_ci PGOSampleType accessorMethod); 2094514f5e3Sopenharmony_ci void UpdatePrototypeChainInfo(JSHClass *receiver, JSHClass *holder, PGOObjectInfo &info); 2104514f5e3Sopenharmony_ci 2114514f5e3Sopenharmony_ci bool AddObjectInfo(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 2124514f5e3Sopenharmony_ci JSHClass *receiver, JSHClass *hold, JSHClass *holdTra, uint32_t accessorMethodId = 0); 2134514f5e3Sopenharmony_ci void AddObjectInfoWithMega(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset); 2144514f5e3Sopenharmony_ci bool AddBuiltinsInfoByNameInInstance(ApEntityId abcId, const CString &recordName, EntityId methodId, 2154514f5e3Sopenharmony_ci int32_t bcOffset, JSHClass *receiver); 2164514f5e3Sopenharmony_ci bool AddBuiltinsInfoByNameInProt(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, 2174514f5e3Sopenharmony_ci JSHClass *receiver, JSHClass *hold); 2184514f5e3Sopenharmony_ci bool AddBuiltinsInfo( 2194514f5e3Sopenharmony_ci ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, JSHClass *receiver, 2204514f5e3Sopenharmony_ci JSHClass *transitionHClass, OnHeapMode onHeap = OnHeapMode::NONE, bool everOutOfBounds = false); 2214514f5e3Sopenharmony_ci void AddBuiltinsGlobalInfo(ApEntityId abcId, const CString &recordName, EntityId methodId, 2224514f5e3Sopenharmony_ci int32_t bcOffset, GlobalIndex globalId); 2234514f5e3Sopenharmony_ci 2244514f5e3Sopenharmony_ci void SetRootProfileType(JSHClass *root, ApEntityId abcId, uint32_t type, ProfileType::Kind kind); 2254514f5e3Sopenharmony_ci ProfileType FindRootProfileType(JSHClass *hclass); 2264514f5e3Sopenharmony_ci 2274514f5e3Sopenharmony_ci ProfileType GetOrInsertProfileType(JSHClass *child, ProfileType rootType); 2284514f5e3Sopenharmony_ci ProfileType GetProfileType(JSHClass *hclass, bool check = false); 2294514f5e3Sopenharmony_ci 2304514f5e3Sopenharmony_ci bool IsRecoredTransRootType(ProfileType type); 2314514f5e3Sopenharmony_ci bool HasValidExtraProfileTypeInfo(JSFunction *func); 2324514f5e3Sopenharmony_ci class WorkNode; 2334514f5e3Sopenharmony_ci void ProcessExtraProfileTypeInfo(JSFunction *func, ApEntityId abcId, const CString &recordName, 2344514f5e3Sopenharmony_ci JSTaggedValue methodValue, WorkNode *current); 2354514f5e3Sopenharmony_ci void UpdateExtraProfileTypeInfo(ApEntityId abcId, const CString &recordName, EntityId methodId, WorkNode* current); 2364514f5e3Sopenharmony_ci WorkNode* PopFromProfileQueue(); 2374514f5e3Sopenharmony_ci void MergeProfilerAndDispatchAsyncSaveTask(bool force); 2384514f5e3Sopenharmony_ci bool IsJSHClassNotEqual(JSHClass *receiver, JSHClass *hold, JSHClass *exceptRecvHClass, 2394514f5e3Sopenharmony_ci JSHClass *exceptRecvHClassOnHeap, JSHClass *exceptHoldHClass, 2404514f5e3Sopenharmony_ci JSHClass *exceptPrototypeOfPrototypeHClass); 2414514f5e3Sopenharmony_ci bool CheckProtoChangeMarker(JSTaggedValue cellValue) const; 2424514f5e3Sopenharmony_ci 2434514f5e3Sopenharmony_ci class PGOProfilerTask : public Task { 2444514f5e3Sopenharmony_ci public: 2454514f5e3Sopenharmony_ci explicit PGOProfilerTask(PGOProfiler *profiler, int32_t id) 2464514f5e3Sopenharmony_ci : Task(id), profiler_(profiler){}; 2474514f5e3Sopenharmony_ci virtual ~PGOProfilerTask() override = default; 2484514f5e3Sopenharmony_ci 2494514f5e3Sopenharmony_ci bool Run([[maybe_unused]] uint32_t threadIndex) override 2504514f5e3Sopenharmony_ci { 2514514f5e3Sopenharmony_ci ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PGOProfilerTask::Run"); 2524514f5e3Sopenharmony_ci profiler_->HandlePGODumpByDumpThread(profiler_->isForce_); 2534514f5e3Sopenharmony_ci profiler_->StopPGODump(); 2544514f5e3Sopenharmony_ci return true; 2554514f5e3Sopenharmony_ci } 2564514f5e3Sopenharmony_ci 2574514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(PGOProfilerTask); 2584514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(PGOProfilerTask); 2594514f5e3Sopenharmony_ci private: 2604514f5e3Sopenharmony_ci PGOProfiler *profiler_; 2614514f5e3Sopenharmony_ci }; 2624514f5e3Sopenharmony_ci 2634514f5e3Sopenharmony_ci using PcOffset = int32_t; 2644514f5e3Sopenharmony_ci 2654514f5e3Sopenharmony_ci class WorkList; 2664514f5e3Sopenharmony_ci class WorkNode { 2674514f5e3Sopenharmony_ci public: 2684514f5e3Sopenharmony_ci WorkNode(JSTaggedType value) : value_(value) {} 2694514f5e3Sopenharmony_ci void SetPrev(WorkNode *prev) 2704514f5e3Sopenharmony_ci { 2714514f5e3Sopenharmony_ci prev_ = prev; 2724514f5e3Sopenharmony_ci } 2734514f5e3Sopenharmony_ci 2744514f5e3Sopenharmony_ci void SetNext(WorkNode *next) 2754514f5e3Sopenharmony_ci { 2764514f5e3Sopenharmony_ci next_ = next; 2774514f5e3Sopenharmony_ci } 2784514f5e3Sopenharmony_ci 2794514f5e3Sopenharmony_ci void SetValue(JSTaggedType value) 2804514f5e3Sopenharmony_ci { 2814514f5e3Sopenharmony_ci value_ = value; 2824514f5e3Sopenharmony_ci } 2834514f5e3Sopenharmony_ci 2844514f5e3Sopenharmony_ci void SetWorkList(WorkList *workList) 2854514f5e3Sopenharmony_ci { 2864514f5e3Sopenharmony_ci workList_ = workList; 2874514f5e3Sopenharmony_ci } 2884514f5e3Sopenharmony_ci 2894514f5e3Sopenharmony_ci WorkNode *GetPrev() const 2904514f5e3Sopenharmony_ci { 2914514f5e3Sopenharmony_ci return prev_; 2924514f5e3Sopenharmony_ci } 2934514f5e3Sopenharmony_ci 2944514f5e3Sopenharmony_ci WorkNode *GetNext() const 2954514f5e3Sopenharmony_ci { 2964514f5e3Sopenharmony_ci return next_; 2974514f5e3Sopenharmony_ci } 2984514f5e3Sopenharmony_ci 2994514f5e3Sopenharmony_ci JSTaggedType GetValue() const 3004514f5e3Sopenharmony_ci { 3014514f5e3Sopenharmony_ci return value_; 3024514f5e3Sopenharmony_ci } 3034514f5e3Sopenharmony_ci 3044514f5e3Sopenharmony_ci uintptr_t GetValueAddr() const 3054514f5e3Sopenharmony_ci { 3064514f5e3Sopenharmony_ci return reinterpret_cast<uintptr_t>(&value_); 3074514f5e3Sopenharmony_ci } 3084514f5e3Sopenharmony_ci 3094514f5e3Sopenharmony_ci WorkList *GetWorkList() const 3104514f5e3Sopenharmony_ci { 3114514f5e3Sopenharmony_ci return workList_; 3124514f5e3Sopenharmony_ci } 3134514f5e3Sopenharmony_ci 3144514f5e3Sopenharmony_ci private: 3154514f5e3Sopenharmony_ci WorkList *workList_ { nullptr }; 3164514f5e3Sopenharmony_ci WorkNode *prev_ { nullptr }; 3174514f5e3Sopenharmony_ci WorkNode *next_ { nullptr }; 3184514f5e3Sopenharmony_ci JSTaggedType value_ { JSTaggedValue::Undefined().GetRawData() }; 3194514f5e3Sopenharmony_ci }; 3204514f5e3Sopenharmony_ci 3214514f5e3Sopenharmony_ci class WorkList { 3224514f5e3Sopenharmony_ci public: 3234514f5e3Sopenharmony_ci using Callback = std::function<void(WorkNode *node)>; 3244514f5e3Sopenharmony_ci bool IsEmpty() const 3254514f5e3Sopenharmony_ci { 3264514f5e3Sopenharmony_ci return first_ == nullptr; 3274514f5e3Sopenharmony_ci } 3284514f5e3Sopenharmony_ci void PushBack(WorkNode *node); 3294514f5e3Sopenharmony_ci WorkNode *PopFront(); 3304514f5e3Sopenharmony_ci void Remove(WorkNode *node); 3314514f5e3Sopenharmony_ci void Iterate(Callback callback) const; 3324514f5e3Sopenharmony_ci private: 3334514f5e3Sopenharmony_ci WorkNode *first_ { nullptr }; 3344514f5e3Sopenharmony_ci WorkNode *last_ { nullptr }; 3354514f5e3Sopenharmony_ci }; 3364514f5e3Sopenharmony_cipublic: 3374514f5e3Sopenharmony_ci static ApEntityId PUBLIC_API GetMethodAbcId(JSFunction *jsFunction); 3384514f5e3Sopenharmony_ci static ApEntityId PUBLIC_API GetMethodAbcId(JSTaggedValue jsMethod); 3394514f5e3Sopenharmony_ci void Reset(bool isEnable); 3404514f5e3Sopenharmony_ciprivate: 3414514f5e3Sopenharmony_ci ProfileType GetRecordProfileType(JSFunction *jsFunction, const CString &recordName); 3424514f5e3Sopenharmony_ci ProfileType GetRecordProfileType(ApEntityId abcId, const CString &recordName); 3434514f5e3Sopenharmony_ci ProfileType GetRecordProfileType(const std::shared_ptr<JSPandaFile> &pf, ApEntityId abcId, 3444514f5e3Sopenharmony_ci const CString &recordName); 3454514f5e3Sopenharmony_ci 3464514f5e3Sopenharmony_ci bool IsSkippableObjectTypeSafe(ProfileType type) 3474514f5e3Sopenharmony_ci { 3484514f5e3Sopenharmony_ci if (type.IsGeneralizedClassType() || type.IsConstructor() || type.IsGeneralizedPrototype()) { 3494514f5e3Sopenharmony_ci uint32_t ctorId = type.GetId(); 3504514f5e3Sopenharmony_ci LockHolder lock(skipCtorMethodIdMutex_); 3514514f5e3Sopenharmony_ci return skipCtorMethodId_.find(ctorId) != skipCtorMethodId_.end(); 3524514f5e3Sopenharmony_ci } 3534514f5e3Sopenharmony_ci return false; 3544514f5e3Sopenharmony_ci } 3554514f5e3Sopenharmony_ci 3564514f5e3Sopenharmony_ci bool IsSkippableCtor(uint32_t entityId) 3574514f5e3Sopenharmony_ci { 3584514f5e3Sopenharmony_ci return entityId == 0 || skipCtorMethodId_.find(entityId) != skipCtorMethodId_.end(); 3594514f5e3Sopenharmony_ci } 3604514f5e3Sopenharmony_ci 3614514f5e3Sopenharmony_ci bool InsertDefinedCtor(uint32_t entityId) 3624514f5e3Sopenharmony_ci { 3634514f5e3Sopenharmony_ci if (definedCtorMethodId_.find(entityId) == definedCtorMethodId_.end()) { 3644514f5e3Sopenharmony_ci definedCtorMethodId_.insert(entityId); 3654514f5e3Sopenharmony_ci return true; 3664514f5e3Sopenharmony_ci } 3674514f5e3Sopenharmony_ci return false; 3684514f5e3Sopenharmony_ci } 3694514f5e3Sopenharmony_ci 3704514f5e3Sopenharmony_ci ConcurrentGuardValues v_; 3714514f5e3Sopenharmony_ci std::unique_ptr<NativeAreaAllocator> nativeAreaAllocator_; 3724514f5e3Sopenharmony_ci EcmaVM *vm_ { nullptr }; 3734514f5e3Sopenharmony_ci bool isEnable_ { false }; 3744514f5e3Sopenharmony_ci bool isForce_ {false}; 3754514f5e3Sopenharmony_ci std::atomic<State> state_ {State::STOP}; 3764514f5e3Sopenharmony_ci uint32_t methodCount_ { 0 }; 3774514f5e3Sopenharmony_ci std::chrono::system_clock::time_point saveTimestamp_; 3784514f5e3Sopenharmony_ci Mutex mutex_; 3794514f5e3Sopenharmony_ci Mutex recordInfoMutex_; 3804514f5e3Sopenharmony_ci ConditionVariable condition_; 3814514f5e3Sopenharmony_ci WorkList dumpWorkList_; 3824514f5e3Sopenharmony_ci WorkList preDumpWorkList_; 3834514f5e3Sopenharmony_ci std::unique_ptr<PGORecordDetailInfos> recordInfos_; 3844514f5e3Sopenharmony_ci // AOT only supports executing Defineclass bc once currently. 3854514f5e3Sopenharmony_ci // If defineclass executed multiple times, It will gives up collection. 3864514f5e3Sopenharmony_ci CUnorderedSet<uint32_t> definedCtorMethodId_; 3874514f5e3Sopenharmony_ci CUnorderedSet<uint32_t> skipCtorMethodId_; 3884514f5e3Sopenharmony_ci Mutex skipCtorMethodIdMutex_; 3894514f5e3Sopenharmony_ci JITProfiler *jitProfiler_ {nullptr}; 3904514f5e3Sopenharmony_ci CVector<ProfileType> recordedTransRootType_; 3914514f5e3Sopenharmony_ci friend class PGOProfilerManager; 3924514f5e3Sopenharmony_ci}; 3934514f5e3Sopenharmony_ci 3944514f5e3Sopenharmony_ciclass PGODumpPauseScope { 3954514f5e3Sopenharmony_cipublic: 3964514f5e3Sopenharmony_ci explicit PGODumpPauseScope(std::shared_ptr<PGOProfiler> profiler): profiler_(profiler) 3974514f5e3Sopenharmony_ci { 3984514f5e3Sopenharmony_ci profiler_->SuspendByGC(); 3994514f5e3Sopenharmony_ci } 4004514f5e3Sopenharmony_ci 4014514f5e3Sopenharmony_ci ~PGODumpPauseScope() 4024514f5e3Sopenharmony_ci { 4034514f5e3Sopenharmony_ci profiler_->ResumeByGC(); 4044514f5e3Sopenharmony_ci } 4054514f5e3Sopenharmony_ci 4064514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(PGODumpPauseScope); 4074514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(PGODumpPauseScope); 4084514f5e3Sopenharmony_ci 4094514f5e3Sopenharmony_ciprivate: 4104514f5e3Sopenharmony_ci std::shared_ptr<PGOProfiler> profiler_; 4114514f5e3Sopenharmony_ci}; 4124514f5e3Sopenharmony_ci} // namespace pgo 4134514f5e3Sopenharmony_ci} // namespace panda::ecmascript 4144514f5e3Sopenharmony_ci#endif // ECMASCRIPT_PGO_PROFILER_H 415