• 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()245     JSTaggedValue GetExtraInfoMap() const
246     {
247         return JSTaggedValue(Barriers::GetValue<JSTaggedType>(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, GetData(), GetExtraInfoMapOffset(),
253                                   extraInfoMap.GetTaggedValue().GetRawData());
254     }
255 
GetJitHotnessThreshold()256     uint16_t GetJitHotnessThreshold() const
257     {
258         return Barriers::GetValue<uint16_t>(GetData(), GetJitHotnessThresholdBitfieldOffset());
259     }
260 
SetJitHotnessThreshold(uint16_t count)261     void SetJitHotnessThreshold(uint16_t count)
262     {
263         Barriers::SetPrimitive(GetData(), GetJitHotnessThresholdBitfieldOffset(), count);
264     }
265 
GetOsrHotnessThreshold()266     uint16_t GetOsrHotnessThreshold() const
267     {
268         return Barriers::GetValue<uint16_t>(GetData(), GetOsrHotnessThresholdBitfieldOffset());
269     }
270 
SetOsrHotnessThreshold(uint16_t count)271     void SetOsrHotnessThreshold(uint16_t count)
272     {
273         Barriers::SetPrimitive(GetData(), GetOsrHotnessThresholdBitfieldOffset(), count);
274     }
275 
GetBaselineJitHotnessThreshold()276     uint16_t GetBaselineJitHotnessThreshold() const
277     {
278         return Barriers::GetValue<uint16_t>(GetData(), GetBaselineJitHotnessThresholdBitfieldOffset());
279     }
280 
SetBaselineJitHotnessThreshold(uint16_t count)281     void SetBaselineJitHotnessThreshold(uint16_t count)
282     {
283         Barriers::SetPrimitive(GetData(), GetBaselineJitHotnessThresholdBitfieldOffset(), count);
284     }
285 
SetJitCallThreshold(uint16_t count)286     void SetJitCallThreshold(uint16_t count)
287     {
288         Barriers::SetPrimitive(GetData(), GetJitCallCntBitfieldOffset(), count);
289     }
290 
GetJitHotnessCnt()291     uint16_t GetJitHotnessCnt() const
292     {
293         return Barriers::GetValue<uint16_t>(GetData(), GetJitHotnessCntBitfieldOffset());
294     }
295 
SetJitHotnessCnt(uint16_t count)296     void SetJitHotnessCnt(uint16_t count)
297     {
298         Barriers::SetPrimitive(GetData(), GetJitHotnessCntBitfieldOffset(), count);
299     }
300 
SetOsrHotnessCnt(uint16_t count)301     void SetOsrHotnessCnt(uint16_t count)
302     {
303         Barriers::SetPrimitive(GetData(), GetOsrHotnessCntBitfieldOffset(), count);
304     }
305 
GetIcSlot(uint32_t idx)306     inline JSTaggedValue GetIcSlot(uint32_t idx) const
307     {
308         ASSERT(idx < GetIcSlotLength());
309         return TaggedArray::Get(idx);
310     }
311 
SetIcSlot(const JSThread * thread,uint32_t idx,const JSTaggedValue & value)312     inline void SetIcSlot(const JSThread* thread, uint32_t idx, const JSTaggedValue& value)
313     {
314         ASSERT(idx < GetIcSlotLength());
315         TaggedArray::Set(thread, idx, value);
316     }
317 
SetMultiIcSlotLocked(JSThread * thread,uint32_t firstIdx,const JSTaggedValue & firstValue,uint32_t secondIdx,const JSTaggedValue & secondValue)318     inline void SetMultiIcSlotLocked(JSThread* thread, uint32_t firstIdx, const JSTaggedValue& firstValue,
319         uint32_t secondIdx, const JSTaggedValue& secondValue)
320     {
321         ProfileTypeAccessorLockScope accessorLockScope(thread);
322         ASSERT(firstIdx < GetIcSlotLength());
323         ASSERT(secondIdx < GetIcSlotLength());
324         TaggedArray::Set(thread, firstIdx, firstValue);
325         TaggedArray::Set(thread, secondIdx, secondValue);
326     }
327 
CreateOrGetExtraInfoMap(const JSThread * thread,JSHandle<ProfileTypeInfo> profileTypeInfo)328     static JSHandle<NumberDictionary> CreateOrGetExtraInfoMap(const JSThread *thread,
329                                                               JSHandle<ProfileTypeInfo> profileTypeInfo)
330     {
331         if (profileTypeInfo->GetExtraInfoMap().IsUndefined()) {
332             JSHandle<NumberDictionary> dictJShandle = NumberDictionary::Create(thread);
333             profileTypeInfo->SetExtraInfoMap(thread, dictJShandle);
334             return dictJShandle;
335         }
336         JSHandle<NumberDictionary> dictJShandle(thread, profileTypeInfo->GetExtraInfoMap());
337         return dictJShandle;
338     }
339 
UpdateExtraInfoMap(const JSThread * thread,JSHandle<NumberDictionary> dictJShandle,JSHandle<JSTaggedValue> key,JSHandle<JSTaggedValue> receiverHClassHandle,JSHandle<JSTaggedValue> holderHClassHandle,JSHandle<ProfileTypeInfo> profileTypeInfo)340     static void UpdateExtraInfoMap(const JSThread *thread, JSHandle<NumberDictionary> dictJShandle,
341                             JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> receiverHClassHandle,
342                             JSHandle<JSTaggedValue> holderHClassHandle,
343                             JSHandle<ProfileTypeInfo> profileTypeInfo)
344     {
345         JSHandle<JSTaggedValue> info(thread->GetEcmaVM()->GetFactory()->NewExtraProfileTypeInfo());
346         JSHandle<ExtraProfileTypeInfo> infoHandle(info);
347         infoHandle->SetReceiver(thread, receiverHClassHandle.GetTaggedValue().CreateAndGetWeakRef());
348         infoHandle->SetHolder(thread, holderHClassHandle.GetTaggedValue());
349         JSHandle<NumberDictionary> dict = NumberDictionary::PutIfAbsent(thread,
350                                                                         dictJShandle,
351                                                                         key,
352                                                                         info,
353                                                                         PropertyAttributes::Default());
354         profileTypeInfo->SetExtraInfoMap(thread, dict);
355     }
356 
357     DECL_VISIT_ARRAY(DATA_OFFSET, GetIcSlotToOsrLength(), GetIcSlotToOsrLength());
358 
DECL_DUMP()359     DECL_DUMP()
360 
361 private:
362     uint32_t GetPeriodIndex() const
363     {
364         return Barriers::GetValue<uint32_t>(GetData(), GetBitfieldOffset());
365     }
366 
SetPeriodIndex(uint32_t count)367     void SetPeriodIndex(uint32_t count)
368     {
369         Barriers::SetPrimitive(GetData(), GetBitfieldOffset(), count);
370     }
371 
GetBitfieldOffset()372     inline size_t GetBitfieldOffset() const
373     {
374         return JSTaggedValue::TaggedTypeSize() * (GetLength() - BIT_FIELD_INDEX);
375     }
376 
GetExtraInfoMapOffset()377     inline size_t GetExtraInfoMapOffset() const
378     {
379         return JSTaggedValue::TaggedTypeSize() * (GetLength() - EXTRA_INFO_MAP_INDEX);
380     }
381 
382     // jit hotness(16bits) + count(16bits)
GetJitHotnessThresholdBitfieldOffset()383     inline size_t GetJitHotnessThresholdBitfieldOffset() const
384     {
385         return GetBitfieldOffset() + JIT_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD;
386     }
387 
GetJitHotnessCntBitfieldOffset()388     inline size_t GetJitHotnessCntBitfieldOffset() const
389     {
390         return GetJitHotnessThresholdBitfieldOffset() + JIT_CNT_OFFSET_FROM_THRESHOLD;
391     }
392 
393     // osr hotness(16bits) + count(16bits)
GetOsrHotnessThresholdBitfieldOffset()394     inline size_t GetOsrHotnessThresholdBitfieldOffset() const
395     {
396         return GetBitfieldOffset() + OSR_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD;
397     }
398 
399     // baselinejit hotness(16bits)
GetBaselineJitHotnessThresholdBitfieldOffset()400     inline size_t GetBaselineJitHotnessThresholdBitfieldOffset() const
401     {
402         return GetBitfieldOffset() + BASELINEJIT_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD;
403     }
404 
GetOsrHotnessCntBitfieldOffset()405     inline size_t GetOsrHotnessCntBitfieldOffset() const
406     {
407         return GetOsrHotnessThresholdBitfieldOffset() + OSR_CNT_OFFSET_FROM_OSR_THRESHOLD;
408     }
409 
410     // jit call count(16bits)
GetJitCallCntBitfieldOffset()411     inline size_t GetJitCallCntBitfieldOffset() const
412     {
413         return GetBitfieldOffset() + JIT_CALL_CNT_OFFSET_FROM_BITFIELD;
414     }
415 };
416 
417 class ProfileTypeAccessor {
418 public:
419     static constexpr size_t CACHE_MAX_LEN = 8;
420     static constexpr size_t MONO_CASE_NUM = 2;
421     static constexpr size_t POLY_CASE_NUM = 4;
422 
423     enum ICState {
424         UNINIT,
425         MONO,
426         POLY,
427         IC_MEGA,
428         MEGA,
429     };
430 
431 #if ECMASCRIPT_ENABLE_TRACE_LOAD
432     enum MegaState {
433         NONE,
434         NOTFOUND_MEGA,
435         DICT_MEGA,
436     };
437 #endif
438 
ProfileTypeAccessor(JSThread * thread,JSHandle<ProfileTypeInfo> profileTypeInfo,uint32_t slotId,ICKind kind)439     ProfileTypeAccessor(JSThread* thread, JSHandle<ProfileTypeInfo> profileTypeInfo, uint32_t slotId, ICKind kind)
440         : thread_(thread), profileTypeInfo_(profileTypeInfo), slotId_(slotId), kind_(kind)
441     {
442         enableICMega_ = thread_->GetEcmaVM()->GetJSOptions().IsEnableMegaIC();
443     }
444     ~ProfileTypeAccessor() = default;
445     ICState GetMegaState() const;
446     ICState GetICState() const;
447     static std::string ICStateToString(ICState state);
448     void AddHandlerWithoutKey(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler,
449                               JSHandle<JSTaggedValue> keyForMegaIC = JSHandle<JSTaggedValue>(),
450                               MegaICCache::MegaICKind kind = MegaICCache::MegaICKind::None) const;
451     void AddWithoutKeyPoly(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler, uint32_t index,
452                            JSTaggedValue profileData, JSHandle<JSTaggedValue> keyForMegaIC = JSHandle<JSTaggedValue>(),
453                            MegaICCache::MegaICKind kind = MegaICCache::MegaICKind::None) const;
454 
455     void AddElementHandler(JSHandle<JSTaggedValue> hclass, JSHandle<JSTaggedValue> handler) const;
456     void AddHandlerWithKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> hclass,
457                            JSHandle<JSTaggedValue> handler) const;
458     void AddGlobalHandlerKey(JSHandle<JSTaggedValue> key, JSHandle<JSTaggedValue> handler) const;
459     void AddGlobalRecordHandler(JSHandle<JSTaggedValue> handler) const;
460 
GetWeakRef(JSTaggedValue value)461     JSTaggedValue GetWeakRef(JSTaggedValue value) const
462     {
463         return JSTaggedValue(value.CreateAndGetWeakRef());
464     }
465 
GetRefFromWeak(const JSTaggedValue & value)466     JSTaggedValue GetRefFromWeak(const JSTaggedValue &value) const
467     {
468         return JSTaggedValue(value.GetWeakReferent());
469     }
470     void SetAsMega() const;
471     void SetAsMegaForTraceSlowMode(ObjectOperator& op) const;
472     void SetAsMegaForTrace(JSTaggedValue value) const;
473 
GetKind()474     ICKind GetKind() const
475     {
476         return kind_;
477     }
478 
GetSlotId()479     uint32_t GetSlotId() const
480     {
481         return slotId_;
482     }
483 
484 private:
485     JSThread* thread_;
486     JSHandle<ProfileTypeInfo> profileTypeInfo_;
487     uint32_t slotId_;
488     ICKind kind_;
489     bool enableICMega_;
490 };
491 }  // namespace panda::ecmascript
492 
493 #endif  // ECMASCRIPT_IC_PROFILE_TYPE_INFO_H
494