• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 COMPILER_RUNTIME_INTERFACE_H
17 #define COMPILER_RUNTIME_INTERFACE_H
18 
19 #include <cstdint>
20 #include <cstddef>
21 #include "assembler/assembly-literals.h"
22 #include "cross_values.h"
23 #include "datatype.h"
24 #include "ir-dyn-base-types.h"
25 #include "mem/gc_barrier.h"
26 #include "runtime/include/coretypes/tagged_value.h"
27 #include "runtime/profiling/profiling.h"
28 #include "source_languages.h"
29 #include "utils/arch.h"
30 #include "utils/span.h"
31 #include "utils/arena_containers.h"
32 #include "libpandabase/mem/mem.h"
33 
34 namespace panda {
35 class Thread;
36 }  // namespace panda
37 
38 namespace panda::compiler {
39 enum class ClassType {
40     UNRESOLVED_CLASS = 0,
41     OBJECT_CLASS,
42     ARRAY_CLASS,
43     ARRAY_OBJECT_CLASS,
44     INTERFACE_CLASS,
45     OTHER_CLASS,
46     FINAL_CLASS,
47     COUNT
48 };
49 
50 enum class StringCtorType { UNKNOWN = 0, STRING, CHAR_ARRAY, COUNT };
51 
52 class IClassHierarchyAnalysis;
53 class InlineCachesInterface;
54 class UnresolvedTypesInterface;
55 
56 class RuntimeInterface {
57 public:
58     using BinaryFilePtr = void *;
59     using MethodPtr = void *;
60     using FieldPtr = void *;
61     using MethodId = uint32_t;
62     using StringPtr = void *;
63     using ClassPtr = void *;
64     using IdType = uint32_t;
65     using FieldId = uint32_t;
66     using StringId = uint32_t;
67     using LiteralArrayId = uint32_t;
68     using MethodIndex = uint16_t;
69     using FieldIndex = uint16_t;
70     using TypeIndex = uint16_t;
71 
72     static const uintptr_t RESOLVE_STRING_AOT_COUNTER_LIMIT = PANDA_32BITS_HEAP_START_ADDRESS;
73     static const uint32_t MEM_PROMISE_CLASS_ID = std::numeric_limits<uint32_t>::max() - 1;
74 
75     enum class NamedAccessProfileType {
76         UNKNOWN = 0,
77         FIELD,
78         FIELD_INLINED,
79         ACCESSOR,
80         ELEMENT,
81         ARRAY_ELEMENT,
82         PROTOTYPE,
83         PROTOTYPE_INLINED,
84         TRANSITION,
85         TRANSITION_INLINED,
86         GLOBAL
87     };
88 
89     struct NamedAccessProfileData {
90         ClassPtr klass;
91         uintptr_t cachedValue;
92         uintptr_t key;
93         uint32_t offset;
94         NamedAccessProfileType type;
95     };
96 
97     enum class InteropCallKind { UNKNOWN = 0, CALL, CALL_BY_VALUE, NEW_INSTANCE, COUNT };
98 
99     RuntimeInterface() = default;
100     virtual ~RuntimeInterface() = default;
101 
GetCha()102     virtual IClassHierarchyAnalysis *GetCha()
103     {
104         return nullptr;
105     }
106 
GetInlineCaches()107     virtual InlineCachesInterface *GetInlineCaches()
108     {
109         return nullptr;
110     }
111 
GetUnresolvedTypes()112     virtual UnresolvedTypesInterface *GetUnresolvedTypes()
113     {
114         return nullptr;
115     }
116 
GetRuntimeEntry()117     virtual void *GetRuntimeEntry()
118     {
119         return nullptr;
120     }
121 
GetReturnReasonOk()122     virtual unsigned GetReturnReasonOk() const
123     {
124         return 0;
125     }
GetReturnReasonDeopt()126     virtual unsigned GetReturnReasonDeopt() const
127     {
128         return 1;
129     }
130 
ResolveMethodIndex(MethodPtr parentMethod,MethodIndex index)131     virtual MethodId ResolveMethodIndex([[maybe_unused]] MethodPtr parentMethod,
132                                         [[maybe_unused]] MethodIndex index) const
133     {
134         return 0;
135     }
136 
ResolveFieldIndex(MethodPtr parentMethod,FieldIndex index)137     virtual FieldId ResolveFieldIndex([[maybe_unused]] MethodPtr parentMethod, [[maybe_unused]] FieldIndex index) const
138     {
139         return 0;
140     }
141 
ResolveTypeIndex(MethodPtr parentMethod,TypeIndex index)142     virtual IdType ResolveTypeIndex([[maybe_unused]] MethodPtr parentMethod, [[maybe_unused]] TypeIndex index) const
143     {
144         return 0;
145     }
146 
GetStackOverflowCheckOffset()147     virtual size_t GetStackOverflowCheckOffset() const
148     {
149         return 0;
150     }
151 
152     /// Binary file information
GetBinaryFileForMethod(MethodPtr method)153     virtual BinaryFilePtr GetBinaryFileForMethod([[maybe_unused]] MethodPtr method) const
154     {
155         return nullptr;
156     }
157 
158     // File offsets
GetBinaryFileBaseOffset(Arch arch)159     uint32_t GetBinaryFileBaseOffset(Arch arch) const
160     {
161         return cross_values::GetFileBaseOffset(arch);
162     }
163 
164     /// Method information
GetMethodById(MethodPtr parentMethod,MethodId id)165     virtual MethodPtr GetMethodById([[maybe_unused]] MethodPtr parentMethod, [[maybe_unused]] MethodId id) const
166     {
167         return nullptr;
168     }
169 
GetMethodByIdAndSaveJsFunction(MethodPtr parentMethod,MethodId id)170     virtual MethodPtr GetMethodByIdAndSaveJsFunction([[maybe_unused]] MethodPtr parentMethod,
171                                                      [[maybe_unused]] MethodId id)
172     {
173         return nullptr;
174     }
175 
GetMethodId(MethodPtr method)176     virtual MethodId GetMethodId([[maybe_unused]] MethodPtr method) const
177     {
178         return 0;
179     }
180 
GetUniqMethodId(MethodPtr method)181     virtual uint64_t GetUniqMethodId([[maybe_unused]] MethodPtr method) const
182     {
183         return 0;
184     }
185 
GetMethodFromFunction(uintptr_t function)186     virtual MethodPtr GetMethodFromFunction([[maybe_unused]] uintptr_t function) const
187     {
188         return nullptr;
189     }
190 
ResolveVirtualMethod(ClassPtr cls,MethodPtr id)191     virtual MethodPtr ResolveVirtualMethod([[maybe_unused]] ClassPtr cls, [[maybe_unused]] MethodPtr id) const
192     {
193         return nullptr;
194     }
195 
ResolveInterfaceMethod(ClassPtr cls,MethodPtr id)196     virtual MethodPtr ResolveInterfaceMethod([[maybe_unused]] ClassPtr cls, [[maybe_unused]] MethodPtr id) const
197     {
198         return nullptr;
199     }
200 
GetMethodReturnType(MethodPtr method)201     virtual DataType::Type GetMethodReturnType([[maybe_unused]] MethodPtr method) const
202     {
203         return DataType::NO_TYPE;
204     }
205 
GetMethodReturnTypeId(MethodPtr method)206     virtual IdType GetMethodReturnTypeId([[maybe_unused]] MethodPtr method) const
207     {
208         return 0;
209     }
210 
GetMethodArgReferenceTypeId(MethodPtr method,uint16_t num)211     virtual IdType GetMethodArgReferenceTypeId([[maybe_unused]] MethodPtr method, [[maybe_unused]] uint16_t num) const
212     {
213         return 0;
214     }
215 
CleanObjectHandles(MethodPtr method)216     virtual void CleanObjectHandles([[maybe_unused]] MethodPtr method) {}
217 
218     // Return this argument type for index == 0 in case of instance method
GetMethodTotalArgumentType(MethodPtr method,size_t index)219     virtual DataType::Type GetMethodTotalArgumentType([[maybe_unused]] MethodPtr method,
220                                                       [[maybe_unused]] size_t index) const
221     {
222         return DataType::NO_TYPE;
223     }
224     // Return total arguments count including this for instance method
GetMethodTotalArgumentsCount(MethodPtr method)225     virtual size_t GetMethodTotalArgumentsCount([[maybe_unused]] MethodPtr method) const
226     {
227         return 0;
228     }
GetMethodReturnType(MethodPtr parentMethod,MethodId id)229     virtual DataType::Type GetMethodReturnType([[maybe_unused]] MethodPtr parentMethod,
230                                                [[maybe_unused]] MethodId id) const
231     {
232         return DataType::NO_TYPE;
233     }
GetMethodArgumentType(MethodPtr parentMethod,MethodId id,size_t index)234     virtual DataType::Type GetMethodArgumentType([[maybe_unused]] MethodPtr parentMethod, [[maybe_unused]] MethodId id,
235                                                  [[maybe_unused]] size_t index) const
236     {
237         return DataType::NO_TYPE;
238     }
GetMethodArgumentsCount(MethodPtr parentMethod,MethodId id)239     virtual size_t GetMethodArgumentsCount([[maybe_unused]] MethodPtr parentMethod, [[maybe_unused]] MethodId id) const
240     {
241         return 0;
242     }
GetMethodArgumentsCount(MethodPtr method)243     virtual size_t GetMethodArgumentsCount([[maybe_unused]] MethodPtr method) const
244     {
245         return 0;
246     }
GetMethodRegistersCount(MethodPtr method)247     virtual size_t GetMethodRegistersCount([[maybe_unused]] MethodPtr method) const
248     {
249         return 0;
250     }
GetMethodCode(MethodPtr method)251     virtual const uint8_t *GetMethodCode([[maybe_unused]] MethodPtr method) const
252     {
253         return nullptr;
254     }
GetMethodCodeSize(MethodPtr method)255     virtual size_t GetMethodCodeSize([[maybe_unused]] MethodPtr method) const
256     {
257         return 0;
258     }
259 
ResolveLookUpCall(FieldPtr rawField,ClassPtr klass,bool isSetter)260     virtual MethodPtr ResolveLookUpCall([[maybe_unused]] FieldPtr rawField, [[maybe_unused]] ClassPtr klass,
261                                         [[maybe_unused]] bool isSetter)
262     {
263         return nullptr;
264     }
265 
GetMethodSourceLanguage(MethodPtr method)266     virtual SourceLanguage GetMethodSourceLanguage([[maybe_unused]] MethodPtr method) const
267     {
268         return SourceLanguage::PANDA_ASSEMBLY;
269     }
270 
SetCompiledEntryPoint(MethodPtr method,void * entryPoint)271     virtual void SetCompiledEntryPoint([[maybe_unused]] MethodPtr method, [[maybe_unused]] void *entryPoint) {}
272 
TrySetOsrCode(MethodPtr method,void * entryPoint)273     virtual bool TrySetOsrCode([[maybe_unused]] MethodPtr method, [[maybe_unused]] void *entryPoint)
274     {
275         return false;
276     }
277 
GetOsrCode(MethodPtr method)278     virtual void *GetOsrCode([[maybe_unused]] MethodPtr method)
279     {
280         return nullptr;
281     }
282 
HasCompiledCode(MethodPtr method)283     virtual bool HasCompiledCode([[maybe_unused]] MethodPtr method)
284     {
285         return false;
286     }
287 
GetAccessFlagAbstractMask()288     virtual uint32_t GetAccessFlagAbstractMask() const
289     {
290         return 0;
291     }
292 
GetVTableIndex(MethodPtr method)293     virtual uint32_t GetVTableIndex([[maybe_unused]] MethodPtr method) const
294     {
295         return 0;
296     }
297 
IsMethodExternal(MethodPtr method,MethodPtr calleeMethod)298     virtual bool IsMethodExternal([[maybe_unused]] MethodPtr method, [[maybe_unused]] MethodPtr calleeMethod) const
299     {
300         return false;
301     }
302 
IsMethodIntrinsic(MethodPtr method)303     virtual bool IsMethodIntrinsic([[maybe_unused]] MethodPtr method) const
304     {
305         return false;
306     }
307 
IsMethodAbstract(MethodPtr method)308     virtual bool IsMethodAbstract([[maybe_unused]] MethodPtr method) const
309     {
310         return false;
311     }
312 
IsMethodIntrinsic(MethodPtr parentMethod,MethodId id)313     virtual bool IsMethodIntrinsic([[maybe_unused]] MethodPtr parentMethod, [[maybe_unused]] MethodId id) const
314     {
315         return false;
316     }
317 
318     // return true if the method is Native with exception
HasNativeException(MethodPtr method)319     virtual bool HasNativeException([[maybe_unused]] MethodPtr method) const
320     {
321         return false;
322     }
323 
IsMethodStatic(MethodPtr parentMethod,MethodId id)324     virtual bool IsMethodStatic([[maybe_unused]] MethodPtr parentMethod, [[maybe_unused]] MethodId id) const
325     {
326         return false;
327     }
328 
IsMethodStatic(MethodPtr method)329     virtual bool IsMethodStatic([[maybe_unused]] MethodPtr method) const
330     {
331         return true;
332     }
333 
IsMethodFinal(MethodPtr method)334     virtual bool IsMethodFinal([[maybe_unused]] MethodPtr method) const
335     {
336         return false;
337     }
338 
ResolveInlinableNativeMethod(MethodPtr method)339     virtual size_t ResolveInlinableNativeMethod([[maybe_unused]] MethodPtr method) const
340     {
341         return 0;
342     }
343 
IsInlinableNativeMethod(MethodPtr method)344     virtual bool IsInlinableNativeMethod([[maybe_unused]] MethodPtr method) const
345     {
346         return false;
347     }
348 
IsMethodCanBeInlined(MethodPtr method)349     virtual bool IsMethodCanBeInlined([[maybe_unused]] MethodPtr method) const
350     {
351         return true;
352     }
353 
IsMethodStaticConstructor(MethodPtr method)354     virtual bool IsMethodStaticConstructor([[maybe_unused]] MethodPtr method) const
355     {
356         return false;
357     }
358 
IsMethodStringBuilderConstructorWithStringArg(MethodPtr method)359     virtual bool IsMethodStringBuilderConstructorWithStringArg([[maybe_unused]] MethodPtr method) const
360     {
361         return false;
362     }
363 
IsMethodStringBuilderToString(MethodPtr method)364     virtual bool IsMethodStringBuilderToString([[maybe_unused]] MethodPtr method) const
365     {
366         return false;
367     }
368 
GetFileName(MethodPtr method)369     virtual std::string GetFileName([[maybe_unused]] MethodPtr method) const
370     {
371         return "UnknownFile";
372     }
373 
GetFullFileName(MethodPtr method)374     virtual std::string GetFullFileName([[maybe_unused]] MethodPtr method) const
375     {
376         return "UnknownFile";
377     }
378 
GetClassNameFromMethod(MethodPtr method)379     virtual std::string GetClassNameFromMethod([[maybe_unused]] MethodPtr method) const
380     {
381         return "UnknownClass";
382     }
383 
GetClassName(ClassPtr klass)384     virtual std::string GetClassName([[maybe_unused]] ClassPtr klass) const
385     {
386         return "UnknownClass";
387     }
388 
GetClass(MethodPtr method)389     virtual ClassPtr GetClass([[maybe_unused]] MethodPtr method) const
390     {
391         return nullptr;
392     }
393 
394     // returns Class for Field
GetClassForField(FieldPtr field)395     virtual ClassPtr GetClassForField([[maybe_unused]] FieldPtr field) const
396     {
397         return nullptr;
398     }
399 
400     ClassPtr ResolveClassForField(MethodPtr method, size_t fieldId);
401 
IsInstantiable(ClassPtr klass)402     virtual bool IsInstantiable([[maybe_unused]] ClassPtr klass) const
403     {
404         return false;
405     }
406 
GetMethodName(MethodPtr method)407     virtual std::string GetMethodName([[maybe_unused]] MethodPtr method) const
408     {
409         return "UnknownMethod";
410     }
411 
GetLineNumberAndSourceFile(MethodPtr method,uint32_t pc)412     virtual std::string GetLineNumberAndSourceFile([[maybe_unused]] MethodPtr method,
413                                                    [[maybe_unused]] uint32_t pc) const
414     {
415         return "UnknownSource";
416     }
417 
GetExternalMethodName(MethodPtr method,uint32_t externalId)418     virtual std::string GetExternalMethodName([[maybe_unused]] MethodPtr method,
419                                               [[maybe_unused]] uint32_t externalId) const
420     {
421         return "UnknownExternalMethod";
422     }
423 
GetBranchTakenCounter(MethodPtr method,uint32_t pc)424     virtual int64_t GetBranchTakenCounter([[maybe_unused]] MethodPtr method, [[maybe_unused]] uint32_t pc) const
425     {
426         return 0;
427     }
428 
GetBranchNotTakenCounter(MethodPtr method,uint32_t pc)429     virtual int64_t GetBranchNotTakenCounter([[maybe_unused]] MethodPtr method, [[maybe_unused]] uint32_t pc) const
430     {
431         return 0;
432     }
433 
GetThrowTakenCounter(MethodPtr method,uint32_t pc)434     virtual int64_t GetThrowTakenCounter([[maybe_unused]] MethodPtr method, [[maybe_unused]] uint32_t pc) const
435     {
436         return 0;
437     }
438 
IsConstructor(MethodPtr method,SourceLanguage lang)439     virtual bool IsConstructor([[maybe_unused]] MethodPtr method, [[maybe_unused]] SourceLanguage lang)
440     {
441         return false;
442     }
443 
444     // returns true if need to encode memory barrier before return
IsMemoryBarrierRequired(MethodPtr method)445     virtual bool IsMemoryBarrierRequired([[maybe_unused]] MethodPtr method) const
446     {
447         return false;
448     }
449 
GetMethodFullName(MethodPtr method,bool withSignature)450     virtual std::string GetMethodFullName([[maybe_unused]] MethodPtr method, [[maybe_unused]] bool withSignature) const
451     {
452         return "UnknownMethod";
453     }
454 
GetMethodFullName(MethodPtr method)455     std::string GetMethodFullName(MethodPtr method) const
456     {
457         return GetMethodFullName(method, false);
458     }
459 
GetMethodNameById(size_t id)460     virtual std::string GetMethodNameById([[maybe_unused]] size_t id) const
461     {
462         return "UnknownMethod";
463     }
464 
GetBytecodeString(MethodPtr method,uintptr_t pc)465     virtual std::string GetBytecodeString([[maybe_unused]] MethodPtr method, [[maybe_unused]] uintptr_t pc) const
466     {
467         return std::string();
468     }
469 
GetLiteralArray(MethodPtr method,LiteralArrayId id)470     virtual panda::pandasm::LiteralArray GetLiteralArray([[maybe_unused]] MethodPtr method,
471                                                          [[maybe_unused]] LiteralArrayId id) const
472     {
473         return panda::pandasm::LiteralArray();
474     }
475 
IsInterfaceMethod(MethodPtr parentMethod,MethodId id)476     virtual bool IsInterfaceMethod([[maybe_unused]] MethodPtr parentMethod, [[maybe_unused]] MethodId id) const
477     {
478         return false;
479     }
480 
IsInterfaceMethod(MethodPtr method)481     virtual bool IsInterfaceMethod([[maybe_unused]] MethodPtr method) const
482     {
483         return false;
484     }
485 
IsInstanceConstructor(MethodPtr method)486     virtual bool IsInstanceConstructor([[maybe_unused]] MethodPtr method) const
487     {
488         return false;
489     }
490 
IsDestroyed(MethodPtr method)491     virtual bool IsDestroyed([[maybe_unused]] MethodPtr method) const
492     {
493         return false;
494     }
495 
CanThrowException(MethodPtr method)496     virtual bool CanThrowException([[maybe_unused]] MethodPtr method) const
497     {
498         return true;
499     }
500 
FindCatchBlock(MethodPtr method,ClassPtr cls,uint32_t pc)501     virtual uint32_t FindCatchBlock([[maybe_unused]] MethodPtr method, [[maybe_unused]] ClassPtr cls,
502                                     [[maybe_unused]] uint32_t pc) const
503     {
504         return panda_file::INVALID_OFFSET;
505     }
506 
507     // Method offsets
GetAccessFlagsOffset(Arch arch)508     uint32_t GetAccessFlagsOffset(Arch arch) const
509     {
510         return panda::cross_values::GetMethodAccessFlagsOffset(arch);
511     }
GetVTableIndexOffset(Arch arch)512     uint32_t GetVTableIndexOffset(Arch arch) const
513     {
514         return panda::cross_values::GetMethodVTableIndexOffset(arch);
515     }
GetClassOffset(Arch arch)516     uint32_t GetClassOffset(Arch arch) const
517     {
518         return panda::cross_values::GetMethodClassOffset(arch);
519     }
GetBaseClassFlagsOffset(Arch arch)520     uint32_t GetBaseClassFlagsOffset(Arch arch) const
521     {
522         return cross_values::GetBaseClassFlagsOffset(arch);
523     }
GetCompiledEntryPointOffset(Arch arch)524     uint32_t GetCompiledEntryPointOffset(Arch arch) const
525     {
526         return panda::cross_values::GetMethodCompiledEntryPointOffset(arch);
527     }
GetPandaFileOffset(Arch arch)528     uint32_t GetPandaFileOffset(Arch arch) const
529     {
530         return panda::cross_values::GetMethodPandaFileOffset(arch);
531     }
532 
GetCallableMask()533     virtual uint32_t GetCallableMask() const
534     {
535         return 0;
536     }
537 
538     /// Exec state information
GetTlsFrameKindOffset(Arch arch)539     size_t GetTlsFrameKindOffset(Arch arch) const
540     {
541         return panda::cross_values::GetManagedThreadFrameKindOffset(arch);
542     }
GetFlagAddrOffset(Arch arch)543     uint32_t GetFlagAddrOffset(Arch arch) const
544     {
545         return panda::cross_values::GetManagedThreadFlagOffset(arch);
546     }
GetTlsFrameOffset(Arch arch)547     size_t GetTlsFrameOffset(Arch arch) const
548     {
549         return panda::cross_values::GetManagedThreadFrameOffset(arch);
550     }
GetExceptionOffset(Arch arch)551     size_t GetExceptionOffset(Arch arch) const
552     {
553         return panda::cross_values::GetManagedThreadExceptionOffset(arch);
554     }
GetTlsNativePcOffset(Arch arch)555     size_t GetTlsNativePcOffset(Arch arch) const
556     {
557         return panda::cross_values::GetManagedThreadNativePcOffset(arch);
558     }
GetTlsCardTableAddrOffset(Arch arch)559     size_t GetTlsCardTableAddrOffset(Arch arch) const
560     {
561         return panda::cross_values::GetManagedThreadCardTableAddrOffset(arch);
562     }
GetTlsCardTableMinAddrOffset(Arch arch)563     size_t GetTlsCardTableMinAddrOffset(Arch arch) const
564     {
565         return panda::cross_values::GetManagedThreadCardTableMinAddrOffset(arch);
566     }
GetTlsPreWrbEntrypointOffset(Arch arch)567     size_t GetTlsPreWrbEntrypointOffset(Arch arch) const
568     {
569         return panda::cross_values::GetManagedThreadPreWrbEntrypointOffset(arch);
570     }
GetTlsPromiseClassPointerOffset(Arch arch)571     virtual size_t GetTlsPromiseClassPointerOffset([[maybe_unused]] Arch arch) const
572     {
573         return 0;
574     }
GetUndefinedObject()575     virtual uint64_t GetUndefinedObject() const
576     {
577         return 0;
578     }
GetTlsUndefinedObjectOffset(Arch arch)579     virtual size_t GetTlsUndefinedObjectOffset([[maybe_unused]] Arch arch) const
580     {
581         return 0;
582     }
GetPreType()583     virtual ::panda::mem::BarrierType GetPreType() const
584     {
585         return ::panda::mem::BarrierType::PRE_WRB_NONE;
586     }
587 
GetPostType()588     virtual ::panda::mem::BarrierType GetPostType() const
589     {
590         return ::panda::mem::BarrierType::POST_WRB_NONE;
591     }
592 
GetBarrierOperand(::panda::mem::BarrierPosition barrierPosition,std::string_view operandName)593     virtual ::panda::mem::BarrierOperand GetBarrierOperand(
594         [[maybe_unused]] ::panda::mem::BarrierPosition barrierPosition,
595         [[maybe_unused]] std::string_view operandName) const
596     {
597         return ::panda::mem::BarrierOperand(::panda::mem::BarrierOperandType::PRE_WRITE_BARRIER_ADDRESS, false);
598     }
599 
GetTlsGlobalObjectOffset(Arch arch)600     virtual uint32_t GetTlsGlobalObjectOffset([[maybe_unused]] Arch arch) const
601     {
602         return 0;
603     }
604 
GetGlobalVarAddress(MethodPtr method,size_t id)605     virtual uintptr_t GetGlobalVarAddress([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t id)
606     {
607         return 0;
608     }
609 
610     /// Array information
GetArrayU16ClassPointerTlsOffset(Arch arch)611     uintptr_t GetArrayU16ClassPointerTlsOffset(Arch arch) const
612     {
613         return cross_values::GetManagedThreadArrayU16ClassPtrOffset(arch);
614     }
615 
GetClassArraySize(Arch arch)616     uint32_t GetClassArraySize(Arch arch) const
617     {
618         return panda::cross_values::GetCoretypesArrayClassSize(arch);
619     }
620 
GetArrayElementSize(MethodPtr method,IdType id)621     virtual uint32_t GetArrayElementSize([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
622     {
623         return ARRAY_DEFAULT_ELEMENT_SIZE;
624     }
625 
GetMaxArrayLength(ClassPtr klass)626     virtual uint32_t GetMaxArrayLength([[maybe_unused]] ClassPtr klass) const
627     {
628         return INT32_MAX;
629     }
630 
GetPointerToConstArrayData(MethodPtr method,IdType id)631     virtual uintptr_t GetPointerToConstArrayData([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
632     {
633         return 0;
634     }
635 
GetOffsetToConstArrayData(MethodPtr method,IdType id)636     virtual size_t GetOffsetToConstArrayData([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
637     {
638         return 0;
639     }
640 
GetArrayU16Class(MethodPtr method)641     virtual ClassPtr GetArrayU16Class([[maybe_unused]] MethodPtr method) const
642     {
643         return nullptr;
644     }
645 
646     // Array offsets
GetArrayDataOffset(Arch arch)647     uint32_t GetArrayDataOffset(Arch arch) const
648     {
649         return panda::cross_values::GetCoretypesArrayDataOffset(arch);
650     }
GetArrayLengthOffset(Arch arch)651     uint32_t GetArrayLengthOffset(Arch arch) const
652     {
653         return panda::cross_values::GetCoretypesArrayLengthOffset(arch);
654     }
655 
656     /// String information
IsCompressedStringsEnabled()657     virtual bool IsCompressedStringsEnabled() const
658     {
659         return true;
660     }
661 
GetStringCompressionMask()662     virtual uint32_t GetStringCompressionMask() const
663     {
664         return 1;
665     }
666 
GetNonMovableString(MethodPtr method,StringId id)667     virtual ObjectPointerType GetNonMovableString([[maybe_unused]] MethodPtr method, [[maybe_unused]] StringId id) const
668     {
669         return 0;
670     }
671 
GetStringClass(MethodPtr method)672     virtual ClassPtr GetStringClass([[maybe_unused]] MethodPtr method) const
673     {
674         return nullptr;
675     }
676 
677     // String offsets
GetStringDataOffset(Arch arch)678     uint32_t GetStringDataOffset(Arch arch) const
679     {
680         return panda::cross_values::GetCoretypesStringDataOffset(arch);
681     }
GetStringLengthOffset(Arch arch)682     uint32_t GetStringLengthOffset(Arch arch) const
683     {
684         return panda::cross_values::GetCoretypesStringLengthOffset(arch);
685     }
GetStringClassPointerTlsOffset(Arch arch)686     uintptr_t GetStringClassPointerTlsOffset(Arch arch) const
687     {
688         return cross_values::GetManagedThreadStringClassPtrOffset(arch);
689     }
690 
691     /// managed Thread object information
692 
GetThreadObjectOffset(Arch arch)693     uint32_t GetThreadObjectOffset(Arch arch) const
694     {
695         return panda::cross_values::GetManagedThreadObjectOffset(arch);
696     }
697 
698     /// TLAB information
699 
GetTLABMaxSize()700     virtual size_t GetTLABMaxSize() const
701     {
702         return 0;
703     }
704 
GetTLABAlignment()705     virtual size_t GetTLABAlignment() const
706     {
707         return 1;
708     }
709 
IsTrackTlabAlloc()710     virtual bool IsTrackTlabAlloc() const
711     {
712         return false;
713     }
714 
715     // TLAB offsets
GetCurrentTLABOffset(Arch arch)716     size_t GetCurrentTLABOffset(Arch arch) const
717     {
718         return panda::cross_values::GetManagedThreadTlabOffset(arch);
719     }
GetTLABStartPointerOffset(Arch arch)720     size_t GetTLABStartPointerOffset(Arch arch) const
721     {
722         return panda::cross_values::GetTlabMemoryStartAddrOffset(arch);
723     }
GetTLABFreePointerOffset(Arch arch)724     size_t GetTLABFreePointerOffset(Arch arch) const
725     {
726         return panda::cross_values::GetTlabCurFreePositionOffset(arch);
727     }
GetTLABEndPointerOffset(Arch arch)728     size_t GetTLABEndPointerOffset(Arch arch) const
729     {
730         return panda::cross_values::GetTlabMemoryEndAddrOffset(arch);
731     }
732 
733     /// Object information
GetClass(MethodPtr method,IdType id)734     virtual ClassPtr GetClass([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
735     {
736         return nullptr;
737     }
738 
GetClassType(MethodPtr method,IdType id)739     virtual ClassType GetClassType([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
740     {
741         return ClassType::UNRESOLVED_CLASS;
742     }
743 
GetClassType(ClassPtr klassPtr)744     virtual ClassType GetClassType([[maybe_unused]] ClassPtr klassPtr) const
745     {
746         return ClassType::UNRESOLVED_CLASS;
747     }
748 
IsArrayClass(MethodPtr method,IdType id)749     virtual bool IsArrayClass([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
750     {
751         return false;
752     }
753 
IsStringClass(MethodPtr method,IdType id)754     virtual bool IsStringClass([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
755     {
756         return false;
757     }
758 
IsArrayClass(ClassPtr klass)759     virtual bool IsArrayClass([[maybe_unused]] ClassPtr klass) const
760     {
761         return false;
762     }
763 
GetArrayElementClass(ClassPtr cls)764     virtual ClassPtr GetArrayElementClass([[maybe_unused]] ClassPtr cls) const
765     {
766         return nullptr;
767     }
768 
CheckStoreArray(ClassPtr arrayCls,ClassPtr strCls)769     virtual bool CheckStoreArray([[maybe_unused]] ClassPtr arrayCls, [[maybe_unused]] ClassPtr strCls) const
770     {
771         return false;
772     }
773 
IsAssignableFrom(ClassPtr cls1,ClassPtr cls2)774     virtual bool IsAssignableFrom([[maybe_unused]] ClassPtr cls1, [[maybe_unused]] ClassPtr cls2) const
775     {
776         return false;
777     }
778 
GetObjectHashedStatusBitNum()779     virtual size_t GetObjectHashedStatusBitNum() const
780     {
781         return 0;
782     }
783 
GetObjectHashShift()784     virtual size_t GetObjectHashShift() const
785     {
786         return 0;
787     }
788 
GetObjectHashMask()789     virtual size_t GetObjectHashMask() const
790     {
791         return 0;
792     }
793 
794     // Offset of class in ObjectHeader
GetObjClassOffset(Arch arch)795     uint32_t GetObjClassOffset(Arch arch) const
796     {
797         return panda::cross_values::GetObjectHeaderClassPointerOffset(arch);
798     }
799 
800     // Offset of the managed object in the BaseClass
GetManagedClassOffset(Arch arch)801     uint32_t GetManagedClassOffset(Arch arch) const
802     {
803         return panda::cross_values::GetBaseClassManagedObjectOffset(arch);
804     }
805 
806     // Offset of mark word in ObjectHeader
GetObjMarkWordOffset(Arch arch)807     uint32_t GetObjMarkWordOffset(Arch arch) const
808     {
809         return panda::cross_values::GetObjectHeaderMarkWordOffset(arch);
810     }
811 
GetTaggedTagMask()812     uint64_t GetTaggedTagMask() const
813     {
814         return coretypes::TaggedValue::TAG_MASK;
815     }
816 
GetTaggedSpecialMask()817     uint64_t GetTaggedSpecialMask() const
818     {
819         return coretypes::TaggedValue::TAG_SPECIAL_MASK;
820     }
821 
GetStringCtorType(MethodPtr ctorMethod)822     virtual StringCtorType GetStringCtorType([[maybe_unused]] MethodPtr ctorMethod) const
823     {
824         return StringCtorType::UNKNOWN;
825     }
826 
827     /// Class information
828 
829     // Returns Class Id for Field.
830     // We don't get class id directly from the field's class, because we need a class id regarding to the current
831     // file. Class id is used in codegen to initialize class in aot mode.
GetClassIdForField(MethodPtr method,size_t unused)832     virtual size_t GetClassIdForField([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
833     {
834         return 0;
835     }
836 
GetClassIdForField(FieldPtr field)837     virtual size_t GetClassIdForField([[maybe_unused]] FieldPtr field) const
838     {
839         return 0;
840     }
841 
842     // returns Class Id for Method
GetClassIdForMethod(MethodPtr method)843     virtual size_t GetClassIdForMethod([[maybe_unused]] MethodPtr method) const
844     {
845         return 0;
846     }
847 
848     // returns Class Id for Method
GetClassIdForMethod(MethodPtr method,size_t unused)849     virtual size_t GetClassIdForMethod([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
850     {
851         return 0;
852     }
853 
GetClassIdWithinFile(MethodPtr method,ClassPtr klass)854     virtual IdType GetClassIdWithinFile([[maybe_unused]] MethodPtr method, [[maybe_unused]] ClassPtr klass) const
855     {
856         return 0;
857     }
858 
GetLiteralArrayClassIdWithinFile(MethodPtr method,panda_file::LiteralTag tag)859     virtual IdType GetLiteralArrayClassIdWithinFile([[maybe_unused]] MethodPtr method,
860                                                     [[maybe_unused]] panda_file::LiteralTag tag) const
861     {
862         return 0;
863     }
864 
CanUseTlabForClass(ClassPtr klass)865     virtual bool CanUseTlabForClass([[maybe_unused]] ClassPtr klass) const
866     {
867         return true;
868     }
869 
870     // returns class size
GetClassSize(ClassPtr klass)871     virtual size_t GetClassSize([[maybe_unused]] ClassPtr klass) const
872     {
873         return 0;
874     }
875 
CanScalarReplaceObject(ClassPtr klass)876     virtual bool CanScalarReplaceObject([[maybe_unused]] ClassPtr klass) const
877     {
878         return false;
879     }
880 
881     // Vtable offset in Class
GetVTableOffset(Arch arch)882     uint32_t GetVTableOffset(Arch arch) const
883     {
884         return panda::cross_values::GetClassVtableOffset(arch);
885     }
886 
887     // returns base offset in Class(for array)
GetClassBaseOffset(Arch arch)888     uint32_t GetClassBaseOffset(Arch arch) const
889     {
890         return panda::cross_values::GetClassBaseOffset(arch);
891     }
892 
893     // returns component type offset in Class(for array)
GetClassComponentTypeOffset(Arch arch)894     uint32_t GetClassComponentTypeOffset(Arch arch) const
895     {
896         return panda::cross_values::GetClassComponentTypeOffset(arch);
897     }
898 
899     // returns type offset in Class(for array)
GetClassTypeOffset(Arch arch)900     uint32_t GetClassTypeOffset(Arch arch) const
901     {
902         return panda::cross_values::GetClassTypeOffset(arch);
903     }
904 
GetClassStateOffset(Arch arch)905     uint32_t GetClassStateOffset(Arch arch) const
906     {
907         return panda::cross_values::GetClassStateOffset(arch);
908     }
909 
GetClassMethodsOffset(Arch arch)910     uint32_t GetClassMethodsOffset(Arch arch) const
911     {
912         return panda::cross_values::GetClassMethodsOffset(arch);
913     }
914 
915     /// Field information
916 
917     /**
918      * Try to resolve field.
919      * @param method method to which the field belongs
920      * @param id id of the field
921      * @param allow_external allow fields defined in the external file, if false - return nullptr for external fields
922      * @param class_id output variable where will be written a field's class
923      * @return return field or nullptr if it cannot be resolved
924      */
ResolveField(MethodPtr method,size_t unused,bool allowExternal,uint32_t * classId)925     virtual FieldPtr ResolveField([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused,
926                                   [[maybe_unused]] bool allowExternal, [[maybe_unused]] uint32_t *classId)
927     {
928         return nullptr;
929     }
930 
ResolveLookUpField(FieldPtr rawField,ClassPtr klass)931     virtual FieldPtr ResolveLookUpField([[maybe_unused]] FieldPtr rawField, [[maybe_unused]] ClassPtr klass)
932     {
933         return nullptr;
934     }
935 
GetFieldType(FieldPtr field)936     virtual DataType::Type GetFieldType([[maybe_unused]] FieldPtr field) const
937     {
938         return DataType::NO_TYPE;
939     }
940 
GetFieldTypeById(MethodPtr method,IdType unused)941     virtual DataType::Type GetFieldTypeById([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType unused) const
942     {
943         return DataType::NO_TYPE;
944     }
945 
GetFieldValueTypeId(MethodPtr method,IdType id)946     virtual IdType GetFieldValueTypeId([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
947     {
948         return 0;
949     }
950 
GetFieldOffset(FieldPtr field)951     virtual size_t GetFieldOffset([[maybe_unused]] FieldPtr field) const
952     {
953         return 0;
954     }
955 
GetFieldByOffset(size_t offset)956     virtual FieldPtr GetFieldByOffset([[maybe_unused]] size_t offset) const
957     {
958         return nullptr;
959     }
960 
GetFieldClass(FieldPtr field)961     virtual uintptr_t GetFieldClass([[maybe_unused]] FieldPtr field) const
962     {
963         return 0;
964     }
965 
IsFieldVolatile(FieldPtr field)966     virtual bool IsFieldVolatile([[maybe_unused]] FieldPtr field) const
967     {
968         return false;
969     }
970 
HasFieldMetadata(FieldPtr field)971     virtual bool HasFieldMetadata([[maybe_unused]] FieldPtr field) const
972     {
973         return false;
974     }
975 
GetFieldName(FieldPtr field)976     virtual std::string GetFieldName([[maybe_unused]] FieldPtr field) const
977     {
978         return "UnknownField";
979     }
980 
981     // Return offset of the managed object in the class
GetFieldClassOffset(Arch arch)982     uint32_t GetFieldClassOffset(Arch arch) const
983     {
984         return panda::cross_values::GetFieldClassOffset(arch);
985     }
986 
987     // Return offset of the managed object in the class
GetFieldOffsetOffset(Arch arch)988     uint32_t GetFieldOffsetOffset(Arch arch) const
989     {
990         return panda::cross_values::GetFieldOffsetOffset(arch);
991     }
992 
GetPropertyBoxOffset(Arch arch)993     virtual size_t GetPropertyBoxOffset([[maybe_unused]] Arch arch) const
994     {
995         return 0;
996     }
997 
GetElementsOffset(Arch arch)998     virtual size_t GetElementsOffset([[maybe_unused]] Arch arch) const
999     {
1000         return 0;
1001     }
1002 
GetPropertiesOffset(Arch arch)1003     virtual size_t GetPropertiesOffset([[maybe_unused]] Arch arch) const
1004     {
1005         return 0;
1006     }
1007 
GetHClassOffset(Arch arch)1008     virtual size_t GetHClassOffset([[maybe_unused]] Arch arch) const
1009     {
1010         UNREACHABLE();
1011     }
1012 
GetHClassBitfieldTypeStartBit(Arch arch)1013     virtual size_t GetHClassBitfieldTypeStartBit([[maybe_unused]] Arch arch) const
1014     {
1015         UNREACHABLE();
1016     }
1017 
GetHClassBitfieldTypeMask(Arch arch)1018     virtual uint64_t GetHClassBitfieldTypeMask([[maybe_unused]] Arch arch) const
1019     {
1020         UNREACHABLE();
1021     }
1022 
GetJshclassBitfieldClassConstructorStartBit(Arch arch)1023     virtual uint64_t GetJshclassBitfieldClassConstructorStartBit([[maybe_unused]] Arch arch) const
1024     {
1025         UNREACHABLE();
1026     }
1027 
GetJstypeJsFunction(Arch arch)1028     virtual size_t GetJstypeJsFunction([[maybe_unused]] Arch arch) const
1029     {
1030         UNREACHABLE();
1031     }
1032 
GetPrototypeHolderOffset(Arch arch)1033     virtual size_t GetPrototypeHolderOffset([[maybe_unused]] Arch arch) const
1034     {
1035         return 0;
1036     }
1037 
GetPrototypeCellOffset(Arch arch)1038     virtual size_t GetPrototypeCellOffset([[maybe_unused]] Arch arch) const
1039     {
1040         return 0;
1041     }
1042 
GetIsChangeFieldOffset(Arch arch)1043     virtual size_t GetIsChangeFieldOffset([[maybe_unused]] Arch arch) const
1044     {
1045         return 0;
1046     }
1047 
GetDynArrayLenthOffset(Arch arch)1048     virtual size_t GetDynArrayLenthOffset([[maybe_unused]] Arch arch) const
1049     {
1050         return 0;
1051     }
1052 
GetFieldId(FieldPtr field)1053     virtual FieldId GetFieldId([[maybe_unused]] FieldPtr field) const
1054     {
1055         return 0;
1056     }
1057 
1058     /// Type information
ResolveType(MethodPtr method,size_t unused)1059     virtual ClassPtr ResolveType([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
1060     {
1061         return nullptr;
1062     }
1063 
IsClassInitialized(uintptr_t unused)1064     virtual bool IsClassInitialized([[maybe_unused]] uintptr_t unused) const
1065     {
1066         return false;
1067     }
1068 
IsClassFinal(ClassPtr unused)1069     virtual bool IsClassFinal([[maybe_unused]] ClassPtr unused) const
1070     {
1071         return false;
1072     }
1073 
IsInterface(ClassPtr unused)1074     virtual bool IsInterface([[maybe_unused]] ClassPtr unused) const
1075     {
1076         return false;
1077     }
1078 
GetManagedType(uintptr_t unused)1079     virtual uintptr_t GetManagedType([[maybe_unused]] uintptr_t unused) const
1080     {
1081         return 0;
1082     }
1083 
GetClassInitializedValue()1084     virtual uint8_t GetClassInitializedValue() const
1085     {
1086         return 0;
1087     }
1088 
GetReferenceTypeMask()1089     virtual uint8_t GetReferenceTypeMask() const
1090     {
1091         return 0;
1092     }
1093 
GetProtectedMemorySize()1094     virtual size_t GetProtectedMemorySize() const
1095     {
1096         // Conservatively, we believe that one page is protected. There can't be less than one.
1097         return PAGE_SIZE;
1098     }
1099 
1100     /// Entrypoints
1101 #include "compiler_interface_extensions.inl.h"
1102 #include <intrinsics_enum.inl>
1103 #include <entrypoints_compiler.inl>
1104 #include <entrypoints_compiler_checksum.inl>
1105 
GetIntrinsicId(MethodPtr method)1106     virtual IntrinsicId GetIntrinsicId([[maybe_unused]] MethodPtr method) const
1107     {
1108         return IntrinsicId::INVALID;
1109     }
1110 
GetIntrinsicAddress(bool runtimeCall,SourceLanguage lang,IntrinsicId unused)1111     virtual uintptr_t GetIntrinsicAddress([[maybe_unused]] bool runtimeCall, [[maybe_unused]] SourceLanguage lang,
1112                                           [[maybe_unused]] IntrinsicId unused) const
1113     {
1114         return 0;
1115     }
1116 
IsIntrinsicStringBuilderToString(IntrinsicId id)1117     virtual bool IsIntrinsicStringBuilderToString([[maybe_unused]] IntrinsicId id) const
1118     {
1119         return false;
1120     }
1121 
GetEntrypointTlsOffset(Arch arch,EntrypointId id)1122     uintptr_t GetEntrypointTlsOffset(Arch arch, EntrypointId id) const
1123     {
1124         return cross_values::GetManagedThreadEntrypointOffset(arch, panda::EntrypointId(static_cast<uint8_t>(id)));
1125     }
1126 
GetGlobalVarEntrypointId()1127     virtual EntrypointId GetGlobalVarEntrypointId()
1128     {
1129         return static_cast<EntrypointId>(0);
1130     }
1131 
GetInteropCallKind(MethodPtr method)1132     virtual InteropCallKind GetInteropCallKind([[maybe_unused]] MethodPtr method) const
1133     {
1134         return InteropCallKind::UNKNOWN;
1135     }
1136 
GetInfoForInteropCallArgsConversion(MethodPtr methodPtr,ArenaVector<std::pair<IntrinsicId,DataType::Type>> * intrinsics)1137     virtual void GetInfoForInteropCallArgsConversion(
1138         [[maybe_unused]] MethodPtr methodPtr,
1139         [[maybe_unused]] ArenaVector<std::pair<IntrinsicId, DataType::Type>> *intrinsics) const
1140     {
1141         UNREACHABLE();
1142     }
1143 
GetInfoForInteropCallRetValueConversion(MethodPtr methodPtr)1144     virtual std::optional<std::pair<IntrinsicId, compiler::DataType::Type>> GetInfoForInteropCallRetValueConversion(
1145         [[maybe_unused]] MethodPtr methodPtr) const
1146     {
1147         UNREACHABLE();
1148     }
1149 
GetFuncPropName(MethodPtr methodPtr,uint32_t strId)1150     virtual char *GetFuncPropName([[maybe_unused]] MethodPtr methodPtr, [[maybe_unused]] uint32_t strId) const
1151     {
1152         UNREACHABLE();
1153     }
1154 
GetFuncPropNameOffset(MethodPtr methodPtr,uint32_t strId)1155     virtual uint64_t GetFuncPropNameOffset([[maybe_unused]] MethodPtr methodPtr, [[maybe_unused]] uint32_t strId) const
1156     {
1157         UNREACHABLE();
1158     }
1159 
GetRetValueClass(MethodPtr methodPtr)1160     virtual ClassPtr GetRetValueClass([[maybe_unused]] MethodPtr methodPtr) const
1161     {
1162         UNREACHABLE();
1163     }
1164 
1165     /// Dynamic object information
1166 
GetFunctionTargetOffset(Arch arch)1167     virtual uint32_t GetFunctionTargetOffset([[maybe_unused]] Arch arch) const
1168     {
1169         return 0;
1170     }
1171 
GetDynamicPrimitiveUndefined()1172     virtual uint64_t GetDynamicPrimitiveUndefined() const
1173     {
1174         return static_cast<uint64_t>(coretypes::TaggedValue::Undefined().GetRawData());
1175     }
1176 
GetPackConstantByPrimitiveType(compiler::AnyBaseType type,uint64_t imm)1177     virtual uint64_t GetPackConstantByPrimitiveType(compiler::AnyBaseType type, uint64_t imm) const
1178     {
1179         auto datatype = AnyBaseTypeToDataType(type);
1180         if (datatype == DataType::INT32) {
1181             return coretypes::TaggedValue::GetIntTaggedValue(imm);
1182         }
1183         if (datatype == DataType::FLOAT64) {
1184             return coretypes::TaggedValue::GetDoubleTaggedValue(imm);
1185         }
1186         if (datatype == DataType::BOOL) {
1187             return coretypes::TaggedValue::GetBoolTaggedValue(imm);
1188         }
1189         UNREACHABLE();
1190         return 0;
1191     }
1192 
GetDynamicPrimitiveFalse()1193     virtual uint64_t GetDynamicPrimitiveFalse() const
1194     {
1195         return static_cast<uint64_t>(coretypes::TaggedValue::False().GetRawData());
1196     }
1197 
GetDynamicPrimitiveTrue()1198     virtual uint64_t GetDynamicPrimitiveTrue() const
1199     {
1200         return static_cast<uint64_t>(coretypes::TaggedValue::True().GetRawData());
1201     }
1202 
DynamicCastDoubleToInt(double value,size_t bits)1203     virtual uint64_t DynamicCastDoubleToInt([[maybe_unused]] double value, [[maybe_unused]] size_t bits) const
1204     {
1205         return 0;
1206     }
1207 
GetDynamicNumFixedArgs()1208     virtual uint8_t GetDynamicNumFixedArgs() const
1209     {
1210         return 0;
1211     }
1212 
GetLanguageExtensionSize(Arch arch)1213     virtual size_t GetLanguageExtensionSize([[maybe_unused]] Arch arch) const
1214     {
1215         return 0;
1216     }
1217 
GetNativePointerTargetOffset(Arch arch)1218     virtual uint32_t GetNativePointerTargetOffset([[maybe_unused]] Arch arch) const
1219     {
1220         return 0;
1221     }
1222 
1223     /**
1224      * Check if GC can be triggered during call.
1225      * This is possible when method A calling method B and waiting while B is compiling.
1226      */
HasSafepointDuringCall()1227     virtual bool HasSafepointDuringCall() const
1228     {
1229         return false;
1230     }
1231 
1232     /// Bytecode profiling
1233     using BytecodeProfile = uintptr_t;
1234     using MethodProfile = profiling::ProfileType;
1235 
1236     /**
1237      * Get profile information for a specific method.
1238      *
1239      * @param method method, which profile data we want to get
1240      * @param from_vector this flag indicates from where we should get profile: from method's profile vector or from
1241      *                    a profile file, which was added via `AddProfile`.
1242      *                    NB: This flag is a workaround and should be deleted. Problem is that Runtime stores methods
1243      *                    vector in different places for different languages. But Paoc uses only place for core part,
1244      *                    i.e. methods in Class objects, that is wrong for some languages.
1245      *                    NOTE: create interface in the runtime to enumerate all methods despite of VM language.
1246      * @return profile data for the given method
1247      */
GetMethodProfile(MethodPtr method,bool fromVector)1248     virtual MethodProfile GetMethodProfile([[maybe_unused]] MethodPtr method, [[maybe_unused]] bool fromVector) const
1249     {
1250         return nullptr;
1251     }
1252 
GetCallProfile(MethodPtr profile,uint32_t pc,ArenaVector<uintptr_t> * methods,bool isAot)1253     virtual profiling::CallKind GetCallProfile([[maybe_unused]] MethodPtr profile, [[maybe_unused]] uint32_t pc,
1254                                                [[maybe_unused]] ArenaVector<uintptr_t> *methods,
1255                                                [[maybe_unused]] bool isAot)
1256     {
1257         return profiling::CallKind::UNKNOWN;
1258     }
1259 
1260     /**
1261      * Get profile for a specific bytecode. Usually profile is a memory buffer, that is treated in different ways,
1262      * according to the bytecode operation.
1263      *
1264      * @param prof Method profile, which should be retrived via `GetMethodProfile` method.
1265      * @param bc_inst pointer to the bytecode instruction
1266      * @param pc offset of the bytecode instruction from the bytecode buffer beginning.
1267      * @return return profile for `bc_inst`
1268      */
GetBytecodeProfile(MethodProfile prof,const uint8_t * bcInst,size_t pc)1269     virtual BytecodeProfile GetBytecodeProfile([[maybe_unused]] MethodProfile prof,
1270                                                [[maybe_unused]] const uint8_t *bcInst, [[maybe_unused]] size_t pc) const
1271     {
1272         return 0;
1273     }
1274 
CanInlineLdStObjByIndex(const BytecodeInstruction * bcInst,size_t pc,MethodProfile methodProfile)1275     virtual bool CanInlineLdStObjByIndex([[maybe_unused]] const BytecodeInstruction *bcInst, [[maybe_unused]] size_t pc,
1276                                          [[maybe_unused]] MethodProfile methodProfile) const
1277     {
1278         return false;
1279     }
1280 
AddProfile(std::string_view fname)1281     virtual Expected<bool, const char *> AddProfile([[maybe_unused]] std::string_view fname)
1282     {
1283         return Unexpected("Not implemented");
1284     }
1285 
GetProfilingAnyType(RuntimeInterface::BytecodeProfile profile,const BytecodeInstruction * bcInst,unsigned index,profiling::AnyInputType * allowedInputType,bool * isTypeProfiled)1286     virtual compiler::AnyBaseType GetProfilingAnyType([[maybe_unused]] RuntimeInterface::BytecodeProfile profile,
1287                                                       [[maybe_unused]] const BytecodeInstruction *bcInst,
1288                                                       [[maybe_unused]] unsigned index,
1289                                                       [[maybe_unused]] profiling::AnyInputType *allowedInputType,
1290                                                       [[maybe_unused]] bool *isTypeProfiled)
1291     {
1292         return compiler::AnyBaseType::UNDEFINED_TYPE;
1293     }
1294 
ResolveSpecialAnyTypeByConstant(coretypes::TaggedValue anyConst)1295     virtual compiler::AnyBaseType ResolveSpecialAnyTypeByConstant([[maybe_unused]] coretypes::TaggedValue anyConst)
1296     {
1297         return compiler::AnyBaseType::UNDEFINED_TYPE;
1298     }
1299 
GetConstantPool(MethodPtr method)1300     virtual void *GetConstantPool([[maybe_unused]] MethodPtr method)
1301     {
1302         return nullptr;
1303     }
1304 
GetConstantPool(uintptr_t funcAddress)1305     virtual void *GetConstantPool([[maybe_unused]] uintptr_t funcAddress)
1306     {
1307         return nullptr;
1308     }
1309 
SetCurrentThread(Thread * thread)1310     virtual void SetCurrentThread([[maybe_unused]] Thread *thread) const
1311     {
1312         UNREACHABLE();
1313     }
1314 
1315     NO_COPY_SEMANTIC(RuntimeInterface);
1316     NO_MOVE_SEMANTIC(RuntimeInterface);
1317 
1318 private:
1319     static constexpr uint32_t ARRAY_DEFAULT_ELEMENT_SIZE = 4;
1320 };
1321 
1322 class IClassHierarchyAnalysis {
1323 public:
1324     IClassHierarchyAnalysis() = default;
1325     virtual ~IClassHierarchyAnalysis() = default;
1326 
1327 public:
1328     virtual RuntimeInterface::MethodPtr GetSingleImplementation(
1329         [[maybe_unused]] RuntimeInterface::MethodPtr method) = 0;
1330     virtual bool IsSingleImplementation([[maybe_unused]] RuntimeInterface::MethodPtr method) = 0;
1331     virtual void AddDependency([[maybe_unused]] RuntimeInterface::MethodPtr caller,
1332                                [[maybe_unused]] RuntimeInterface::MethodPtr callee) = 0;
1333 
1334     NO_COPY_SEMANTIC(IClassHierarchyAnalysis);
1335     NO_MOVE_SEMANTIC(IClassHierarchyAnalysis);
1336 };
1337 
1338 class InlineCachesInterface {
1339 public:
1340     using ClassList = Span<RuntimeInterface::ClassPtr>;
1341     enum class CallKind { UNKNOWN, MONOMORPHIC, POLYMORPHIC, MEGAMORPHIC };
1342 
1343     virtual CallKind GetClasses(RuntimeInterface::MethodPtr method, uintptr_t unused,
1344                                 ArenaVector<RuntimeInterface::ClassPtr> *classes) = 0;
1345     virtual ~InlineCachesInterface() = default;
1346     InlineCachesInterface() = default;
1347 
1348     DEFAULT_COPY_SEMANTIC(InlineCachesInterface);
1349     DEFAULT_MOVE_SEMANTIC(InlineCachesInterface);
1350 };
1351 
1352 class UnresolvedTypesInterface {
1353 public:
1354     enum class SlotKind { UNKNOWN, CLASS, MANAGED_CLASS, METHOD, VIRTUAL_METHOD, FIELD, STATIC_FIELD_PTR };
1355     virtual bool AddTableSlot([[maybe_unused]] RuntimeInterface::MethodPtr method, [[maybe_unused]] uint32_t typeId,
1356                               [[maybe_unused]] SlotKind kind) = 0;
1357     virtual uintptr_t GetTableSlot([[maybe_unused]] RuntimeInterface::MethodPtr method,
1358                                    [[maybe_unused]] uint32_t typeId, [[maybe_unused]] SlotKind kind) const = 0;
1359     virtual ~UnresolvedTypesInterface() = default;
1360     UnresolvedTypesInterface() = default;
1361 
1362     DEFAULT_COPY_SEMANTIC(UnresolvedTypesInterface);
1363     DEFAULT_MOVE_SEMANTIC(UnresolvedTypesInterface);
1364 };
1365 
1366 enum class TraceId {
1367     METHOD_ENTER = 1U << 0U,
1368     METHOD_EXIT = 1U << 1U,
1369     PRINT_ARG = 1U << 2U,
1370 };
1371 
1372 enum class DeoptimizeType : uint8_t {
1373     INVALID = 0,
1374     INLINE_CHA,
1375     NULL_CHECK,
1376     BOUNDS_CHECK,
1377     ZERO_CHECK,
1378     NEGATIVE_CHECK,
1379     CHECK_CAST,
1380     ANY_TYPE_CHECK,
1381     OVERFLOW,
1382     HOLE,
1383     NOT_NUMBER,
1384     CAUSE_METHOD_DESTRUCTION,
1385     NOT_SMALL_INT = CAUSE_METHOD_DESTRUCTION,
1386     BOUNDS_CHECK_WITH_DEOPT,
1387     DOUBLE_WITH_INT,
1388     INLINE_IC,
1389     INLINE_DYN,
1390     NOT_PROFILED,
1391     COUNT
1392 };
1393 
DeoptimizeTypeToString(DeoptimizeType deoptType)1394 inline const char *DeoptimizeTypeToString(DeoptimizeType deoptType)
1395 {
1396     static constexpr auto COUNT = static_cast<uint8_t>(DeoptimizeType::COUNT);
1397 
1398     static constexpr std::array<const char *, COUNT> DEOPT_TYPE_NAMES = {"INVALID_TYPE",
1399                                                                          "INLINE_CHA",
1400                                                                          "NULL_CHECK",
1401                                                                          "BOUNDS_CHECK",
1402                                                                          "ZERO_CHECK",
1403                                                                          "NEGATIVE_CHECK",
1404                                                                          "CHECK_CAST",
1405                                                                          "ANY_TYPE_CHECK",
1406                                                                          "OVERFLOW",
1407                                                                          "HOLE ",
1408                                                                          "NOT_NUMBER",
1409                                                                          "NOT_SMALL_INT",
1410                                                                          "BOUNDS_CHECK_WITH_DEOPT",
1411                                                                          "DOUBLE_WITH_INT",
1412                                                                          "INLINE_IC",
1413                                                                          "INLINE_DYN",
1414                                                                          "NOT_PROFILED"};
1415 
1416     auto idx = static_cast<uint8_t>(deoptType);
1417     ASSERT(idx < COUNT);
1418     return DEOPT_TYPE_NAMES[idx];
1419 }
1420 }  // namespace panda::compiler
1421 
1422 #endif  // COMPILER_RUNTIME_INTERFACE_H
1423