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
GetArrayU16ClassPointerTlsOffset(Arch arch)679 uintptr_t GetArrayU16ClassPointerTlsOffset(Arch arch) const
680 {
681 return cross_values::GetManagedThreadArrayU16ClassPtrOffset(arch);
682 }
683
GetClassArraySize(Arch arch)684 uint32_t GetClassArraySize(Arch arch) const
685 {
686 return ark::cross_values::GetCoretypesArrayClassSize(arch);
687 }
688
GetArrayElementSize(MethodPtr method,IdType id)689 virtual uint32_t GetArrayElementSize([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
690 {
691 return ARRAY_DEFAULT_ELEMENT_SIZE;
692 }
693
GetMaxArrayLength(ClassPtr klass)694 virtual uint32_t GetMaxArrayLength([[maybe_unused]] ClassPtr klass) const
695 {
696 return INT32_MAX;
697 }
698
GetPointerToConstArrayData(MethodPtr method,IdType id)699 virtual uintptr_t GetPointerToConstArrayData([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
700 {
701 return 0;
702 }
703
GetOffsetToConstArrayData(MethodPtr method,IdType id)704 virtual size_t GetOffsetToConstArrayData([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
705 {
706 return 0;
707 }
708
GetArrayU16Class(MethodPtr method)709 virtual ClassPtr GetArrayU16Class([[maybe_unused]] MethodPtr method) const
710 {
711 return nullptr;
712 }
713
714 // Array offsets
GetArrayDataOffset(Arch arch)715 uint32_t GetArrayDataOffset(Arch arch) const
716 {
717 return ark::cross_values::GetCoretypesArrayDataOffset(arch);
718 }
GetArrayLengthOffset(Arch arch)719 uint32_t GetArrayLengthOffset(Arch arch) const
720 {
721 return ark::cross_values::GetCoretypesArrayLengthOffset(arch);
722 }
723
724 /// String information
IsCompressedStringsEnabled()725 virtual bool IsCompressedStringsEnabled() const
726 {
727 return true;
728 }
729
GetStringCompressionMask()730 virtual uint32_t GetStringCompressionMask() const
731 {
732 return 1;
733 }
734
GetNonMovableString(MethodPtr method,StringId id)735 virtual ObjectPointerType GetNonMovableString([[maybe_unused]] MethodPtr method, [[maybe_unused]] StringId id) const
736 {
737 return 0;
738 }
739
GetStringClass(MethodPtr method)740 virtual ClassPtr GetStringClass([[maybe_unused]] MethodPtr method) const
741 {
742 return nullptr;
743 }
744
GetStringBuilderClass()745 virtual ClassPtr GetStringBuilderClass() const
746 {
747 return nullptr;
748 }
749
GetStringBuilderDefaultConstructor()750 virtual MethodPtr GetStringBuilderDefaultConstructor() const
751 {
752 return nullptr;
753 }
754
755 // String offsets
GetStringDataOffset(Arch arch)756 uint32_t GetStringDataOffset(Arch arch) const
757 {
758 return ark::cross_values::GetCoretypesStringDataOffset(arch);
759 }
GetStringLengthOffset(Arch arch)760 uint32_t GetStringLengthOffset(Arch arch) const
761 {
762 return ark::cross_values::GetCoretypesStringLengthOffset(arch);
763 }
GetStringClassPointerTlsOffset(Arch arch)764 uintptr_t GetStringClassPointerTlsOffset(Arch arch) const
765 {
766 return cross_values::GetManagedThreadStringClassPtrOffset(arch);
767 }
768
769 // StringBuilder offsets.
770 // cross_values are not used here as StringBuilder doesn't have a corresponding c++ representative.
GetSbBufferOffset()771 static constexpr uint32_t GetSbBufferOffset()
772 {
773 return ObjectHeader::ObjectHeaderSize();
774 }
GetSbIndexOffset()775 static constexpr uint32_t GetSbIndexOffset()
776 {
777 return GetSbBufferOffset() + ark::OBJECT_POINTER_SIZE;
778 }
GetSbLengthOffset()779 static constexpr uint32_t GetSbLengthOffset()
780 {
781 return GetSbIndexOffset() + sizeof(int32_t);
782 }
GetSbCompressOffset()783 static constexpr uint32_t GetSbCompressOffset()
784 {
785 return GetSbLengthOffset() + sizeof(int32_t);
786 }
787
788 /// managed Thread object information
789
GetThreadObjectOffset(Arch arch)790 uint32_t GetThreadObjectOffset(Arch arch) const
791 {
792 return ark::cross_values::GetManagedThreadObjectOffset(arch);
793 }
794
795 /// TLAB information
796
GetTLABMaxSize()797 virtual size_t GetTLABMaxSize() const
798 {
799 return 0;
800 }
801
GetTLABAlignment()802 virtual size_t GetTLABAlignment() const
803 {
804 return 1;
805 }
806
IsTrackTlabAlloc()807 virtual bool IsTrackTlabAlloc() const
808 {
809 return false;
810 }
811
812 // TLAB offsets
GetCurrentTLABOffset(Arch arch)813 size_t GetCurrentTLABOffset(Arch arch) const
814 {
815 return ark::cross_values::GetManagedThreadTlabOffset(arch);
816 }
GetTLABStartPointerOffset(Arch arch)817 size_t GetTLABStartPointerOffset(Arch arch) const
818 {
819 return ark::cross_values::GetTlabMemoryStartAddrOffset(arch);
820 }
GetTLABFreePointerOffset(Arch arch)821 size_t GetTLABFreePointerOffset(Arch arch) const
822 {
823 return ark::cross_values::GetTlabCurFreePositionOffset(arch);
824 }
GetTLABEndPointerOffset(Arch arch)825 size_t GetTLABEndPointerOffset(Arch arch) const
826 {
827 return ark::cross_values::GetTlabMemoryEndAddrOffset(arch);
828 }
829
830 /// Object information
GetClass(MethodPtr method,IdType id)831 virtual ClassPtr GetClass([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
832 {
833 return nullptr;
834 }
835
GetClassType(MethodPtr method,IdType id)836 virtual ClassType GetClassType([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
837 {
838 return ClassType::UNRESOLVED_CLASS;
839 }
840
GetClassType(ClassPtr klassPtr)841 virtual ClassType GetClassType([[maybe_unused]] ClassPtr klassPtr) const
842 {
843 return ClassType::UNRESOLVED_CLASS;
844 }
845
IsArrayClass(MethodPtr method,IdType id)846 virtual bool IsArrayClass([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
847 {
848 return false;
849 }
850
IsStringClass(MethodPtr method,IdType id)851 virtual bool IsStringClass([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
852 {
853 return false;
854 }
855
IsArrayClass(ClassPtr klass)856 virtual bool IsArrayClass([[maybe_unused]] ClassPtr klass) const
857 {
858 return false;
859 }
860
GetArrayElementClass(ClassPtr cls)861 virtual ClassPtr GetArrayElementClass([[maybe_unused]] ClassPtr cls) const
862 {
863 return nullptr;
864 }
865
CheckStoreArray(ClassPtr arrayCls,ClassPtr strCls)866 virtual bool CheckStoreArray([[maybe_unused]] ClassPtr arrayCls, [[maybe_unused]] ClassPtr strCls) const
867 {
868 return false;
869 }
870
IsAssignableFrom(ClassPtr cls1,ClassPtr cls2)871 virtual bool IsAssignableFrom([[maybe_unused]] ClassPtr cls1, [[maybe_unused]] ClassPtr cls2) const
872 {
873 return false;
874 }
875
GetObjectHashedStatusBitNum()876 virtual size_t GetObjectHashedStatusBitNum() const
877 {
878 return 0;
879 }
880
GetObjectHashShift()881 virtual size_t GetObjectHashShift() const
882 {
883 return 0;
884 }
885
GetObjectHashMask()886 virtual size_t GetObjectHashMask() const
887 {
888 return 0;
889 }
890
891 // Offset of class in ObjectHeader
GetObjClassOffset(Arch arch)892 uint32_t GetObjClassOffset(Arch arch) const
893 {
894 return ark::cross_values::GetObjectHeaderClassPointerOffset(arch);
895 }
896
897 // Offset of the managed object in the BaseClass
GetManagedClassOffset(Arch arch)898 uint32_t GetManagedClassOffset(Arch arch) const
899 {
900 return ark::cross_values::GetBaseClassManagedObjectOffset(arch);
901 }
902
903 // Offset of mark word in ObjectHeader
GetObjMarkWordOffset(Arch arch)904 uint32_t GetObjMarkWordOffset(Arch arch) const
905 {
906 return ark::cross_values::GetObjectHeaderMarkWordOffset(arch);
907 }
908
GetTaggedTagMask()909 uint64_t GetTaggedTagMask() const
910 {
911 return coretypes::TaggedValue::TAG_MASK;
912 }
913
GetTaggedSpecialMask()914 uint64_t GetTaggedSpecialMask() const
915 {
916 return coretypes::TaggedValue::TAG_SPECIAL_MASK;
917 }
918
GetStringCtorType(MethodPtr ctorMethod)919 virtual StringCtorType GetStringCtorType([[maybe_unused]] MethodPtr ctorMethod) const
920 {
921 return StringCtorType::UNKNOWN;
922 }
923
924 /// Class information
925
926 // Returns Class Id for Field.
927 // We don't get class id directly from the field's class, because we need a class id regarding to the current
928 // file. Class id is used in codegen to initialize class in aot mode.
GetClassIdForField(MethodPtr method,size_t unused)929 virtual size_t GetClassIdForField([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
930 {
931 return 0;
932 }
933
GetClassIdForField(FieldPtr field)934 virtual size_t GetClassIdForField([[maybe_unused]] FieldPtr field) const
935 {
936 return 0;
937 }
938
939 // returns Class Id for Method
GetClassIdForMethod(MethodPtr method)940 virtual uint32_t GetClassIdForMethod([[maybe_unused]] MethodPtr method) const
941 {
942 return 0;
943 }
944
945 // returns Class Id for Method
GetClassIdForMethod(MethodPtr method,size_t unused)946 virtual uint32_t GetClassIdForMethod([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
947 {
948 return 0;
949 }
950
GetClassIdWithinFile(MethodPtr method,ClassPtr klass)951 virtual IdType GetClassIdWithinFile([[maybe_unused]] MethodPtr method, [[maybe_unused]] ClassPtr klass) const
952 {
953 return 0;
954 }
955
GetLiteralArrayClassIdWithinFile(MethodPtr method,panda_file::LiteralTag tag)956 virtual IdType GetLiteralArrayClassIdWithinFile([[maybe_unused]] MethodPtr method,
957 [[maybe_unused]] panda_file::LiteralTag tag) const
958 {
959 return 0;
960 }
961
CanUseTlabForClass(ClassPtr klass)962 virtual bool CanUseTlabForClass([[maybe_unused]] ClassPtr klass) const
963 {
964 return true;
965 }
966
967 // returns class size
GetClassSize(ClassPtr klass)968 virtual size_t GetClassSize([[maybe_unused]] ClassPtr klass) const
969 {
970 return 0;
971 }
972
CanScalarReplaceObject(ClassPtr klass)973 virtual bool CanScalarReplaceObject([[maybe_unused]] ClassPtr klass) const
974 {
975 return false;
976 }
977
978 // Vtable offset in Class
GetVTableOffset(Arch arch)979 uint32_t GetVTableOffset(Arch arch) const
980 {
981 return ark::cross_values::GetClassVtableOffset(arch);
982 }
983
984 // returns base offset in Class(for array)
GetClassBaseOffset(Arch arch)985 uint32_t GetClassBaseOffset(Arch arch) const
986 {
987 return ark::cross_values::GetClassBaseOffset(arch);
988 }
989
990 // returns component type offset in Class(for array)
GetClassComponentTypeOffset(Arch arch)991 uint32_t GetClassComponentTypeOffset(Arch arch) const
992 {
993 return ark::cross_values::GetClassComponentTypeOffset(arch);
994 }
995
996 // returns type offset in Class(for array)
GetClassTypeOffset(Arch arch)997 uint32_t GetClassTypeOffset(Arch arch) const
998 {
999 return ark::cross_values::GetClassTypeOffset(arch);
1000 }
1001
GetClassStateOffset(Arch arch)1002 uint32_t GetClassStateOffset(Arch arch) const
1003 {
1004 return ark::cross_values::GetClassStateOffset(arch);
1005 }
1006
GetClassMethodsOffset(Arch arch)1007 uint32_t GetClassMethodsOffset(Arch arch) const
1008 {
1009 return ark::cross_values::GetClassMethodsOffset(arch);
1010 }
1011
1012 /// Field information
1013
1014 /**
1015 * Try to resolve field.
1016 * @param method method to which the field belongs
1017 * @param id id of the field
1018 * @param allow_external allow fields defined in the external file, if false - return nullptr for external fields
1019 * @param class_id output variable where will be written a field's class
1020 * @return return field or nullptr if it cannot be resolved
1021 */
ResolveField(MethodPtr method,size_t unused,bool allowExternal,uint32_t * classId)1022 virtual FieldPtr ResolveField([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused,
1023 [[maybe_unused]] bool allowExternal, [[maybe_unused]] uint32_t *classId)
1024 {
1025 return nullptr;
1026 }
1027
ResolveLookUpField(FieldPtr rawField,ClassPtr klass)1028 virtual FieldPtr ResolveLookUpField([[maybe_unused]] FieldPtr rawField, [[maybe_unused]] ClassPtr klass)
1029 {
1030 return nullptr;
1031 }
1032
GetFieldType(FieldPtr field)1033 virtual DataType::Type GetFieldType([[maybe_unused]] FieldPtr field) const
1034 {
1035 return DataType::NO_TYPE;
1036 }
1037
GetArrayComponentType(ClassPtr klass)1038 virtual DataType::Type GetArrayComponentType([[maybe_unused]] ClassPtr klass) const
1039 {
1040 return DataType::NO_TYPE;
1041 }
1042
GetFieldTypeById(MethodPtr method,IdType unused)1043 virtual DataType::Type GetFieldTypeById([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType unused) const
1044 {
1045 return DataType::NO_TYPE;
1046 }
1047
GetFieldValueTypeId(MethodPtr method,IdType id)1048 virtual IdType GetFieldValueTypeId([[maybe_unused]] MethodPtr method, [[maybe_unused]] IdType id) const
1049 {
1050 return 0;
1051 }
1052
GetFieldOffset(FieldPtr field)1053 virtual size_t GetFieldOffset([[maybe_unused]] FieldPtr field) const
1054 {
1055 return 0;
1056 }
1057
GetFieldByOffset(size_t offset)1058 virtual FieldPtr GetFieldByOffset([[maybe_unused]] size_t offset) const
1059 {
1060 return nullptr;
1061 }
1062
GetFieldClass(FieldPtr field)1063 virtual uintptr_t GetFieldClass([[maybe_unused]] FieldPtr field) const
1064 {
1065 return 0;
1066 }
1067
IsFieldVolatile(FieldPtr field)1068 virtual bool IsFieldVolatile([[maybe_unused]] FieldPtr field) const
1069 {
1070 return false;
1071 }
1072
IsFieldFinal(FieldPtr field)1073 virtual bool IsFieldFinal([[maybe_unused]] FieldPtr field) const
1074 {
1075 return false;
1076 }
1077
IsFieldReadonly(FieldPtr field)1078 virtual bool IsFieldReadonly([[maybe_unused]] FieldPtr field) const
1079 {
1080 return false;
1081 }
1082
HasFieldMetadata(FieldPtr field)1083 virtual bool HasFieldMetadata([[maybe_unused]] FieldPtr field) const
1084 {
1085 return false;
1086 }
1087
GetStaticFieldValue(FieldPtr fieldPtr)1088 virtual uint64_t GetStaticFieldValue([[maybe_unused]] FieldPtr fieldPtr) const
1089 {
1090 return 0;
1091 }
1092
GetFieldName(FieldPtr field)1093 virtual std::string GetFieldName([[maybe_unused]] FieldPtr field) const
1094 {
1095 return "UnknownField";
1096 }
1097
1098 // Return offset of the managed object in the class
GetFieldClassOffset(Arch arch)1099 uint32_t GetFieldClassOffset(Arch arch) const
1100 {
1101 return ark::cross_values::GetFieldClassOffset(arch);
1102 }
1103
1104 // Return offset of the managed object in the class
GetFieldOffsetOffset(Arch arch)1105 uint32_t GetFieldOffsetOffset(Arch arch) const
1106 {
1107 return ark::cross_values::GetFieldOffsetOffset(arch);
1108 }
1109
GetPropertyBoxOffset(Arch arch)1110 virtual size_t GetPropertyBoxOffset([[maybe_unused]] Arch arch) const
1111 {
1112 return 0;
1113 }
1114
GetElementsOffset(Arch arch)1115 virtual size_t GetElementsOffset([[maybe_unused]] Arch arch) const
1116 {
1117 return 0;
1118 }
1119
GetPropertiesOffset(Arch arch)1120 virtual size_t GetPropertiesOffset([[maybe_unused]] Arch arch) const
1121 {
1122 return 0;
1123 }
1124
GetHClassOffset(Arch arch)1125 virtual size_t GetHClassOffset([[maybe_unused]] Arch arch) const
1126 {
1127 UNREACHABLE();
1128 }
1129
GetHClassBitfieldTypeStartBit(Arch arch)1130 virtual size_t GetHClassBitfieldTypeStartBit([[maybe_unused]] Arch arch) const
1131 {
1132 UNREACHABLE();
1133 }
1134
GetHClassBitfieldTypeMask(Arch arch)1135 virtual uint64_t GetHClassBitfieldTypeMask([[maybe_unused]] Arch arch) const
1136 {
1137 UNREACHABLE();
1138 }
1139
GetJshclassBitfieldClassConstructorStartBit(Arch arch)1140 virtual uint64_t GetJshclassBitfieldClassConstructorStartBit([[maybe_unused]] Arch arch) const
1141 {
1142 UNREACHABLE();
1143 }
1144
GetJstypeJsFunction(Arch arch)1145 virtual size_t GetJstypeJsFunction([[maybe_unused]] Arch arch) const
1146 {
1147 UNREACHABLE();
1148 }
1149
GetPrototypeHolderOffset(Arch arch)1150 virtual size_t GetPrototypeHolderOffset([[maybe_unused]] Arch arch) const
1151 {
1152 return 0;
1153 }
1154
GetPrototypeCellOffset(Arch arch)1155 virtual size_t GetPrototypeCellOffset([[maybe_unused]] Arch arch) const
1156 {
1157 return 0;
1158 }
1159
GetIsChangeFieldOffset(Arch arch)1160 virtual size_t GetIsChangeFieldOffset([[maybe_unused]] Arch arch) const
1161 {
1162 return 0;
1163 }
1164
GetDynArrayLenthOffset(Arch arch)1165 virtual size_t GetDynArrayLenthOffset([[maybe_unused]] Arch arch) const
1166 {
1167 return 0;
1168 }
1169
GetFieldId(FieldPtr field)1170 virtual FieldId GetFieldId([[maybe_unused]] FieldPtr field) const
1171 {
1172 return 0;
1173 }
1174
1175 /// Type information
ResolveType(MethodPtr method,size_t unused)1176 virtual ClassPtr ResolveType([[maybe_unused]] MethodPtr method, [[maybe_unused]] size_t unused) const
1177 {
1178 return nullptr;
1179 }
1180
IsClassInitialized(uintptr_t unused)1181 virtual bool IsClassInitialized([[maybe_unused]] uintptr_t unused) const
1182 {
1183 return false;
1184 }
1185
IsClassFinal(ClassPtr unused)1186 virtual bool IsClassFinal([[maybe_unused]] ClassPtr unused) const
1187 {
1188 return false;
1189 }
1190
IsInterface(ClassPtr unused)1191 virtual bool IsInterface([[maybe_unused]] ClassPtr unused) const
1192 {
1193 return false;
1194 }
1195
GetManagedType(uintptr_t unused)1196 virtual uintptr_t GetManagedType([[maybe_unused]] uintptr_t unused) const
1197 {
1198 return 0;
1199 }
1200
GetClassInitializedValue()1201 virtual uint8_t GetClassInitializedValue() const
1202 {
1203 return 0;
1204 }
1205
GetReferenceTypeMask()1206 virtual uint8_t GetReferenceTypeMask() const
1207 {
1208 return 0;
1209 }
1210
GetProtectedMemorySize()1211 virtual size_t GetProtectedMemorySize() const
1212 {
1213 // Conservatively, we believe that one page is protected. There can't be less than one.
1214 return PAGE_SIZE;
1215 }
1216
1217 /// Entrypoints
1218 #include "compiler_interface_extensions.inl.h"
1219 #include <intrinsics_enum.inl>
1220 #include <entrypoints_compiler.inl>
1221 #include <entrypoints_compiler_checksum.inl>
1222
GetIntrinsicId(MethodPtr method)1223 virtual IntrinsicId GetIntrinsicId([[maybe_unused]] MethodPtr method) const
1224 {
1225 return IntrinsicId::INVALID;
1226 }
1227
GetIntrinsicAddress(bool runtimeCall,SourceLanguage lang,IntrinsicId unused)1228 virtual uintptr_t GetIntrinsicAddress([[maybe_unused]] bool runtimeCall, [[maybe_unused]] SourceLanguage lang,
1229 [[maybe_unused]] IntrinsicId unused) const
1230 {
1231 return 0;
1232 }
1233
IsIntrinsicStringBuilderToString(IntrinsicId id)1234 virtual bool IsIntrinsicStringBuilderToString([[maybe_unused]] IntrinsicId id) const
1235 {
1236 return false;
1237 }
1238
IsIntrinsicStringBuilderAppendString(IntrinsicId id)1239 virtual bool IsIntrinsicStringBuilderAppendString([[maybe_unused]] IntrinsicId id) const
1240 {
1241 return false;
1242 }
1243
IsIntrinsicStringBuilderAppend(IntrinsicId id)1244 virtual bool IsIntrinsicStringBuilderAppend([[maybe_unused]] IntrinsicId id) const
1245 {
1246 return false;
1247 }
1248
ConvertTypeToStringBuilderAppendIntrinsicId(DataType::Type type)1249 virtual IntrinsicId ConvertTypeToStringBuilderAppendIntrinsicId([[maybe_unused]] DataType::Type type) const
1250 {
1251 UNREACHABLE();
1252 }
1253
GetStringConcatStringsIntrinsicId(size_t numArgs)1254 virtual IntrinsicId GetStringConcatStringsIntrinsicId([[maybe_unused]] size_t numArgs) const
1255 {
1256 UNREACHABLE();
1257 }
1258
GetStringIsCompressedIntrinsicId()1259 virtual IntrinsicId GetStringIsCompressedIntrinsicId() const
1260 {
1261 UNREACHABLE();
1262 }
1263
GetStringBuilderAppendStringIntrinsicId()1264 virtual IntrinsicId GetStringBuilderAppendStringIntrinsicId() const
1265 {
1266 UNREACHABLE();
1267 }
1268
GetStringBuilderToStringIntrinsicId()1269 virtual IntrinsicId GetStringBuilderToStringIntrinsicId() const
1270 {
1271 UNREACHABLE();
1272 }
1273
IsClassValueTyped(ClassPtr klass)1274 virtual bool IsClassValueTyped([[maybe_unused]] ClassPtr klass) const
1275 {
1276 UNREACHABLE();
1277 }
1278
GetEntrypointTlsOffset(Arch arch,EntrypointId id)1279 uintptr_t GetEntrypointTlsOffset(Arch arch, EntrypointId id) const
1280 {
1281 return cross_values::GetManagedThreadEntrypointOffset(arch, ark::EntrypointId(static_cast<uint8_t>(id)));
1282 }
1283
GetGlobalVarEntrypointId()1284 virtual EntrypointId GetGlobalVarEntrypointId()
1285 {
1286 return static_cast<EntrypointId>(0);
1287 }
1288
GetInteropCallKind(MethodPtr method)1289 virtual InteropCallKind GetInteropCallKind([[maybe_unused]] MethodPtr method) const
1290 {
1291 return InteropCallKind::UNKNOWN;
1292 }
1293
GetInfoForInteropCallArgsConversion(MethodPtr methodPtr,uint32_t skipArgs,ArenaVector<std::pair<IntrinsicId,DataType::Type>> * intrinsics)1294 virtual void GetInfoForInteropCallArgsConversion(
1295 [[maybe_unused]] MethodPtr methodPtr, [[maybe_unused]] uint32_t skipArgs,
1296 [[maybe_unused]] ArenaVector<std::pair<IntrinsicId, DataType::Type>> *intrinsics) const
1297 {
1298 UNREACHABLE();
1299 }
1300
GetInfoForInteropCallRetValueConversion(MethodPtr methodPtr)1301 virtual std::optional<std::pair<IntrinsicId, compiler::DataType::Type>> GetInfoForInteropCallRetValueConversion(
1302 [[maybe_unused]] MethodPtr methodPtr) const
1303 {
1304 UNREACHABLE();
1305 }
1306
GetFuncPropName(MethodPtr methodPtr,uint32_t strId)1307 virtual char *GetFuncPropName([[maybe_unused]] MethodPtr methodPtr, [[maybe_unused]] uint32_t strId) const
1308 {
1309 UNREACHABLE();
1310 }
1311
GetFuncPropNameOffset(MethodPtr methodPtr,uint32_t strId)1312 virtual uint64_t GetFuncPropNameOffset([[maybe_unused]] MethodPtr methodPtr, [[maybe_unused]] uint32_t strId) const
1313 {
1314 UNREACHABLE();
1315 }
1316
GetAnnotationElementUniqueIndex(MethodPtr methodPtr,const char * annotation,uint32_t index)1317 virtual uint32_t GetAnnotationElementUniqueIndex([[maybe_unused]] MethodPtr methodPtr,
1318 [[maybe_unused]] const char *annotation,
1319 [[maybe_unused]] uint32_t index)
1320 {
1321 UNREACHABLE();
1322 }
1323
GetRetValueClass(MethodPtr methodPtr)1324 virtual ClassPtr GetRetValueClass([[maybe_unused]] MethodPtr methodPtr) const
1325 {
1326 UNREACHABLE();
1327 }
1328
1329 /// Dynamic object information
1330
GetFunctionTargetOffset(Arch arch)1331 virtual uint32_t GetFunctionTargetOffset([[maybe_unused]] Arch arch) const
1332 {
1333 return 0;
1334 }
1335
GetDynamicPrimitiveUndefined()1336 virtual uint64_t GetDynamicPrimitiveUndefined() const
1337 {
1338 return static_cast<uint64_t>(coretypes::TaggedValue::Undefined().GetRawData());
1339 }
1340
GetPackConstantByPrimitiveType(compiler::AnyBaseType type,uint64_t imm)1341 virtual uint64_t GetPackConstantByPrimitiveType(compiler::AnyBaseType type, uint64_t imm) const
1342 {
1343 auto datatype = AnyBaseTypeToDataType(type);
1344 if (datatype == DataType::INT32) {
1345 return coretypes::TaggedValue::GetIntTaggedValue(imm);
1346 }
1347 if (datatype == DataType::FLOAT64) {
1348 return coretypes::TaggedValue::GetDoubleTaggedValue(imm);
1349 }
1350 if (datatype == DataType::BOOL) {
1351 return coretypes::TaggedValue::GetBoolTaggedValue(imm);
1352 }
1353 UNREACHABLE();
1354 return 0;
1355 }
1356
GetDynamicPrimitiveFalse()1357 virtual uint64_t GetDynamicPrimitiveFalse() const
1358 {
1359 return static_cast<uint64_t>(coretypes::TaggedValue::False().GetRawData());
1360 }
1361
GetDynamicPrimitiveTrue()1362 virtual uint64_t GetDynamicPrimitiveTrue() const
1363 {
1364 return static_cast<uint64_t>(coretypes::TaggedValue::True().GetRawData());
1365 }
1366
DynamicCastDoubleToInt(double value,size_t bits)1367 virtual uint64_t DynamicCastDoubleToInt([[maybe_unused]] double value, [[maybe_unused]] size_t bits) const
1368 {
1369 return 0;
1370 }
1371
GetDynamicNumFixedArgs()1372 virtual uint8_t GetDynamicNumFixedArgs() const
1373 {
1374 return 0;
1375 }
1376
GetLanguageExtensionSize(Arch arch)1377 virtual size_t GetLanguageExtensionSize([[maybe_unused]] Arch arch) const
1378 {
1379 return 0;
1380 }
1381
GetNativePointerTargetOffset(Arch arch)1382 virtual uint32_t GetNativePointerTargetOffset([[maybe_unused]] Arch arch) const
1383 {
1384 return 0;
1385 }
1386
1387 /**
1388 * Check if GC can be triggered during call.
1389 * This is possible when method A calling method B and waiting while B is compiling.
1390 */
HasSafepointDuringCall()1391 virtual bool HasSafepointDuringCall() const
1392 {
1393 return false;
1394 }
1395
1396 /// Bytecode profiling
1397 using BytecodeProfile = uintptr_t;
1398 using MethodProfile = profiling::ProfileType;
1399
1400 /**
1401 * Get profile information for a specific method.
1402 *
1403 * @param method method, which profile data we want to get
1404 * @param from_vector this flag indicates from where we should get profile: from method's profile vector or from
1405 * a profile file, which was added via `AddProfile`.
1406 * NB: This flag is a workaround and should be deleted. Problem is that Runtime stores methods
1407 * vector in different places for different languages. But Paoc uses only place for core part,
1408 * i.e. methods in Class objects, that is wrong for some languages.
1409 * NOTE: create interface in the runtime to enumerate all methods despite of VM language.
1410 * @return profile data for the given method
1411 */
GetMethodProfile(MethodPtr method,bool fromVector)1412 virtual MethodProfile GetMethodProfile([[maybe_unused]] MethodPtr method, [[maybe_unused]] bool fromVector) const
1413 {
1414 return nullptr;
1415 }
1416
GetCallProfile(MethodPtr profile,uint32_t pc,ArenaVector<uintptr_t> * methods,bool isAot)1417 virtual profiling::CallKind GetCallProfile([[maybe_unused]] MethodPtr profile, [[maybe_unused]] uint32_t pc,
1418 [[maybe_unused]] ArenaVector<uintptr_t> *methods,
1419 [[maybe_unused]] bool isAot)
1420 {
1421 return profiling::CallKind::UNKNOWN;
1422 }
1423
1424 /**
1425 * Get profile for a specific bytecode. Usually profile is a memory buffer, that is treated in different ways,
1426 * according to the bytecode operation.
1427 *
1428 * @param prof Method profile, which should be retrived via `GetMethodProfile` method.
1429 * @param bc_inst pointer to the bytecode instruction
1430 * @param pc offset of the bytecode instruction from the bytecode buffer beginning.
1431 * @return return profile for `bc_inst`
1432 */
GetBytecodeProfile(MethodProfile prof,const uint8_t * bcInst,size_t pc)1433 virtual BytecodeProfile GetBytecodeProfile([[maybe_unused]] MethodProfile prof,
1434 [[maybe_unused]] const uint8_t *bcInst, [[maybe_unused]] size_t pc) const
1435 {
1436 return 0;
1437 }
1438
CanInlineLdStObjByIndex(const BytecodeInstruction * bcInst,size_t pc,MethodProfile methodProfile)1439 virtual bool CanInlineLdStObjByIndex([[maybe_unused]] const BytecodeInstruction *bcInst, [[maybe_unused]] size_t pc,
1440 [[maybe_unused]] MethodProfile methodProfile) const
1441 {
1442 return false;
1443 }
1444
AddProfile(std::string_view fname)1445 virtual Expected<bool, const char *> AddProfile([[maybe_unused]] std::string_view fname)
1446 {
1447 return Unexpected("Not implemented");
1448 }
1449
GetProfilingAnyType(RuntimeInterface::BytecodeProfile profile,const BytecodeInstruction * bcInst,unsigned index,profiling::AnyInputType * allowedInputType,bool * isTypeProfiled)1450 virtual compiler::AnyBaseType GetProfilingAnyType([[maybe_unused]] RuntimeInterface::BytecodeProfile profile,
1451 [[maybe_unused]] const BytecodeInstruction *bcInst,
1452 [[maybe_unused]] unsigned index,
1453 [[maybe_unused]] profiling::AnyInputType *allowedInputType,
1454 [[maybe_unused]] bool *isTypeProfiled)
1455 {
1456 return compiler::AnyBaseType::UNDEFINED_TYPE;
1457 }
1458
ResolveSpecialAnyTypeByConstant(coretypes::TaggedValue anyConst)1459 virtual compiler::AnyBaseType ResolveSpecialAnyTypeByConstant([[maybe_unused]] coretypes::TaggedValue anyConst)
1460 {
1461 return compiler::AnyBaseType::UNDEFINED_TYPE;
1462 }
1463
GetConstantPool(MethodPtr method)1464 virtual void *GetConstantPool([[maybe_unused]] MethodPtr method)
1465 {
1466 return nullptr;
1467 }
1468
GetConstantPool(uintptr_t funcAddress)1469 virtual void *GetConstantPool([[maybe_unused]] uintptr_t funcAddress)
1470 {
1471 return nullptr;
1472 }
1473
CreateCompilerThread()1474 virtual ThreadPtr CreateCompilerThread()
1475 {
1476 return nullptr;
1477 }
1478
DestroyCompilerThread(ThreadPtr thread)1479 virtual void DestroyCompilerThread([[maybe_unused]] ThreadPtr thread)
1480 {
1481 UNREACHABLE();
1482 }
1483
SetCurrentThread(ThreadPtr thread)1484 virtual void SetCurrentThread([[maybe_unused]] ThreadPtr thread) const
1485 {
1486 UNREACHABLE();
1487 }
1488
GetCurrentThread()1489 virtual ThreadPtr GetCurrentThread() const
1490 {
1491 UNREACHABLE();
1492 }
1493
GetDoubleToStringCache()1494 virtual void *GetDoubleToStringCache() const
1495 {
1496 return nullptr;
1497 }
1498
1499 NO_COPY_SEMANTIC(RuntimeInterface);
1500 NO_MOVE_SEMANTIC(RuntimeInterface);
1501
1502 private:
1503 static constexpr uint32_t ARRAY_DEFAULT_ELEMENT_SIZE = 4;
1504 };
1505
1506 class IClassHierarchyAnalysis {
1507 public:
1508 IClassHierarchyAnalysis() = default;
1509 virtual ~IClassHierarchyAnalysis() = default;
1510
1511 public:
1512 virtual RuntimeInterface::MethodPtr GetSingleImplementation(
1513 [[maybe_unused]] RuntimeInterface::MethodPtr method) = 0;
1514 virtual bool IsSingleImplementation([[maybe_unused]] RuntimeInterface::MethodPtr method) = 0;
1515 virtual void AddDependency([[maybe_unused]] RuntimeInterface::MethodPtr caller,
1516 [[maybe_unused]] RuntimeInterface::MethodPtr callee) = 0;
1517
1518 NO_COPY_SEMANTIC(IClassHierarchyAnalysis);
1519 NO_MOVE_SEMANTIC(IClassHierarchyAnalysis);
1520 };
1521
1522 class InlineCachesInterface {
1523 public:
1524 using ClassList = Span<RuntimeInterface::ClassPtr>;
1525 enum class CallKind { UNKNOWN, MONOMORPHIC, POLYMORPHIC, MEGAMORPHIC };
1526
1527 virtual CallKind GetClasses(RuntimeInterface::MethodPtr method, uintptr_t unused,
1528 ArenaVector<RuntimeInterface::ClassPtr> *classes) = 0;
1529 virtual ~InlineCachesInterface() = default;
1530 InlineCachesInterface() = default;
1531
1532 DEFAULT_COPY_SEMANTIC(InlineCachesInterface);
1533 DEFAULT_MOVE_SEMANTIC(InlineCachesInterface);
1534 };
1535
1536 class UnresolvedTypesInterface {
1537 public:
1538 enum class SlotKind { UNKNOWN, CLASS, MANAGED_CLASS, METHOD, VIRTUAL_METHOD, FIELD, STATIC_FIELD_PTR };
1539 virtual bool AddTableSlot([[maybe_unused]] RuntimeInterface::MethodPtr method, [[maybe_unused]] uint32_t typeId,
1540 [[maybe_unused]] SlotKind kind) = 0;
1541 virtual uintptr_t GetTableSlot([[maybe_unused]] RuntimeInterface::MethodPtr method,
1542 [[maybe_unused]] uint32_t typeId, [[maybe_unused]] SlotKind kind) const = 0;
1543 virtual ~UnresolvedTypesInterface() = default;
1544 UnresolvedTypesInterface() = default;
1545
1546 DEFAULT_COPY_SEMANTIC(UnresolvedTypesInterface);
1547 DEFAULT_MOVE_SEMANTIC(UnresolvedTypesInterface);
1548 };
1549
1550 enum class TraceId {
1551 METHOD_ENTER = 1U << 0U,
1552 METHOD_EXIT = 1U << 1U,
1553 PRINT_ARG = 1U << 2U,
1554 };
1555
1556 enum class DeoptimizeType : uint8_t {
1557 INVALID = 0,
1558 INLINE_CHA,
1559 NULL_CHECK,
1560 BOUNDS_CHECK,
1561 ZERO_CHECK,
1562 NEGATIVE_CHECK,
1563 CHECK_CAST,
1564 ANY_TYPE_CHECK,
1565 OVERFLOW,
1566 HOLE,
1567 NOT_NUMBER,
1568 CAUSE_METHOD_DESTRUCTION,
1569 NOT_SMALL_INT = CAUSE_METHOD_DESTRUCTION,
1570 BOUNDS_CHECK_WITH_DEOPT,
1571 DOUBLE_WITH_INT,
1572 INLINE_IC,
1573 INLINE_DYN,
1574 NOT_PROFILED,
1575 IFIMM_TRY,
1576 COUNT
1577 };
1578
1579 inline constexpr auto DEOPT_COUNT = static_cast<uint8_t>(DeoptimizeType::COUNT);
1580
1581 inline constexpr std::array<const char *, DEOPT_COUNT> DEOPT_TYPE_NAMES = {"INVALID_TYPE",
1582 "INLINE_CHA",
1583 "NULL_CHECK",
1584 "BOUNDS_CHECK",
1585 "ZERO_CHECK",
1586 "NEGATIVE_CHECK",
1587 "CHECK_CAST",
1588 "ANY_TYPE_CHECK",
1589 "OVERFLOW",
1590 "HOLE ",
1591 "NOT_NUMBER",
1592 "NOT_SMALL_INT",
1593 "BOUNDS_CHECK_WITH_DEOPT",
1594 "DOUBLE_WITH_INT",
1595 "INLINE_IC",
1596 "INLINE_DYN",
1597 "NOT_PROFILED",
1598 "IFIMM_TRY"};
1599
DeoptimizeTypeToString(DeoptimizeType deoptType)1600 inline const char *DeoptimizeTypeToString(DeoptimizeType deoptType)
1601 {
1602 auto idx = static_cast<uint8_t>(deoptType);
1603 ASSERT(idx < DEOPT_COUNT);
1604 return DEOPT_TYPE_NAMES[idx];
1605 }
1606 } // namespace ark::compiler
1607
1608 #endif // COMPILER_RUNTIME_INTERFACE_H
1609