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 "art_field.h"
21 #include "art_method.h"
22 #include "class.h"
23 #include "object.h"
24 #include "object_array.h"
25 
26 namespace art {
27 
28 struct DexCacheOffsets;
29 class DexFile;
30 class ImageWriter;
31 union JValue;
32 
33 namespace mirror {
34 
35 class String;
36 
37 // C++ mirror of java.lang.DexCache.
38 class MANAGED DexCache FINAL : public Object {
39  public:
40   // Size of java.lang.DexCache.class.
41   static uint32_t ClassSize();
42 
43   // Size of an instance of java.lang.DexCache not including referenced values.
InstanceSize()44   static constexpr uint32_t InstanceSize() {
45     return sizeof(DexCache);
46   }
47 
48   void Init(const DexFile* dex_file,
49             String* location,
50             ObjectArray<String>* strings,
51             ObjectArray<Class>* types,
52             ObjectArray<ArtMethod>* methods,
53             ObjectArray<ArtField>* fields)
54       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
55 
56   void Fixup(ArtMethod* trampoline) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
57 
GetLocation()58   String* GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
59     return GetFieldObject<String>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_));
60   }
61 
StringsOffset()62   static MemberOffset StringsOffset() {
63     return OFFSET_OF_OBJECT_MEMBER(DexCache, strings_);
64   }
65 
ResolvedFieldsOffset()66   static MemberOffset ResolvedFieldsOffset() {
67     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_fields_);
68   }
69 
ResolvedMethodsOffset()70   static MemberOffset ResolvedMethodsOffset() {
71     return OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_methods_);
72   }
73 
NumStrings()74   size_t NumStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
75     return GetStrings()->GetLength();
76   }
77 
NumResolvedTypes()78   size_t NumResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
79     return GetResolvedTypes()->GetLength();
80   }
81 
NumResolvedMethods()82   size_t NumResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
83     return GetResolvedMethods()->GetLength();
84   }
85 
NumResolvedFields()86   size_t NumResolvedFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
87     return GetResolvedFields()->GetLength();
88   }
89 
GetResolvedString(uint32_t string_idx)90   String* GetResolvedString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
91     return GetStrings()->Get(string_idx);
92   }
93 
SetResolvedString(uint32_t string_idx,String * resolved)94   void SetResolvedString(uint32_t string_idx, String* resolved) ALWAYS_INLINE
95       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
96     // TODO default transaction support.
97     GetStrings()->Set(string_idx, resolved);
98   }
99 
GetResolvedType(uint32_t type_idx)100   Class* GetResolvedType(uint32_t type_idx) ALWAYS_INLINE
101       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
102     return GetResolvedTypes()->Get(type_idx);
103   }
104 
105   void SetResolvedType(uint32_t type_idx, Class* resolved)
106       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
107 
108   ArtMethod* GetResolvedMethod(uint32_t method_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
109 
SetResolvedMethod(uint32_t method_idx,ArtMethod * resolved)110   void SetResolvedMethod(uint32_t method_idx, ArtMethod* resolved) ALWAYS_INLINE
111       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
112     GetResolvedMethods()->Set(method_idx, resolved);
113   }
114 
GetResolvedField(uint32_t field_idx)115   ArtField* GetResolvedField(uint32_t field_idx) ALWAYS_INLINE
116       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
117     ArtField* field = GetResolvedFields()->Get(field_idx);
118     if (UNLIKELY(field == nullptr || field->GetDeclaringClass()->IsErroneous())) {
119       return nullptr;
120     } else {
121       return field;
122     }
123   }
124 
SetResolvedField(uint32_t field_idx,ArtField * resolved)125   void SetResolvedField(uint32_t field_idx, ArtField* resolved) ALWAYS_INLINE
126       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
127     GetResolvedFields()->Set(field_idx, resolved);
128   }
129 
GetStrings()130   ObjectArray<String>* GetStrings() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
131     return GetFieldObject< ObjectArray<String>>(StringsOffset());
132   }
133 
GetResolvedTypes()134   ObjectArray<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
135     return GetFieldObject<ObjectArray<Class>>(
136         OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_));
137   }
138 
GetResolvedMethods()139   ObjectArray<ArtMethod>* GetResolvedMethods() ALWAYS_INLINE
140       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
141     return GetFieldObject< ObjectArray<ArtMethod>>(ResolvedMethodsOffset());
142   }
143 
GetResolvedFields()144   ObjectArray<ArtField>* GetResolvedFields() ALWAYS_INLINE
145       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
146     return GetFieldObject<ObjectArray<ArtField>>(ResolvedFieldsOffset());
147   }
148 
GetDexFile()149   const DexFile* GetDexFile() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
150     return GetFieldPtr<const DexFile*>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_));
151   }
152 
SetDexFile(const DexFile * dex_file)153   void SetDexFile(const DexFile* dex_file) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
154       ALWAYS_INLINE {
155     return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
156   }
157 
158  private:
159   HeapReference<Object> dex_;
160   HeapReference<String> location_;
161   HeapReference<ObjectArray<ArtField>> resolved_fields_;
162   HeapReference<ObjectArray<ArtMethod>> resolved_methods_;
163   HeapReference<ObjectArray<Class>> resolved_types_;
164   HeapReference<ObjectArray<String>> strings_;
165   uint64_t dex_file_;
166 
167   friend struct art::DexCacheOffsets;  // for verifying offset information
168   DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
169 };
170 
171 }  // namespace mirror
172 }  // namespace art
173 
174 #endif  // ART_RUNTIME_MIRROR_DEX_CACHE_H_
175