xref: /aosp_15_r20/art/compiler/optimizing/jit_patches_arm64.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_OPTIMIZING_JIT_PATCHES_ARM64_H_
18 #define ART_COMPILER_OPTIMIZING_JIT_PATCHES_ARM64_H_
19 
20 #include "base/arena_allocator.h"
21 #include "base/arena_containers.h"
22 #include "dex/dex_file.h"
23 #include "dex/proto_reference.h"
24 #include "dex/string_reference.h"
25 #include "dex/type_reference.h"
26 #include "handle.h"
27 #include "mirror/class.h"
28 #include "mirror/method_type.h"
29 #include "mirror/string.h"
30 #include "utils/arm64/assembler_arm64.h"
31 
32 // TODO(VIXL): Make VIXL compile cleanly with -Wshadow, -Wdeprecated-declarations.
33 #pragma GCC diagnostic push
34 #pragma GCC diagnostic ignored "-Wshadow"
35 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
36 #include "aarch64/disasm-aarch64.h"
37 #include "aarch64/macro-assembler-aarch64.h"
38 #pragma GCC diagnostic pop
39 
40 namespace art HIDDEN {
41 
42 class CodeGenerationData;
43 
44 namespace arm64 {
45 
46 /**
47  * Helper for emitting string or class literals into JIT generated code,
48  * which can be shared between different compilers.
49  */
50 class JitPatchesARM64 {
51  public:
JitPatchesARM64(Arm64Assembler * assembler,ArenaAllocator * allocator)52   JitPatchesARM64(Arm64Assembler* assembler, ArenaAllocator* allocator) :
53       assembler_(assembler),
54       uint32_literals_(std::less<uint32_t>(),
55                        allocator->Adapter(kArenaAllocCodeGenerator)),
56       uint64_literals_(std::less<uint64_t>(),
57                        allocator->Adapter(kArenaAllocCodeGenerator)),
58       jit_string_patches_(StringReferenceValueComparator(),
59                           allocator->Adapter(kArenaAllocCodeGenerator)),
60       jit_class_patches_(TypeReferenceValueComparator(),
61                          allocator->Adapter(kArenaAllocCodeGenerator)),
62       jit_method_type_patches_(ProtoReferenceValueComparator(),
63                                allocator->Adapter(kArenaAllocCodeGenerator)) {
64   }
65 
66   using Uint64ToLiteralMap = ArenaSafeMap<uint64_t, vixl::aarch64::Literal<uint64_t>*>;
67   using Uint32ToLiteralMap = ArenaSafeMap<uint32_t, vixl::aarch64::Literal<uint32_t>*>;
68   using StringToLiteralMap = ArenaSafeMap<StringReference,
69                                           vixl::aarch64::Literal<uint32_t>*,
70                                           StringReferenceValueComparator>;
71   using TypeToLiteralMap = ArenaSafeMap<TypeReference,
72                                         vixl::aarch64::Literal<uint32_t>*,
73                                         TypeReferenceValueComparator>;
74   using ProtoToLiteralMap = ArenaSafeMap<ProtoReference,
75                                          vixl::aarch64::Literal<uint32_t>*,
76                                          ProtoReferenceValueComparator>;
77 
78   vixl::aarch64::Literal<uint32_t>* DeduplicateUint32Literal(uint32_t value);
79   vixl::aarch64::Literal<uint64_t>* DeduplicateUint64Literal(uint64_t value);
80   vixl::aarch64::Literal<uint32_t>* DeduplicateBootImageAddressLiteral(uint64_t address);
81   vixl::aarch64::Literal<uint32_t>* DeduplicateJitStringLiteral(
82       const DexFile& dex_file,
83       dex::StringIndex string_index,
84       Handle<mirror::String> handle,
85       CodeGenerationData* code_generation_data);
86   vixl::aarch64::Literal<uint32_t>* DeduplicateJitClassLiteral(
87       const DexFile& dex_file,
88       dex::TypeIndex type_index,
89       Handle<mirror::Class> handle,
90       CodeGenerationData* code_generation_data);
91   vixl::aarch64::Literal<uint32_t>* DeduplicateJitMethodTypeLiteral(
92       const DexFile& dex_file,
93       dex::ProtoIndex proto_index,
94       Handle<mirror::MethodType> handle,
95       CodeGenerationData* code_generation_data);
96 
97   void EmitJitRootPatches(uint8_t* code,
98                           const uint8_t* roots_data,
99                           const CodeGenerationData& code_generation_data) const;
100 
GetAssembler()101   Arm64Assembler* GetAssembler() const { return assembler_; }
GetVIXLAssembler()102   vixl::aarch64::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->GetVIXLAssembler(); }
103 
104  private:
105   Arm64Assembler* assembler_;
106   // Deduplication map for 32-bit literals, used for JIT for boot image addresses.
107   Uint32ToLiteralMap uint32_literals_;
108   // Deduplication map for 64-bit literals, used for JIT for method address or method code.
109   Uint64ToLiteralMap uint64_literals_;
110   // Patches for string literals in JIT compiled code.
111   StringToLiteralMap jit_string_patches_;
112   // Patches for class literals in JIT compiled code.
113   TypeToLiteralMap jit_class_patches_;
114   // Patches for MethodType literals in JIT compiled code.
115   ProtoToLiteralMap jit_method_type_patches_;
116 };
117 
118 }  // namespace arm64
119 
120 }  // namespace art
121 
122 #endif  // ART_COMPILER_OPTIMIZING_JIT_PATCHES_ARM64_H_
123