array.h revision 4f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5
12dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers/* 22dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Copyright (C) 2011 The Android Open Source Project 32dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 42dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 52dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * you may not use this file except in compliance with the License. 62dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * You may obtain a copy of the License at 72dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 82dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 92dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * 102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * Unless required by applicable law or agreed to in writing, software 112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * See the License for the specific language governing permissions and 142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers * limitations under the License. 152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers */ 162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_MIRROR_ARRAY_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_MIRROR_ARRAY_H_ 192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 20b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "gc/allocator_type.h" 212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "object.h" 2283c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier#include "object_callbacks.h" 234f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchi#include "read_barrier.h" 242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 26b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 27eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiertemplate<class T> class Handle; 28b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass MANAGED Array : public Object { 322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers public: 336fac447555dc94a935b78198479cce645c837b89Ian Rogers // Allocates an array with the given properties, if fill_usable is true the array will be of at 346fac447555dc94a935b78198479cce645c837b89Ian Rogers // least component_count size, however, if there's usable space at the end of the allocation the 356fac447555dc94a935b78198479cce645c837b89Ian Rogers // array will fill it. 36cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier template <bool kIsInstrumented> 37cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier static Array* Alloc(Thread* self, Class* array_class, int32_t component_count, 386fac447555dc94a935b78198479cce645c837b89Ian Rogers size_t component_size, gc::AllocatorType allocator_type, 396fac447555dc94a935b78198479cce645c837b89Ian Rogers bool fill_usable = false) 40cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 420cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier static Array* CreateMultiArray(Thread* self, Handle<Class> element_class, 430cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier Handle<IntArray> dimensions) 442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 466e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags, 476e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi ReadBarrierOption kReadBarrierOption = kWithReadBarrier> 48ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers size_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 494e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 50ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers int32_t GetLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 51b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Array, length_)); 522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 54ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers void SetLength(int32_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers CHECK_GE(length, 0); 56d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // We use non transactional version since we can't undo this write. We also disable checking 57d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // since it would fail during a transaction. 58b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers SetField32<false, false, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Array, length_), length); 592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static MemberOffset LengthOffset() { 622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return OFFSET_OF_OBJECT_MEMBER(Array, length_); 632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static MemberOffset DataOffset(size_t component_size) { 662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers if (component_size != sizeof(int64_t)) { 672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return OFFSET_OF_OBJECT_MEMBER(Array, first_element_); 682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } else { 692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Align longs and doubles. 702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return MemberOffset(OFFSETOF_MEMBER(Array, first_element_) + 4); 712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 74ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers void* GetRawData(size_t component_size, int32_t index) 75ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 76ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value() + 77ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers + (index * component_size); 782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return reinterpret_cast<void*>(data); 792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 81ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers const void* GetRawData(size_t component_size, int32_t index) const { 82ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value() + 83ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers + (index * component_size); 84ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return reinterpret_cast<void*>(data); 852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 87abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz // Returns true if the index is valid. If not, throws an ArrayIndexOutOfBoundsException and 88abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz // returns false. 894e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> 90b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers bool CheckIsValidIndex(int32_t index) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers protected: 93ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers void ThrowArrayStoreException(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers private: 96ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers void ThrowArrayIndexOutOfBoundsException(int32_t index) 97abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 98abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz 992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // The number of array elements. 1002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers int32_t length_; 1012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // Marker for the data (used by generated code) 1022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers uint32_t first_element_[0]; 1032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DISALLOW_IMPLICIT_CONSTRUCTORS(Array); 1052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}; 1062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 107b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T> 1082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass MANAGED PrimitiveArray : public Array { 1092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers public: 1102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers typedef T ElementType; 1112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static PrimitiveArray<T>* Alloc(Thread* self, size_t length) 1132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 115b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers const T* GetData() const ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 116ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return reinterpret_cast<const T*>(GetRawData(sizeof(T), 0)); 1172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 119b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers T* GetData() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 120ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers return reinterpret_cast<T*>(GetRawData(sizeof(T), 0)); 1212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 123b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers T Get(int32_t i) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 124abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz 125b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers T GetWithoutChecks(int32_t i) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 126abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz DCHECK(CheckIsValidIndex(i)); 1272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers return GetData()[i]; 1282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 130b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers void Set(int32_t i, T value) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 131d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 132d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // TODO fix thread safety analysis broken by the use of template. This should be 133d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // SHARED_LOCKS_REQUIRED(Locks::mutator_lock_). 134d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz template<bool kTransactionActive, bool kCheckTransaction = true> 135b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers void Set(int32_t i, T value) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS; 1362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 137d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // TODO fix thread safety analysis broken by the use of template. This should be 138d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // SHARED_LOCKS_REQUIRED(Locks::mutator_lock_). 139d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz template<bool kTransactionActive, bool kCheckTransaction = true> 140b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers void SetWithoutChecks(int32_t i, T value) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS; 141abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz 142ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers /* 143ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * Works like memmove(), except we guarantee not to allow tearing of array values (ie using 144ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * smaller than element size copies). Arguments are assumed to be within the bounds of the array 145ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * and the arrays non-null. 146ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers */ 147ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers void Memmove(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos, int32_t count) 148ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 149ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 150ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers /* 151ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * Works like memcpy(), except we guarantee not to allow tearing of array values (ie using 152ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * smaller than element size copies). Arguments are assumed to be within the bounds of the array 153ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers * and the arrays non-null. 154ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers */ 155ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers void Memcpy(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos, int32_t count) 156ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 157ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 1582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static void SetArrayClass(Class* array_class) { 1592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers CHECK(array_class_ == nullptr); 1602d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers CHECK(array_class != nullptr); 1612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers array_class_ = array_class; 1622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1644f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchi static Class* GetArrayClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers DCHECK(array_class_ != nullptr); 1664f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchi return ReadBarrier::BarrierForRoot<mirror::Class, kWithReadBarrier>( 1674f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchi &array_class_); 1682d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers } 1692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers 1702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static void ResetArrayClass() { 1712d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers CHECK(array_class_ != nullptr); 1722d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers array_class_ = nullptr; 1732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers } 1742dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 17583c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier static void VisitRoots(RootCallback* callback, void* arg) 176c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 177c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier 1782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers private: 1792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers static Class* array_class_; 1802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers DISALLOW_IMPLICIT_CONSTRUCTORS(PrimitiveArray); 1822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}; 1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 1842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 1852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace art 1862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 187fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_MIRROR_ARRAY_H_ 188