• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #ifndef ECMASCRIPT_IC_PROFILE_TYPE_INFO_H
17 #define ECMASCRIPT_IC_PROFILE_TYPE_INFO_H
18 
19 #include "ecmascript/ic/mega_ic_cache.h"
20 #include "ecmascript/js_function.h"
21 #include "ecmascript/js_tagged_value.h"
22 #include "ecmascript/tagged_array.h"
23 #include "ecmascript/tagged_dictionary.h"
24 
25 namespace panda::ecmascript {
26 enum class ICKind : uint32_t {
27     NamedLoadIC,
28     NamedStoreIC,
29     LoadIC,
30     StoreIC,
31     NamedGlobalLoadIC,
32     NamedGlobalStoreIC,
33     NamedGlobalTryLoadIC,
34     NamedGlobalTryStoreIC,
35     GlobalLoadIC,
36     GlobalStoreIC,
37 };
38 
IsNamedGlobalIC(ICKind kind)39 static inline bool IsNamedGlobalIC(ICKind kind)
40 {
41     return (kind == ICKind::NamedGlobalLoadIC) || (kind == ICKind::NamedGlobalStoreIC) ||
42            (kind == ICKind::NamedGlobalTryLoadIC) || (kind == ICKind::NamedGlobalTryStoreIC);
43 }
44 
IsValueGlobalIC(ICKind kind)45 static inline bool IsValueGlobalIC(ICKind kind)
46 {
47     return (kind == ICKind::GlobalLoadIC) || (kind == ICKind::GlobalStoreIC);
48 }
49 
IsValueNormalIC(ICKind kind)50 static inline bool IsValueNormalIC(ICKind kind)
51 {
52     return (kind == ICKind::LoadIC) || (kind == ICKind::StoreIC);
53 }
54 
IsValueIC(ICKind kind)55 static inline bool IsValueIC(ICKind kind)
56 {
57     return IsValueNormalIC(kind) || IsValueGlobalIC(kind);
58 }
59 
IsNamedNormalIC(ICKind kind)60 static inline bool IsNamedNormalIC(ICKind kind)
61 {
62     return (kind == ICKind::NamedLoadIC) || (kind == ICKind::NamedStoreIC);
63 }
64 
IsNamedIC(ICKind kind)65 static inline bool IsNamedIC(ICKind kind)
66 {
67     return IsNamedNormalIC(kind) || IsNamedGlobalIC(kind);
68 }
69 
IsGlobalLoadIC(ICKind kind)70 static inline bool IsGlobalLoadIC(ICKind kind)
71 {
72     return (kind == ICKind::NamedGlobalLoadIC) || (kind == ICKind::GlobalLoadIC) ||
73            (kind == ICKind::NamedGlobalTryLoadIC);
74 }
75 
IsGlobalStoreIC(ICKind kind)76 static inline bool IsGlobalStoreIC(ICKind kind)
77 {
78     return (kind == ICKind::NamedGlobalStoreIC) || (kind == ICKind::GlobalStoreIC) ||
79            (kind == ICKind::NamedGlobalTryStoreIC);
80 }
81 
IsGlobalIC(ICKind kind)82 static inline bool IsGlobalIC(ICKind kind)
83 {
84     return IsValueGlobalIC(kind) || IsNamedGlobalIC(kind);
85 }
86 
87 std::string ICKindToString(ICKind kind);
88 
89 class ProfileTypeAccessorLockScope {
90 public:
ProfileTypeAccessorLockScope(JSThread * thread)91     ProfileTypeAccessorLockScope(JSThread *thread)
92     {
93         if (thread->GetEcmaVM()->IsEnableFastJit() || thread->GetEcmaVM()->IsEnableBaselineJit()) {
94             lockHolder_.emplace(thread->GetProfileTypeAccessorLock());
95         }
96     }
97 
98 private:
99     std::optional<LockHolder> lockHolder_;
100 };
101 
102 /**
103  *              ProfileTypeInfo
104  *      +--------------------------------+
105  *      |           ic slot              |
106  *      |            .....               |
107  *      +--------------------------------+
108  *      |        64 bits jit osr         |
109  *      |      tagged array address      |
110  *      +--------------------------------+
111  *      |    low 32 bits(PeriodCount)    |
112  *      |    hight 32 bits(jit hotness)  |
113  *      +--------------------------------+
114  *      |    low 32 bits(osr hotness)    |
115  *      | hight 32 bits(baseline hotness)|
116  *      +--------------------------------+
117  */
118 class ProfileTypeInfo : public TaggedArray {
119 public:
120     static const uint32_t MAX_FUNC_CACHE_INDEX = std::numeric_limits<uint32_t>::max();
121     static constexpr uint32_t INVALID_SLOT_INDEX = 0xFF;
122     static constexpr uint32_t MAX_SLOT_INDEX = 0xFFFF;
123     static constexpr size_t BIT_FIELD_INDEX = 2;
124     static constexpr size_t JIT_OSR_INDEX = 3;
125     static constexpr size_t EXTRA_INFO_MAP_INDEX = 4;
126     static constexpr size_t RESERVED_LENGTH = EXTRA_INFO_MAP_INDEX;
127     static constexpr size_t INITIAL_PERIOD_INDEX = 0;
128     static constexpr size_t PRE_DUMP_PERIOD_INDEX = 1;
129     static constexpr size_t DUMP_PERIOD_INDEX = 2;
130     static constexpr size_t BIG_METHOD_PERIOD_INDEX = 3;
131     static constexpr size_t INITIAL_OSR_HOTNESS_THRESHOLD = 0;
132     static constexpr size_t INITIAL_OSR_HOTNESS_CNT = 0;
133     static constexpr size_t INITIAL_JIT_CALL_THRESHOLD = 0;
134     static constexpr size_t INITIAL_JIT_CALL_CNT = 0;
135     static constexpr uint16_t JIT_DISABLE_FLAG = 0xFFFF;
136     static constexpr size_t JIT_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD = 4;  // 4 : 4 byte offset from bitfield
137     static constexpr size_t JIT_CNT_OFFSET_FROM_THRESHOLD = 2;  // 2 : 2 byte offset from jit hotness threshold
138     static constexpr size_t OSR_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD = 8;  // 8 : 8 byte offset from bitfield
139     static constexpr size_t OSR_CNT_OFFSET_FROM_OSR_THRESHOLD = 2;  // 2 : 2 byte offset from osr hotness threshold
140     static constexpr size_t BASELINEJIT_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD = 12; // 12: bytes offset from bitfield
141     static constexpr size_t JIT_CALL_CNT_OFFSET_FROM_BITFIELD = 14;  // 14 : 14 byte offset from bitfield
142 
Cast(TaggedObject * object)143     static ProfileTypeInfo *Cast(TaggedObject *object)
144     {
145         ASSERT(JSTaggedValue(object).IsTaggedArray());
146         return static_cast<ProfileTypeInfo *>(object);
147     }
148 
ComputeSize(uint32_t icSlotSize)149     static size_t ComputeSize(uint32_t icSlotSize)
150     {
151         return TaggedArray::ComputeSize(JSTaggedValue::TaggedTypeSize(), AdjustSlotSize(icSlotSize) + RESERVED_LENGTH);
152     }
153 
GetIcSlotLength()154     inline uint32_t GetIcSlotLength() const
155     {
156         return GetLength() - RESERVED_LENGTH;
157     }
158 
GetIcSlotToOsrLength()159     inline uint32_t GetIcSlotToOsrLength() const
160     {
161         return GetLength() - BIT_FIELD_INDEX;
162     }
163 
AdjustSlotSize(uint32_t icSlotSize)164     static inline uint32_t AdjustSlotSize(uint32_t icSlotSize)
165     {
166         // if ic slot size is 0xff comes from frontend, it means the actual size is 0x100.
167         // 0xff is a invalid slot index, which value is hole.
168         if (icSlotSize == INVALID_SLOT_INDEX) {
169             ++icSlotSize;
170         }
171         return icSlotSize;
172     }
173 
SetPrimitiveOfSlot(JSTaggedValue initValue,uint32_t icSlotSize)174     inline void SetPrimitiveOfSlot(JSTaggedValue initValue, uint32_t icSlotSize)
175     {
176         for (uint32_t i = 0; i < icSlotSize; i++) {
177             size_t offset = JSTaggedValue::TaggedTypeSize() * i;
178             if (i == INVALID_SLOT_INDEX) {
179                 Barriers::SetPrimitive<JSTaggedType>(GetData(), offset, JSTaggedValue::Hole().GetRawData());
180             } else {
181                 Barriers::SetPrimitive<JSTaggedType>(GetData(), offset, initValue.GetRawData());
182             }
183         }
184     }
185 
SetSpecialValue()186     inline void SetSpecialValue()
187     {
188         SetPeriodIndex(INITIAL_PERIOD_INDEX);
189         SetJitHotnessThreshold(JIT_DISABLE_FLAG);
190         SetJitHotnessCnt(0);
191         SetBaselineJitHotnessThreshold(JIT_DISABLE_FLAG);
192         SetOsrHotnessThreshold(INITIAL_OSR_HOTNESS_THRESHOLD);
193         SetOsrHotnessCnt(INITIAL_OSR_HOTNESS_CNT);
194         SetJitCallThreshold(INITIAL_JIT_CALL_THRESHOLD);
195     }
196 
InitializeExtraInfoMap()197     inline void InitializeExtraInfoMap()
198     {
199         // the last-1 of the cache is used to save extra info map
200         Barriers::SetPrimitive<JSTaggedType>(
201             GetData(), GetIcSlotLength() * JSTaggedValue::TaggedTypeSize(),
202             JSTaggedValue::Undefined().GetRawData());
203     }
204 
InitializeJitOsr()205     inline void InitializeJitOsr()
206     {
207         // the last of the cache is used to save osr jit tagged array
208         Barriers::SetPrimitive<JSTaggedType>(
209             GetData(), (GetIcSlotLength() + 1) * JSTaggedValue::TaggedTypeSize(),
210             JSTaggedValue::Undefined().GetRawData());
211     }
212 
213     inline void InitializeWithSpecialValue(JSTaggedValue initValue, uint32_t icSlotSize, uint32_t extraLength = 0)
214     {
215         ASSERT(initValue.IsSpecial());
216         icSlotSize = AdjustSlotSize(icSlotSize);
217         SetLength(icSlotSize + RESERVED_LENGTH);
218         SetExtraLength(extraLength);
219         SetPrimitiveOfSlot(initValue, icSlotSize);
220         InitializeExtraInfoMap();
221         InitializeJitOsr();
222         SetSpecialValue();
223     }
224 
SetPreDumpPeriodIndex()225     void SetPreDumpPeriodIndex()
226     {
227         SetPeriodIndex(PRE_DUMP_PERIOD_INDEX);
228     }
229 
IsProfileTypeInfoPreDumped()230     bool IsProfileTypeInfoPreDumped() const
231     {
232         return GetPeriodIndex() == PRE_DUMP_PERIOD_INDEX;
233     }
234 
SetBigMethodPeriodIndex()235     void SetBigMethodPeriodIndex()
236     {
237         SetPeriodIndex(BIG_METHOD_PERIOD_INDEX);
238     }
239 
IsProfileTypeInfoWithBigMethod()240     bool IsProfileTypeInfoWithBigMethod() const
241     {
242         return GetPeriodIndex() == BIG_METHOD_PERIOD_INDEX;
243     }
244 
GetExtraInfoMap(const JSThread * thread)245     JSTaggedValue GetExtraInfoMap(const JSThread *thread) const
246     {
247         return JSTaggedValue(Barriers::GetTaggedValue(thread, GetData(), GetExtraInfoMapOffset()));
248     }
249 
SetExtraInfoMap(const JSThread * thread,JSHandle<NumberDictionary> extraInfoMap)250     void SetExtraInfoMap(const JSThread *thread, JSHandle<NumberDictionary> extraInfoMap)
251     {
252         Barriers::SetObject<true>(thread, reinterpret_cast<void*>(this),
253                                   TaggedArray::DATA_OFFSET + GetExtraInfoMapOffset(),
254                                   extraInfoMap.GetTaggedValue().GetRawData());
255     }
256 
GetJitHotnessThreshold()257     uint16_t GetJitHotnessThreshold() const
258     {
259         return Barriers::GetPrimitive<uint16_t>(GetData(), GetJitHotnessThresholdBitfieldOffset());
260     }
261 
SetJitHotnessThreshold(uint16_t count)262     void SetJitHotnessThreshold(uint16_t count)
263     {
264         Barriers::SetPrimitive(GetData(), GetJitHotnessThresholdBitfieldOffset(), count);
265     }
266 
GetOsrHotnessThreshold()267     uint16_t GetOsrHotnessThreshold() const
268     {
269         return Barriers::GetPrimitive<uint16_t>(GetData(), GetOsrHotnessThresholdBitfieldOffset());
270     }
271 
SetOsrHotnessThreshold(uint16_t count)272     void SetOsrHotnessThreshold(uint16_t count)
273     {
274         Barriers::SetPrimitive(GetData(), GetOsrHotnessThresholdBitfieldOffset(), count);
275     }
276 
GetBaselineJitHotnessThreshold()277     uint16_t GetBaselineJitHotnessThreshold() const
278     {
279         return Barriers::GetPrimitive<uint16_t>(GetData(), GetBaselineJitHotnessThresholdBitfieldOffset());
280     }
281 
SetBaselineJitHotnessThreshold(uint16_t count)282     void SetBaselineJitHotnessThreshold(uint16_t count)
283     {
284         Barriers::SetPrimitive(GetData(), GetBaselineJitHotnessThresholdBitfieldOffset(), count);
285     }
286 
SetJitCallThreshold(uint16_t count)287     void SetJitCallThreshold(uint16_t count)
288     {
289         Barriers::SetPrimitive(GetData(), GetJitCallCntBitfieldOffset(), count);
290     }
291 
GetJitHotnessCnt()292     uint16_t GetJitHotnessCnt() const
293     {
294         return Barriers::GetPrimitive<uint16_t>(GetData(), GetJitHotnessCntBitfieldOffset());
295     }
296 
SetJitHotnessCnt(uint16_t count)297     void SetJitHotnessCnt(uint16_t count)
298     {
299         Barriers::SetPrimitive(GetData(), GetJitHotnessCntBitfieldOffset(), count);
300     }
301 
SetOsrHotnessCnt(uint16_t count)302     void SetOsrHotnessCnt(uint16_t count)
303     {
304         Barriers::SetPrimitive(GetData(), GetOsrHotnessCntBitfieldOffset(), count);
305     }
306 
GetIcSlot(const JSThread * thread,uint32_t idx)307     inline JSTaggedValue GetIcSlot(const JSThread* thread, uint32_t idx) const
308     {
309         ASSERT(idx < GetIcSlotLength());
310         return TaggedArray::Get(thread, idx);
311     }
312 
SetIcSlot(const JSThread * thread,uint32_t idx,const JSTaggedValue & value)313     inline void SetIcSlot(const JSThread* thread, uint32_t idx, const JSTaggedValue& value)
314     {
315         ASSERT(idx < GetIcSlotLength());
316         TaggedArray::Set(thread, idx, value);
317     }
318 
SetMultiIcSlotLocked(JSThread * thread,uint32_t firstIdx,const JSTaggedValue & firstValue,uint32_t secondIdx,const JSTaggedValue & secondValue)319     inline void SetMultiIcSlotLocked(JSThread* thread, uint32_t firstIdx, const JSTaggedValue& firstValue,
320         uint32_t secondIdx, const JSTaggedValue& secondValue)
321     {
322         ProfileTypeAccessorLockScope accessorLockScope(thread);
323         ASSERT(firstIdx < GetIcSlotLength());
324         ASSERT(secondIdx < GetIcSlotLength());
325         TaggedArray::Set(thread, firstIdx, firstValue);
326         TaggedArray::Set(thread, secondIdx, secondValue);
327     }
328 
CreateOrGetExtraInfoMap(const JSThread * thread,JSHandle<ProfileTypeInfo> profileTypeInfo)329     static JSHandle<NumberDictionary> CreateOrGetExtraInfoMap(const JSThread *thread,
330                                                               JSHandle<ProfileTypeInfo> profileTypeInfo)
331     {
332         if (profileTypeInfo->GetExtraInfoMap(thread).IsUndefined()) {
333             JSHandle<NumberDictionary> dictJShandle = NumberDictionary::Create(thread);
334             profileTypeInfo->SetExtraInfoMap(thread, dictJShandle);
335             return dictJShandle;
336         }
337         JSHandle<NumberDictionary> dictJShandle(thread, profileTypeInfo->GetExtraInfoMap(thread));
338         return dictJShandle;
339     }
340 
UpdateExtraInfoMap(const JSThread * thread,JSHandle<NumberDictionary> dictJShandle,JSHandle<JSTaggedValue> key,JSHandle<JSTaggedValue> receiverHClassHandle,JSHandle<JSTaggedValue> holderHClassHandle,JSHandle<ProfileTypeInfo> profileTypeInfo)341     static void UpdateExtraInfoMap(const JSThread *thread, JSHandle<NumberDictionary> dictJShandle,
342                             JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> receiverHClassHandle,
343                             JSHandle<JSTaggedValue> holderHClassHandle,
344                             JSHandle<ProfileTypeInfo> profileTypeInfo)
345     {
346         JSHandle<JSTaggedValue> info(thread->GetEcmaVM()->GetFactory()->NewExtraProfileTypeInfo());
347         JSHandle<ExtraProfileTypeInfo> infoHandle(info);
348         infoHandle->SetReceiver(thread, receiverHClassHandle.GetTaggedValue().CreateAndGetWeakRef());
349         infoHandle->SetHolder(thread, holderHClassHandle.GetTaggedValue());
350         JSHandle<NumberDictionary> dict = NumberDictionary::PutIfAbsent(thread,
351                                                                         dictJShandle,
352                                                                         key,
353                                                                         info,
354                                                                         PropertyAttributes::Default());
355         profileTypeInfo->SetExtraInfoMap(thread, dict);
356     }
357 
358     DECL_VISIT_ARRAY(DATA_OFFSET, GetIcSlotToOsrLength(), GetIcSlotToOsrLength());
359 
DECL_DUMP()360     DECL_DUMP()
361 
362 private:
363     uint32_t GetPeriodIndex() const
364     {
365         return Barriers::GetPrimitive<uint32_t>(GetData(), GetBitfieldOffset());
366     }
367 
SetPeriodIndex(uint32_t count)368     void SetPeriodIndex(uint32_t count)
369     {
370         Barriers::SetPrimitive(GetData(), GetBitfieldOffset(), count);
371     }
372 
GetBitfieldOffset()373     inline size_t GetBitfieldOffset() const
374     {
375         return JSTaggedValue::TaggedTypeSize() * (GetLength() - BIT_FIELD_INDEX);
376     }
377 
GetExtraInfoMapOffset()378     inline size_t GetExtraInfoMapOffset() const
379     {
380         return JSTaggedValue::TaggedTypeSize() * (GetLength() - EXTRA_INFO_MAP_INDEX);
381     }
382 
383     // jit hotness(16bits) + count(16bits)
GetJitHotnessThresholdBitfieldOffset()384     inline size_t GetJitHotnessThresholdBitfieldOffset() const
385     {
386         return GetBitfieldOffset() + JIT_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD;
387     }
388 
GetJitHotnessCntBitfieldOffset()389     inline size_t GetJitHotnessCntBitfieldOffset() const
390     {
391         return GetJitHotnessThresholdBitfieldOffset() + JIT_CNT_OFFSET_FROM_THRESHOLD;
392     }
393 
394     // osr hotness(16bits) + count(16bits)
GetOsrHotnessThresholdBitfieldOffset()395     inline size_t GetOsrHotnessThresholdBitfieldOffset() const
396     {
397         return GetBitfieldOffset() + OSR_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD;
398     }
399 
400     // baselinejit hotness(16bits)
GetBaselineJitHotnessThresholdBitfieldOffset()401     inline size_t GetBaselineJitHotnessThresholdBitfieldOffset() const
402     {
403         return GetBitfieldOffset() + BASELINEJIT_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD;
404     }
405 
GetOsrHotnessCntBitfieldOffset()406     inline size_t GetOsrHotnessCntBitfieldOffset() const
407     {
408         return GetOsrHotnessThresholdBitfieldOffset() + OSR_CNT_OFFSET_FROM_OSR_THRESHOLD;
409     }
410 
411     // jit call count(16bits)
GetJitCallCntBitfieldOffset()412     inline size_t GetJitCallCntBitfieldOffset() const
413     {
414         return GetBitfieldOffset() + JIT_CALL_CNT_OFFSET_FROM_BITFIELD;
415     }
416 };
417 
418 class ProfileTypeAccessor {
419 public:
420     static constexpr size_t CACHE_MAX_LEN = 8;
421     static constexpr size_t MONO_CASE_NUM = 2;
422     static constexpr size_t POLY_CASE_NUM = 4;
423 
424     enum ICState {
425         UNINIT,
426         MONO,
427         POLY,
428         IC_MEGA,
429         MEGA,
430     };
431 
432 #if ECMASCRIPT_ENABLE_TRACE_LOAD
433     enum MegaState {
434         NONE,
435         NOTFOUND_MEGA,
436         DICT_MEGA,
437     };
438 #endif
439 
ProfileTypeAccessor(JSThread * thread,JSHandle<ProfileTypeInfo> profileTypeInfo,uint32_t slotId,ICKind kind)440     ProfileTypeAccessor(JSThread* thread, JSHandle<ProfileTypeInfo> profileTypeInfo, uint32_t slotId, ICKind kind)
441         : thread_(thread), profileTypeInfo_(profileTypeInfo), slotId_(slotId), kind_(kind)
442     {
443         enableICMega_ = thread_->GetEcmaVM()->GetJSOptions().IsEnableMegaIC();
444     }
445     ~ProfileTypeAccessor() = default;
446     ICState GetMegaState() const;
447     ICState GetICState() const;
448     static std::string ICStateToString(ICState state);
449     void AddHandlerWithoutKey(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler,
450                               JSHandle<JSTaggedValue> keyForMegaIC = JSHandle<JSTaggedValue>(),
451                               MegaICCache::MegaICKind kind = MegaICCache::MegaICKind::None) const;
452     void AddWithoutKeyPoly(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler, uint32_t index,
453                            JSTaggedValue profileData, JSHandle<JSTaggedValue> keyForMegaIC = JSHandle<JSTaggedValue>(),
454                            MegaICCache::MegaICKind kind = MegaICCache::MegaICKind::None) const;
455 
456     void AddElementHandler(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler) const;
457     void AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> hclass,
458                            JSHandle<JSTaggedValue> handler) const;
459     void AddGlobalHandlerKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> handler) const;
460     void AddGlobalRecordHandler(JSHandle<JSTaggedValue> handler) const;
461 
GetWeakRef(JSTaggedValue value)462     JSTaggedValue GetWeakRef(JSTaggedValue value) const
463     {
464         return JSTaggedValue(value.CreateAndGetWeakRef());
465     }
466 
GetRefFromWeak(const JSTaggedValue & value)467     JSTaggedValue GetRefFromWeak(const JSTaggedValue &value) const
468     {
469         return JSTaggedValue(value.GetWeakReferent());
470     }
471     void SetAsMega() const;
472     void SetAsMegaIfUndefined() const;
473     void SetAsMegaForTraceSlowMode(ObjectOperator& op) const;
474     void SetAsMegaForTrace(JSTaggedValue value) const;
475 
GetKind()476     ICKind GetKind() const
477     {
478         return kind_;
479     }
480 
GetSlotId()481     uint32_t GetSlotId() const
482     {
483         return slotId_;
484     }
485 
486 private:
487     JSThread* thread_;
488     JSHandle<ProfileTypeInfo> profileTypeInfo_;
489     uint32_t slotId_;
490     ICKind kind_;
491     bool enableICMega_;
492 };
493 }  // namespace panda::ecmascript
494 
495 #endif  // ECMASCRIPT_IC_PROFILE_TYPE_INFO_H
496