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