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 } InitJITProfiler()69 void InitJITProfiler() 70 { 71 ptManager_ = vm_->GetJSThread()->GetCurrentEcmaContext()->GetPTManager(); 72 } SetCompilationEnv(CompilationEnv *env)73 void SetCompilationEnv(CompilationEnv *env) 74 { 75 compilationEnv_ = env; 76 } InitChunk(Chunk* chunk)77 void InitChunk(Chunk* chunk) 78 { 79 chunk_ = chunk; 80 } 81 private: 82 enum class BCType : uint8_t { 83 STORE, 84 LOAD, 85 }; 86 87 // SampleType 88 void ConvertOpType(uint32_t slotId, long bcOffset); 89 void ConvertCall(uint32_t slotId, long bcOffset); 90 void ConvertNewObjRange(uint32_t slotId, long bcOffset); 91 void ConvertGetIterator(uint32_t slotId, long bcOffset); 92 93 // DefineType 94 void ConvertCreateObject(uint32_t slotId, long bcOffset, int32_t traceId); 95 96 // RwOpType 97 void ConvertICByName(int32_t bcOffset, uint32_t slotId, BCType type); 98 void ConvertICByNameWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass, 99 JSTaggedValue secondValue, BCType type, uint32_t slotId); 100 void HandleLoadType(ApEntityId &abcId, int32_t &bcOffset, 101 JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 102 void HandleLoadTypeInt(ApEntityId &abcId, int32_t &bcOffset, 103 JSHClass *hclass, JSTaggedValue &secondValue); 104 void HandleLoadTypePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 105 JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 106 void HandleOtherTypes(ApEntityId &abcId, int32_t &bcOffset, 107 JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 108 void HandleTransitionHandler(ApEntityId &abcId, int32_t &bcOffset, 109 JSHClass *hclass, JSTaggedValue &secondValue); 110 void HandleTransWithProtoHandler(ApEntityId &abcId, int32_t &bcOffset, 111 JSHClass *hclass, JSTaggedValue &secondValue); 112 void HandleOtherTypesPrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 113 JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId); 114 void HandleStoreTSHandler(ApEntityId &abcId, int32_t &bcOffset, 115 JSHClass *hclass, JSTaggedValue &secondValue); 116 void ConvertICByNameWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type, 117 uint32_t slotId); 118 void ConvertICByValue(int32_t bcOffset, uint32_t slotId, BCType type); 119 void ConvertICByValueWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass, 120 JSTaggedValue secondValue, BCType type); 121 void HandleStoreType(ApEntityId &abcId, int32_t &bcOffset, 122 JSHClass *hclass, JSTaggedValue &secondValue); 123 void HandleTransition(ApEntityId &abcId, int32_t &bcOffset, 124 JSHClass *hclass, JSTaggedValue &secondValue); 125 void HandleTransWithProto(ApEntityId &abcId, int32_t &bcOffset, 126 JSHClass *hclass, JSTaggedValue &secondValue); 127 void HandlePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 128 JSHClass *hclass, JSTaggedValue &secondValue); 129 void ConvertICByValueWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type); 130 void ConvertInstanceof(int32_t bcOffset, uint32_t slotId); 131 132 // RwOpType related 133 void AddObjectInfoWithMega(int32_t bcOffset); 134 void AddObjectInfoImplement(int32_t bcOffset, const PGOObjectInfo &info); 135 bool AddTranstionObjectInfo(int32_t bcOffset, JSHClass *receiver, 136 JSHClass *hold, JSHClass *holdTra, PGOSampleType accessorMethod); 137 bool AddObjectInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, 138 JSHClass *hold, JSHClass *holdTra, uint32_t accessorMethodId = 0); 139 void AddBuiltinsInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, 140 JSHClass *transitionHClass, OnHeapMode onHeap = OnHeapMode::NONE, 141 bool everOutOfBounds = false); 142 void AddBuiltinsGlobalInfo(ApEntityId abcId, int32_t bcOffset, GlobalIndex globalsId); 143 bool AddBuiltinsInfoByNameInInstance(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver); 144 bool AddBuiltinsInfoByNameInProt(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, JSHClass *hold); 145 146 JSTaggedValue TryFindKeyInPrototypeChain(TaggedObject *currObj, JSHClass *currHC, JSTaggedValue key); 147 bool IsJSHClassNotEqual(JSHClass *receiver, JSHClass *hold, JSHClass *exceptRecvHClass, 148 JSHClass *exceptRecvHClassOnHeap, JSHClass *exceptHoldHClass, 149 JSHClass *exceptPrototypeOfPrototypeHClass); 150 // Other UpdatePGOType(uint32_t offset, const pgo::PGOType *type)151 void UpdatePGOType(uint32_t offset, const pgo::PGOType *type) 152 { 153 if (type->IsScalarOpType()) { 154 bcOffsetPGOOpTypeMap_[offset] = reinterpret_cast<const PGOSampleType *>(type); 155 } else if (type->IsRwOpType()) { 156 bcOffsetPGORwTypeMap_[offset] = reinterpret_cast<const PGORWOpType *>(type); 157 } else if (type->IsDefineOpType()) { 158 bcOffsetPGODefOpTypeMap_[offset] = reinterpret_cast<const PGODefineOpType *>(type); 159 } else { 160 UNREACHABLE(); 161 } 162 } 163 164 void Clear(); 165 166 EcmaVM *vm_ { nullptr }; 167 kungfu::PGOTypeManager *ptManager_ { nullptr }; 168 ProfileTypeInfo* profileTypeInfo_ { nullptr }; 169 ApEntityId abcId_ { 0 }; 170 EntityId methodId_ {}; 171 std::unordered_map<int32_t, const PGOSampleType*> bcOffsetPGOOpTypeMap_ {}; 172 std::unordered_map<int32_t, const PGORWOpType*> bcOffsetPGORwTypeMap_ {}; 173 std::unordered_map<int32_t, const PGODefineOpType*> bcOffsetPGODefOpTypeMap_{}; 174 RecursiveMutex mutex_; 175 CompilationEnv *compilationEnv_ {nullptr}; 176 Chunk *chunk_ {nullptr}; 177 }; 178 179 } 180 #endif //ECMASCRIPT_JIT_PROFILER_H 181