1 /*
2  * Copyright (C) 2016 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_CLASS_EXT_H_
18 #define ART_RUNTIME_MIRROR_CLASS_EXT_H_
19 
20 #include "array.h"
21 #include "class.h"
22 #include "dex_cache.h"
23 #include "object.h"
24 #include "object_array.h"
25 #include "string.h"
26 
27 namespace art {
28 
29 struct ClassExtOffsets;
30 
31 namespace mirror {
32 
33 // C++ mirror of dalvik.system.ClassExt
34 class MANAGED ClassExt : public Object {
35  public:
36   static uint32_t ClassSize(PointerSize pointer_size);
37 
38   // Size of an instance of dalvik.system.ClassExt.
InstanceSize()39   static constexpr uint32_t InstanceSize() {
40     return sizeof(ClassExt);
41   }
42 
43   void SetVerifyError(ObjPtr<Object> obj) REQUIRES_SHARED(Locks::mutator_lock_);
44 
45   ObjPtr<Object> GetVerifyError() REQUIRES_SHARED(Locks::mutator_lock_);
46 
47   ObjPtr<ObjectArray<DexCache>> GetObsoleteDexCaches() REQUIRES_SHARED(Locks::mutator_lock_);
48 
49   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
50            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
51   bool EnsureInstanceJFieldIDsArrayPresent(size_t count)
52       REQUIRES_SHARED(Locks::mutator_lock_);
53 
54   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
55            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
56   ObjPtr<PointerArray> GetInstanceJFieldIDsPointerArray() REQUIRES_SHARED(Locks::mutator_lock_);
57   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
58            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
59   ObjPtr<Object> GetInstanceJFieldIDs() REQUIRES_SHARED(Locks::mutator_lock_);
60   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
61            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
62   bool HasInstanceFieldPointerIdMarker() REQUIRES_SHARED(Locks::mutator_lock_);
63 
64   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
65            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
66   bool EnsureStaticJFieldIDsArrayPresent(size_t count)
67       REQUIRES_SHARED(Locks::mutator_lock_);
68 
69   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
70            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
71   ObjPtr<PointerArray> GetStaticJFieldIDsPointerArray() REQUIRES_SHARED(Locks::mutator_lock_);
72   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
73            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
74   ObjPtr<Object> GetStaticJFieldIDs() REQUIRES_SHARED(Locks::mutator_lock_);
75   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
76            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
77   bool HasStaticFieldPointerIdMarker() REQUIRES_SHARED(Locks::mutator_lock_);
78 
79   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
80            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
81   bool EnsureJMethodIDsArrayPresent(size_t count)
82       REQUIRES_SHARED(Locks::mutator_lock_);
83 
84   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
85            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
86   ObjPtr<Object> GetJMethodIDs() REQUIRES_SHARED(Locks::mutator_lock_);
87   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
88            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
89   ObjPtr<PointerArray> GetJMethodIDsPointerArray() REQUIRES_SHARED(Locks::mutator_lock_);
90   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
91            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
92   bool HasMethodPointerIdMarker() REQUIRES_SHARED(Locks::mutator_lock_);
93 
94   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
95            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
96   ObjPtr<PointerArray> GetObsoleteMethods() REQUIRES_SHARED(Locks::mutator_lock_);
97 
98   ObjPtr<Object> GetOriginalDexFile() REQUIRES_SHARED(Locks::mutator_lock_);
99 
100   // Used to manually initialize the ext-ids arrays for the ClassExt associated
101   // with the Class<ClassExt>. This simplifies the id allocation path.
102   void SetIdsArraysForClassExtExtData(ObjPtr<Object> marker) REQUIRES_SHARED(Locks::mutator_lock_);
103 
104   void SetOriginalDexFile(ObjPtr<Object> bytes) REQUIRES_SHARED(Locks::mutator_lock_);
105 
GetPreRedefineClassDefIndex()106   uint16_t GetPreRedefineClassDefIndex() REQUIRES_SHARED(Locks::mutator_lock_) {
107     return static_cast<uint16_t>(
108         GetField32(OFFSET_OF_OBJECT_MEMBER(ClassExt, pre_redefine_class_def_index_)));
109   }
110 
111   void SetPreRedefineClassDefIndex(uint16_t index) REQUIRES_SHARED(Locks::mutator_lock_);
112 
GetPreRedefineDexFile()113   const DexFile* GetPreRedefineDexFile() REQUIRES_SHARED(Locks::mutator_lock_) {
114     return reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
115         GetField64(OFFSET_OF_OBJECT_MEMBER(ClassExt, pre_redefine_dex_file_ptr_))));
116   }
117 
118   void SetPreRedefineDexFile(const DexFile* dex_file) REQUIRES_SHARED(Locks::mutator_lock_);
119 
120   void SetObsoleteArrays(ObjPtr<PointerArray> methods, ObjPtr<ObjectArray<DexCache>> dex_caches)
121       REQUIRES_SHARED(Locks::mutator_lock_);
122 
123   // Extend the obsolete arrays by the given amount.
124   static bool ExtendObsoleteArrays(Handle<ClassExt> h_this, Thread* self, uint32_t increase)
125       REQUIRES_SHARED(Locks::mutator_lock_);
126 
127   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier, class Visitor>
128   inline void VisitNativeRoots(Visitor& visitor, PointerSize pointer_size)
129       REQUIRES_SHARED(Locks::mutator_lock_);
130 
131   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier, class Visitor>
132   inline void VisitMethods(Visitor visitor, PointerSize pointer_size)
133       REQUIRES_SHARED(Locks::mutator_lock_);
134 
135   static ObjPtr<ClassExt> Alloc(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
136 
137   // TODO Save the obsolete class, if we have one.
138   // TODO We need this so jit-cleanup can work. the obsolete class might get cleaned up early
139   // otherwise. We should remove the need for this.
140   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
141            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
142   ObjPtr<Class> GetObsoleteClass() REQUIRES_SHARED(Locks::mutator_lock_);
143   void SetObsoleteClass(ObjPtr<Class> classes) REQUIRES_SHARED(Locks::mutator_lock_);
144 
145   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
146   inline void VisitJFieldIDs(Visitor v) REQUIRES_SHARED(Locks::mutator_lock_);
147 
148   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
149   inline void VisitJMethodIDs(Visitor v) REQUIRES_SHARED(Locks::mutator_lock_);
150 
151  private:
152   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
153            ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
154   bool EnsureJniIdsArrayPresent(MemberOffset off, size_t count)
155       REQUIRES_SHARED(Locks::mutator_lock_);
156 
157   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
158   // An array containing the jfieldIDs assigned to each field in the corresponding position in the
159   // classes ifields_ array or '0' if no id has been assigned to that field yet.
160   HeapReference<PointerArray> instance_jfield_ids_;
161 
162   // An array containing the jmethodIDs assigned to each method in the corresponding position in
163   // the classes methods_ array or '0' if no id has been assigned to that method yet.
164   HeapReference<PointerArray> jmethod_ids_;
165 
166   // If set this is the Class object that was being used before a structural redefinition occurred.
167   HeapReference<Class> obsolete_class_;
168 
169   HeapReference<ObjectArray<DexCache>> obsolete_dex_caches_;
170 
171   HeapReference<PointerArray> obsolete_methods_;
172 
173   HeapReference<Object> original_dex_file_;
174 
175   // An array containing the jfieldIDs assigned to each field in the corresponding position in the
176   // classes sfields_ array or '0' if no id has been assigned to that field yet.
177   HeapReference<PointerArray> static_jfield_ids_;
178 
179   // The saved verification error of this class.
180   HeapReference<Object> verify_error_;
181 
182   // Native pointer to DexFile and ClassDef index of this class before it was JVMTI-redefined.
183   int64_t pre_redefine_dex_file_ptr_;
184   int32_t pre_redefine_class_def_index_;
185 
186   friend struct art::ClassExtOffsets;  // for verifying offset information
187   DISALLOW_IMPLICIT_CONSTRUCTORS(ClassExt);
188 };
189 
190 }  // namespace mirror
191 }  // namespace art
192 
193 #endif  // ART_RUNTIME_MIRROR_CLASS_EXT_H_
194