• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 "constants.h"
23 #include "cross_values.h"
24 #include "datatype.h"
25 #include "ir-dyn-base-types.h"
26 #include "mem/gc_barrier.h"
27 #include "runtime/include/coretypes/tagged_value.h"
28 #include "source_languages.h"
29 #include "utils/arch.h"
30 #include "utils/span.h"
31 #include "utils/arena_containers.h"
32 
33 namespace panda::compiler {
34 enum class ClassType {
35     UNRESOLVED_CLASS = 0,
36     OBJECT_CLASS,
37     ARRAY_CLASS,
38     ARRAY_OBJECT_CLASS,
39     INTERFACE_CLASS,
40     OTHER_CLASS,
41     FINAL_CLASS,
42     COUNT
43 };
44 
45 class IClassHierarchyAnalysis;
46 class InlineCachesInterface;
47 class UnresolvedTypesInterface;
48 class Inst;
49 
50 class RuntimeInterface {
51 public:
52     using BinaryFilePtr = void *;
53     using MethodPtr = void *;
54     using FieldPtr = void *;
55     using MethodId = uint32_t;
56     using StringPtr = void *;
57     using ClassPtr = void *;
58     using IdType = uint32_t;
59     using FieldId = uint32_t;
60     using StringId = uint32_t;
61     using LiteralArrayId = uint32_t;
62     using MethodIndex = uint16_t;
63     using FieldIndex = uint16_t;
64     using TypeIndex = uint16_t;
65     using StringIndex = uint16_t;
66     using LiteralArrayIndex = uint16_t;
67 
68     static const uintptr_t RESOLVE_STRING_AOT_COUNTER_LIMIT = PANDA_32BITS_HEAP_START_ADDRESS;
69 
70     RuntimeInterface() = default;
71     virtual ~RuntimeInterface() = default;
72 
GetCha()73     virtual IClassHierarchyAnalysis *GetCha()
74     {
75         return nullptr;
76     }
77 
GetInlineCaches()78     virtual InlineCachesInterface *GetInlineCaches()
79     {
80         return nullptr;
81     }
82 
GetUnresolvedTypes()83     virtual UnresolvedTypesInterface *GetUnresolvedTypes()
84     {
85         return nullptr;
86     }
87 
GetRuntimeEntry()88     virtual void *GetRuntimeEntry()
89     {
90         return nullptr;
91     }
92 
GetReturnReasonOk()93     virtual unsigned GetReturnReasonOk() const
94     {
95         return 0;
96     }
GetReturnReasonDeopt()97     virtual unsigned GetReturnReasonDeopt() const
98     {
99         return 1;
100     }
101 
ResolveMethodIndex(MethodPtr parent_method,MethodIndex index)102     virtual MethodId ResolveMethodIndex([[maybe_unused]] MethodPtr parent_method,
103                                         [[maybe_unused]] MethodIndex index) const
104     {
105         return 0;
106     }
107 
ResolveOffsetByIndex(MethodPtr parent_method,uint16_t index)108     virtual uint32_t ResolveOffsetByIndex([[maybe_unused]] MethodPtr parent_method,
109                                           [[maybe_unused]] uint16_t index) const
110     {
111         return 0;
112     }
113 
ResolveFieldIndex(MethodPtr parent_method,FieldIndex index)114     virtual FieldId ResolveFieldIndex([[maybe_unused]] MethodPtr parent_method, [[maybe_unused]] FieldIndex index) const
115     {
116         return 0;
117     }
118 
ResolveTypeIndex(MethodPtr parent_method,TypeIndex index)119     virtual IdType ResolveTypeIndex([[maybe_unused]] MethodPtr parent_method, [[maybe_unused]] TypeIndex index) const
120     {
121         return 0;
122     }
123 
GetStackOverflowCheckOffset()124     virtual size_t GetStackOverflowCheckOffset() const
125     {
126         return 0;
127     }
128 
129     /**************************************************************************
130      * Binary file information
131      */
GetBinaryFileForMethod(MethodPtr method)132     virtual BinaryFilePtr GetBinaryFileForMethod([[maybe_unused]] MethodPtr method) const
133     {
134         return nullptr;
135     }
136 
137     // File offsets
GetBinaryFileBaseOffset(Arch arch)138     uint32_t GetBinaryFileBaseOffset(Arch arch) const
139     {
140         return cross_values::GetFileBaseOffset(arch);
141     }
142 
143     /**************************************************************************
144      * Method information
145      */
GetMethodById(MethodPtr parent_method,MethodId id)146     virtual MethodPtr GetMethodById([[maybe_unused]] MethodPtr parent_method, [[maybe_unused]] MethodId id) const
147     {
148         return nullptr;
149     }
150 
GetMethodId(MethodPtr method)151     virtual MethodId GetMethodId([[maybe_unused]] MethodPtr method) const
152     {
153         return 0;
154     }
155 
ResolveVirtualMethod(ClassPtr cls,MethodPtr id)156     virtual MethodPtr ResolveVirtualMethod([[maybe_unused]] ClassPtr cls, [[maybe_unused]] MethodPtr id) const
157     {
158         return nullptr;
159     }
160 
ResolveInterfaceMethod(ClassPtr cls,MethodPtr id)161     virtual MethodPtr ResolveInterfaceMethod([[maybe_unused]] ClassPtr cls, [[maybe_unused]] MethodPtr id) const
162     {
163         return nullptr;
164     }
165 
GetMethodReturnType(MethodPtr method)166     virtual DataType::Type GetMethodReturnType([[maybe_unused]] MethodPtr method) const
167     {
168         return DataType::NO_TYPE;
169     }
170 
171     // Return this argument type for index == 0 in case of instance method
GetMethodTotalArgumentType(MethodPtr method,size_t index)172     virtual DataType::Type GetMethodTotalArgumentType([[maybe_unused]] MethodPtr method,
173                                                       [[maybe_unused]] size_t index) const
174     {
175         return DataType::NO_TYPE;
176     }
177     // Return total arguments count including this for instance method
GetMethodTotalArgumentsCount(MethodPtr method)178     virtual size_t GetMethodTotalArgumentsCount([[maybe_unused]] MethodPtr method) const
179     {
180         return 0;
181     }
GetMethodReturnType(MethodPtr parent_method,MethodId id)182     virtual DataType::Type GetMethodReturnType([[maybe_unused]] MethodPtr parent_method,
183                                                [[maybe_unused]] MethodId id) const
184     {
185         return DataType::NO_TYPE;
186     }
GetMethodArgumentType(MethodPtr parent_method,MethodId id,size_t index)187     virtual DataType::Type GetMethodArgumentType([[maybe_unused]] MethodPtr parent_method, [[maybe_unused]] MethodId id,
188                                                  [[maybe_unused]] size_t index) const
189     {
190         return DataType::NO_TYPE;
191     }
GetMethodArgumentsCount(MethodPtr parent_method,MethodId id)192     virtual size_t GetMethodArgumentsCount([[maybe_unused]] MethodPtr parent_method, [[maybe_unused]] MethodId id) const
193     {
194         return 0;
195     }
GetMethodArgumentsCount(MethodPtr method)196     virtual size_t GetMethodArgumentsCount([[maybe_unused]] MethodPtr method) const
197     {
198         return 0;
199     }
GetMethodRegistersCount(MethodPtr method)200     virtual size_t GetMethodRegistersCount([[maybe_unused]] MethodPtr method) const
201     {
202         return 0;
203     }
GetMethodCode(MethodPtr method)204     virtual const uint8_t *GetMethodCode([[maybe_unused]] MethodPtr method) const
205     {
206         return nullptr;
207     }
GetMethodCodeSize(MethodPtr method)208     virtual size_t GetMethodCodeSize([[maybe_unused]] MethodPtr method) const
209     {
210         return 0;
211     }
212 
GetMethodSourceLanguage(MethodPtr method)213     virtual SourceLanguage GetMethodSourceLanguage([[maybe_unused]] MethodPtr method) const
214     {
215         return SourceLanguage::PANDA_ASSEMBLY;
216     }
217 
SetCompiledEntryPoint(MethodPtr method,void * entry_point)218     virtual void SetCompiledEntryPoint([[maybe_unused]] MethodPtr method, [[maybe_unused]] void *entry_point) {}
219 
SetOsrCode(MethodPtr method,void * entry_point)220     virtual void SetOsrCode([[maybe_unused]] MethodPtr method, [[maybe_unused]] void *entry_point) {}
221 
GetOsrCode(MethodPtr method)222     virtual void *GetOsrCode([[maybe_unused]] MethodPtr method)
223     {
224         return nullptr;
225     }
226 
HasCompiledCode(MethodPtr method)227     virtual bool HasCompiledCode([[maybe_unused]] MethodPtr method)
228     {
229         return false;
230     }
231 
GetAccessFlagAbstractMask()232     virtual uint32_t GetAccessFlagAbstractMask() const
233     {
234         return 0;
235     }
236 
GetVTableIndex(MethodPtr method)237     virtual uint32_t GetVTableIndex([[maybe_unused]] MethodPtr method) const
238     {
239         return 0;
240     }
241 
IsMethodExternal(MethodPtr method,MethodPtr callee_method)242     virtual bool IsMethodExternal([[maybe_unused]] MethodPtr method, [[maybe_unused]] MethodPtr callee_method) const
243     {
244         return false;
245     }
246 
IsMethodIntrinsic(MethodPtr method)247     virtual bool IsMethodIntrinsic([[maybe_unused]] MethodPtr method) const
248     {
249         return false;
250     }
251 
IsMethodAbstract(MethodPtr method)252     virtual bool IsMethodAbstract([[maybe_unused]] MethodPtr method) const
253     {
254         return false;
255     }
256 
IsMethodIntrinsic(MethodPtr parent_method,MethodId id)257     virtual bool IsMethodIntrinsic([[maybe_unused]] MethodPtr parent_method, [[maybe_unused]] MethodId id) const
258     {
259         return false;
260     }
261 
262     // return true if the method is Jni with exception
HasNativeException(MethodPtr method)263     virtual bool HasNativeException([[maybe_unused]] MethodPtr method) const
264     {
265         return false;
266     }
267 
IsMethodStatic(MethodPtr parent_method,MethodId id)268     virtual bool IsMethodStatic([[maybe_unused]] MethodPtr parent_method, [[maybe_unused]] MethodId id) const
269     {
270         return false;
271     }
272 
IsMethodStatic(MethodPtr method)273     virtual bool IsMethodStatic([[maybe_unused]] MethodPtr method) const
274     {
275         return true;
276     }
277 
IsMethodFinal(MethodPtr method)278     virtual bool IsMethodFinal([[maybe_unused]] MethodPtr method) const
279     {
280         return false;
281     }
282 
IsMethodCanBeInlined(MethodPtr method)283     virtual bool IsMethodCanBeInlined([[maybe_unused]] MethodPtr method) const
284     {
285         return true;
286     }
287 
IsMethodStaticConstructor(MethodPtr method)288     virtual bool IsMethodStaticConstructor([[maybe_unused]] MethodPtr method) const
289     {
290         return false;
291     }
292 
GetFileName(MethodPtr method)293     virtual std::string GetFileName([[maybe_unused]] MethodPtr method) const
294     {
295         return "UnknownFile";
296     }
297 
GetClassNameFromMethod(MethodPtr method)298     virtual std::string GetClassNameFromMethod([[maybe_unused]] MethodPtr method) const
299     {
300         return "UnknownClass";
301     }
302 
GetClassName(ClassPtr klass)303     virtual std::string GetClassName([[maybe_unused]] ClassPtr klass) const
304     {
305         return "UnknownClass";
306     }
307 
GetClass(MethodPtr method)308     virtual ClassPtr GetClass([[maybe_unused]] MethodPtr method) const
309     {
310         return nullptr;
311     }
312 
313     // returns Class for Field
GetClassForField(FieldPtr field)314     virtual ClassPtr GetClassForField([[maybe_unused]] FieldPtr field) const
315     {
316         return nullptr;
317     }
318 
319     ClassPtr ResolveClassForField(MethodPtr method, size_t field_id);
320 
GetMethodName(MethodPtr method)321     virtual std::string GetMethodName([[maybe_unused]] MethodPtr method) const
322     {
323         return "UnknownMethod";
324     }
325 
GetBranchTakenCounter(MethodPtr method,uint32_t pc)326     virtual int64_t GetBranchTakenCounter([[maybe_unused]] MethodPtr method, [[maybe_unused]] uint32_t pc) const
327     {
328         return 0;
329     }
330 
GetBranchNotTakenCounter(MethodPtr method,uint32_t pc)331     virtual int64_t GetBranchNotTakenCounter([[maybe_unused]] MethodPtr method, [[maybe_unused]] uint32_t pc) const
332     {
333         return 0;
334     }
335 
IsConstructor(MethodPtr method,uint32_t class_id)336     virtual bool IsConstructor([[maybe_unused]] MethodPtr method, [[maybe_unused]] uint32_t class_id)
337     {
338         return false;
339     }
340 
341     // returns true if need to encode memory barrier before return
IsMemoryBarrierRequired(MethodPtr method)342     virtual bool IsMemoryBarrierRequired([[maybe_unused]] MethodPtr method) const
343     {
344         return false;
345     }
346 
GetMethodFullName(MethodPtr method,bool with_signature)347     virtual std::string GetMethodFullName([[maybe_unused]] MethodPtr method, [[maybe_unused]] bool with_signature) const
348     {
349         return "UnknownMethod";
350     }
351 
GetMethodFullName(MethodPtr method)352     std::string GetMethodFullName(MethodPtr method) const
353     {
354         return GetMethodFullName(method, false);
355     }
356 
GetBytecodeString(MethodPtr method,uintptr_t pc)357     virtual std::string GetBytecodeString([[maybe_unused]] MethodPtr method, [[maybe_unused]] uintptr_t pc) const
358     {
359         return std::string();
360     }
361 
GetLiteralArray(MethodPtr method,LiteralArrayId id)362     virtual panda::pandasm::LiteralArray GetLiteralArray([[maybe_unused]] MethodPtr method,
363                                                          [[maybe_unused]] LiteralArrayId id) const
364     {
365         return panda::pandasm::LiteralArray();
366     }
367 
IsInterfaceMethod(MethodPtr parent_method,MethodId id)368     virtual bool IsInterfaceMethod([[maybe_unused]] MethodPtr parent_method, [[maybe_unused]] MethodId id) const
369     {
370         return false;
371     }
372 
IsInterfaceMethod(MethodPtr method)373     virtual bool IsInterfaceMethod([[maybe_unused]] MethodPtr method) const
374     {
375         return false;
376     }
377 
IsInstanceConstructor(MethodPtr method)378     virtual bool IsInstanceConstructor([[maybe_unused]] MethodPtr method) const
379     {
380         return false;
381     }
382 
CanThrowException(MethodPtr method)383     virtual bool CanThrowException([[maybe_unused]] MethodPtr method) const
384     {
385         return true;
386     }
387 
388     // Method offsets
GetAccessFlagsOffset(Arch arch)389     uint32_t GetAccessFlagsOffset(Arch arch) const
390     {
391         return panda::cross_values::GetMethodAccessFlagsOffset(arch);
392     }
GetVTableIndexOffset(Arch arch)393     uint32_t GetVTableIndexOffset(Arch arch) const
394     {
395         return panda::cross_values::GetMethodVTableIndexOffset(arch);
396     }
GetClassOffset(Arch arch)397     uint32_t GetClassOffset(Arch arch) const
398     {
399         return panda::cross_values::GetMethodClassOffset(arch);
400     }
GetCompiledEntryPointOffset(Arch arch)401     uint32_t GetCompiledEntryPointOffset(Arch arch) const
402     {
403         return panda::cross_values::GetMethodCompiledEntryPointOffset(arch);
404     }
GetPandaFileOffset(Arch arch)405     uint32_t GetPandaFileOffset(Arch arch) const
406     {
407         return panda::cross_values::GetMethodPandaFileOffset(arch);
408     }
409 
410     /**************************************************************************
411      * Exec state information
412      */
GetTlsFrameKindOffset(Arch arch)413     size_t GetTlsFrameKindOffset(Arch arch) const
414     {
415         return panda::cross_values::GetManagedThreadFrameKindOffset(arch);
416     }
GetFlagAddrOffset(Arch arch)417     uint32_t GetFlagAddrOffset(Arch arch) const
418     {
419         return panda::cross_values::GetManagedThreadFlagOffset(arch);
420     }
GetTlsFrameOffset(Arch arch)421     size_t GetTlsFrameOffset(Arch arch) const
422     {
423         return panda::cross_values::GetManagedThreadFrameOffset(arch);
424     }
GetExceptionOffset(Arch arch)425     size_t GetExceptionOffset(Arch arch) const
426     {
427         return panda::cross_values::GetManagedThreadExceptionOffset(arch);
428     }
GetTlsNativePcOffset(Arch arch)429     size_t GetTlsNativePcOffset(Arch arch) const
430     {
431         return panda::cross_values::GetManagedThreadNativePcOffset(arch);
432     }
GetTlsCardTableAddrOffset(Arch arch)433     size_t GetTlsCardTableAddrOffset(Arch arch) const
434     {
435         return panda::cross_values::GetManagedThreadCardTableAddrOffset(arch);
436     }
GetTlsCardTableMinAddrOffset(Arch arch)437     size_t GetTlsCardTableMinAddrOffset(Arch arch) const
438     {
439         return panda::cross_values::GetManagedThreadCardTableMinAddrOffset(arch);
440     }
GetTlsConcurrentMarkingAddrOffset(Arch arch)441     size_t GetTlsConcurrentMarkingAddrOffset(Arch arch) const
442     {
443         return panda::cross_values::GetManagedThreadConcurrentMarkingAddrOffset(arch);
444     }
GetLanguageExtensionsDataOffset(Arch arch)445     uint32_t GetLanguageExtensionsDataOffset([[maybe_unused]] Arch arch) const
446     {
447         return panda::cross_values::GetManagedThreadLanguageExtensionDataOffset(arch);
448     }
449 
GetPreType()450     virtual ::panda::mem::BarrierType GetPreType() const
451     {
452         return ::panda::mem::BarrierType::PRE_WRB_NONE;
453     }
454 
GetPostType()455     virtual ::panda::mem::BarrierType GetPostType() const
456     {
457         return ::panda::mem::BarrierType::POST_WRB_NONE;
458     }
459 
GetBarrierOperand(::panda::mem::BarrierPosition barrier_position,std::string_view operand_name)460     virtual ::panda::mem::BarrierOperand GetBarrierOperand(
461         [[maybe_unused]] ::panda::mem::BarrierPosition barrier_position,
462         [[maybe_unused]] std::string_view operand_name) const
463     {
464         return ::panda::mem::BarrierOperand(::panda::mem::BarrierOperandType::BOOL_ADDRESS, false);
465     }
466 
467     /**************************************************************************
468      * Array information
469      */
GetClassArraySize(Arch arch)470     uint32_t GetClassArraySize(Arch arch) const
471     {
472         return panda::cross_values::GetCoretypesArrayClassSize(arch);
473     }
474 
GetArrayElementSize(MethodPtr method,IdType id)475     virtual uint32_t GetArrayElementSize([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
476     {
477         return ARRAY_DEFAULT_ELEMENT_SIZE;
478     }
479 
GetPointerToConstArrayData(MethodPtr method,IdType id)480     virtual uintptr_t GetPointerToConstArrayData([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
481     {
482         return 0;
483     }
484 
GetOffsetToConstArrayData(MethodPtr method,IdType id)485     virtual size_t GetOffsetToConstArrayData([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
486     {
487         return 0;
488     }
489 
490     // Array offsets
GetArrayDataOffset(Arch arch)491     uint32_t GetArrayDataOffset(Arch arch) const
492     {
493         return panda::cross_values::GetCoretypesArrayDataOffset(arch);
494     }
GetArrayLengthOffset(Arch arch)495     uint32_t GetArrayLengthOffset(Arch arch) const
496     {
497         return panda::cross_values::GetCoretypesArrayLengthOffset(arch);
498     }
499 
500     /**************************************************************************
501      * String information
502      */
IsCompressedStringsEnabled()503     virtual bool IsCompressedStringsEnabled() const
504     {
505         return true;
506     }
507 
GetStringCompressionMask()508     virtual uint32_t GetStringCompressionMask() const
509     {
510         return 1;
511     }
512 
GetNonMovableString(MethodPtr method,StringId id)513     virtual object_pointer_type GetNonMovableString([[maybe_unused]] MethodPtr method,
514                                                     [[maybe_unused]] StringId id) const
515     {
516         return 0;
517     }
518 
GetStringClass(MethodPtr method)519     virtual ClassPtr GetStringClass([[maybe_unused]] MethodPtr method) const
520     {
521         return nullptr;
522     }
523 
524     // String offsets
GetStringDataOffset(Arch arch)525     uint32_t GetStringDataOffset(Arch arch) const
526     {
527         return panda::cross_values::GetCoretypesStringDataOffset(arch);
528     }
GetStringLengthOffset(Arch arch)529     uint32_t GetStringLengthOffset(Arch arch) const
530     {
531         return panda::cross_values::GetCoretypesStringLengthOffset(arch);
532     }
GetStringClassPointerTlsOffset(Arch arch)533     uintptr_t GetStringClassPointerTlsOffset(Arch arch) const
534     {
535         return cross_values::GetManagedThreadStringClassPtrOffset(arch);
536     }
537 
538     /**************************************************************************
539      * managed Thread object information
540      */
541 
GetThreadObjectOffset(Arch arch)542     uint32_t GetThreadObjectOffset(Arch arch) const
543     {
544         return panda::cross_values::GetManagedThreadObjectOffset(arch);
545     }
546 
547     /**************************************************************************
548      * TLAB information
549      */
550 
GetTLABMaxSize()551     virtual size_t GetTLABMaxSize() const
552     {
553         return 0;
554     }
555 
GetTLABAlignment()556     virtual size_t GetTLABAlignment() const
557     {
558         return 1;
559     }
560 
IsTrackTlabAlloc()561     virtual bool IsTrackTlabAlloc() const
562     {
563         return false;
564     }
565 
566     // TLAB offsets
GetCurrentTLABOffset(Arch arch)567     size_t GetCurrentTLABOffset(Arch arch) const
568     {
569         return panda::cross_values::GetManagedThreadTlabOffset(arch);
570     }
GetTLABStartPointerOffset(Arch arch)571     size_t GetTLABStartPointerOffset(Arch arch) const
572     {
573         return panda::cross_values::GetTlabMemoryStartAddrOffset(arch);
574     }
GetTLABFreePointerOffset(Arch arch)575     size_t GetTLABFreePointerOffset(Arch arch) const
576     {
577         return panda::cross_values::GetTlabCurFreePositionOffset(arch);
578     }
GetTLABEndPointerOffset(Arch arch)579     size_t GetTLABEndPointerOffset(Arch arch) const
580     {
581         return panda::cross_values::GetTlabMemoryEndAddrOffset(arch);
582     }
583 
584     /**************************************************************************
585      * Object information
586      */
GetClass(MethodPtr method,IdType id)587     virtual ClassPtr GetClass([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
588     {
589         return nullptr;
590     }
591 
GetClassType(MethodPtr method,IdType id)592     virtual ClassType GetClassType([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
593     {
594         return ClassType::UNRESOLVED_CLASS;
595     }
596 
IsArrayClass(MethodPtr method,IdType id)597     virtual bool IsArrayClass([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
598     {
599         return false;
600     }
601 
IsArrayClass(ClassPtr klass)602     virtual bool IsArrayClass([[maybe_unused]] ClassPtr klass) const
603     {
604         return false;
605     }
606 
GetArrayElementClass(ClassPtr cls)607     virtual ClassPtr GetArrayElementClass([[maybe_unused]] ClassPtr cls) const
608     {
609         return nullptr;
610     }
611 
CheckStoreArray(ClassPtr array_cls,ClassPtr str_cls)612     virtual bool CheckStoreArray([[maybe_unused]] ClassPtr array_cls, [[maybe_unused]] ClassPtr str_cls) const
613     {
614         return false;
615     }
616 
IsAssignableFrom(ClassPtr cls1,ClassPtr cls2)617     virtual bool IsAssignableFrom([[maybe_unused]] ClassPtr cls1, [[maybe_unused]] ClassPtr cls2) const
618     {
619         return false;
620     }
621 
GetObjectHashedStatusBitNum()622     virtual size_t GetObjectHashedStatusBitNum() const
623     {
624         return 0;
625     }
626 
GetObjectHashShift()627     virtual size_t GetObjectHashShift() const
628     {
629         return 0;
630     }
631 
GetObjectHashMask()632     virtual size_t GetObjectHashMask() const
633     {
634         return 0;
635     }
636 
637     // Offset of class in ObjectHeader
GetObjClassOffset(Arch arch)638     uint32_t GetObjClassOffset(Arch arch) const
639     {
640         return panda::cross_values::GetObjectHeaderClassPointerOffset(arch);
641     }
642 
643     // Offset of the managed object in the BaseClass
GetManagedClassOffset(Arch arch)644     uint32_t GetManagedClassOffset(Arch arch) const
645     {
646         return panda::cross_values::GetBaseClassManagedObjectOffset(arch);
647     }
648 
649     // Offset of mark word in ObjectHeader
GetObjMarkWordOffset(Arch arch)650     uint32_t GetObjMarkWordOffset(Arch arch) const
651     {
652         return panda::cross_values::GetObjectHeaderMarkWordOffset(arch);
653     }
654 
655     /**************************************************************************
656      * Class information
657      */
658 
659     // Returns Class Id for Field.
660     // We don't get class id directly from the field's class, because we need a class id regarding to the current
661     // file. Class id is used in codegen to initialize class in aot mode.
GetClassIdForField(MethodPtr method,size_t unused)662     virtual size_t GetClassIdForField([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
663     {
664         return 0;
665     }
666 
GetClassIdForField(FieldPtr field)667     virtual size_t GetClassIdForField([[maybe_unused]] FieldPtr field) const
668     {
669         return 0;
670     }
671 
672     // returns Class Id for Method
GetClassIdForMethod(MethodPtr method)673     virtual size_t GetClassIdForMethod([[maybe_unused]] MethodPtr method) const
674     {
675         return 0;
676     }
677 
678     // returns Class Id for Method
GetClassIdForMethod(MethodPtr method,size_t unused)679     virtual size_t GetClassIdForMethod([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
680     {
681         return 0;
682     }
683 
GetClassIdWithinFile(MethodPtr method,ClassPtr klass)684     virtual IdType GetClassIdWithinFile([[maybe_unused]] MethodPtr method, [[maybe_unused]] ClassPtr klass) const
685     {
686         return 0;
687     }
688 
GetLiteralArrayClassIdWithinFile(MethodPtr method,panda_file::LiteralTag tag)689     virtual IdType GetLiteralArrayClassIdWithinFile([[maybe_unused]] MethodPtr method,
690                                                     [[maybe_unused]] panda_file::LiteralTag tag) const
691     {
692         return 0;
693     }
694 
CanUseTlabForClass(ClassPtr klass)695     virtual bool CanUseTlabForClass([[maybe_unused]] ClassPtr klass) const
696     {
697         return true;
698     }
699 
700     // returns class size
GetClassSize(ClassPtr klass)701     virtual size_t GetClassSize([[maybe_unused]] ClassPtr klass) const
702     {
703         return 0;
704     }
705 
706     // Vtable offset in Class
GetVTableOffset(Arch arch)707     uint32_t GetVTableOffset(Arch arch) const
708     {
709         return panda::cross_values::GetClassVtableOffset(arch);
710     }
711 
712     // returns base offset in Class(for array)
GetClassBaseOffset(Arch arch)713     uint32_t GetClassBaseOffset(Arch arch) const
714     {
715         return panda::cross_values::GetClassBaseOffset(arch);
716     }
717 
718     // returns component type offset in Class(for array)
GetClassComponentTypeOffset(Arch arch)719     uint32_t GetClassComponentTypeOffset(Arch arch) const
720     {
721         return panda::cross_values::GetClassComponentTypeOffset(arch);
722     }
723 
724     // returns type offset in Class(for array)
GetClassTypeOffset(Arch arch)725     uint32_t GetClassTypeOffset(Arch arch) const
726     {
727         return panda::cross_values::GetClassTypeOffset(arch);
728     }
729 
GetClassStateOffset(Arch arch)730     uint32_t GetClassStateOffset(Arch arch) const
731     {
732         return panda::cross_values::GetClassStateOffset(arch);
733     }
734 
GetClassMethodsOffset(Arch arch)735     uint32_t GetClassMethodsOffset(Arch arch) const
736     {
737         return panda::cross_values::GetClassMethodsOffset(arch);
738     }
739 
740     /**************************************************************************
741      * Field information
742      */
743 
744     /**
745      * Try to resolve field.
746      * @param method method to which the field belongs
747      * @param id id of the field
748      * @param allow_external allow fields defined in the external file, if false - return nullptr for external fields
749      * @param class_id output variable where will be written a field's class
750      * @return return field or nullptr if it cannot be resolved
751      */
ResolveField(MethodPtr method,size_t unused,bool allow_external,uint32_t * class_id)752     virtual FieldPtr ResolveField([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused,
753                                   [[maybe_unused]] bool allow_external, [[maybe_unused]] uint32_t *class_id)
754     {
755         return nullptr;
756     }
757 
GetFieldType(FieldPtr field)758     virtual DataType::Type GetFieldType([[maybe_unused]] FieldPtr field) const
759     {
760         return DataType::NO_TYPE;
761     }
762 
GetFieldTypeById(MethodPtr method,IdType unused)763     virtual DataType::Type GetFieldTypeById([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType unused) const
764     {
765         return DataType::NO_TYPE;
766     }
767 
GetFieldOffset(FieldPtr field)768     virtual size_t GetFieldOffset([[maybe_unused]] FieldPtr field) const
769     {
770         return 0;
771     }
772 
GetFieldByOffset(size_t offset)773     virtual FieldPtr GetFieldByOffset([[maybe_unused]] size_t offset) const
774     {
775         return nullptr;
776     }
777 
GetFieldClass(FieldPtr field)778     virtual uintptr_t GetFieldClass([[maybe_unused]] FieldPtr field) const
779     {
780         return 0;
781     }
782 
IsFieldVolatile(FieldPtr field)783     virtual bool IsFieldVolatile([[maybe_unused]] FieldPtr field) const
784     {
785         return false;
786     }
787 
HasFieldMetadata(FieldPtr field)788     virtual bool HasFieldMetadata([[maybe_unused]] FieldPtr field) const
789     {
790         return false;
791     }
792 
GetFieldName(FieldPtr field)793     virtual std::string GetFieldName([[maybe_unused]] FieldPtr field) const
794     {
795         return "UnknownField";
796     }
797 
798     // Return offset of the managed object in the class
GetFieldClassOffset(Arch arch)799     uint32_t GetFieldClassOffset(Arch arch) const
800     {
801         return panda::cross_values::GetFieldClassOffset(arch);
802     }
803 
804     // Return offset of the managed object in the class
GetFieldOffsetOffset(Arch arch)805     uint32_t GetFieldOffsetOffset(Arch arch) const
806     {
807         return panda::cross_values::GetFieldOffsetOffset(arch);
808     }
809 
810     /**************************************************************************
811      * Type information
812      */
ResolveType(MethodPtr method,size_t unused)813     virtual ClassPtr ResolveType([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
814     {
815         return nullptr;
816     }
817 
IsClassInitialized(uintptr_t unused)818     virtual bool IsClassInitialized([[maybe_unused]] uintptr_t unused) const
819     {
820         return true;
821     }
822 
IsClassFinal(ClassPtr unused)823     virtual bool IsClassFinal([[maybe_unused]] ClassPtr unused) const
824     {
825         return false;
826     }
827 
GetManagedType(uintptr_t unused)828     virtual uintptr_t GetManagedType([[maybe_unused]] uintptr_t unused) const
829     {
830         return 0;
831     }
832 
GetClassInitializedValue()833     virtual uint8_t GetClassInitializedValue() const
834     {
835         return 0;
836     }
837 
GetReferenceTypeMask()838     virtual uint8_t GetReferenceTypeMask() const
839     {
840         return 0;
841     }
842 
843     /**************************************************************************
844      * Entrypoints
845      */
846 #include <intrinsics_enum.inl>
847 #include <entrypoints_compiler.inl>
848 #include <entrypoints_compiler_checksum.inl>
849 #include "compiler_interface_extensions.inl.h"
850 
GetIntrinsicId(MethodPtr method)851     virtual IntrinsicId GetIntrinsicId([[maybe_unused]] MethodPtr method) const
852     {
853         return static_cast<IntrinsicId>(0);
854     }
855 
GetIntrinsicAddress(bool runtime_call,IntrinsicId unused)856     virtual uintptr_t GetIntrinsicAddress([[maybe_unused]] bool runtime_call, [[maybe_unused]] IntrinsicId unused) const
857     {
858         return 0;
859     }
860 
GetEntrypointTlsOffset(Arch arch,EntrypointId id)861     uintptr_t GetEntrypointTlsOffset(Arch arch, EntrypointId id) const
862     {
863         return cross_values::GetManagedThreadEntrypointOffset(arch, panda::EntrypointId(static_cast<uint8_t>(id)));
864     }
865 
866     /**************************************************************************
867      * Dynamic object information
868      */
869 
GetFunctionTargetOffset(Arch arch)870     virtual uint32_t GetFunctionTargetOffset([[maybe_unused]] Arch arch) const
871     {
872         return 0;
873     }
874 
GetDynamicPrimitiveUndefined()875     virtual uint64_t GetDynamicPrimitiveUndefined() const
876     {
877         return static_cast<uint64_t>(coretypes::TaggedValue::Undefined().GetRawData());
878     }
879 
GetPackConstantByPrimitiveType(compiler::AnyBaseType type,uint64_t imm)880     virtual uint64_t GetPackConstantByPrimitiveType(compiler::AnyBaseType type, uint64_t imm) const
881     {
882         auto datatype = AnyBaseTypeToDataType(type);
883         if (datatype == DataType::INT32) {
884             return coretypes::TaggedValue::GetIntTaggedValue(imm);
885         }
886         if (datatype == DataType::FLOAT64) {
887             return coretypes::TaggedValue::GetDoubleTaggedValue(imm);
888         }
889         if (datatype == DataType::BOOL) {
890             return coretypes::TaggedValue::GetBoolTaggedValue(imm);
891         }
892         UNREACHABLE();
893         return 0;
894     }
895 
GetDynamicPrimitiveFalse()896     virtual uint64_t GetDynamicPrimitiveFalse() const
897     {
898         return static_cast<uint64_t>(coretypes::TaggedValue::False().GetRawData());
899     }
900 
GetDynamicPrimitiveTrue()901     virtual uint64_t GetDynamicPrimitiveTrue() const
902     {
903         return static_cast<uint64_t>(coretypes::TaggedValue::True().GetRawData());
904     }
905 
GetNativePointerTargetOffset(Arch arch)906     virtual uint32_t GetNativePointerTargetOffset([[maybe_unused]] Arch arch) const
907     {
908         return 0;
909     }
910 
911     /**************************************************************************
912      * Check if GC can be triggered during call.
913      * This is possible when method A calling method B and waiting while B is compiling.
914      */
HasSafepointDuringCall()915     virtual bool HasSafepointDuringCall() const
916     {
917         return false;
918     }
919 
920     // TypeInfoIndex adaption
GetTypeInfoIndexByInstId(size_t id)921     virtual TypeInfoIndex GetTypeInfoIndexByInstId([[maybe_unused]] size_t id) const
922     {
923         return NO_EXPLICIT_TYPE;
924     }
925 
IsPcBindType(int32_t pc)926     virtual bool IsPcBindType([[maybe_unused]] int32_t pc) const
927     {
928         return false;
929     }
930 
FillInstIdTypePairByPc(size_t id,int32_t pc)931     virtual bool FillInstIdTypePairByPc([[maybe_unused]] size_t id, [[maybe_unused]] int32_t pc)
932     {
933         return false;
934     }
935 
HasInsTypeinfo()936     virtual bool HasInsTypeinfo() const
937     {
938         return false;
939     }
940 
AddPcTypePair(int32_t pc,TypeInfoIndex type)941     virtual bool AddPcTypePair([[maybe_unused]] int32_t pc, [[maybe_unused]] TypeInfoIndex type)
942     {
943         return false;
944     }
945 
FillArgTypePairs(std::unordered_map<int32_t,TypeInfoIndex> * map)946     virtual bool FillArgTypePairs([[maybe_unused]] std::unordered_map<int32_t, TypeInfoIndex> *map) const
947     {
948         return false;
949     }
950 
SetTypeLiteralArrayKey(std::string key)951     virtual bool SetTypeLiteralArrayKey([[maybe_unused]] std::string key)
952     {
953         return false;
954     }
955 
GetTypeLiteralArrayKey()956     virtual const std::string *GetTypeLiteralArrayKey() const
957     {
958         return nullptr;
959     }
960 
961     NO_COPY_SEMANTIC(RuntimeInterface);
962     NO_MOVE_SEMANTIC(RuntimeInterface);
963 
964 private:
965     static constexpr uint32_t ARRAY_DEFAULT_ELEMENT_SIZE = 4;
966 };
967 
968 class IClassHierarchyAnalysis {
969 public:
970     IClassHierarchyAnalysis() = default;
971     virtual ~IClassHierarchyAnalysis() = default;
972 
973 public:
974     virtual RuntimeInterface::MethodPtr GetSingleImplementation([
975         [maybe_unused]] RuntimeInterface::MethodPtr method) = 0;
976     virtual bool IsSingleImplementation([[maybe_unused]] RuntimeInterface::MethodPtr method) = 0;
977     virtual void AddDependency([[maybe_unused]] RuntimeInterface::MethodPtr caller,
978                                [[maybe_unused]] RuntimeInterface::MethodPtr callee) = 0;
979 
980     NO_COPY_SEMANTIC(IClassHierarchyAnalysis);
981     NO_MOVE_SEMANTIC(IClassHierarchyAnalysis);
982 };
983 
984 class InlineCachesInterface {
985 public:
986     using ClassList = Span<RuntimeInterface::ClassPtr>;
987     enum class CallKind { UNKNOWN, MONOMORPHIC, POLYMORPHIC, MEGAMORPHIC };
988 
989     virtual CallKind GetClasses(RuntimeInterface::MethodPtr method, uintptr_t unused,
990                                 ArenaVector<RuntimeInterface::ClassPtr> *classes) = 0;
991     virtual ~InlineCachesInterface() = default;
992     InlineCachesInterface() = default;
993 
994     DEFAULT_COPY_SEMANTIC(InlineCachesInterface);
995     DEFAULT_MOVE_SEMANTIC(InlineCachesInterface);
996 };
997 
998 class UnresolvedTypesInterface {
999 public:
1000     enum class SlotKind { UNKNOWN, CLASS, MANAGED_CLASS, METHOD, VIRTUAL_METHOD, FIELD, STATIC_FIELD_PTR };
1001     virtual bool AddTableSlot([[maybe_unused]] RuntimeInterface::MethodPtr method, [[maybe_unused]] uint32_t type_id,
1002                               [[maybe_unused]] SlotKind kind) = 0;
1003     virtual uintptr_t GetTableSlot([[maybe_unused]] RuntimeInterface::MethodPtr method,
1004                                    [[maybe_unused]] uint32_t type_id, [[maybe_unused]] SlotKind kind) const = 0;
1005     virtual ~UnresolvedTypesInterface() = default;
1006     UnresolvedTypesInterface() = default;
1007 
1008     DEFAULT_COPY_SEMANTIC(UnresolvedTypesInterface);
1009     DEFAULT_MOVE_SEMANTIC(UnresolvedTypesInterface);
1010 };
1011 
1012 enum class TraceId {
1013     METHOD_ENTER = 1U << 0U,
1014     METHOD_EXIT = 1U << 1U,
1015     PRINT_ARG = 1U << 2U,
1016     TLAB_EVENT = 1U << 3U,
1017 };
1018 
1019 enum class DeoptimizeType {
1020     INVALID = 0,
1021     INLINE_IC,
1022     INLINE_CHA,
1023     NULL_CHECK,
1024     BOUNDS_CHECK,
1025     ZERO_CHECK,
1026     NEGATIVE_CHECK,
1027     CHECK_CAST,
1028     ANY_TYPE_CHECK,
1029     DEOPT_OVERFLOW,
1030     COUNT
1031 };
1032 
DeoptimizeTypeToString(DeoptimizeType deopt_type)1033 inline const char *DeoptimizeTypeToString(DeoptimizeType deopt_type)
1034 {
1035     static constexpr auto COUNT = static_cast<uint8_t>(DeoptimizeType::COUNT);
1036     static constexpr std::array<const char *, COUNT> DEOPT_TYPE_NAMES = {
1037         "INVALID_TYPE", "INLINE_IC",      "INLINE_CHA", "NULL_CHECK",    "BOUNDS_CHECK",
1038         "ZERO_CHECK",   "NEGATIVE_CHECK", "CHECK_CAST", "ANY_TYPE_CHECK"};
1039     auto idx = static_cast<uint8_t>(deopt_type);
1040     ASSERT(idx < COUNT);
1041     return DEOPT_TYPE_NAMES[idx];
1042 }
1043 }  // namespace panda::compiler
1044 
1045 #endif  // COMPILER_RUNTIME_INTERFACE_H
1046