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