• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_COMPILER_TYPE_INFO_ACCESSORS_H
17 #define ECMASCRIPT_COMPILER_TYPE_INFO_ACCESSORS_H
18 
19 #include "ecmascript/compiler/aot_compiler_preprocessor.h"
20 #include "ecmascript/compiler/argument_accessor.h"
21 #include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
22 #include "ecmascript/enum_conversion.h"
23 #include "ecmascript/global_index.h"
24 #include "ecmascript/jspandafile/program_object.h"
25 #include "ecmascript/mem/chunk.h"
26 #include "libpandafile/index_accessor.h"
27 
28 namespace panda::ecmascript::kungfu {
29 class TypeInfoAccessor {
30 public:
TypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)31     TypeInfoAccessor(const CompilationEnv *env, Circuit* circuit, GateRef gate)
32         : compilationEnv_(env),
33           acc_(circuit),
34           argAcc_(circuit),
35           gate_(gate)
36     {
37         pgoType_ = acc_.TryGetPGOType(gate);
38         // NOTICE-PGO: wx delete in part3
39         ptManager_ = compilationEnv_->GetPTManager();
40         isAot_ = compilationEnv_->IsAotCompiler();
41     }
42 
GetGate()43     inline GateRef GetGate() const
44     {
45         return gate_;
46     }
47 
48     static bool IsTrustedBooleanType(GateAccessor acc, GateRef gate);
49 
50     static bool IsTrustedNumberType(GateAccessor acc, GateRef gate);
51 
52     static bool IsTrustedStringType(
53         const CompilationEnv *env, Circuit *circuit, Chunk *chunk, GateAccessor acc, GateRef gate);
54 
IsTrustedBooleanOrNumberOrStringType(const CompilationEnv * env,Circuit * circuit,Chunk * chunk,GateAccessor acc,GateRef gate)55     static inline bool IsTrustedBooleanOrNumberOrStringType(const CompilationEnv *env, Circuit *circuit,
56                                                             Chunk *chunk, GateAccessor acc, GateRef gate)
57     {
58         return IsTrustedBooleanType(acc, gate) || IsTrustedNumberType(acc, gate) ||
59                IsTrustedStringType(env, circuit, chunk, acc, gate);
60     }
61 
IsAot()62     inline bool IsAot() const
63     {
64         return isAot_;
65     }
66 
67     static bool IsTrustedNotSameType(const CompilationEnv *env, Circuit *circuit, Chunk *chunk,
68                                      GateAccessor acc, GateRef left, GateRef right);
69 
70     BuiltinsStubCSigns::ID TryGetPGOBuiltinMethodId() const;
71 
72     static constexpr uint32_t INVALID_LEN = std::numeric_limits<uint32_t>::max();
73 
74 protected:
75     ParamType PGOSampleTypeToParamType() const;
76     static ParamType PGOBuiltinTypeToParamType(ProfileType pgoType);
77     bool IsMegaType() const;
78 
79     const CompilationEnv *compilationEnv_ {nullptr};
80     GateAccessor acc_;
81     ArgumentAccessor argAcc_;
82     GateRef gate_;
83     PGOTypeRef pgoType_;
84     // NOTICE-PGO: wx delete in part3
85     PGOTypeManager *ptManager_ {nullptr};
86     bool isAot_;
87 };
88 
89 class BinOpTypeInfoAccessor final : public TypeInfoAccessor {
90 public:
BinOpTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)91     BinOpTypeInfoAccessor(const CompilationEnv *env,
92                           Circuit *circuit,
93                           GateRef gate)
94         : TypeInfoAccessor(env, circuit, gate)
95     {
96         left_ = acc_.GetValueIn(gate, 0);   // 0: left
97         right_ = acc_.GetValueIn(gate, 1);  // 1: right
98     }
99     NO_COPY_SEMANTIC(BinOpTypeInfoAccessor);
100     NO_MOVE_SEMANTIC(BinOpTypeInfoAccessor);
101 
GetLeftGate()102     inline GateRef GetLeftGate() const
103     {
104         return left_;
105     }
106 
GetReightGate()107     inline GateRef GetReightGate() const
108     {
109         return right_;
110     }
111 
HasNumberType()112     inline bool HasNumberType() const
113     {
114         if (LeftOrRightIsUndefinedOrNull()) {
115             return false;
116         }
117         return pgoType_.HasNumber();
118     }
119 
IsStringType()120     inline bool IsStringType() const
121     {
122         if (LeftOrRightIsUndefinedOrNull()) {
123             return false;
124         }
125         return pgoType_.IsString();
126     }
127 
IsInternStringType()128     inline bool IsInternStringType() const
129     {
130         if (LeftOrRightIsUndefinedOrNull()) {
131             return false;
132         }
133         return pgoType_.IsInternString();
134     }
135 
IsNumberOrStringType()136     inline bool IsNumberOrStringType() const
137     {
138         if (LeftOrRightIsUndefinedOrNull()) {
139             return false;
140         }
141         return pgoType_.IsNumberOrString();
142     }
143 
LeftOrRightIsUndefinedOrNull()144     inline bool LeftOrRightIsUndefinedOrNull() const
145     {
146         return acc_.IsUndefinedOrNullOrHole(left_) || acc_.IsUndefinedOrNullOrHole(right_);
147     }
148 
GetParamType()149     inline ParamType GetParamType() const
150     {
151         if (LeftOrRightIsUndefinedOrNull()) {
152             return ParamType::AnyType();
153         }
154         return PGOSampleTypeToParamType();
155     }
156 
157 private:
158     GateRef left_;
159     GateRef right_;
160 };
161 
162 class UnOpTypeInfoAccessor : public TypeInfoAccessor {
163 public:
UnOpTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)164     UnOpTypeInfoAccessor(const CompilationEnv *env,
165                          Circuit *circuit,
166                          GateRef gate)
167         : TypeInfoAccessor(env, circuit, gate)
168     {
169         value_ = acc_.GetValueIn(gate, 0); // 0: value
170     }
171     NO_COPY_SEMANTIC(UnOpTypeInfoAccessor);
172     NO_MOVE_SEMANTIC(UnOpTypeInfoAccessor);
173 
GetValue()174     inline GateRef GetValue() const
175     {
176         return value_;
177     }
178 
HasNumberType()179     inline bool HasNumberType() const
180     {
181         return pgoType_.HasNumber();
182     }
183 
IsBooleanType()184     inline bool IsBooleanType() const
185     {
186         return pgoType_.IsBoolean();
187     }
188 
IsUndefinedOrNullType()189     inline bool IsUndefinedOrNullType() const
190     {
191         return pgoType_.IsUndefinedOrNull();
192     }
193 
GetParamType()194     inline ParamType GetParamType() const
195     {
196         return PGOSampleTypeToParamType();
197     }
198 
GetValueGateType()199     GateType GetValueGateType() const
200     {
201         return acc_.GetGateType(value_);
202     }
203 
204 protected:
205     GateRef value_ {Circuit::NullGate()};
206 };
207 
208 class ConditionJumpTypeInfoAccessor final : public UnOpTypeInfoAccessor {
209 public:
ConditionJumpTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)210     ConditionJumpTypeInfoAccessor(const CompilationEnv *env,
211                                   Circuit *circuit,
212                                   GateRef gate)
213         : UnOpTypeInfoAccessor(env, circuit, gate) {}
214     NO_COPY_SEMANTIC(ConditionJumpTypeInfoAccessor);
215     NO_MOVE_SEMANTIC(ConditionJumpTypeInfoAccessor);
216 
GetBranchWeight()217     uint32_t GetBranchWeight() const
218     {
219         return acc_.TryGetPGOType(value_).GetPGOSampleType()->GetWeight();
220     }
221 };
222 
223 class NewObjRangeTypeInfoAccessor final : public UnOpTypeInfoAccessor {
224 public:
225     class AccessorStrategy {
226     public:
227         virtual ~AccessorStrategy() = default;
228         virtual bool IsValidCallMethodId() const = 0;
229         virtual uint32_t GetCallMethodId() const = 0;
230         virtual bool FindHClass() const = 0;
231         virtual JSTaggedValue GetHClass() const = 0;
232     };
233 
234     class AotAccessorStrategy : public AccessorStrategy {
235     public:
AotAccessorStrategy(NewObjRangeTypeInfoAccessor & parent)236         explicit AotAccessorStrategy(NewObjRangeTypeInfoAccessor &parent) : parent_(parent)
237         {
238         }
239 
IsValidCallMethodId()240         bool IsValidCallMethodId() const override
241         {
242             return parent_.pgoType_.IsValidCallMethodId();
243         }
244 
GetCallMethodId()245         uint32_t GetCallMethodId() const override
246         {
247             ASSERT(IsValidCallMethodId());
248             return parent_.pgoType_.GetCallMethodId();
249         }
250         bool FindHClass() const override;
251         JSTaggedValue GetHClass() const override;
252 
253     private:
254         NewObjRangeTypeInfoAccessor &parent_;
255     };
256 
257     class JitAccessorStrategy : public AccessorStrategy {
258     public:
JitAccessorStrategy(NewObjRangeTypeInfoAccessor & parent)259         explicit JitAccessorStrategy(NewObjRangeTypeInfoAccessor &parent) : parent_(parent)
260         {
261         }
262 
IsValidCallMethodId()263         bool IsValidCallMethodId() const override
264         {
265             return parent_.pgoType_.IsDefOpValidCallMethodId();
266         }
267 
GetCallMethodId()268         uint32_t GetCallMethodId() const override
269         {
270             ASSERT(IsValidCallMethodId());
271             return parent_.pgoType_.GetDefOpCallMethodId();
272         }
273         bool FindHClass() const override;
274         JSTaggedValue GetHClass() const override;
275 
276     private:
277         NewObjRangeTypeInfoAccessor &parent_;
278     };
279 
NewObjRangeTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk)280     NewObjRangeTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk* chunk)
281         : UnOpTypeInfoAccessor(env, circuit, gate), hclassIndex_(-1), traHClassIndex_(-1)
282     {
283         if (IsAot()) {
284             strategy_ = chunk->New<AotAccessorStrategy>(*this);
285         } else {
286             strategy_ = chunk->New<JitAccessorStrategy>(*this);
287         }
288     }
289     NO_COPY_SEMANTIC(NewObjRangeTypeInfoAccessor);
290     NO_MOVE_SEMANTIC(NewObjRangeTypeInfoAccessor);
291 
FindHClass()292     bool FindHClass()
293     {
294         return strategy_->FindHClass();
295     }
GetHClass()296     JSTaggedValue GetHClass()
297     {
298         return strategy_->GetHClass();
299     }
300 
IsValidCallMethodId()301     bool IsValidCallMethodId() const
302     {
303         return strategy_->IsValidCallMethodId();
304     }
305 
GetCallMethodId()306     uint32_t GetCallMethodId() const
307     {
308         ASSERT(IsValidCallMethodId());
309         return strategy_->GetCallMethodId();
310     }
311 
GetHClassIndex()312     int GetHClassIndex() const
313     {
314         if (traHClassIndex_ != -1) {
315             return traHClassIndex_;
316         }
317         return hclassIndex_;
318     }
319 
320 private:
321     int hclassIndex_;
322     int traHClassIndex_ {-1};
323     AccessorStrategy* strategy_;
324 
325     friend class AotAccessorStrategy;
326     friend class JitAccessorStrategy;
327 };
328 
329 class NewBuiltinCtorTypeInfoAccessor final : public UnOpTypeInfoAccessor {
330 public:
NewBuiltinCtorTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)331     NewBuiltinCtorTypeInfoAccessor(const CompilationEnv *env,
332                                    Circuit *circuit,
333                                    GateRef gate)
334         : UnOpTypeInfoAccessor(env, circuit, gate) {}
335     NO_COPY_SEMANTIC(NewBuiltinCtorTypeInfoAccessor);
336     NO_MOVE_SEMANTIC(NewBuiltinCtorTypeInfoAccessor);
337 
IsBuiltinId(BuiltinsStubCSigns::ID id)338     bool IsBuiltinId(BuiltinsStubCSigns::ID id)
339     {
340         if (pgoType_.IsPGOSampleType()) {
341             return TryGetPGOBuiltinMethodId() == id;
342         } else {
343             return false;
344         }
345     }
346 
347 private:
GetCtorGT()348     GlobalTSTypeRef GetCtorGT() const
349     {
350         return GetValueGateType().GetGTRef();
351     }
352 };
353 
354 class TypeOfTypeInfoAccessor final : public UnOpTypeInfoAccessor {
355 public:
TypeOfTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)356     TypeOfTypeInfoAccessor(const CompilationEnv *env,
357                            Circuit *circuit,
358                            GateRef gate)
359         : UnOpTypeInfoAccessor(env, circuit, gate) {}
360     NO_COPY_SEMANTIC(TypeOfTypeInfoAccessor);
361     NO_MOVE_SEMANTIC(TypeOfTypeInfoAccessor);
362 
363     bool IsIllegalType() const;
364 };
365 
366 class SuperCallTypeInfoAccessor final : public TypeInfoAccessor {
367 public:
368     SuperCallTypeInfoAccessor(const CompilationEnv *env,
369                               Circuit *circuit,
370                               GateRef gate,
371                               const JSPandaFile *jsPandaFile = nullptr,
372                               const CallMethodFlagMap *callMethodFlagMap = nullptr);
373     NO_COPY_SEMANTIC(SuperCallTypeInfoAccessor);
374     NO_MOVE_SEMANTIC(SuperCallTypeInfoAccessor);
375 
IsValidCallMethodId()376     bool IsValidCallMethodId() const
377     {
378         return pgoType_.IsValidCallMethodId();
379     }
380 
GetMethodId()381     uint32_t GetMethodId() const
382     {
383         if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
384             return 0;
385         }
386         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
387         if (!profileType->IsNone()) {
388             return profileType->GetProfileType().GetId();
389         }
390         return 0;
391     }
392 
GetCtor()393     GateRef GetCtor() const
394     {
395         return ctor_;
396     }
397 
398 protected:
399     const JSPandaFile *jsPandaFile_;
400     const CallMethodFlagMap *callMethodFlagMap_;
401 
402 private:
403     GateRef ctor_;
404 };
405 
406 class CallTypeInfoAccessor : public TypeInfoAccessor {
407 public:
408     CallTypeInfoAccessor(const CompilationEnv *env,
409                          Circuit *circuit,
410                          GateRef gate,
411                          const JSPandaFile *jsPandaFile = nullptr,
412                          const CallMethodFlagMap *callMethodFlagMap = nullptr)
TypeInfoAccessor(env,circuit,gate)413         : TypeInfoAccessor(env, circuit, gate),
414           argc_(0),
415           func_(Circuit::NullGate()),
416           jsPandaFile_(jsPandaFile),
417           callMethodFlagMap_(callMethodFlagMap)
418     {}
419 
GetArgc()420     size_t GetArgc() const
421     {
422         return argc_;
423     }
424 
GetFunc()425     GateRef GetFunc() const
426     {
427         return func_;
428     }
429 
GetFuncGateType()430     GateType GetFuncGateType() const
431     {
432         return acc_.GetGateType(func_);
433     }
434 
IsValidCallMethodId()435     bool IsValidCallMethodId() const
436     {
437         return pgoType_.IsValidCallMethodId();
438     }
439 
IsHotnessFunc()440     bool IsHotnessFunc() const
441     {
442         if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
443             return false;
444         }
445         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
446         bool haveProfileType = !profileType->IsNone();
447         if (haveProfileType) {
448             CString fileDesc = jsPandaFile_->GetNormalizedFileDesc();
449             uint32_t methodId = profileType->GetProfileType().GetId();
450             return callMethodFlagMap_->IsAotCompile(fileDesc, methodId);
451         }
452         return false;
453     }
454 
GetFunctionTypeLength()455     uint32_t GetFunctionTypeLength() const
456     {
457         if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
458             return INVALID_LEN;
459         }
460         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
461         bool haveProfileType = !profileType->IsNone();
462         if (haveProfileType) {
463             uint32_t methodId = profileType->GetProfileType().GetId();
464             MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId);
465             if (UNLIKELY(targetMethodLiteral == nullptr)) {
466                 return INVALID_LEN;
467             }
468 
469             return targetMethodLiteral->GetNumArgsWithCallField();
470         }
471         return INVALID_LEN;
472     }
473 
IsNoGC()474     bool IsNoGC() const
475     {
476         if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
477             return false;
478         }
479         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
480         bool haveProfileType = !profileType->IsNone();
481         if (haveProfileType) {
482             uint32_t methodId = profileType->GetProfileType().GetId();
483             MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId);
484             if (UNLIKELY(targetMethodLiteral == nullptr)) {
485                 return false;
486             }
487             return targetMethodLiteral->IsNoGC();
488         }
489         return false;
490     }
491 
GetMethodIndex()492     int GetMethodIndex() const
493     {
494         if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
495             return -1;
496         }
497         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
498         bool haveProfileType = !profileType->IsNone();
499         if (haveProfileType) {
500             uint32_t methodId = profileType->GetProfileType().GetId();
501             panda_file::IndexAccessor indexAccessor(*(jsPandaFile_->GetPandaFile()),
502                                             panda_file::File::EntityId(methodId));
503             uint32_t cpId = static_cast<uint32_t>(indexAccessor.GetHeaderIndex());
504             ConstantPool *constpoolHandle =
505                 ConstantPool::Cast(compilationEnv_->FindConstpool(jsPandaFile_, cpId).GetTaggedObject());
506             return constpoolHandle->GetMethodIndexByEntityId(panda_file::File::EntityId(methodId));
507         }
508         return -1;
509     }
510 
GetPandaFile()511     const JSPandaFile *GetPandaFile() const
512     {
513         return jsPandaFile_;
514     }
515 
GetMethodId()516     uint32_t GetMethodId() const
517     {
518         if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
519             return 0;
520         }
521         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
522         if (!profileType->IsNone()) {
523             return profileType->GetProfileType().GetId();
524         }
525         return 0;
526     }
527 
MethodOffsetIsVaild()528     bool MethodOffsetIsVaild() const
529     {
530         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
531         return !profileType->IsNone();
532     }
533 
CanFastCall()534     bool CanFastCall() const
535     {
536         if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
537             return false;
538         }
539         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
540         bool haveProfileType = !profileType->IsNone();
541         if (haveProfileType) {
542             CString fileDesc = jsPandaFile_->GetNormalizedFileDesc();
543             uint32_t methodId = profileType->GetProfileType().GetId();
544             return (callMethodFlagMap_->IsAotCompile(fileDesc, methodId) ||
545                     callMethodFlagMap_->IsJitCompile(fileDesc, methodId)) &&
546                    callMethodFlagMap_->IsFastCall(fileDesc, methodId);
547         }
548         return false;
549     }
550 
GetFuncMethodOffset()551     uint32_t GetFuncMethodOffset() const
552     {
553         if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) {
554             return false;
555         }
556         auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType();
557         bool haveProfileType = !profileType->IsNone();
558         if (haveProfileType) {
559             uint32_t methodId = profileType->GetProfileType().GetId();
560             MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId);
561             if (UNLIKELY(targetMethodLiteral == nullptr)) {
562                 return false;
563             }
564             return targetMethodLiteral->GetMethodId().GetOffset();
565         }
566         return 0;
567     }
568 
569 protected:
570     size_t argc_;
571     GateRef func_;
572     const JSPandaFile *jsPandaFile_;
573     const CallMethodFlagMap *callMethodFlagMap_;
574 };
575 
576 class GetIteratorTypeInfoAccessor final : public CallTypeInfoAccessor {
577 public:
578     GetIteratorTypeInfoAccessor(const CompilationEnv *env,
579                              Circuit *circuit,
580                              GateRef gate,
581                              const JSPandaFile *jsPandaFile = nullptr,
582                              const CallMethodFlagMap *callMethodFlagMap = nullptr);
583     NO_COPY_SEMANTIC(GetIteratorTypeInfoAccessor);
584     NO_MOVE_SEMANTIC(GetIteratorTypeInfoAccessor);
585 
GetCallee()586     GateRef GetCallee()
587     {
588         return func_;
589     }
590 };
591 
592 class CallArg0TypeInfoAccessor final : public CallTypeInfoAccessor {
593 public:
594     CallArg0TypeInfoAccessor(const CompilationEnv *env,
595                              Circuit *circuit,
596                              GateRef gate,
597                              const JSPandaFile *jsPandaFile = nullptr,
598                              const CallMethodFlagMap *callMethodFlagMap = nullptr);
599     NO_COPY_SEMANTIC(CallArg0TypeInfoAccessor);
600     NO_MOVE_SEMANTIC(CallArg0TypeInfoAccessor);
601 };
602 
603 class CallArg1TypeInfoAccessor final : public CallTypeInfoAccessor {
604 public:
605     CallArg1TypeInfoAccessor(const CompilationEnv *env,
606                              Circuit *circuit,
607                              GateRef gate,
608                              const JSPandaFile *jsPandaFile = nullptr,
609                              const CallMethodFlagMap *callMethodFlagMap = nullptr);
610     NO_COPY_SEMANTIC(CallArg1TypeInfoAccessor);
611     NO_MOVE_SEMANTIC(CallArg1TypeInfoAccessor);
612 
GetValue()613     GateRef GetValue()
614     {
615         return value_;
616     }
617 
GetValueGateType()618     GateType GetValueGateType()
619     {
620         return acc_.GetGateType(value_);
621     }
622 
623 private:
624     GateRef value_;
625 };
626 
627 class CallArg2TypeInfoAccessor final : public CallTypeInfoAccessor {
628 public:
629     CallArg2TypeInfoAccessor(const CompilationEnv *env,
630                              Circuit *circuit,
631                              GateRef gate,
632                              const JSPandaFile *jsPandaFile = nullptr,
633                              const CallMethodFlagMap *callMethodFlagMap = nullptr);
634     NO_COPY_SEMANTIC(CallArg2TypeInfoAccessor);
635     NO_MOVE_SEMANTIC(CallArg2TypeInfoAccessor);
636 };
637 
638 class CallArg3TypeInfoAccessor final : public CallTypeInfoAccessor {
639 public:
640     CallArg3TypeInfoAccessor(const CompilationEnv *env,
641                              Circuit *circuit,
642                              GateRef gate,
643                              const JSPandaFile *jsPandaFile = nullptr,
644                              const CallMethodFlagMap *callMethodFlagMap = nullptr);
645     NO_COPY_SEMANTIC(CallArg3TypeInfoAccessor);
646     NO_MOVE_SEMANTIC(CallArg3TypeInfoAccessor);
647 };
648 
649 class CallRangeTypeInfoAccessor final : public CallTypeInfoAccessor {
650 public:
651     CallRangeTypeInfoAccessor(const CompilationEnv *env,
652                               Circuit *circuit,
653                               GateRef gate,
654                               const JSPandaFile *jsPandaFile = nullptr,
655                               const CallMethodFlagMap *callMethodFlagMap = nullptr);
656     NO_COPY_SEMANTIC(CallRangeTypeInfoAccessor);
657     NO_MOVE_SEMANTIC(CallRangeTypeInfoAccessor);
658 };
659 
660 class CallThisTypeInfoAccessor : public CallTypeInfoAccessor {
661 public:
662     CallThisTypeInfoAccessor(const CompilationEnv *env,
663                              Circuit *circuit,
664                              GateRef gate,
665                              const JSPandaFile *jsPandaFile = nullptr,
666                              const CallMethodFlagMap *callMethodFlagMap = nullptr)
CallTypeInfoAccessor(env,circuit,gate,jsPandaFile,callMethodFlagMap)667         : CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap)
668     {
669         thisObj_ = acc_.GetValueIn(gate, 0);
670     }
671     NO_COPY_SEMANTIC(CallThisTypeInfoAccessor);
672     NO_MOVE_SEMANTIC(CallThisTypeInfoAccessor);
673 
674     bool CanOptimizeAsFastCall();
675 
GetThisObj()676     GateRef GetThisObj() const
677     {
678         return thisObj_;
679     }
680 protected:
681     GateRef thisObj_;
682 };
683 
684 class CallThis0TypeInfoAccessor final : public CallThisTypeInfoAccessor {
685 public:
686     CallThis0TypeInfoAccessor(const CompilationEnv *env,
687                               Circuit *circuit,
688                               GateRef gate,
689                               const JSPandaFile *jsPandaFile = nullptr,
690                               const CallMethodFlagMap *callMethodFlagMap = nullptr);
691     NO_COPY_SEMANTIC(CallThis0TypeInfoAccessor);
692     NO_MOVE_SEMANTIC(CallThis0TypeInfoAccessor);
693 };
694 
695 class CallThis1TypeInfoAccessor final : public CallThisTypeInfoAccessor {
696 public:
697     CallThis1TypeInfoAccessor(const CompilationEnv *env,
698                               Circuit *circuit,
699                               GateRef gate,
700                               const JSPandaFile *jsPandaFile = nullptr,
701                               const CallMethodFlagMap *callMethodFlagMap = nullptr);
702     NO_COPY_SEMANTIC(CallThis1TypeInfoAccessor);
703     NO_MOVE_SEMANTIC(CallThis1TypeInfoAccessor);
704 
GetArg0()705     GateRef GetArg0() const
706     {
707         return a0_;
708     }
709 
GetArgs()710     std::vector<GateRef> GetArgs()
711     {
712         return { thisObj_, a0_ };
713     }
714 
Arg0IsNumberType()715     bool Arg0IsNumberType() const
716     {
717         return acc_.GetGateType(a0_).IsNumberType();
718     }
719 
720 private:
721     GateRef a0_;
722 };
723 
724 class CallThis2TypeInfoAccessor final : public CallThisTypeInfoAccessor {
725 public:
726     CallThis2TypeInfoAccessor(const CompilationEnv *env,
727                               Circuit *circuit,
728                               GateRef gate,
729                               const JSPandaFile *jsPandaFile = nullptr,
730                               const CallMethodFlagMap *callMethodFlagMap = nullptr);
731     NO_COPY_SEMANTIC(CallThis2TypeInfoAccessor);
732     NO_MOVE_SEMANTIC(CallThis2TypeInfoAccessor);
733 
GetArgs()734     std::vector<GateRef> GetArgs()
735     {
736         return { thisObj_, a0_, a1_ };
737     }
738 private:
739     GateRef a0_;
740     GateRef a1_;
741 };
742 
743 class CallThis3TypeInfoAccessor final : public CallThisTypeInfoAccessor {
744 public:
745     CallThis3TypeInfoAccessor(const CompilationEnv *env,
746                               Circuit *circuit,
747                               GateRef gate,
748                               const JSPandaFile *jsPandaFile = nullptr,
749                               const CallMethodFlagMap *callMethodFlagMap = nullptr);
750     NO_COPY_SEMANTIC(CallThis3TypeInfoAccessor);
751     NO_MOVE_SEMANTIC(CallThis3TypeInfoAccessor);
752 
GetArgs()753     std::vector<GateRef> GetArgs()
754     {
755         return { thisObj_, a0_, a1_, a2_ };
756     }
757 
758 private:
759     GateRef a0_;
760     GateRef a1_;
761     GateRef a2_;
762 };
763 
764 class CallThisRangeTypeInfoAccessor final : public CallThisTypeInfoAccessor {
765 public:
766     CallThisRangeTypeInfoAccessor(const CompilationEnv *env,
767                               Circuit *circuit,
768                               GateRef gate,
769                               const JSPandaFile *jsPandaFile = nullptr,
770                               const CallMethodFlagMap *callMethodFlagMap = nullptr);
771     NO_COPY_SEMANTIC(CallThisRangeTypeInfoAccessor);
772     NO_MOVE_SEMANTIC(CallThisRangeTypeInfoAccessor);
773 };
774 
775 enum CallKind : uint8_t {
776     CALL,
777     CALL_THIS,
778     CALL_INIT,
779     CALL_SETTER,
780     CALL_GETTER,
781     INVALID
782 };
783 
784 class InlineTypeInfoAccessor final : public TypeInfoAccessor {
785 public:
786     InlineTypeInfoAccessor(const CompilationEnv *env,
787                            Circuit *circuit,
788                            GateRef gate,
789                            GateRef receiver,
790                            CallKind kind);
791 
IsEnableNormalInline()792     bool IsEnableNormalInline() const
793     {
794         return IsValidCallMethodId();
795     }
796 
IsEnableAccessorInline()797     bool IsEnableAccessorInline() const
798     {
799         if (plr_.IsAccessor()) {
800             const PGORWOpType *pgoTypes = acc_.TryGetPGOType(gate_).GetPGORWOpType();
801             auto pgoType = pgoTypes->GetObjectInfo(0);
802             if (pgoType.GetAccessorMethod().GetProfileType().IsValidCallMethodId()) {
803                 return true;
804             }
805         }
806         return false;
807     }
808 
IsValidCallMethodId()809     bool IsValidCallMethodId() const
810     {
811         return pgoType_.IsValidCallMethodId();
812     }
813 
GetFuncMethodOffsetFromPGO()814     uint32_t GetFuncMethodOffsetFromPGO() const
815     {
816         if (IsValidCallMethodId()) {
817             return pgoType_.GetCallMethodId();
818         }
819         return 0;
820     }
821 
GetReceiverGT()822     GateType GetReceiverGT() const
823     {
824         return acc_.GetGateType(receiver_);
825     }
826 
827     uint32_t GetCallMethodId() const;
828 
GetCallGate()829     GateRef GetCallGate() const
830     {
831         return GetGate();
832     }
833 
IsCallInit()834     bool IsCallInit() const
835     {
836         return kind_ == CallKind::CALL_INIT;
837     }
838 
IsCallThis()839     bool IsCallThis() const
840     {
841         return kind_ == CallKind::CALL_THIS || kind_ == CallKind::CALL_INIT;
842     }
843 
IsNormalCall()844     bool IsNormalCall() const
845     {
846         return kind_ == CallKind::CALL || kind_ == CallKind::CALL_THIS || kind_ == CallKind::CALL_INIT;
847     }
848 
IsCallAccessor()849     bool IsCallAccessor() const
850     {
851         return kind_ == CallKind::CALL_SETTER || kind_ == CallKind::CALL_GETTER;
852     }
853 
IsCallGetter()854     bool IsCallGetter() const
855     {
856         return kind_ == CallKind::CALL_GETTER;
857     }
858 
IsCallSetter()859     bool IsCallSetter() const
860     {
861         return kind_ == CallKind::CALL_SETTER;
862     }
863 
GetType()864     uint32_t GetType() const
865     {
866         return GetFuncMethodOffsetFromPGO();
867     }
868 
GetPlr()869     PropertyLookupResult GetPlr() const
870     {
871         return plr_;
872     }
873 
874 private:
875     PropertyLookupResult GetAccessorPlr() const;
876     PropertyLookupResult GetAccessorPlrInJIT() const;
877     bool InitPropAndCheck(JSTaggedValue &prop) const;
878 
879     GateRef receiver_;
880     CallKind kind_ {CallKind::INVALID};
881     PropertyLookupResult plr_ { PropertyLookupResult() };
882 };
883 
884 class ObjectAccessTypeInfoAccessor : public TypeInfoAccessor {
885 public:
886     class ObjectAccessInfo final {
887     public:
888         explicit ObjectAccessInfo(int hclassIndex = -1, PropertyLookupResult plr = PropertyLookupResult())
hclassIndex_(hclassIndex)889             : hclassIndex_(hclassIndex), plr_(plr), hclass_(nullptr) {}
890 
Set(int hclassIndex,PropertyLookupResult plr)891         void Set(int hclassIndex, PropertyLookupResult plr)
892         {
893             hclassIndex_ = hclassIndex;
894             plr_ = plr;
895         }
896 
Set(JSHClass * hclass,PropertyLookupResult plr)897         void Set(JSHClass* hclass, PropertyLookupResult plr)
898         {
899             hclass_ = hclass;
900             plr_ = plr;
901         }
902 
HClassIndex()903         int HClassIndex() const
904         {
905             return hclassIndex_;
906         }
907 
Plr()908         PropertyLookupResult Plr() const
909         {
910             return plr_;
911         }
912 
913     private:
914         int hclassIndex_;
915         PropertyLookupResult plr_;
916         JSHClass* hclass_;
917     };
918 
919     enum AccessMode : uint8_t {
920         LOAD = 0,
921         STORE
922     };
923 
ObjectAccessTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk,AccessMode mode)924     ObjectAccessTypeInfoAccessor(const CompilationEnv *env,
925                                  Circuit *circuit,
926                                  GateRef gate,
927                                  Chunk *chunk,
928                                  AccessMode mode)
929         : TypeInfoAccessor(env, circuit, gate),
930           chunk_(chunk),
931           mode_(mode),
932           key_(Circuit::NullGate()),
933           receiver_(Circuit::NullGate())
934     {}
935     NO_COPY_SEMANTIC(ObjectAccessTypeInfoAccessor);
936     NO_MOVE_SEMANTIC(ObjectAccessTypeInfoAccessor);
937 
938     JSTaggedValue GetKeyTaggedValue() const;
939 
GetKey()940     GateRef GetKey() const
941     {
942         return key_;
943     }
944 
GetReceiver()945     GateRef GetReceiver() const
946     {
947         return receiver_;
948     }
949 
IsMegaType(const PGORWOpType * pgoTypes)950     static bool IsMegaType(const PGORWOpType *pgoTypes)
951     {
952         for (uint32_t i = 0; i < pgoTypes->GetCount(); ++i) {
953             auto temp = pgoTypes->GetObjectInfo(i);
954             if (temp.GetReceiverType().IsMegaStateType()) {
955                 return true;
956             }
957         }
958         return false;
959     }
960 
961 protected:
962     Chunk *chunk_;
963     AccessMode mode_;
964     GateRef key_;
965     GateRef receiver_;
966 };
967 
968 class ObjAccByNameTypeInfoAccessor : public ObjectAccessTypeInfoAccessor {
969 public:
ObjAccByNameTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk,AccessMode mode)970     ObjAccByNameTypeInfoAccessor(const CompilationEnv *env,
971                                  Circuit *circuit,
972                                  GateRef gate,
973                                  Chunk *chunk,
974                                  AccessMode mode)
975         : ObjectAccessTypeInfoAccessor(env, circuit, gate, chunk, mode),
976           hasIllegalType_(false),
977           accessInfos_(chunk),
978           checkerInfos_(chunk)
979     {}
980 
981     NO_COPY_SEMANTIC(ObjAccByNameTypeInfoAccessor);
982     NO_MOVE_SEMANTIC(ObjAccByNameTypeInfoAccessor);
983 
HasIllegalType()984     bool HasIllegalType() const
985     {
986         return hasIllegalType_;
987     }
988 
GetExpectedHClassIndex(size_t index)989     int GetExpectedHClassIndex(size_t index) const
990     {
991         ASSERT(index < checkerInfos_.size());
992         return checkerInfos_[index].HClassIndex();
993     }
994 
GetAccessInfo(size_t index)995     ObjectAccessInfo GetAccessInfo(size_t index) const
996     {
997         ASSERT(index < accessInfos_.size());
998         return accessInfos_[index];
999     }
1000 
1001 protected:
1002     bool GeneratePlr(ProfileTyper type, ObjectAccessInfo &info, JSTaggedValue key) const;
1003     bool GeneratePlrInJIT(JSHClass* hclass, ObjectAccessInfo &info, JSTaggedValue key) const;
1004 
1005     bool hasIllegalType_;
1006     ChunkVector<ObjectAccessInfo> accessInfos_;
1007     ChunkVector<ObjectAccessInfo> checkerInfos_;
1008 };
1009 
1010 class LoadPrivatePropertyTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor {
1011 public:
1012     class AccessorStrategy {
1013     public:
1014         virtual ~AccessorStrategy() = default;
1015         virtual bool TypesIsEmpty() const = 0;
1016         virtual bool IsMono() const = 0;
1017         virtual void FetchPGORWTypesDual() = 0;
1018         virtual bool GenerateObjectAccessInfo() = 0;
1019     };
1020 
1021     class AotAccessorStrategy : public AccessorStrategy {
1022     public:
AotAccessorStrategy(LoadPrivatePropertyTypeInfoAccessor & parent)1023         explicit AotAccessorStrategy(LoadPrivatePropertyTypeInfoAccessor &parent) : parent_(parent)
1024         {
1025         }
1026 
TypesIsEmpty()1027         bool TypesIsEmpty() const override
1028         {
1029             return parent_.types_.empty();
1030         }
1031 
IsMono()1032         bool IsMono() const override
1033         {
1034             return parent_.types_.size() == 1;
1035         }
1036 
1037         void FetchPGORWTypesDual() override;
1038         bool GenerateObjectAccessInfo() override;
1039 
1040     private:
1041         LoadPrivatePropertyTypeInfoAccessor &parent_;
1042     };
1043 
1044     class JitAccessorStrategy : public AccessorStrategy {
1045     public:
JitAccessorStrategy(LoadPrivatePropertyTypeInfoAccessor & parent)1046         explicit JitAccessorStrategy(LoadPrivatePropertyTypeInfoAccessor &parent) : parent_(parent)
1047         {
1048         }
1049 
TypesIsEmpty()1050         bool TypesIsEmpty() const override
1051         {
1052             return parent_.jitTypes_.empty();
1053         }
1054 
IsMono()1055         bool IsMono() const override
1056         {
1057             return parent_.jitTypes_.size() == 1;
1058         }
1059 
1060         void FetchPGORWTypesDual() override;
1061         bool GenerateObjectAccessInfo() override;
1062 
1063     private:
1064         LoadPrivatePropertyTypeInfoAccessor &parent_;
1065     };
1066 
LoadPrivatePropertyTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk)1067     LoadPrivatePropertyTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk)
1068         : ObjAccByNameTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::STORE), types_(chunk_), jitTypes_(chunk_)
1069     {
1070         levelIndex_ = acc_.GetValueIn(gate, 1); // 1: levelIndex
1071         slotIndex_ = acc_.GetValueIn(gate, 2);  // 2: slotIndex
1072         lexicalEnv_ = acc_.GetValueIn(gate, 3); // 3: lexicalEnv
1073         receiver_ = acc_.GetValueIn(gate, 4);   // 4: acc as receiver
1074         if (IsAot()) {
1075             strategy_ = chunk_->New<AotAccessorStrategy>(*this);
1076         } else {
1077             strategy_ = chunk_->New<JitAccessorStrategy>(*this);
1078         }
1079         strategy_->FetchPGORWTypesDual();
1080         hasIllegalType_ = !strategy_->GenerateObjectAccessInfo();
1081     }
1082     NO_COPY_SEMANTIC(LoadPrivatePropertyTypeInfoAccessor);
1083     NO_MOVE_SEMANTIC(LoadPrivatePropertyTypeInfoAccessor);
1084 
IsMono()1085     bool IsMono() const
1086     {
1087         return strategy_->IsMono();
1088     }
1089 
TypesIsEmpty()1090     bool TypesIsEmpty() const
1091     {
1092         return strategy_->TypesIsEmpty();
1093     }
1094 
GetLevelIndex()1095     GateRef GetLevelIndex() const
1096     {
1097         return levelIndex_;
1098     }
1099 
GetSlotIndex()1100     GateRef GetSlotIndex() const
1101     {
1102         return slotIndex_;
1103     }
1104 
GetLexicalEnv()1105     GateRef GetLexicalEnv() const
1106     {
1107         return lexicalEnv_;
1108     }
1109 
IsAccessor()1110     bool IsAccessor() const
1111     {
1112         return isAccessor_;
1113     }
1114 
1115 private:
1116     void FetchPGORWTypesDual();
1117     bool GenerateObjectAccessInfo();
1118 
1119     void FetchPGORWTypesDualInJIT();
1120     bool GenerateObjectAccessInfoInJIT();
1121     JSTaggedValue GetKeyTaggedValue() const;
1122 
1123     ChunkVector<std::pair<ProfileTyper, ProfileTyper>> types_;
1124     ChunkVector<pgo::PGOObjectInfo> jitTypes_;
1125     GateRef levelIndex_;
1126     GateRef slotIndex_;
1127     GateRef lexicalEnv_;
1128     bool isAccessor_{false};
1129     AccessorStrategy* strategy_;
1130     friend class AotAccessorStrategy;
1131     friend class JitAccessorStrategy;
1132 };
1133 
1134 class StorePrivatePropertyTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor {
1135 public:
1136     class AccessorStrategy {
1137     public:
1138         virtual ~AccessorStrategy() = default;
1139         virtual bool TypesIsEmpty() const = 0;
1140         virtual bool IsMono() const = 0;
1141         virtual void FetchPGORWTypesDual() = 0;
1142         virtual bool GenerateObjectAccessInfo() = 0;
1143     };
1144 
1145     class AotAccessorStrategy : public AccessorStrategy {
1146     public:
AotAccessorStrategy(StorePrivatePropertyTypeInfoAccessor & parent)1147         explicit AotAccessorStrategy(StorePrivatePropertyTypeInfoAccessor &parent) : parent_(parent)
1148         {
1149         }
1150 
TypesIsEmpty()1151         bool TypesIsEmpty() const override
1152         {
1153             return parent_.types_.empty();
1154         }
1155 
IsMono()1156         bool IsMono() const override
1157         {
1158             return parent_.types_.size() == 1;
1159         }
1160 
1161         void FetchPGORWTypesDual() override;
1162         bool GenerateObjectAccessInfo() override;
1163 
1164     private:
1165         StorePrivatePropertyTypeInfoAccessor &parent_;
1166     };
1167 
1168     class JitAccessorStrategy : public AccessorStrategy {
1169     public:
JitAccessorStrategy(StorePrivatePropertyTypeInfoAccessor & parent)1170         explicit JitAccessorStrategy(StorePrivatePropertyTypeInfoAccessor &parent) : parent_(parent)
1171         {
1172         }
1173 
TypesIsEmpty()1174         bool TypesIsEmpty() const override
1175         {
1176             return parent_.jitTypes_.empty();
1177         }
1178 
IsMono()1179         bool IsMono() const override
1180         {
1181             return parent_.jitTypes_.size() == 1;
1182         }
1183 
1184         void FetchPGORWTypesDual() override;
1185         bool GenerateObjectAccessInfo() override;
1186 
1187     private:
1188         StorePrivatePropertyTypeInfoAccessor &parent_;
1189     };
1190 
StorePrivatePropertyTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk)1191     StorePrivatePropertyTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk)
1192         : ObjAccByNameTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::STORE), types_(chunk_), jitTypes_(chunk)
1193     {
1194         levelIndex_ = acc_.GetValueIn(gate, 1); // 1: levelIndex
1195         slotIndex_ = acc_.GetValueIn(gate, 2);  // 2: slotIndex
1196         receiver_ = acc_.GetValueIn(gate, 3);   // 3: receiver
1197         lexicalEnv_ = acc_.GetValueIn(gate, 4); // 4: lexicalEnv
1198         value_ = acc_.GetValueIn(gate, 5);      // 5: acc as value
1199         if (IsAot()) {
1200             strategy_ = chunk_->New<AotAccessorStrategy>(*this);
1201         } else {
1202             strategy_ = chunk_->New<JitAccessorStrategy>(*this);
1203         }
1204         strategy_->FetchPGORWTypesDual();
1205         hasIllegalType_ = !strategy_->GenerateObjectAccessInfo();
1206     }
1207     NO_COPY_SEMANTIC(StorePrivatePropertyTypeInfoAccessor);
1208     NO_MOVE_SEMANTIC(StorePrivatePropertyTypeInfoAccessor);
1209 
IsMono()1210     bool IsMono() const
1211     {
1212         return strategy_->IsMono();
1213     }
1214 
TypesIsEmpty()1215     bool TypesIsEmpty() const
1216     {
1217         return strategy_->TypesIsEmpty();
1218     }
1219 
GetValue()1220     GateRef GetValue() const
1221     {
1222         return value_;
1223     }
1224 
GetLevelIndex()1225     GateRef GetLevelIndex() const
1226     {
1227         return levelIndex_;
1228     }
1229 
GetSlotIndex()1230     GateRef GetSlotIndex() const
1231     {
1232         return slotIndex_;
1233     }
1234 
GetLexicalEnv()1235     GateRef GetLexicalEnv() const
1236     {
1237         return lexicalEnv_;
1238     }
1239 
IsAccessor()1240     bool IsAccessor() const
1241     {
1242         return isAccessor_;
1243     }
1244 
1245 private:
1246     JSTaggedValue GetKeyTaggedValue() const;
1247 
1248     ChunkVector<std::tuple<ProfileTyper, ProfileTyper, ProfileTyper>> types_;
1249     ChunkVector<pgo::PGOObjectInfo> jitTypes_;
1250     GateRef value_;
1251     GateRef levelIndex_;
1252     GateRef slotIndex_;
1253     GateRef lexicalEnv_;
1254     bool isAccessor_{false};
1255     AccessorStrategy* strategy_;
1256     friend class AotAccessorStrategy;
1257     friend class JitAccessorStrategy;
1258 };
1259 
1260 class LoadObjByNameTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor {
1261 public:
1262     class AccessorStrategy {
1263     public:
1264         virtual ~AccessorStrategy() = default;
1265         virtual size_t GetTypeCount() const = 0;
1266         virtual bool TypesIsEmpty() const = 0;
1267         virtual bool IsMono() const = 0;
1268         virtual bool IsReceiverEqHolder(size_t index) const = 0;
1269         virtual void FetchPGORWTypesDual() = 0;
1270         virtual bool GenerateObjectAccessInfo() = 0;
1271     };
1272 
1273     class AotAccessorStrategy : public AccessorStrategy {
1274     public:
AotAccessorStrategy(LoadObjByNameTypeInfoAccessor & parent)1275         explicit AotAccessorStrategy(LoadObjByNameTypeInfoAccessor &parent) : parent_(parent)
1276         {
1277         }
1278 
GetTypeCount()1279         size_t GetTypeCount() const override
1280         {
1281             return parent_.types_.size();
1282         }
1283 
TypesIsEmpty()1284         bool TypesIsEmpty() const override
1285         {
1286             return parent_.types_.empty();
1287         }
1288 
IsMono()1289         bool IsMono() const override
1290         {
1291             return parent_.types_.size() == 1;
1292         }
1293 
IsReceiverEqHolder(size_t index)1294         bool IsReceiverEqHolder(size_t index) const override
1295         {
1296             ASSERT(index < parent_.types_.size());
1297             return parent_.types_[index].first == parent_.types_[index].second;
1298         }
1299 
1300         void FetchPGORWTypesDual() override;
1301         bool GenerateObjectAccessInfo() override;
1302 
1303     private:
1304         LoadObjByNameTypeInfoAccessor &parent_;
1305     };
1306 
1307     class JitAccessorStrategy : public AccessorStrategy {
1308     public:
JitAccessorStrategy(LoadObjByNameTypeInfoAccessor & parent)1309         explicit JitAccessorStrategy(LoadObjByNameTypeInfoAccessor &parent) : parent_(parent)
1310         {
1311         }
1312 
GetTypeCount()1313         size_t GetTypeCount() const override
1314         {
1315             return parent_.jitTypes_.size();
1316         }
1317 
TypesIsEmpty()1318         bool TypesIsEmpty() const override
1319         {
1320             return parent_.jitTypes_.empty();
1321         }
1322 
IsMono()1323         bool IsMono() const override
1324         {
1325             return parent_.jitTypes_.size() == 1;
1326         }
1327 
IsReceiverEqHolder(size_t index)1328         bool IsReceiverEqHolder(size_t index) const override
1329         {
1330             return parent_.jitTypes_[index].GetReceiverHclass() == parent_.jitTypes_[index].GetHolderHclass();
1331         }
1332 
1333         void FetchPGORWTypesDual() override;
1334         bool GenerateObjectAccessInfo() override;
1335 
1336     private:
1337         LoadObjByNameTypeInfoAccessor &parent_;
1338     };
1339     LoadObjByNameTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk);
1340     NO_COPY_SEMANTIC(LoadObjByNameTypeInfoAccessor);
1341     NO_MOVE_SEMANTIC(LoadObjByNameTypeInfoAccessor);
1342 
GetTypeCount()1343     size_t GetTypeCount()
1344     {
1345         return strategy_->GetTypeCount();
1346     }
1347 
TypesIsEmpty()1348     bool TypesIsEmpty()
1349     {
1350         return strategy_->TypesIsEmpty();
1351     }
1352 
IsMono()1353     bool IsMono()
1354     {
1355         return strategy_->IsMono();
1356     }
1357 
IsReceiverEqHolder(size_t index)1358     bool IsReceiverEqHolder(size_t index)
1359     {
1360         return strategy_->IsReceiverEqHolder(index);
1361     }
1362 
1363 private:
1364     ChunkVector<std::pair<ProfileTyper, ProfileTyper>> types_;
1365     ChunkVector<pgo::PGOObjectInfo> jitTypes_;
1366 
1367     AccessorStrategy* strategy_;
1368     friend class AotAccessorStrategy;
1369     friend class JitAccessorStrategy;
1370 };
1371 
1372 class StoreObjByNameTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor {
1373 public:
1374     class AccessorStrategy {
1375     public:
1376         virtual ~AccessorStrategy() = default;
1377         virtual size_t GetTypeCount() const = 0;
1378         virtual bool TypesIsEmpty() const = 0;
1379         virtual bool IsMono() const = 0;
1380         virtual bool IsReceiverEqHolder(size_t index) const = 0;
1381         virtual bool IsReceiverNoEqNewHolder(size_t index) const = 0;
1382         virtual bool IsHolderEqNewHolder(size_t index) const = 0;
1383         virtual void FetchPGORWTypesDual() = 0;
1384         virtual bool GenerateObjectAccessInfo() = 0;
1385         virtual bool IsPrototypeHclass(size_t index) const = 0;
1386     };
1387 
1388     class AotAccessorStrategy : public AccessorStrategy {
1389     public:
AotAccessorStrategy(StoreObjByNameTypeInfoAccessor & parent)1390         explicit AotAccessorStrategy(StoreObjByNameTypeInfoAccessor &parent) : parent_(parent)
1391         {
1392         }
1393 
GetTypeCount()1394         size_t GetTypeCount() const override
1395         {
1396             return parent_.types_.size();
1397         }
1398 
TypesIsEmpty()1399         bool TypesIsEmpty() const override
1400         {
1401             return parent_.types_.empty();
1402         }
1403 
IsMono()1404         bool IsMono() const override
1405         {
1406             return parent_.types_.size() == 1;
1407         }
1408 
IsReceiverEqHolder(size_t index)1409         bool IsReceiverEqHolder(size_t index) const override
1410         {
1411             return std::get<HclassIndex::Reciver>(parent_.types_[index]) ==
1412                    std::get<HclassIndex::Holder>(parent_.types_[index]);
1413         }
1414 
IsReceiverNoEqNewHolder(size_t index)1415         bool IsReceiverNoEqNewHolder(size_t index) const override
1416         {
1417             return std::get<HclassIndex::Reciver>(parent_.types_[index]) !=
1418                    std::get<HclassIndex::HolderTra>(parent_.types_[index]);
1419         }
1420 
IsHolderEqNewHolder(size_t index)1421         bool IsHolderEqNewHolder(size_t index) const override
1422         {
1423             return std::get<HclassIndex::Holder>(parent_.types_[index]) ==
1424                    std::get<HclassIndex::HolderTra>(parent_.types_[index]);
1425         }
1426 
IsPrototypeHclass(size_t index)1427         bool IsPrototypeHclass(size_t index) const override
1428         {
1429             ProfileTyper recv = std::get<HclassIndex::Reciver>(parent_.types_[index]);
1430             JSTaggedValue hclass = parent_.ptManager_->QueryHClass(recv.first, recv.second);
1431             if (!hclass.IsJSHClass()) {
1432                 return false;
1433             }
1434             return JSHClass::Cast(hclass.GetTaggedObject())->IsPrototype();
1435         }
1436 
1437         void FetchPGORWTypesDual() override;
1438         bool GenerateObjectAccessInfo() override;
1439 
1440     private:
1441         StoreObjByNameTypeInfoAccessor &parent_;
1442     };
1443 
1444     class JitAccessorStrategy : public AccessorStrategy {
1445     public:
JitAccessorStrategy(StoreObjByNameTypeInfoAccessor & parent)1446         explicit JitAccessorStrategy(StoreObjByNameTypeInfoAccessor &parent) : parent_(parent)
1447         {
1448         }
1449 
GetTypeCount()1450         size_t GetTypeCount() const override
1451         {
1452             return parent_.jitTypes_.size();
1453         }
1454 
TypesIsEmpty()1455         bool TypesIsEmpty() const override
1456         {
1457             return parent_.jitTypes_.empty();
1458         }
1459 
IsMono()1460         bool IsMono() const override
1461         {
1462             return parent_.jitTypes_.size() == 1;
1463         }
1464 
IsReceiverEqHolder(size_t index)1465         bool IsReceiverEqHolder(size_t index) const override
1466         {
1467             return parent_.jitTypes_[index].GetReceiverHclass() == parent_.jitTypes_[index].GetHolderHclass();
1468         }
1469 
IsReceiverNoEqNewHolder(size_t index)1470         bool IsReceiverNoEqNewHolder(size_t index) const override
1471         {
1472             return parent_.jitTypes_[index].GetReceiverHclass() != parent_.jitTypes_[index].GetHolderTraHclass();
1473         }
1474 
IsHolderEqNewHolder(size_t index)1475         bool IsHolderEqNewHolder(size_t index) const override
1476         {
1477             return parent_.jitTypes_[index].GetHolderHclass() == parent_.jitTypes_[index].GetHolderTraHclass();
1478         }
1479 
IsPrototypeHclass(size_t index)1480         bool IsPrototypeHclass(size_t index) const override
1481         {
1482             return parent_.jitTypes_[index].GetReceiverHclass()->IsPrototype();
1483         }
1484 
1485         void FetchPGORWTypesDual() override;
1486         bool GenerateObjectAccessInfo() override;
1487 
1488     private:
1489         StoreObjByNameTypeInfoAccessor &parent_;
1490     };
1491 
1492     StoreObjByNameTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk);
1493     NO_COPY_SEMANTIC(StoreObjByNameTypeInfoAccessor);
1494     NO_MOVE_SEMANTIC(StoreObjByNameTypeInfoAccessor);
1495 
GetTypeCount()1496     size_t GetTypeCount()
1497     {
1498         return strategy_->GetTypeCount();
1499     }
1500 
TypesIsEmpty()1501     bool TypesIsEmpty()
1502     {
1503         return strategy_->TypesIsEmpty();
1504     }
1505 
IsMono()1506     bool IsMono()
1507     {
1508         return strategy_->IsMono();
1509     }
1510 
IsReceiverEqHolder(size_t index)1511     bool IsReceiverEqHolder(size_t index) const
1512     {
1513         return strategy_->IsReceiverEqHolder(index);
1514     }
1515 
IsReceiverNoEqNewHolder(size_t index)1516     bool IsReceiverNoEqNewHolder(size_t index) const
1517     {
1518         return strategy_->IsReceiverNoEqNewHolder(index);
1519     }
1520 
IsHolderEqNewHolder(size_t index)1521     bool IsHolderEqNewHolder(size_t index) const
1522     {
1523         return strategy_->IsHolderEqNewHolder(index);
1524     }
1525 
IsPrototypeHclass(size_t index)1526     bool IsPrototypeHclass(size_t index) const
1527     {
1528         return strategy_->IsPrototypeHclass(index);
1529     }
1530 
GetValue()1531     GateRef GetValue() const
1532     {
1533         return value_;
1534     }
1535 
1536 private:
1537     enum HclassIndex {
1538         Reciver = 0,
1539         Holder,
1540         HolderTra
1541     };
1542     ChunkVector<std::tuple<ProfileTyper, ProfileTyper, ProfileTyper>> types_;
1543     ChunkVector<pgo::PGOObjectInfo> jitTypes_;
1544     GateRef value_;
1545     AccessorStrategy* strategy_;
1546     friend class AotAccessorStrategy;
1547     friend class JitAccessorStrategy;
1548 };
1549 
1550 class InstanceOfTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor {
1551 public:
1552     class AccessorStrategy {
1553     public:
1554         virtual ~AccessorStrategy() = default;
1555         virtual size_t GetTypeCount() const = 0;
1556         virtual bool TypesIsEmpty() const = 0;
1557         virtual bool IsMono() const = 0;
1558         virtual void FetchPGORWTypesDual() = 0;
1559         virtual bool GenerateObjectAccessInfo() = 0;
1560         virtual bool ClassInstanceIsCallable(ProfileTyper type) const = 0;
1561         virtual bool ClassInstanceIsCallable(JSHClass *hclass) const = 0;
1562     };
1563 
1564     class AotAccessorStrategy : public AccessorStrategy {
1565     public:
AotAccessorStrategy(InstanceOfTypeInfoAccessor & parent)1566         explicit AotAccessorStrategy(InstanceOfTypeInfoAccessor &parent) : parent_(parent)
1567         {
1568         }
1569 
GetTypeCount()1570         size_t GetTypeCount() const override
1571         {
1572             return parent_.types_.size();
1573         }
1574 
TypesIsEmpty()1575         bool TypesIsEmpty() const override
1576         {
1577             return parent_.types_.empty();
1578         }
1579 
IsMono()1580         bool IsMono() const override
1581         {
1582             return parent_.types_.size() == 1;
1583         }
1584 
1585         void FetchPGORWTypesDual() override;
1586         bool GenerateObjectAccessInfo() override;
1587         bool ClassInstanceIsCallable(ProfileTyper type) const override;
ClassInstanceIsCallable(JSHClass * hclass)1588         bool ClassInstanceIsCallable([[maybe_unused]] JSHClass *hclass) const override
1589         {
1590             ASSERT(0);
1591             return false;
1592         }
1593 
1594     private:
1595         InstanceOfTypeInfoAccessor &parent_;
1596     };
1597 
1598     class JitAccessorStrategy : public AccessorStrategy {
1599     public:
JitAccessorStrategy(InstanceOfTypeInfoAccessor & parent)1600         explicit JitAccessorStrategy(InstanceOfTypeInfoAccessor &parent) : parent_(parent)
1601         {
1602         }
1603 
GetTypeCount()1604         size_t GetTypeCount() const override
1605         {
1606             return parent_.jitTypes_.size();
1607         }
1608 
TypesIsEmpty()1609         bool TypesIsEmpty() const override
1610         {
1611             return parent_.jitTypes_.empty();
1612         }
1613 
IsMono()1614         bool IsMono() const override
1615         {
1616             return parent_.jitTypes_.size() == 1;
1617         }
1618         void FetchPGORWTypesDual() override;
1619         bool GenerateObjectAccessInfo() override;
1620         bool ClassInstanceIsCallable(JSHClass *hclass) const override;
ClassInstanceIsCallable(ProfileTyper type)1621         bool ClassInstanceIsCallable([[maybe_unused]] ProfileTyper type) const override
1622         {
1623             ASSERT(0);
1624             return false;
1625         }
1626 
1627     private:
1628         InstanceOfTypeInfoAccessor &parent_;
1629     };
1630 
1631     InstanceOfTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk);
1632     NO_COPY_SEMANTIC(InstanceOfTypeInfoAccessor);
1633     NO_MOVE_SEMANTIC(InstanceOfTypeInfoAccessor);
1634 
GetTypeCount()1635     size_t GetTypeCount()
1636     {
1637         return strategy_->GetTypeCount();
1638     }
1639 
TypesIsEmpty()1640     bool TypesIsEmpty()
1641     {
1642         return strategy_->TypesIsEmpty();
1643     }
1644 
IsMono()1645     bool IsMono()
1646     {
1647         return strategy_->IsMono();
1648     }
1649 
1650     JSTaggedValue GetKeyTaggedValue() const;
1651 
GetTarget()1652     GateRef GetTarget() const
1653     {
1654         return target_;
1655     }
1656 
1657 private:
1658     ChunkVector<std::pair<ProfileTyper, ProfileTyper>> types_;
1659     ChunkVector<pgo::PGOObjectInfo> jitTypes_;
1660     GateRef target_;
1661     AccessorStrategy* strategy_;
1662 
1663     friend class AotAccessorStrategy;
1664     friend class JitAccessorStrategy;
1665 };
1666 
1667 class AccBuiltinObjTypeInfoAccessor : public ObjectAccessTypeInfoAccessor {
1668 public:
AccBuiltinObjTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk,AccessMode mode)1669     AccBuiltinObjTypeInfoAccessor(const CompilationEnv *env,
1670                                   Circuit *circuit,
1671                                   GateRef gate,
1672                                   Chunk *chunk,
1673                                   AccessMode mode)
1674         : ObjectAccessTypeInfoAccessor(env, circuit, gate, chunk, mode), types_(chunk_)
1675     {}
1676     NO_COPY_SEMANTIC(AccBuiltinObjTypeInfoAccessor);
1677     NO_MOVE_SEMANTIC(AccBuiltinObjTypeInfoAccessor);
1678 
IsMono()1679     bool IsMono() const
1680     {
1681         return types_.size() == 1 || IsMonoBuiltins();
1682     }
1683 
GetTypeCount()1684     size_t GetTypeCount()
1685     {
1686         return types_.size();
1687     }
1688 
IsBuiltinsMap()1689     bool IsBuiltinsMap() const
1690     {
1691         return types_[0].IsBuiltinsMap();
1692     }
1693 
IsBuiltinsString()1694     bool IsBuiltinsString() const
1695     {
1696         return types_[0].IsBuiltinsString();
1697     }
1698 
IsBuiltinsArray()1699     bool IsBuiltinsArray() const
1700     {
1701         return types_[0].IsBuiltinsArray();
1702     }
1703 
IsBuiltinsTypeArray()1704     bool IsBuiltinsTypeArray() const
1705     {
1706         return types_[0].IsBuiltinsTypeArray();
1707     }
1708 
IsStoreOutOfBounds()1709     bool IsStoreOutOfBounds() const
1710     {
1711         ASSERT(types_.size() > 0);
1712         return types_[0].IsEverOutOfBounds();
1713     }
1714 
HasNoType()1715     bool HasNoType() const
1716     {
1717         return types_.empty();
1718     }
1719 
GetBuiltinsJSType()1720     JSType GetBuiltinsJSType() const
1721     {
1722         if (types_[0].IsBuiltinsType()) {
1723             return types_[0].GetBuiltinsType();
1724         }
1725         return JSType::INVALID;
1726     }
1727 
GetParamType()1728     ParamType GetParamType() const
1729     {
1730         ASSERT(IsMono());
1731         return TypeInfoAccessor::PGOBuiltinTypeToParamType(types_[0]);
1732     }
1733 
IsPolyBuiltinsArray()1734     bool IsPolyBuiltinsArray() const
1735     {
1736         if (types_.size() == 0) {
1737             return false;
1738         }
1739         for (size_t i = 0; i < types_.size(); ++i) {
1740             if (!types_[i].IsBuiltinsArray()) {
1741                 return false;
1742             }
1743         }
1744         return true;
1745     }
1746 
GetElementsKindBeforeTransition(size_t index)1747     ElementsKind GetElementsKindBeforeTransition(size_t index)
1748     {
1749         ProfileType currType = types_[index];
1750         return currType.GetElementsKindBeforeTransition();
1751     }
1752 
GetElementsKindAfterTransition(size_t index)1753     ElementsKind GetElementsKindAfterTransition(size_t index)
1754     {
1755         ProfileType currType = types_[index];
1756         return currType.GetElementsKindAfterTransition();
1757     }
1758 
IsBuiltinsType()1759     bool IsBuiltinsType() const
1760     {
1761         return IsMono() && types_[0].IsBuiltinsType();
1762     }
1763 
IsGlobalsType()1764     bool IsGlobalsType() const
1765     {
1766         return IsMono() && types_[0].IsGlobalsType();
1767     }
1768 
GetBuiltinsTypeId()1769     std::optional<BuiltinTypeId> GetBuiltinsTypeId() const
1770     {
1771         if (!IsMono()) {
1772             return std::nullopt;
1773         }
1774         auto type = types_[0].GetBuiltinsType();
1775         return ToBuiltinsTypeId(type);
1776     }
1777 
GetGlobalsId()1778     std::optional<GlobalIndex> GetGlobalsId() const
1779     {
1780         return types_[0].GetGlobalsId();
1781     }
1782 
TryGetHeapMode()1783     OnHeapMode TryGetHeapMode() const
1784     {
1785         return acc_.TryGetOnHeapMode(gate_);
1786     }
1787 
TryConvertKeyToInt()1788     uint32_t TryConvertKeyToInt() const
1789     {
1790         return static_cast<uint32_t>(acc_.GetConstantValue(GetKey()));
1791     }
1792 
1793     // Default get is elementsKind before possible transition
TryGetArrayElementsKind()1794     ElementsKind TryGetArrayElementsKind() const
1795     {
1796         [[maybe_unused]] bool condition = (IsMono() && IsBuiltinsArray());
1797         ASSERT(condition);
1798         return acc_.TryGetArrayElementsKind(gate_);
1799     }
1800 
TryGetArrayElementsKindAfterTransition()1801     ElementsKind TryGetArrayElementsKindAfterTransition() const
1802     {
1803         [[maybe_unused]] bool condition = (IsMono() && IsBuiltinsArray());
1804         ASSERT(condition);
1805         return acc_.TryGetArrayElementsKindAfterTransition(gate_);
1806     }
1807 
1808 protected:
1809     bool IsMonoBuiltins() const;
1810     bool IsStringMonoBuiltins() const;
1811     void FetchBuiltinsTypes();
1812     bool CheckDuplicatedBuiltinType(ProfileType newType) const;
1813 
1814     ChunkVector<ProfileType> types_;
1815 };
1816 
1817 class LoadBulitinObjTypeInfoAccessor final : public AccBuiltinObjTypeInfoAccessor {
1818 public:
1819     LoadBulitinObjTypeInfoAccessor(const CompilationEnv *env,
1820                                    Circuit *circuit,
1821                                    GateRef gate,
1822                                    Chunk *chunk);
1823     NO_COPY_SEMANTIC(LoadBulitinObjTypeInfoAccessor);
1824     NO_MOVE_SEMANTIC(LoadBulitinObjTypeInfoAccessor);
1825 };
1826 
1827 class StoreBulitinObjTypeInfoAccessor final : public AccBuiltinObjTypeInfoAccessor {
1828 public:
1829     StoreBulitinObjTypeInfoAccessor(const CompilationEnv *env,
1830                                     Circuit *circuit,
1831                                     GateRef gate,
1832                                     Chunk *chunk);
1833     NO_COPY_SEMANTIC(StoreBulitinObjTypeInfoAccessor);
1834     NO_MOVE_SEMANTIC(StoreBulitinObjTypeInfoAccessor);
1835 
ValueIsNumberType()1836     bool ValueIsNumberType() const
1837     {
1838         return acc_.GetGateType(value_).IsNumberType();
1839     }
1840 
GetValue()1841     GateRef GetValue() const
1842     {
1843         return value_;
1844     }
1845 
1846 private:
1847     GateRef value_ {Circuit::NullGate()};
1848 };
1849 
1850 class GlobalObjAccTypeInfoAccessor : public ObjectAccessTypeInfoAccessor {
1851 public:
GlobalObjAccTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,AccessMode mode)1852     GlobalObjAccTypeInfoAccessor(const CompilationEnv *env,
1853                                  Circuit *circuit,
1854                                  GateRef gate,
1855                                  AccessMode mode)
1856         : ObjectAccessTypeInfoAccessor(env, circuit, gate, nullptr, mode) {}
1857 
1858     NO_COPY_SEMANTIC(GlobalObjAccTypeInfoAccessor);
1859     NO_MOVE_SEMANTIC(GlobalObjAccTypeInfoAccessor);
1860 };
1861 
1862 class LoadGlobalObjByNameTypeInfoAccessor final : public GlobalObjAccTypeInfoAccessor {
1863 public:
LoadGlobalObjByNameTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)1864     LoadGlobalObjByNameTypeInfoAccessor(const CompilationEnv *env,
1865                                         Circuit *circuit,
1866                                         GateRef gate)
1867         : GlobalObjAccTypeInfoAccessor(env, circuit, gate, AccessMode::LOAD)
1868     {
1869         key_ = acc_.GetValueIn(gate, 1);
1870     }
1871     NO_COPY_SEMANTIC(LoadGlobalObjByNameTypeInfoAccessor);
1872     NO_MOVE_SEMANTIC(LoadGlobalObjByNameTypeInfoAccessor);
1873 };
1874 
1875 class CreateObjWithBufferTypeInfoAccessor : public TypeInfoAccessor {
1876 public:
1877     CreateObjWithBufferTypeInfoAccessor(const CompilationEnv *env,
1878                                         Circuit *circuit,
1879                                         GateRef gate,
1880                                         const CString &recordName,
1881                                         Chunk* chunk);
1882 
1883     NO_COPY_SEMANTIC(CreateObjWithBufferTypeInfoAccessor);
1884     NO_MOVE_SEMANTIC(CreateObjWithBufferTypeInfoAccessor);
1885 
1886     class AccessorStrategy {
1887     public:
1888         virtual ~AccessorStrategy() = default;
1889         virtual JSTaggedValue GetHClass() const = 0;
1890     };
1891 
1892     class AotAccessorStrategy : public AccessorStrategy {
1893     public:
AotAccessorStrategy(CreateObjWithBufferTypeInfoAccessor & parent)1894         explicit AotAccessorStrategy(CreateObjWithBufferTypeInfoAccessor &parent) : parent_(parent)
1895         {
1896         }
1897 
1898         JSTaggedValue GetHClass() const override;
1899 
1900     private:
1901         CreateObjWithBufferTypeInfoAccessor &parent_;
1902     };
1903 
1904     class JitAccessorStrategy : public AccessorStrategy {
1905     public:
JitAccessorStrategy(CreateObjWithBufferTypeInfoAccessor & parent)1906         explicit JitAccessorStrategy(CreateObjWithBufferTypeInfoAccessor &parent) : parent_(parent)
1907         {
1908         }
1909 
1910         JSTaggedValue GetHClass() const override;
1911 
1912     private:
1913         CreateObjWithBufferTypeInfoAccessor &parent_;
1914     };
1915 
GetHClass()1916     JSTaggedValue GetHClass() const
1917     {
1918         return strategy_->GetHClass();
1919     }
1920 
1921     JSTaggedValue GetObject() const;
1922 
GetIndex()1923     GateRef GetIndex() const
1924     {
1925         return index_;
1926     }
1927 
CanOptimize()1928     bool CanOptimize() const
1929     {
1930         JSTaggedValue obj = GetObject();
1931         if (obj.IsUndefined()) {
1932             return false;
1933         }
1934         JSObject *jsObj = JSObject::Cast(obj);
1935         TaggedArray *properties = TaggedArray::Cast(jsObj->GetProperties());
1936         TaggedArray *elements = TaggedArray::Cast(jsObj->GetElements());
1937         return properties->GetLength() == 0 && elements->GetLength() == 0;
1938     }
1939 
1940 private:
1941     void Init();
1942 
1943     const CString &recordName_;
1944     GateRef index_;
1945     AccessorStrategy* strategy_;
1946 
1947     friend class AotAccessorStrategy;
1948     friend class JitAccessorStrategy;
1949 };
1950 }   // panda::ecmascript::kungfu
1951 #endif  // ECMASCRIPT_COMPILER_TYPE_INFO_ACCESSORS_H
1952