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