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