• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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