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