• 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 "common_components/taskpool/task.h"
20 #include "ecmascript/common.h"
21 #include "ecmascript/compiler/bytecodes.h"
22 #include "ecmascript/compiler/compilation_env.h"
23 #include "ecmascript/elements.h"
24 #include "ecmascript/js_primitive_ref.h"
25 #include "ecmascript/js_tagged_value.h"
26 #include "ecmascript/jspandafile/method_literal.h"
27 #include "ecmascript/mem/c_containers.h"
28 #include "ecmascript/mem/native_area_allocator.h"
29 #include "ecmascript/mem/region.h"
30 #include "ecmascript/mem/visitor.h"
31 #include "ecmascript/patch/patch_loader.h"
32 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
33 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
34 #include "ecmascript/pgo_profiler/types/pgo_type_generator.h"
35 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
36 #include "ecmascript/platform/mutex.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                                     JSHandle<JSFunction> jsFunction, JSHandle<GlobalEnv> env,
56                                     bool useRawProfileTypeInfo = false);
57 
GetOpTypeMap()58     std::unordered_map<int32_t, const PGOSampleType *> GetOpTypeMap()
59     {
60         return bcOffsetPGOOpTypeMap_;
61     }
GetRwTypeMap()62     std::unordered_map<int32_t, const PGORWOpType *> GetRwTypeMap()
63     {
64         return bcOffsetPGORwTypeMap_;
65     }
GetDefOpTypeMap()66     std::unordered_map<int32_t, const PGODefineOpType *> GetDefOpTypeMap()
67     {
68         return bcOffsetPGODefOpTypeMap_;
69     }
GetBoolMap()70     std::unordered_map<int32_t, bool> GetBoolMap()
71     {
72         return bcOffsetBoolMap_;
73     }
InitJITProfiler()74     void InitJITProfiler()
75     {
76         mainThread_ = vm_->GetJSThread();
77         ptManager_ = vm_->GetPTManager();
78     }
SetCompilationEnv(CompilationEnv * env)79     void SetCompilationEnv(CompilationEnv *env)
80     {
81         compilationEnv_ = env;
82     }
InitChunk(Chunk * chunk)83     void InitChunk(Chunk* chunk)
84     {
85         chunk_ = chunk;
86     }
87 private:
88     static const int INVALID_METHOD_INDEX = 0;
89     enum class BCType : uint8_t {
90         STORE,
91         LOAD,
92     };
93 
94     // SampleType
95     void ConvertOpType(uint32_t slotId, long bcOffset);
96     void ConvertCall(uint32_t slotId, long bcOffset);
97     void ConvertNewObjRange(uint32_t slotId, long bcOffset);
98     void ConvertGetIterator(uint32_t slotId, long bcOffset);
99 
100     // DefineType
101     void ConvertCreateObject(uint32_t slotId, long bcOffset, int32_t traceId);
102 
103     // RwOpType
104     void ConvertICByName(int32_t bcOffset, uint32_t slotId,  BCType type);
105     void ConvertICByNameWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass,
106 		                    JSTaggedValue secondValue, BCType type, uint32_t slotId);
107     void HandleLoadType(ApEntityId &abcId, int32_t &bcOffset,
108                         JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId);
109     void HandleLoadTypeInt(ApEntityId &abcId, int32_t &bcOffset,
110                            JSHClass *hclass, JSTaggedValue &secondValue);
111     void HandleLoadTypePrototypeHandler(
112         ApEntityId &abcId, int32_t &bcOffset, JSHClass *hclass,
113         JSTaggedValue &secondValue, uint32_t slotId,
114         JSTaggedValue = JSTaggedValue::Undefined());
115     void HandleOtherTypes(ApEntityId &abcId, int32_t &bcOffset,
116                           JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId);
117     void HandleTransitionHandler(ApEntityId &abcId, int32_t &bcOffset,
118                                  JSHClass *hclass, JSTaggedValue &secondValue);
119     void HandleTransWithProtoHandler(ApEntityId &abcId, int32_t &bcOffset,
120                                      JSHClass *hclass, JSTaggedValue &secondValue);
121     void HandleOtherTypesPrototypeHandler(ApEntityId &abcId, int32_t &bcOffset,
122                                           JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId);
123     void HandleStoreAOTHandler(ApEntityId &abcId, int32_t &bcOffset,
124                               JSHClass *hclass, JSTaggedValue &secondValue);
125     void ConvertICByNameWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type,
126                                  uint32_t slotId);
127     void ConvertICByValue(int32_t bcOffset, uint32_t slotId, BCType type);
128     void ConvertICByValueWithHandler(ApEntityId abcId, int32_t bcOffset, JSHClass *hclass, JSTaggedValue secondValue,
129                                      BCType type, uint32_t slotId, JSTaggedValue name = JSTaggedValue::Undefined());
130     void HandleStoreType(ApEntityId &abcId, int32_t &bcOffset,
131                          JSHClass *hclass, JSTaggedValue &secondValue);
132     void HandleTransition(ApEntityId &abcId, int32_t &bcOffset,
133                           JSHClass *hclass, JSTaggedValue &secondValue);
134     void HandleTransWithProto(ApEntityId &abcId, int32_t &bcOffset,
135                               JSHClass *hclass, JSTaggedValue &secondValue);
136     void HandlePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset,
137                                 JSHClass *hclass, JSTaggedValue &secondValue);
138     void ConvertICByValueWithPoly(ApEntityId abcId, int32_t bcOffset,
139                                   JSTaggedValue name, JSTaggedValue cacheValue,
140                                   BCType type, uint32_t slotId);
141     void ConvertInstanceof(int32_t bcOffset, uint32_t slotId);
142     void ConvertTryldGlobalByName(uint32_t bcOffset, uint32_t slotId);
143 
144     void ConvertExternalModuleVar(uint32_t index, uint32_t bcOffset);
145 
146     // RwOpType related
147     void AddObjectInfoWithMega(int32_t bcOffset);
148     void AddObjectInfoImplement(int32_t bcOffset, const PGOObjectInfo &info,
149                                 JSTaggedValue name = JSTaggedValue::Undefined());
150     bool AddTranstionObjectInfo(int32_t bcOffset, JSHClass *receiver, JSHClass *hold, JSHClass *holdTra,
151                                 PGOSampleType accessorMethod, PrimitiveType primitiveType = PRIMITIVE_TYPE_INVALID,
152                                 JSTaggedValue name = JSTaggedValue::Undefined());
153     bool AddObjectInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver,
154                        JSHClass *hold, JSHClass *holdTra, uint32_t accessorMethodId = INVALID_METHOD_INDEX,
155                        PrimitiveType primitiveType = PRIMITIVE_TYPE_INVALID,
156                        JSTaggedValue name = JSTaggedValue::Undefined());
157     void AddBuiltinsInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver,
158                          JSHClass *transitionHClass, OnHeapMode onHeap = OnHeapMode::NONE,
159                          bool everOutOfBounds = false);
160     bool IsTypedArrayRootHClass(JSType jsType, OnHeapMode mode, JSHClass *receiver);
161     void AddBuiltinsGlobalInfo(ApEntityId abcId, int32_t bcOffset, GlobalIndex globalId);
162     bool AddBuiltinsInfoByNameInInstance(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver);
163     bool AddBuiltinsInfoByNameInProt(ApEntityId abcId, int32_t bcOffset,
164                                      JSHClass *receiver, JSHClass *hold, bool isNonExist);
165     JSTaggedValue TryFindKeyInPrototypeChain(TaggedObject *currObj, JSHClass *currHC, JSTaggedValue key);
166     bool IsJSHClassNotEqual(JSHClass *receiver, JSHClass *hold, JSHClass *exceptRecvHClass,
167 		            JSHClass *exceptRecvHClassOnHeap, JSHClass *exceptHoldHClass,
168 			    JSHClass *exceptPrototypeOfPrototypeHClass);
169     // Other
UpdatePGOType(uint32_t offset,const pgo::PGOType * type)170     void UpdatePGOType(uint32_t offset, const pgo::PGOType *type)
171     {
172         if (type->IsScalarOpType()) {
173             bcOffsetPGOOpTypeMap_[offset] = reinterpret_cast<const PGOSampleType *>(type);
174         } else if (type->IsRwOpType()) {
175             bcOffsetPGORwTypeMap_[offset] = reinterpret_cast<const PGORWOpType *>(type);
176         } else if (type->IsDefineOpType()) {
177             bcOffsetPGODefOpTypeMap_[offset] = reinterpret_cast<const PGODefineOpType *>(type);
178         } else {
179             UNREACHABLE();
180         }
181     }
182 
183     inline void SetBcOffsetBool(uint32_t offset, bool isInsufficientProfile = false)
184     {
185         bcOffsetBoolMap_[offset] = isInsufficientProfile;
186     }
187 
188     inline bool IsIncompleteProfileTypeInfo();
189     inline bool SlotValueIsUndefined(uint32_t slotId);
190     inline void UpdateBcOffsetBool(uint32_t offset, uint32_t slotId);
191     inline void UpdateBcOffsetBoolWithNearSlotId(uint32_t offset, uint32_t slotId);
192 
193     void Clear();
194 
SetCurrentGlobalEnv(JSHandle<GlobalEnv> env)195     inline void SetCurrentGlobalEnv(JSHandle<GlobalEnv> env)
196     {
197         env_ = env;
198     }
199 
GetCurrentGlobalEnv()200     inline const JSHandle<GlobalEnv> GetCurrentGlobalEnv()
201     {
202         return env_;
203     }
204 
205     EcmaVM *vm_ { nullptr };
206     JSThread *mainThread_ {nullptr};
207     kungfu::PGOTypeManager *ptManager_ { nullptr };
208     JSHandle<ProfileTypeInfo> profileTypeInfo_;
209     ApEntityId abcId_ { 0 };
210     EntityId methodId_ {};
211     std::unordered_map<int32_t, const PGOSampleType*> bcOffsetPGOOpTypeMap_ {};
212     std::unordered_map<int32_t, const PGORWOpType*> bcOffsetPGORwTypeMap_ {};
213     std::unordered_map<int32_t, const PGODefineOpType*> bcOffsetPGODefOpTypeMap_{};
214     std::unordered_map<int32_t, bool> bcOffsetBoolMap_ {};
215     RecursiveMutex mutex_;
216     CompilationEnv *compilationEnv_ {nullptr};
217     Chunk *chunk_ {nullptr};
218     JSHandle<JSFunction> jsFunction_;
219     JSHandle<GlobalEnv> env_;
220 };
221 
222 }
223 #endif //ECMASCRIPT_JIT_PROFILER_H
224