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/string_reference.h"
24 #include "dex/type_reference.h"
25 #include "handle.h"
26 #include "mirror/class.h"
27 #include "mirror/string.h"
28 #include "utils/arm64/assembler_arm64.h"
29 
30 // TODO(VIXL): Make VIXL compile with -Wshadow.
31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wshadow"
33 #include "aarch64/disasm-aarch64.h"
34 #include "aarch64/macro-assembler-aarch64.h"
35 #pragma GCC diagnostic pop
36 
37 namespace art HIDDEN {
38 
39 class CodeGenerationData;
40 
41 namespace arm64 {
42 
43 /**
44  * Helper for emitting string or class literals into JIT generated code,
45  * which can be shared between different compilers.
46  */
47 class JitPatchesARM64 {
48  public:
JitPatchesARM64(Arm64Assembler * assembler,ArenaAllocator * allocator)49   JitPatchesARM64(Arm64Assembler* assembler, ArenaAllocator* allocator) :
50       assembler_(assembler),
51       uint32_literals_(std::less<uint32_t>(),
52                        allocator->Adapter(kArenaAllocCodeGenerator)),
53       uint64_literals_(std::less<uint64_t>(),
54                        allocator->Adapter(kArenaAllocCodeGenerator)),
55       jit_string_patches_(StringReferenceValueComparator(),
56                           allocator->Adapter(kArenaAllocCodeGenerator)),
57       jit_class_patches_(TypeReferenceValueComparator(),
58                          allocator->Adapter(kArenaAllocCodeGenerator)) {
59   }
60 
61   using Uint64ToLiteralMap = ArenaSafeMap<uint64_t, vixl::aarch64::Literal<uint64_t>*>;
62   using Uint32ToLiteralMap = ArenaSafeMap<uint32_t, vixl::aarch64::Literal<uint32_t>*>;
63   using StringToLiteralMap = ArenaSafeMap<StringReference,
64                                           vixl::aarch64::Literal<uint32_t>*,
65                                           StringReferenceValueComparator>;
66   using TypeToLiteralMap = ArenaSafeMap<TypeReference,
67                                         vixl::aarch64::Literal<uint32_t>*,
68                                         TypeReferenceValueComparator>;
69 
70   vixl::aarch64::Literal<uint32_t>* DeduplicateUint32Literal(uint32_t value);
71   vixl::aarch64::Literal<uint64_t>* DeduplicateUint64Literal(uint64_t value);
72   vixl::aarch64::Literal<uint32_t>* DeduplicateBootImageAddressLiteral(uint64_t address);
73   vixl::aarch64::Literal<uint32_t>* DeduplicateJitStringLiteral(
74       const DexFile& dex_file,
75       dex::StringIndex string_index,
76       Handle<mirror::String> handle,
77       CodeGenerationData* code_generation_data);
78   vixl::aarch64::Literal<uint32_t>* DeduplicateJitClassLiteral(
79       const DexFile& dex_file,
80       dex::TypeIndex type_index,
81       Handle<mirror::Class> handle,
82       CodeGenerationData* code_generation_data);
83 
84   void EmitJitRootPatches(uint8_t* code,
85                           const uint8_t* roots_data,
86                           const CodeGenerationData& code_generation_data) const;
87 
GetAssembler()88   Arm64Assembler* GetAssembler() const { return assembler_; }
GetVIXLAssembler()89   vixl::aarch64::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->GetVIXLAssembler(); }
90 
91  private:
92   Arm64Assembler* assembler_;
93   // Deduplication map for 32-bit literals, used for JIT for boot image addresses.
94   Uint32ToLiteralMap uint32_literals_;
95   // Deduplication map for 64-bit literals, used for JIT for method address or method code.
96   Uint64ToLiteralMap uint64_literals_;
97   // Patches for string literals in JIT compiled code.
98   StringToLiteralMap jit_string_patches_;
99   // Patches for class literals in JIT compiled code.
100   TypeToLiteralMap jit_class_patches_;
101 };
102 
103 }  // namespace arm64
104 
105 }  // namespace art
106 
107 #endif  // ART_COMPILER_OPTIMIZING_JIT_PATCHES_ARM64_H_
108