summaryrefslogtreecommitdiff
path: root/compiler/optimizing/jit_patches_arm64.h
blob: e13060210a1ecb1ffaac46e2930c6deffe8885d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_COMPILER_OPTIMIZING_JIT_PATCHES_ARM64_H_
#define ART_COMPILER_OPTIMIZING_JIT_PATCHES_ARM64_H_

#include "base/arena_allocator.h"
#include "base/arena_containers.h"
#include "dex/dex_file.h"
#include "dex/proto_reference.h"
#include "dex/string_reference.h"
#include "dex/type_reference.h"
#include "handle.h"
#include "mirror/class.h"
#include "mirror/method_type.h"
#include "mirror/string.h"
#include "utils/arm64/assembler_arm64.h"

// TODO(VIXL): Make VIXL compile cleanly with -Wshadow, -Wdeprecated-declarations.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include "aarch64/disasm-aarch64.h"
#include "aarch64/macro-assembler-aarch64.h"
#pragma GCC diagnostic pop

namespace art HIDDEN {

class CodeGenerationData;

namespace arm64 {

/**
 * Helper for emitting string or class literals into JIT generated code,
 * which can be shared between different compilers.
 */
class JitPatchesARM64 {
 public:
  JitPatchesARM64(Arm64Assembler* assembler, ArenaAllocator* allocator) :
      assembler_(assembler),
      uint32_literals_(std::less<uint32_t>(),
                       allocator->Adapter(kArenaAllocCodeGenerator)),
      uint64_literals_(std::less<uint64_t>(),
                       allocator->Adapter(kArenaAllocCodeGenerator)),
      jit_string_patches_(StringReferenceValueComparator(),
                          allocator->Adapter(kArenaAllocCodeGenerator)),
      jit_class_patches_(TypeReferenceValueComparator(),
                         allocator->Adapter(kArenaAllocCodeGenerator)),
      jit_method_type_patches_(ProtoReferenceValueComparator(),
                               allocator->Adapter(kArenaAllocCodeGenerator)) {
  }

  using Uint64ToLiteralMap = ArenaSafeMap<uint64_t, vixl::aarch64::Literal<uint64_t>*>;
  using Uint32ToLiteralMap = ArenaSafeMap<uint32_t, vixl::aarch64::Literal<uint32_t>*>;
  using StringToLiteralMap = ArenaSafeMap<StringReference,
                                          vixl::aarch64::Literal<uint32_t>*,
                                          StringReferenceValueComparator>;
  using TypeToLiteralMap = ArenaSafeMap<TypeReference,
                                        vixl::aarch64::Literal<uint32_t>*,
                                        TypeReferenceValueComparator>;
  using ProtoToLiteralMap = ArenaSafeMap<ProtoReference,
                                         vixl::aarch64::Literal<uint32_t>*,
                                         ProtoReferenceValueComparator>;

  vixl::aarch64::Literal<uint32_t>* DeduplicateUint32Literal(uint32_t value);
  vixl::aarch64::Literal<uint64_t>* DeduplicateUint64Literal(uint64_t value);
  vixl::aarch64::Literal<uint32_t>* DeduplicateBootImageAddressLiteral(uint64_t address);
  vixl::aarch64::Literal<uint32_t>* DeduplicateJitStringLiteral(
      const DexFile& dex_file,
      dex::StringIndex string_index,
      Handle<mirror::String> handle,
      CodeGenerationData* code_generation_data);
  vixl::aarch64::Literal<uint32_t>* DeduplicateJitClassLiteral(
      const DexFile& dex_file,
      dex::TypeIndex type_index,
      Handle<mirror::Class> handle,
      CodeGenerationData* code_generation_data);
  vixl::aarch64::Literal<uint32_t>* DeduplicateJitMethodTypeLiteral(
      const DexFile& dex_file,
      dex::ProtoIndex proto_index,
      Handle<mirror::MethodType> handle,
      CodeGenerationData* code_generation_data);

  void EmitJitRootPatches(uint8_t* code,
                          const uint8_t* roots_data,
                          const CodeGenerationData& code_generation_data) const;

  Arm64Assembler* GetAssembler() const { return assembler_; }
  vixl::aarch64::MacroAssembler* GetVIXLAssembler() { return GetAssembler()->GetVIXLAssembler(); }

 private:
  Arm64Assembler* assembler_;
  // Deduplication map for 32-bit literals, used for JIT for boot image addresses.
  Uint32ToLiteralMap uint32_literals_;
  // Deduplication map for 64-bit literals, used for JIT for method address or method code.
  Uint64ToLiteralMap uint64_literals_;
  // Patches for string literals in JIT compiled code.
  StringToLiteralMap jit_string_patches_;
  // Patches for class literals in JIT compiled code.
  TypeToLiteralMap jit_class_patches_;
  // Patches for MethodType literals in JIT compiled code.
  ProtoToLiteralMap jit_method_type_patches_;
};

}  // namespace arm64

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_JIT_PATCHES_ARM64_H_