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