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, String* location, ObjectArray<String>* strings,
50             ObjectArray<Class>* types, PointerArray* methods, PointerArray* fields,
51             size_t pointer_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
52 
53   void Fixup(ArtMethod* trampoline, size_t pointer_size)
54       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
55 
GetLocation()56   String* GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
57     return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_));
58   }
59 
DexOffset()60   static MemberOffset DexOffset() {
61     return OFFSET_OF_OBJECT_MEMBER(DexCache, dex_);
62   }
63 
StringsOffset()64   static MemberOffset StringsOffset() {
65     return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_);
66   }
67 
ResolvedFieldsOffset()68   static MemberOffset ResolvedFieldsOffset() {
69     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_);
70   }
71 
ResolvedMethodsOffset()72   static MemberOffset ResolvedMethodsOffset() {
73     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
74   }
75 
NumStrings()76   size_t NumStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
77     return GetStrings()->GetLength();
78   }
79 
NumResolvedTypes()80   size_t NumResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
81     return GetResolvedTypes()->GetLength();
82   }
83 
NumResolvedMethods()84   size_t NumResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
85     return GetResolvedMethods()->GetLength();
86   }
87 
NumResolvedFields()88   size_t NumResolvedFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
89     return GetResolvedFields()->GetLength();
90   }
91 
GetResolvedString(uint32_t string_idx)92   String* GetResolvedString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
93     return GetStrings()->Get(string_idx);
94   }
95 
SetResolvedString(uint32_t string_idx,String * resolved)96   void SetResolvedString(uint32_t string_idx, String* resolved) ALWAYS_INLINE
97       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
98     // TODO default transaction support.
99     GetStrings()->Set(string_idx, resolved);
100   }
101 
GetResolvedType(uint32_t type_idx)102   Class* GetResolvedType(uint32_t type_idx) ALWAYS_INLINE
103       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
104     return GetResolvedTypes()->Get(type_idx);
105   }
106 
107   void SetResolvedType(uint32_t type_idx, Class* resolved)
108       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
109 
110   ALWAYS_INLINE ArtMethod* GetResolvedMethod(uint32_t method_idx, size_t ptr_size)
111       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
112 
113   ALWAYS_INLINE void SetResolvedMethod(uint32_t method_idx, ArtMethod* resolved, size_t ptr_size)
114       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
115 
116   // Pointer sized variant, used for patching.
117   ALWAYS_INLINE ArtField* GetResolvedField(uint32_t idx, size_t ptr_size)
118       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
119 
120   // Pointer sized variant, used for patching.
121   ALWAYS_INLINE void SetResolvedField(uint32_t idx, ArtField* field, size_t ptr_size)
122       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
123 
GetStrings()124   ObjectArray<String>* GetStrings() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
125     return GetFieldObject<ObjectArray<String>>(StringsOffset());
126   }
127 
GetResolvedTypes()128   ObjectArray<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
129     return GetFieldObject<ObjectArray<Class>>(
130         OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_));
131   }
132 
GetResolvedMethods()133   PointerArray* GetResolvedMethods() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
134     return GetFieldObject<PointerArray>(ResolvedMethodsOffset());
135   }
136 
GetResolvedFields()137   PointerArray* GetResolvedFields() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
138     return GetFieldObject<PointerArray>(ResolvedFieldsOffset());
139   }
140 
GetDexFile()141   const DexFile* GetDexFile() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
142     return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
143   }
144 
SetDexFile(const DexFile * dex_file)145   void SetDexFile(const DexFile* dex_file) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
146       ALWAYS_INLINE {
147     return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
148   }
149 
150  private:
151   HeapReference<Object> dex_;
152   HeapReference<String> location_;
153   // Either an int array or long array based on runtime ISA since these arrays hold pointers.
154   HeapReference<PointerArray> resolved_fields_;
155   HeapReference<PointerArray> resolved_methods_;
156   HeapReference<ObjectArray<Class>> resolved_types_;
157   HeapReference<ObjectArray<String>> strings_;
158   uint64_t dex_file_;
159 
160   friend struct art::DexCacheOffsets;  // for verifying offset information
161   DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
162 };
163 
164 }  // namespace mirror
165 }  // namespace art
166 
167 #endif  // ART_RUNTIME_MIRROR_DEX_CACHE_H_
168