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