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 
27 namespace art {
28 
29 struct DexCacheOffsets;
30 class DexFile;
31 class ImageWriter;
32 union JValue;
33 
34 namespace mirror {
35 
36 class String;
37 
38 // C++ mirror of java.lang.DexCache.
39 class 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.
InstanceSize()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 
GetLocation()72   String* GetLocation() SHARED_REQUIRES(Locks::mutator_lock_) {
73     return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_));
74   }
75 
DexOffset()76   static MemberOffset DexOffset() {
77     return OFFSET_OF_OBJECT_MEMBER(DexCache, dex_);
78   }
79 
StringsOffset()80   static MemberOffset StringsOffset() {
81     return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_);
82   }
83 
ResolvedTypesOffset()84   static MemberOffset ResolvedTypesOffset() {
85     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_);
86   }
87 
ResolvedFieldsOffset()88   static MemberOffset ResolvedFieldsOffset() {
89     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_);
90   }
91 
ResolvedMethodsOffset()92   static MemberOffset ResolvedMethodsOffset() {
93     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
94   }
95 
NumStringsOffset()96   static MemberOffset NumStringsOffset() {
97     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_strings_);
98   }
99 
NumResolvedTypesOffset()100   static MemberOffset NumResolvedTypesOffset() {
101     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_types_);
102   }
103 
NumResolvedFieldsOffset()104   static MemberOffset NumResolvedFieldsOffset() {
105     return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_fields_);
106   }
107 
NumResolvedMethodsOffset()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 
GetStrings()136   GcRoot<String>* GetStrings() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
137     return GetFieldPtr<GcRoot<String>*>(StringsOffset());
138   }
139 
SetStrings(GcRoot<String> * strings)140   void SetStrings(GcRoot<String>* strings) ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
141     SetFieldPtr<false>(StringsOffset(), strings);
142   }
143 
GetResolvedTypes()144   GcRoot<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
145     return GetFieldPtr<GcRoot<Class>*>(ResolvedTypesOffset());
146   }
147 
SetResolvedTypes(GcRoot<Class> * resolved_types)148   void SetResolvedTypes(GcRoot<Class>* resolved_types)
149       ALWAYS_INLINE
150       SHARED_REQUIRES(Locks::mutator_lock_) {
151     SetFieldPtr<false>(ResolvedTypesOffset(), resolved_types);
152   }
153 
GetResolvedMethods()154   ArtMethod** GetResolvedMethods() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
155     return GetFieldPtr<ArtMethod**>(ResolvedMethodsOffset());
156   }
157 
SetResolvedMethods(ArtMethod ** resolved_methods)158   void SetResolvedMethods(ArtMethod** resolved_methods)
159       ALWAYS_INLINE
160       SHARED_REQUIRES(Locks::mutator_lock_) {
161     SetFieldPtr<false>(ResolvedMethodsOffset(), resolved_methods);
162   }
163 
GetResolvedFields()164   ArtField** GetResolvedFields() ALWAYS_INLINE SHARED_REQUIRES(Locks::mutator_lock_) {
165     return GetFieldPtr<ArtField**>(ResolvedFieldsOffset());
166   }
167 
SetResolvedFields(ArtField ** resolved_fields)168   void SetResolvedFields(ArtField** resolved_fields)
169       ALWAYS_INLINE
170       SHARED_REQUIRES(Locks::mutator_lock_) {
171     SetFieldPtr<false>(ResolvedFieldsOffset(), resolved_fields);
172   }
173 
NumStrings()174   size_t NumStrings() SHARED_REQUIRES(Locks::mutator_lock_) {
175     return GetField32(NumStringsOffset());
176   }
177 
NumResolvedTypes()178   size_t NumResolvedTypes() SHARED_REQUIRES(Locks::mutator_lock_) {
179     return GetField32(NumResolvedTypesOffset());
180   }
181 
NumResolvedMethods()182   size_t NumResolvedMethods() SHARED_REQUIRES(Locks::mutator_lock_) {
183     return GetField32(NumResolvedMethodsOffset());
184   }
185 
NumResolvedFields()186   size_t NumResolvedFields() SHARED_REQUIRES(Locks::mutator_lock_) {
187     return GetField32(NumResolvedFieldsOffset());
188   }
189 
GetDexFile()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 
SetDexFile(const DexFile * dex_file)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