14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 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#ifndef ECMASCRIPT_JIT_PROFILER_H 164514f5e3Sopenharmony_ci#define ECMASCRIPT_JIT_PROFILER_H 174514f5e3Sopenharmony_ci#include <chrono> 184514f5e3Sopenharmony_ci#include <memory> 194514f5e3Sopenharmony_ci#include "ecmascript/common.h" 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/bytecodes.h" 214514f5e3Sopenharmony_ci#include "ecmascript/compiler/compilation_env.h" 224514f5e3Sopenharmony_ci#include "ecmascript/elements.h" 234514f5e3Sopenharmony_ci#include "ecmascript/ecma_context.h" 244514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value.h" 254514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/method_literal.h" 264514f5e3Sopenharmony_ci#include "ecmascript/mem/c_containers.h" 274514f5e3Sopenharmony_ci#include "ecmascript/mem/native_area_allocator.h" 284514f5e3Sopenharmony_ci#include "ecmascript/mem/region.h" 294514f5e3Sopenharmony_ci#include "ecmascript/mem/visitor.h" 304514f5e3Sopenharmony_ci#include "ecmascript/patch/patch_loader.h" 314514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 324514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 334514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/types/pgo_type_generator.h" 344514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 354514f5e3Sopenharmony_ci#include "ecmascript/platform/mutex.h" 364514f5e3Sopenharmony_ci#include "ecmascript/taskpool/task.h" 374514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_utils.h" 384514f5e3Sopenharmony_cinamespace panda::ecmascript { 394514f5e3Sopenharmony_ciusing namespace pgo; 404514f5e3Sopenharmony_ciclass ProfileTypeInfo; 414514f5e3Sopenharmony_ciclass JSFunction; 424514f5e3Sopenharmony_ciclass PGOProfilerManager; 434514f5e3Sopenharmony_ciclass JITProfiler { 444514f5e3Sopenharmony_cipublic: 454514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(JITProfiler); 464514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(JITProfiler); 474514f5e3Sopenharmony_ci 484514f5e3Sopenharmony_ci JITProfiler(EcmaVM *vm); 494514f5e3Sopenharmony_ci 504514f5e3Sopenharmony_ci virtual ~JITProfiler(); 514514f5e3Sopenharmony_ci void PUBLIC_API ProfileBytecode(JSThread *thread, const JSHandle<ProfileTypeInfo> &profileTypeInfo, 524514f5e3Sopenharmony_ci ProfileTypeInfo *rawProfileTypeInfo, 534514f5e3Sopenharmony_ci EntityId methodId, ApEntityId abcId, const uint8_t *pcStart, 544514f5e3Sopenharmony_ci uint32_t codeSize, const panda_file::File::Header *header, 554514f5e3Sopenharmony_ci bool useRawProfileTypeInfo = false); 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_ci std::unordered_map<int32_t, const PGOSampleType *> GetOpTypeMap() 584514f5e3Sopenharmony_ci { 594514f5e3Sopenharmony_ci return bcOffsetPGOOpTypeMap_; 604514f5e3Sopenharmony_ci } 614514f5e3Sopenharmony_ci std::unordered_map<int32_t, const PGORWOpType *> GetRwTypeMap() 624514f5e3Sopenharmony_ci { 634514f5e3Sopenharmony_ci return bcOffsetPGORwTypeMap_; 644514f5e3Sopenharmony_ci } 654514f5e3Sopenharmony_ci std::unordered_map<int32_t, const PGODefineOpType *> GetDefOpTypeMap() 664514f5e3Sopenharmony_ci { 674514f5e3Sopenharmony_ci return bcOffsetPGODefOpTypeMap_; 684514f5e3Sopenharmony_ci } 694514f5e3Sopenharmony_ci void InitJITProfiler() 704514f5e3Sopenharmony_ci { 714514f5e3Sopenharmony_ci ptManager_ = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager(); 724514f5e3Sopenharmony_ci } 734514f5e3Sopenharmony_ci void SetCompilationEnv(CompilationEnv *env) 744514f5e3Sopenharmony_ci { 754514f5e3Sopenharmony_ci compilationEnv_ = env; 764514f5e3Sopenharmony_ci } 774514f5e3Sopenharmony_ci void InitChunk(Chunk* chunk) 784514f5e3Sopenharmony_ci { 794514f5e3Sopenharmony_ci chunk_ = chunk; 804514f5e3Sopenharmony_ci } 814514f5e3Sopenharmony_ciprivate: 824514f5e3Sopenharmony_ci enum class BCType : uint8_t { 834514f5e3Sopenharmony_ci STORE, 844514f5e3Sopenharmony_ci LOAD, 854514f5e3Sopenharmony_ci }; 864514f5e3Sopenharmony_ci 874514f5e3Sopenharmony_ci // SampleType 884514f5e3Sopenharmony_ci void ConvertOpType(uint32_t slotId, long bcOffset); 894514f5e3Sopenharmony_ci void ConvertCall(uint32_t slotId, long bcOffset); 904514f5e3Sopenharmony_ci void ConvertNewObjRange(uint32_t slotId, long bcOffset); 914514f5e3Sopenharmony_ci void ConvertGetIterator(uint32_t slotId, long bcOffset); 924514f5e3Sopenharmony_ci 934514f5e3Sopenharmony_ci // DefineType 944514f5e3Sopenharmony_ci void ConvertCreateObject(uint32_t slotId, long bcOffset, int32_t traceId); 954514f5e3Sopenharmony_ci 964514f5e3Sopenharmony_ci // RwOpType 974514f5e3Sopenharmony_ci void ConvertICByName(int32_t bcOffset, uint32_t slotId, BCType type); 984514f5e3Sopenharmony_ci void ConvertICByNameWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass, 994514f5e3Sopenharmony_ci JSTaggedValue secondValue, BCType type, uint32_t slotId); 1004514f5e3Sopenharmony_ci void HandleLoadType(ApEntityId &abcId, int32_t &bcOffset, 1014514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 1024514f5e3Sopenharmony_ci void HandleLoadTypeInt(ApEntityId &abcId, int32_t &bcOffset, 1034514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue); 1044514f5e3Sopenharmony_ci void HandleLoadTypePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 1054514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 1064514f5e3Sopenharmony_ci void HandleOtherTypes(ApEntityId &abcId, int32_t &bcOffset, 1074514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 1084514f5e3Sopenharmony_ci void HandleTransitionHandler(ApEntityId &abcId, int32_t &bcOffset, 1094514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue); 1104514f5e3Sopenharmony_ci void HandleTransWithProtoHandler(ApEntityId &abcId, int32_t &bcOffset, 1114514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue); 1124514f5e3Sopenharmony_ci void HandleOtherTypesPrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 1134514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 1144514f5e3Sopenharmony_ci void HandleStoreTSHandler(ApEntityId &abcId, int32_t &bcOffset, 1154514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue); 1164514f5e3Sopenharmony_ci void ConvertICByNameWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type, 1174514f5e3Sopenharmony_ci uint32_t slotId); 1184514f5e3Sopenharmony_ci void ConvertICByValue(int32_t bcOffset, uint32_t slotId, BCType type); 1194514f5e3Sopenharmony_ci void ConvertICByValueWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass, 1204514f5e3Sopenharmony_ci JSTaggedValue secondValue, BCType type); 1214514f5e3Sopenharmony_ci void HandleStoreType(ApEntityId &abcId, int32_t &bcOffset, 1224514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue); 1234514f5e3Sopenharmony_ci void HandleTransition(ApEntityId &abcId, int32_t &bcOffset, 1244514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue); 1254514f5e3Sopenharmony_ci void HandleTransWithProto(ApEntityId &abcId, int32_t &bcOffset, 1264514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue); 1274514f5e3Sopenharmony_ci void HandlePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 1284514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue); 1294514f5e3Sopenharmony_ci void ConvertICByValueWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type); 1304514f5e3Sopenharmony_ci void ConvertInstanceof(int32_t bcOffset, uint32_t slotId); 1314514f5e3Sopenharmony_ci 1324514f5e3Sopenharmony_ci // RwOpType related 1334514f5e3Sopenharmony_ci void AddObjectInfoWithMega(int32_t bcOffset); 1344514f5e3Sopenharmony_ci void AddObjectInfoImplement(int32_t bcOffset, const PGOObjectInfo &info); 1354514f5e3Sopenharmony_ci bool AddTranstionObjectInfo(int32_t bcOffset, JSHClass *receiver, 1364514f5e3Sopenharmony_ci JSHClass *hold, JSHClass *holdTra, PGOSampleType accessorMethod); 1374514f5e3Sopenharmony_ci bool AddObjectInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, 1384514f5e3Sopenharmony_ci JSHClass *hold, JSHClass *holdTra, uint32_t accessorMethodId = 0); 1394514f5e3Sopenharmony_ci void AddBuiltinsInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, 1404514f5e3Sopenharmony_ci JSHClass *transitionHClass, OnHeapMode onHeap = OnHeapMode::NONE, 1414514f5e3Sopenharmony_ci bool everOutOfBounds = false); 1424514f5e3Sopenharmony_ci void AddBuiltinsGlobalInfo(ApEntityId abcId, int32_t bcOffset, GlobalIndex globalsId); 1434514f5e3Sopenharmony_ci bool AddBuiltinsInfoByNameInInstance(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver); 1444514f5e3Sopenharmony_ci bool AddBuiltinsInfoByNameInProt(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, JSHClass *hold); 1454514f5e3Sopenharmony_ci 1464514f5e3Sopenharmony_ci JSTaggedValue TryFindKeyInPrototypeChain(TaggedObject *currObj, JSHClass *currHC, JSTaggedValue key); 1474514f5e3Sopenharmony_ci bool IsJSHClassNotEqual(JSHClass *receiver, JSHClass *hold, JSHClass *exceptRecvHClass, 1484514f5e3Sopenharmony_ci JSHClass *exceptRecvHClassOnHeap, JSHClass *exceptHoldHClass, 1494514f5e3Sopenharmony_ci JSHClass *exceptPrototypeOfPrototypeHClass); 1504514f5e3Sopenharmony_ci // Other 1514514f5e3Sopenharmony_ci void UpdatePGOType(uint32_t offset, const pgo::PGOType *type) 1524514f5e3Sopenharmony_ci { 1534514f5e3Sopenharmony_ci if (type->IsScalarOpType()) { 1544514f5e3Sopenharmony_ci bcOffsetPGOOpTypeMap_[offset] = reinterpret_cast<const PGOSampleType *>(type); 1554514f5e3Sopenharmony_ci } else if (type->IsRwOpType()) { 1564514f5e3Sopenharmony_ci bcOffsetPGORwTypeMap_[offset] = reinterpret_cast<const PGORWOpType *>(type); 1574514f5e3Sopenharmony_ci } else if (type->IsDefineOpType()) { 1584514f5e3Sopenharmony_ci bcOffsetPGODefOpTypeMap_[offset] = reinterpret_cast<const PGODefineOpType *>(type); 1594514f5e3Sopenharmony_ci } else { 1604514f5e3Sopenharmony_ci UNREACHABLE(); 1614514f5e3Sopenharmony_ci } 1624514f5e3Sopenharmony_ci } 1634514f5e3Sopenharmony_ci 1644514f5e3Sopenharmony_ci void Clear(); 1654514f5e3Sopenharmony_ci 1664514f5e3Sopenharmony_ci EcmaVM *vm_ { nullptr }; 1674514f5e3Sopenharmony_ci kungfu::PGOTypeManager *ptManager_ { nullptr }; 1684514f5e3Sopenharmony_ci ProfileTypeInfo* profileTypeInfo_ { nullptr }; 1694514f5e3Sopenharmony_ci ApEntityId abcId_ { 0 }; 1704514f5e3Sopenharmony_ci EntityId methodId_ {}; 1714514f5e3Sopenharmony_ci std::unordered_map<int32_t, const PGOSampleType*> bcOffsetPGOOpTypeMap_ {}; 1724514f5e3Sopenharmony_ci std::unordered_map<int32_t, const PGORWOpType*> bcOffsetPGORwTypeMap_ {}; 1734514f5e3Sopenharmony_ci std::unordered_map<int32_t, const PGODefineOpType*> bcOffsetPGODefOpTypeMap_{}; 1744514f5e3Sopenharmony_ci RecursiveMutex mutex_; 1754514f5e3Sopenharmony_ci CompilationEnv *compilationEnv_ {nullptr}; 1764514f5e3Sopenharmony_ci Chunk *chunk_ {nullptr}; 1774514f5e3Sopenharmony_ci}; 1784514f5e3Sopenharmony_ci 1794514f5e3Sopenharmony_ci} 1804514f5e3Sopenharmony_ci#endif //ECMASCRIPT_JIT_PROFILER_H 181