1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_MIRROR_OBJECT_ARRAY_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_MIRROR_OBJECT_ARRAY_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <iterator> 21*795d594fSAndroid Build Coastguard Worker #include "array.h" 22*795d594fSAndroid Build Coastguard Worker #include "base/iteration_range.h" 23*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 24*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h" 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 27*795d594fSAndroid Build Coastguard Worker namespace mirror { 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker template<typename T, typename Container> class ArrayIter; 30*795d594fSAndroid Build Coastguard Worker template <typename T> using ConstObjPtrArrayIter = ArrayIter<T, const ObjPtr<ObjectArray<T>>>; 31*795d594fSAndroid Build Coastguard Worker template <typename T> using ConstHandleArrayIter = ArrayIter<T, const Handle<ObjectArray<T>>>; 32*795d594fSAndroid Build Coastguard Worker template <typename T> using ObjPtrArrayIter = ArrayIter<T, ObjPtr<ObjectArray<T>>>; 33*795d594fSAndroid Build Coastguard Worker template <typename T> using HandleArrayIter = ArrayIter<T, Handle<ObjectArray<T>>>; 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker template<class T> 36*795d594fSAndroid Build Coastguard Worker class MANAGED ObjectArray: public Array { 37*795d594fSAndroid Build Coastguard Worker public: 38*795d594fSAndroid Build Coastguard Worker MIRROR_CLASS("[Ljava/lang/Object;"); 39*795d594fSAndroid Build Coastguard Worker 40*795d594fSAndroid Build Coastguard Worker // The size of Object[].class. ClassSize(PointerSize pointer_size)41*795d594fSAndroid Build Coastguard Worker static uint32_t ClassSize(PointerSize pointer_size) { 42*795d594fSAndroid Build Coastguard Worker return Array::ClassSize(pointer_size); 43*795d594fSAndroid Build Coastguard Worker } 44*795d594fSAndroid Build Coastguard Worker 45*795d594fSAndroid Build Coastguard Worker static ObjPtr<ObjectArray<T>> Alloc(Thread* self, 46*795d594fSAndroid Build Coastguard Worker ObjPtr<Class> object_array_class, 47*795d594fSAndroid Build Coastguard Worker int32_t length, 48*795d594fSAndroid Build Coastguard Worker gc::AllocatorType allocator_type) 49*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker static ObjPtr<ObjectArray<T>> Alloc(Thread* self, 52*795d594fSAndroid Build Coastguard Worker ObjPtr<Class> object_array_class, 53*795d594fSAndroid Build Coastguard Worker int32_t length) 54*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 55*795d594fSAndroid Build Coastguard Worker 56*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, 57*795d594fSAndroid Build Coastguard Worker ReadBarrierOption kReadBarrierOption = kWithReadBarrier> 58*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE ObjPtr<T> Get(int32_t i) REQUIRES_SHARED(Locks::mutator_lock_); 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker // Returns true if the object can be stored into the array. If not, throws 61*795d594fSAndroid Build Coastguard Worker // an ArrayStoreException and returns false. 62*795d594fSAndroid Build Coastguard Worker // TODO fix thread safety analysis: should be REQUIRES_SHARED(Locks::mutator_lock_). 63*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 64*795d594fSAndroid Build Coastguard Worker bool CheckAssignable(ObjPtr<T> object) NO_THREAD_SAFETY_ANALYSIS; 65*795d594fSAndroid Build Coastguard Worker 66*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void Set(int32_t i, ObjPtr<T> object) REQUIRES_SHARED(Locks::mutator_lock_); 67*795d594fSAndroid Build Coastguard Worker // TODO fix thread safety analysis: should be REQUIRES_SHARED(Locks::mutator_lock_). 68*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction = true, 69*795d594fSAndroid Build Coastguard Worker VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 70*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void Set(int32_t i, ObjPtr<T> object) NO_THREAD_SAFETY_ANALYSIS; 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker // Set element without bound and element type checks, to be used in limited 73*795d594fSAndroid Build Coastguard Worker // circumstances, such as during boot image writing. 74*795d594fSAndroid Build Coastguard Worker // TODO fix thread safety analysis broken by the use of template. This should be 75*795d594fSAndroid Build Coastguard Worker // REQUIRES_SHARED(Locks::mutator_lock_). 76*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction = true, 77*795d594fSAndroid Build Coastguard Worker VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 78*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void SetWithoutChecks(int32_t i, ObjPtr<T> object) NO_THREAD_SAFETY_ANALYSIS; 79*795d594fSAndroid Build Coastguard Worker // TODO fix thread safety analysis broken by the use of template. This should be 80*795d594fSAndroid Build Coastguard Worker // REQUIRES_SHARED(Locks::mutator_lock_). 81*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive, bool kCheckTransaction = true, 82*795d594fSAndroid Build Coastguard Worker VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 83*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void SetWithoutChecksAndWriteBarrier(int32_t i, ObjPtr<T> object) 84*795d594fSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS; 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, 87*795d594fSAndroid Build Coastguard Worker ReadBarrierOption kReadBarrierOption = kWithReadBarrier> 88*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE ObjPtr<T> GetWithoutChecks(int32_t i) REQUIRES_SHARED(Locks::mutator_lock_); 89*795d594fSAndroid Build Coastguard Worker 90*795d594fSAndroid Build Coastguard Worker // Copy src into this array (dealing with overlaps as memmove does) without assignability checks. 91*795d594fSAndroid Build Coastguard Worker void AssignableMemmove(int32_t dst_pos, 92*795d594fSAndroid Build Coastguard Worker ObjPtr<ObjectArray<T>> src, 93*795d594fSAndroid Build Coastguard Worker int32_t src_pos, 94*795d594fSAndroid Build Coastguard Worker int32_t count) 95*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker // Copy src into this array assuming no overlap and without assignability checks. 98*795d594fSAndroid Build Coastguard Worker void AssignableMemcpy(int32_t dst_pos, 99*795d594fSAndroid Build Coastguard Worker ObjPtr<ObjectArray<T>> src, 100*795d594fSAndroid Build Coastguard Worker int32_t src_pos, 101*795d594fSAndroid Build Coastguard Worker int32_t count) 102*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 103*795d594fSAndroid Build Coastguard Worker 104*795d594fSAndroid Build Coastguard Worker // Copy src into this array with assignability checks. 105*795d594fSAndroid Build Coastguard Worker template<bool kTransactionActive> 106*795d594fSAndroid Build Coastguard Worker void AssignableCheckingMemcpy(int32_t dst_pos, 107*795d594fSAndroid Build Coastguard Worker ObjPtr<ObjectArray<T>> src, 108*795d594fSAndroid Build Coastguard Worker int32_t src_pos, 109*795d594fSAndroid Build Coastguard Worker int32_t count, 110*795d594fSAndroid Build Coastguard Worker bool throw_exception) 111*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker static ObjPtr<ObjectArray<T>> CopyOf(Handle<ObjectArray<T>> h_this, 114*795d594fSAndroid Build Coastguard Worker Thread* self, 115*795d594fSAndroid Build Coastguard Worker int32_t new_length) 116*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) 117*795d594fSAndroid Build Coastguard Worker REQUIRES(!Roles::uninterruptible_); 118*795d594fSAndroid Build Coastguard Worker 119*795d594fSAndroid Build Coastguard Worker static MemberOffset OffsetOfElement(int32_t i); 120*795d594fSAndroid Build Coastguard Worker 121*795d594fSAndroid Build Coastguard Worker inline ConstObjPtrArrayIter<T> cbegin() const REQUIRES_SHARED(Locks::mutator_lock_); 122*795d594fSAndroid Build Coastguard Worker inline ConstObjPtrArrayIter<T> cend() const REQUIRES_SHARED(Locks::mutator_lock_); ConstIterate()123*795d594fSAndroid Build Coastguard Worker inline IterationRange<ConstObjPtrArrayIter<T>> ConstIterate() const REQUIRES_SHARED(Locks::mutator_lock_) { 124*795d594fSAndroid Build Coastguard Worker return IterationRange(cbegin(), cend()); 125*795d594fSAndroid Build Coastguard Worker } 126*795d594fSAndroid Build Coastguard Worker inline ObjPtrArrayIter<T> begin() REQUIRES_SHARED(Locks::mutator_lock_); 127*795d594fSAndroid Build Coastguard Worker inline ObjPtrArrayIter<T> end() REQUIRES_SHARED(Locks::mutator_lock_); Iterate()128*795d594fSAndroid Build Coastguard Worker inline IterationRange<ObjPtrArrayIter<T>> Iterate() REQUIRES_SHARED(Locks::mutator_lock_) { 129*795d594fSAndroid Build Coastguard Worker return IterationRange(begin(), end()); 130*795d594fSAndroid Build Coastguard Worker } 131*795d594fSAndroid Build Coastguard Worker 132*795d594fSAndroid Build Coastguard Worker static inline ConstHandleArrayIter<T> cbegin(const Handle<ObjectArray<T>>& h_this) 133*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 134*795d594fSAndroid Build Coastguard Worker static inline ConstHandleArrayIter<T> cend(const Handle<ObjectArray<T>>& h_this) 135*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); ConstIterate(const Handle<ObjectArray<T>> & h_this)136*795d594fSAndroid Build Coastguard Worker static inline IterationRange<ConstHandleArrayIter<T>> ConstIterate( 137*795d594fSAndroid Build Coastguard Worker const Handle<ObjectArray<T>>& h_this) REQUIRES_SHARED(Locks::mutator_lock_) { 138*795d594fSAndroid Build Coastguard Worker return IterationRange(cbegin(h_this), cend(h_this)); 139*795d594fSAndroid Build Coastguard Worker } 140*795d594fSAndroid Build Coastguard Worker static inline HandleArrayIter<T> begin(Handle<ObjectArray<T>>& h_this) 141*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 142*795d594fSAndroid Build Coastguard Worker static inline HandleArrayIter<T> end(Handle<ObjectArray<T>>& h_this) 143*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); Iterate(Handle<ObjectArray<T>> & h_this)144*795d594fSAndroid Build Coastguard Worker static inline IterationRange<HandleArrayIter<T>> Iterate(Handle<ObjectArray<T>>& h_this) 145*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 146*795d594fSAndroid Build Coastguard Worker return IterationRange(begin(h_this), end(h_this)); 147*795d594fSAndroid Build Coastguard Worker } 148*795d594fSAndroid Build Coastguard Worker 149*795d594fSAndroid Build Coastguard Worker private: 150*795d594fSAndroid Build Coastguard Worker // TODO fix thread safety analysis broken by the use of template. This should be 151*795d594fSAndroid Build Coastguard Worker // REQUIRES_SHARED(Locks::mutator_lock_). 152*795d594fSAndroid Build Coastguard Worker template<typename Visitor> 153*795d594fSAndroid Build Coastguard Worker void VisitReferences(const Visitor& visitor) NO_THREAD_SAFETY_ANALYSIS; 154*795d594fSAndroid Build Coastguard Worker template<typename Visitor> 155*795d594fSAndroid Build Coastguard Worker void VisitReferences(const Visitor& visitor, 156*795d594fSAndroid Build Coastguard Worker MemberOffset begin, 157*795d594fSAndroid Build Coastguard Worker MemberOffset end) NO_THREAD_SAFETY_ANALYSIS; 158*795d594fSAndroid Build Coastguard Worker 159*795d594fSAndroid Build Coastguard Worker friend class Object; // For VisitReferences 160*795d594fSAndroid Build Coastguard Worker DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectArray); 161*795d594fSAndroid Build Coastguard Worker }; 162*795d594fSAndroid Build Coastguard Worker 163*795d594fSAndroid Build Coastguard Worker // Everything is NO_THREAD_SAFETY_ANALYSIS to work-around STL incompat with thread-annotations. 164*795d594fSAndroid Build Coastguard Worker // Everything should have REQUIRES_SHARED(Locks::mutator_lock_). 165*795d594fSAndroid Build Coastguard Worker template <typename T, typename Container> 166*795d594fSAndroid Build Coastguard Worker class ArrayIter { 167*795d594fSAndroid Build Coastguard Worker private: 168*795d594fSAndroid Build Coastguard Worker using Iter = ArrayIter<T, Container>; 169*795d594fSAndroid Build Coastguard Worker 170*795d594fSAndroid Build Coastguard Worker public: 171*795d594fSAndroid Build Coastguard Worker using iterator_category = std::forward_iterator_tag; 172*795d594fSAndroid Build Coastguard Worker using value_type = ObjPtr<T>; 173*795d594fSAndroid Build Coastguard Worker using difference_type = ptrdiff_t; 174*795d594fSAndroid Build Coastguard Worker using pointer = value_type*; 175*795d594fSAndroid Build Coastguard Worker using reference = value_type&; 176*795d594fSAndroid Build Coastguard Worker ArrayIter(Container array,int32_t idx)177*795d594fSAndroid Build Coastguard Worker ArrayIter(Container array, int32_t idx) NO_THREAD_SAFETY_ANALYSIS : array_(array), idx_(idx) { 178*795d594fSAndroid Build Coastguard Worker CheckIdx(); 179*795d594fSAndroid Build Coastguard Worker } 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker ArrayIter(const Iter& other) = default; // NOLINT(runtime/explicit) 182*795d594fSAndroid Build Coastguard Worker Iter& operator=(const Iter& other) = default; 183*795d594fSAndroid Build Coastguard Worker 184*795d594fSAndroid Build Coastguard Worker bool operator!=(const Iter& other) const NO_THREAD_SAFETY_ANALYSIS { 185*795d594fSAndroid Build Coastguard Worker CheckIdx(); 186*795d594fSAndroid Build Coastguard Worker return !(*this == other); 187*795d594fSAndroid Build Coastguard Worker } 188*795d594fSAndroid Build Coastguard Worker bool operator==(const Iter& other) const NO_THREAD_SAFETY_ANALYSIS { 189*795d594fSAndroid Build Coastguard Worker return Ptr(other.array_) == Ptr(array_) && other.idx_ == idx_; 190*795d594fSAndroid Build Coastguard Worker } 191*795d594fSAndroid Build Coastguard Worker Iter& operator++() NO_THREAD_SAFETY_ANALYSIS { 192*795d594fSAndroid Build Coastguard Worker idx_++; 193*795d594fSAndroid Build Coastguard Worker CheckIdx(); 194*795d594fSAndroid Build Coastguard Worker return *this; 195*795d594fSAndroid Build Coastguard Worker } 196*795d594fSAndroid Build Coastguard Worker Iter operator++(int) NO_THREAD_SAFETY_ANALYSIS { 197*795d594fSAndroid Build Coastguard Worker Iter res(this); 198*795d594fSAndroid Build Coastguard Worker idx_++; 199*795d594fSAndroid Build Coastguard Worker CheckIdx(); 200*795d594fSAndroid Build Coastguard Worker return res; 201*795d594fSAndroid Build Coastguard Worker } 202*795d594fSAndroid Build Coastguard Worker ObjPtr<T> operator->() const NO_THREAD_SAFETY_ANALYSIS { 203*795d594fSAndroid Build Coastguard Worker CheckIdx(); 204*795d594fSAndroid Build Coastguard Worker return array_->GetWithoutChecks(idx_); 205*795d594fSAndroid Build Coastguard Worker } 206*795d594fSAndroid Build Coastguard Worker ObjPtr<T> operator*() const NO_THREAD_SAFETY_ANALYSIS { 207*795d594fSAndroid Build Coastguard Worker CheckIdx(); 208*795d594fSAndroid Build Coastguard Worker return array_->GetWithoutChecks(idx_); 209*795d594fSAndroid Build Coastguard Worker } 210*795d594fSAndroid Build Coastguard Worker 211*795d594fSAndroid Build Coastguard Worker private: 212*795d594fSAndroid Build Coastguard Worker // Checks current index and that locks are properly held. 213*795d594fSAndroid Build Coastguard Worker void CheckIdx() const REQUIRES_SHARED(Locks::mutator_lock_); 214*795d594fSAndroid Build Coastguard Worker Ptr(const Handle<ObjectArray<T>> & p)215*795d594fSAndroid Build Coastguard Worker static ObjectArray<T>* Ptr(const Handle<ObjectArray<T>>& p) 216*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 217*795d594fSAndroid Build Coastguard Worker return p.Get(); 218*795d594fSAndroid Build Coastguard Worker } Ptr(const ObjPtr<ObjectArray<T>> & p)219*795d594fSAndroid Build Coastguard Worker static ObjectArray<T>* Ptr(const ObjPtr<ObjectArray<T>>& p) 220*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 221*795d594fSAndroid Build Coastguard Worker return p.Ptr(); 222*795d594fSAndroid Build Coastguard Worker } 223*795d594fSAndroid Build Coastguard Worker 224*795d594fSAndroid Build Coastguard Worker Container array_; 225*795d594fSAndroid Build Coastguard Worker int32_t idx_; 226*795d594fSAndroid Build Coastguard Worker }; 227*795d594fSAndroid Build Coastguard Worker 228*795d594fSAndroid Build Coastguard Worker } // namespace mirror 229*795d594fSAndroid Build Coastguard Worker } // namespace art 230*795d594fSAndroid Build Coastguard Worker 231*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_MIRROR_OBJECT_ARRAY_H_ 232