1/*
2 * Copyright (C) 2011 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_RUNTIME_MIRROR_DEX_CACHE_H_
18#define ART_RUNTIME_MIRROR_DEX_CACHE_H_
19
20#include "array.h"
21#include "art_field.h"
22#include "art_method.h"
23#include "class.h"
24#include "object.h"
25#include "object_array.h"
26
27namespace art {
28
29struct DexCacheOffsets;
30class DexFile;
31class ImageWriter;
32union JValue;
33
34namespace mirror {
35
36class String;
37
38// C++ mirror of java.lang.DexCache.
39class MANAGED DexCache FINAL : public Object {
40 public:
41  // Size of java.lang.DexCache.class.
42  static uint32_t ClassSize(size_t pointer_size);
43
44  // Size of an instance of java.lang.DexCache not including referenced values.
45  static constexpr uint32_t InstanceSize() {
46    return sizeof(DexCache);
47  }
48
49  void Init(const DexFile* dex_file,
50            String* location,
51            GcRoot<String>* strings,
52            uint32_t num_strings,
53            GcRoot<Class>* resolved_types,
54            uint32_t num_resolved_types,
55            ArtMethod** resolved_methods,
56            uint32_t num_resolved_methods,
57            ArtField** resolved_fields,
58            uint32_t num_resolved_fields,
59            size_t pointer_size) SHARED_REQUIRES(Locks::mutator_lock_);
60
61  void Fixup(ArtMethod* trampoline, size_t pointer_size)
62      SHARED_REQUIRES(Locks::mutator_lock_);
63
64  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
65  void FixupStrings(GcRoot<mirror::String>* dest, const Visitor& visitor)
66      SHARED_REQUIRES(Locks::mutator_lock_);
67
68  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
69  void FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor)
70      SHARED_REQUIRES(Locks::mutator_lock_);
71
72  String* GetLocation() SHARED_REQUIRES(Locks::mutator_lock_) {
73    return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_));
74  }
75
76  static MemberOffset DexOffset() {
77    return OFFSET_OF_OBJECT_MEMBER(DexCache, dex_);
78  }
79
80  static MemberOffset StringsOffset() {
81    return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_);
82  }
83
84  static MemberOffset ResolvedTypesOffset() {
85    return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_);
86  }
87
88  static MemberOffset ResolvedFieldsOffset() {
89    return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_);
90  }
91
92  static MemberOffset ResolvedMethodsOffset() {
93    return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
94  }
95
96  static MemberOffset NumStringsOffset() {
97    return OFFSET_OF_OBJECT_MEMBER(DexCache, num_strings_);
98  }
99
100  static MemberOffset NumResolvedTypesOffset() {
101    return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_types_);
102  }
103
104  static MemberOffset NumResolvedFieldsOffset() {
105    return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_fields_);
106  }
107
108  static MemberOffset NumResolvedMethodsOffset() {
109    return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_methods_);
110  }
111
112  String* GetResolvedString(uint32_t string_idx) ALWAYS_INLINE
113      SHARED_REQUIRES(Locks::mutator_lock_);
114
115  void SetResolvedString(uint32_t string_idx, String* resolved) ALWAYS_INLINE
116      SHARED_REQUIRES(Locks::mutator_lock_);
117
118  Class* GetResolvedType(uint32_t type_idx) SHARED_REQUIRES(Locks::mutator_lock_);
119
120  void SetResolvedType(uint32_t type_idx, Class* resolved) SHARED_REQUIRES(Locks::mutator_lock_);
121
122  ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, size_t ptr_size)
123      SHARED_REQUIRES(Locks::mutator_lock_);
124
125  ALWAYS_INLINE void SetResolvedMethod(uint32_t method_idx, ArtMethod* resolved, size_t ptr_size)
126      SHARED_REQUIRES(Locks::mutator_lock_);
127
128  // Pointer sized variant, used for patching.
129  ALWAYS_INLINE ArtField* GetResolvedField(uint32_t idx, size_t ptr_size)
130      SHARED_REQUIRES(Locks::mutator_lock_);
131
132  // Pointer sized variant, used for patching.
133  ALWAYS_INLINE void SetResolvedField(uint32_t idx, ArtField* field, size_t ptr_size)
134      SHARED_REQUIRES(Locks::mutator_lock_);
135
136  GcRoot<String>* GetStrings() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
137    return GetFieldPtr<GcRoot<String>*>(StringsOffset());
138  }
139
140  void SetStrings(GcRoot<String>* strings) ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
141    SetFieldPtr<false>(StringsOffset(), strings);
142  }
143
144  GcRoot<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
145    return GetFieldPtr<GcRoot<Class>*>(ResolvedTypesOffset());
146  }
147
148  void SetResolvedTypes(GcRoot<Class>* resolved_types)
149      ALWAYS_INLINE
150      SHARED_REQUIRES(Locks::mutator_lock_) {
151    SetFieldPtr<false>(ResolvedTypesOffset(), resolved_types);
152  }
153
154  ArtMethod** GetResolvedMethods() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
155    return GetFieldPtr<ArtMethod**>(ResolvedMethodsOffset());
156  }
157
158  void SetResolvedMethods(ArtMethod** resolved_methods)
159      ALWAYS_INLINE
160      SHARED_REQUIRES(Locks::mutator_lock_) {
161    SetFieldPtr<false>(ResolvedMethodsOffset(), resolved_methods);
162  }
163
164  ArtField** GetResolvedFields() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
165    return GetFieldPtr<ArtField**>(ResolvedFieldsOffset());
166  }
167
168  void SetResolvedFields(ArtField** resolved_fields)
169      ALWAYS_INLINE
170      SHARED_REQUIRES(Locks::mutator_lock_) {
171    SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields);
172  }
173
174  size_t NumStrings() SHARED_REQUIRES(Locks::mutator_lock_) {
175    return GetField32(NumStringsOffset());
176  }
177
178  size_t NumResolvedTypes() SHARED_REQUIRES(Locks::mutator_lock_) {
179    return GetField32(NumResolvedTypesOffset());
180  }
181
182  size_t NumResolvedMethods() SHARED_REQUIRES(Locks::mutator_lock_) {
183    return GetField32(NumResolvedMethodsOffset());
184  }
185
186  size_t NumResolvedFields() SHARED_REQUIRES(Locks::mutator_lock_) {
187    return GetField32(NumResolvedFieldsOffset());
188  }
189
190  const DexFile* GetDexFile() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
191    return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
192  }
193
194  void SetDexFile(const DexFile* dex_file) SHARED_REQUIRES(Locks::mutator_lock_) {
195    SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
196  }
197
198  void SetLocation(mirror::String* location) SHARED_REQUIRES(Locks::mutator_lock_);
199
200  // NOTE: Get/SetElementPtrSize() are intended for working with ArtMethod** and ArtField**
201  // provided by GetResolvedMethods/Fields() and ArtMethod::GetDexCacheResolvedMethods(),
202  // so they need to be public.
203
204  template <typename PtrType>
205  static PtrType GetElementPtrSize(PtrType* ptr_array, size_t idx, size_t ptr_size);
206
207  template <typename PtrType>
208  static void SetElementPtrSize(PtrType* ptr_array, size_t idx, PtrType ptr, size_t ptr_size);
209
210 private:
211  // Visit instance fields of the dex cache as well as its associated arrays.
212  template <bool kVisitNativeRoots,
213            VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
214            ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
215            typename Visitor>
216  void VisitReferences(mirror::Class* klass, const Visitor& visitor)
217      SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_);
218
219  HeapReference<Object> dex_;
220  HeapReference<String> location_;
221  uint64_t dex_file_;           // const DexFile*
222  uint64_t resolved_fields_;    // ArtField*, array with num_resolved_fields_ elements.
223  uint64_t resolved_methods_;   // ArtMethod*, array with num_resolved_methods_ elements.
224  uint64_t resolved_types_;     // GcRoot<Class>*, array with num_resolved_types_ elements.
225  uint64_t strings_;            // GcRoot<String>*, array with num_strings_ elements.
226  uint32_t num_resolved_fields_;    // Number of elements in the resolved_fields_ array.
227  uint32_t num_resolved_methods_;   // Number of elements in the resolved_methods_ array.
228  uint32_t num_resolved_types_;     // Number of elements in the resolved_types_ array.
229  uint32_t num_strings_;            // Number of elements in the strings_ array.
230
231  friend struct art::DexCacheOffsets;  // for verifying offset information
232  friend class Object;  // For VisitReferences
233  DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
234};
235
236}  // namespace mirror
237}  // namespace art
238
239#endif  // ART_RUNTIME_MIRROR_DEX_CACHE_H_
240