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