1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef ECMASCRIPT_JIT_PROFILER_H 16 #define ECMASCRIPT_JIT_PROFILER_H 17 #include <chrono> 18 #include <memory> 19 #include "ecmascript/common.h" 20 #include "ecmascript/compiler/bytecodes.h" 21 #include "ecmascript/compiler/compilation_env.h" 22 #include "ecmascript/elements.h" 23 #include "ecmascript/ecma_context.h" 24 #include "ecmascript/js_tagged_value.h" 25 #include "ecmascript/jspandafile/method_literal.h" 26 #include "ecmascript/mem/c_containers.h" 27 #include "ecmascript/mem/native_area_allocator.h" 28 #include "ecmascript/mem/region.h" 29 #include "ecmascript/mem/visitor.h" 30 #include "ecmascript/patch/patch_loader.h" 31 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 32 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 33 #include "ecmascript/pgo_profiler/types/pgo_type_generator.h" 34 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 35 #include "ecmascript/platform/mutex.h" 36 #include "ecmascript/taskpool/task.h" 37 #include "ecmascript/pgo_profiler/pgo_utils.h" 38 namespace panda::ecmascript { 39 using namespace pgo; 40 class ProfileTypeInfo; 41 class JSFunction; 42 class PGOProfilerManager; 43 class JITProfiler { 44 public: 45 NO_COPY_SEMANTIC(JITProfiler); 46 NO_MOVE_SEMANTIC(JITProfiler); 47 48 JITProfiler(EcmaVM *vm); 49 50 virtual ~JITProfiler(); 51 void PUBLIC_API ProfileBytecode(JSThread *thread, const JSHandle<ProfileTypeInfo> &profileTypeInfo, 52 ProfileTypeInfo *rawProfileTypeInfo, 53 EntityId methodId, ApEntityId abcId, const uint8_t *pcStart, 54 uint32_t codeSize, const panda_file::File::Header *header, 55 bool useRawProfileTypeInfo = false); 56 GetOpTypeMap()57 std::unordered_map<int32_t, const PGOSampleType *> GetOpTypeMap() 58 { 59 return bcOffsetPGOOpTypeMap_; 60 } GetRwTypeMap()61 std::unordered_map<int32_t, const PGORWOpType *> GetRwTypeMap() 62 { 63 return bcOffsetPGORwTypeMap_; 64 } GetDefOpTypeMap()65 std::unordered_map<int32_t, const PGODefineOpType *> GetDefOpTypeMap() 66 { 67 return bcOffsetPGODefOpTypeMap_; 68 } GetBoolMap()69 std::unordered_map<int32_t, bool> GetBoolMap() 70 { 71 return bcOffsetBoolMap_; 72 } InitJITProfiler()73 void InitJITProfiler() 74 { 75 mainThread_ = vm_->GetJSThread(); 76 ptManager_ = mainThread_->GetCurrentEcmaContext()->GetPTManager(); 77 } SetCompilationEnv(CompilationEnv * env)78 void SetCompilationEnv(CompilationEnv *env) 79 { 80 compilationEnv_ = env; 81 } InitChunk(Chunk * chunk)82 void InitChunk(Chunk* chunk) 83 { 84 chunk_ = chunk; 85 } 86 private: 87 enum class BCType : uint8_t { 88 STORE, 89 LOAD, 90 }; 91 92 // SampleType 93 void ConvertOpType(uint32_t slotId, long bcOffset); 94 void ConvertCall(uint32_t slotId, long bcOffset); 95 void ConvertNewObjRange(uint32_t slotId, long bcOffset); 96 void ConvertGetIterator(uint32_t slotId, long bcOffset); 97 98 // DefineType 99 void ConvertCreateObject(uint32_t slotId, long bcOffset, int32_t traceId); 100 101 // RwOpType 102 void ConvertICByName(int32_t bcOffset, uint32_t slotId, BCType type); 103 void ConvertICByNameWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass, 104 JSTaggedValue secondValue, BCType type, uint32_t slotId); 105 void HandleLoadType(ApEntityId &abcId, int32_t &bcOffset, 106 JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 107 void HandleLoadTypeInt(ApEntityId &abcId, int32_t &bcOffset, 108 JSHClass *hclass, JSTaggedValue &secondValue); 109 void HandleLoadTypePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 110 JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 111 void HandleOtherTypes(ApEntityId &abcId, int32_t &bcOffset, 112 JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 113 void HandleTransitionHandler(ApEntityId &abcId, int32_t &bcOffset, 114 JSHClass *hclass, JSTaggedValue &secondValue); 115 void HandleTransWithProtoHandler(ApEntityId &abcId, int32_t &bcOffset, 116 JSHClass *hclass, JSTaggedValue &secondValue); 117 void HandleOtherTypesPrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 118 JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 119 void HandleStoreAOTHandler(ApEntityId &abcId, int32_t &bcOffset, 120 JSHClass *hclass, JSTaggedValue &secondValue); 121 void ConvertICByNameWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type, 122 uint32_t slotId); 123 void ConvertICByValue(int32_t bcOffset, uint32_t slotId, BCType type); 124 void ConvertICByValueWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass, 125 JSTaggedValue secondValue, BCType type); 126 void HandleStoreType(ApEntityId &abcId, int32_t &bcOffset, 127 JSHClass *hclass, JSTaggedValue &secondValue); 128 void HandleTransition(ApEntityId &abcId, int32_t &bcOffset, 129 JSHClass *hclass, JSTaggedValue &secondValue); 130 void HandleTransWithProto(ApEntityId &abcId, int32_t &bcOffset, 131 JSHClass *hclass, JSTaggedValue &secondValue); 132 void HandlePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 133 JSHClass *hclass, JSTaggedValue &secondValue); 134 void ConvertICByValueWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type); 135 void ConvertInstanceof(int32_t bcOffset, uint32_t slotId); 136 137 // RwOpType related 138 void AddObjectInfoWithMega(int32_t bcOffset); 139 void AddObjectInfoImplement(int32_t bcOffset, const PGOObjectInfo &info); 140 bool AddTranstionObjectInfo(int32_t bcOffset, JSHClass *receiver, 141 JSHClass *hold, JSHClass *holdTra, PGOSampleType accessorMethod); 142 bool AddObjectInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, 143 JSHClass *hold, JSHClass *holdTra, uint32_t accessorMethodId = 0); 144 void AddBuiltinsInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, 145 JSHClass *transitionHClass, OnHeapMode onHeap = OnHeapMode::NONE, 146 bool everOutOfBounds = false); 147 void AddBuiltinsGlobalInfo(ApEntityId abcId, int32_t bcOffset, GlobalIndex globalId); 148 bool AddBuiltinsInfoByNameInInstance(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver); 149 bool AddBuiltinsInfoByNameInProt(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, JSHClass *hold); 150 151 JSTaggedValue TryFindKeyInPrototypeChain(TaggedObject *currObj, JSHClass *currHC, JSTaggedValue key); 152 bool IsJSHClassNotEqual(JSHClass *receiver, JSHClass *hold, JSHClass *exceptRecvHClass, 153 JSHClass *exceptRecvHClassOnHeap, JSHClass *exceptHoldHClass, 154 JSHClass *exceptPrototypeOfPrototypeHClass); 155 // Other UpdatePGOType(uint32_t offset,const pgo::PGOType * type)156 void UpdatePGOType(uint32_t offset, const pgo::PGOType *type) 157 { 158 if (type->IsScalarOpType()) { 159 bcOffsetPGOOpTypeMap_[offset] = reinterpret_cast<const PGOSampleType *>(type); 160 } else if (type->IsRwOpType()) { 161 bcOffsetPGORwTypeMap_[offset] = reinterpret_cast<const PGORWOpType *>(type); 162 } else if (type->IsDefineOpType()) { 163 bcOffsetPGODefOpTypeMap_[offset] = reinterpret_cast<const PGODefineOpType *>(type); 164 } else { 165 UNREACHABLE(); 166 } 167 } 168 169 inline void SetBcOffsetBool(uint32_t offset, bool isInsufficientProfile = false) 170 { 171 bcOffsetBoolMap_[offset] = isInsufficientProfile; 172 } 173 174 inline bool IsIncompleteProfileTypeInfo(); 175 inline bool SlotValueIsUndefined(uint32_t slotId); 176 inline void UpdateBcOffsetBool(uint32_t offset, uint32_t slotId); 177 inline void UpdateBcOffsetBoolWithNearSlotId(uint32_t offset, uint32_t slotId); 178 179 void Clear(); 180 181 EcmaVM *vm_ { nullptr }; 182 JSThread *mainThread_ {nullptr}; 183 kungfu::PGOTypeManager *ptManager_ { nullptr }; 184 ProfileTypeInfo* profileTypeInfo_ { nullptr }; 185 ApEntityId abcId_ { 0 }; 186 EntityId methodId_ {}; 187 std::unordered_map<int32_t, const PGOSampleType*> bcOffsetPGOOpTypeMap_ {}; 188 std::unordered_map<int32_t, const PGORWOpType*> bcOffsetPGORwTypeMap_ {}; 189 std::unordered_map<int32_t, const PGODefineOpType*> bcOffsetPGODefOpTypeMap_{}; 190 std::unordered_map<int32_t, bool> bcOffsetBoolMap_ {}; 191 RecursiveMutex mutex_; 192 CompilationEnv *compilationEnv_ {nullptr}; 193 Chunk *chunk_ {nullptr}; 194 }; 195 196 } 197 #endif //ECMASCRIPT_JIT_PROFILER_H 198