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
20542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe#include "base/enums.h"
21b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "gc/allocator_type.h"
228cf9cb386cd9286d67e879f1ee501ec00d72a4e1Andreas Gampe#include "gc_root.h"
231a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartier#include "obj_ptr.h"
242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "object.h"
252dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
27b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
28eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiertemplate<class T> class Handle;
29b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass MANAGED Array : public Object {
332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers public:
3498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  // The size of a java.lang.Class representing an array.
35542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe  static uint32_t ClassSize(PointerSize pointer_size);
3698d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
37f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi  // Allocates an array with the given properties, if kFillUsable is true the array will be of at
386fac447555dc94a935b78198479cce645c837b89Ian Rogers  // least component_count size, however, if there's usable space at the end of the allocation the
396fac447555dc94a935b78198479cce645c837b89Ian Rogers  // array will fill it.
40f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi  template <bool kIsInstrumented, bool kFillUsable = false>
4131e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier  ALWAYS_INLINE static Array* Alloc(Thread* self,
4231e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier                                    ObjPtr<Class> array_class,
4331e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier                                    int32_t component_count,
4431e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier                                    size_t component_size_shift,
4531e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier                                    gc::AllocatorType allocator_type)
4631e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier      REQUIRES_SHARED(Locks::mutator_lock_)
4731e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier      REQUIRES(!Roles::uninterruptible_);
482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
4931e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier  static Array* CreateMultiArray(Thread* self,
5031e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier                                 Handle<Class> element_class,
510cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier                                 Handle<IntArray> dimensions)
5231e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier      REQUIRES_SHARED(Locks::mutator_lock_)
5331e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier      REQUIRES(!Roles::uninterruptible_);
542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
556e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
566e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi           ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
57bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  size_t SizeOf() REQUIRES_SHARED(Locks::mutator_lock_);
584e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
59bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  ALWAYS_INLINE int32_t GetLength() REQUIRES_SHARED(Locks::mutator_lock_) {
60b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Array, length_));
612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
63bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  void SetLength(int32_t length) REQUIRES_SHARED(Locks::mutator_lock_) {
64c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier    DCHECK_GE(length, 0);
65d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    // We use non transactional version since we can't undo this write. We also disable checking
66d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    // since it would fail during a transaction.
67b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetField32<false, false, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Array, length_), length);
682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static MemberOffset LengthOffset() {
712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return OFFSET_OF_OBJECT_MEMBER(Array, length_);
722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
747e70b002c4552347ed1af8c002a0e13f08864f20Ian Rogers  static MemberOffset DataOffset(size_t component_size);
752dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
76ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void* GetRawData(size_t component_size, int32_t index)
77bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
78ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value() +
79ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        + (index * component_size);
802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return reinterpret_cast<void*>(data);
812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
83ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  const void* GetRawData(size_t component_size, int32_t index) const {
84ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value() +
85ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        + (index * component_size);
86ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reinterpret_cast<void*>(data);
872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
89abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz  // Returns true if the index is valid. If not, throws an ArrayIndexOutOfBoundsException and
90abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz  // returns false.
914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
92bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  ALWAYS_INLINE bool CheckIsValidIndex(int32_t index) REQUIRES_SHARED(Locks::mutator_lock_);
932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
94bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  Array* CopyOf(Thread* self, int32_t new_length) REQUIRES_SHARED(Locks::mutator_lock_)
954e2cb098017bf073335ebb02b1bc0a36828cd720Mathieu Chartier      REQUIRES(!Roles::uninterruptible_);
96e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
972dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers protected:
981a5337fff2cc6cb9d563c8b32aca75f485d23373Mathieu Chartier  void ThrowArrayStoreException(ObjPtr<Object> object) REQUIRES_SHARED(Locks::mutator_lock_)
99ed8990a467f3d93545221a33e43a9d34b1cc363fMathieu Chartier      REQUIRES(!Roles::uninterruptible_);
1002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers private:
102ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void ThrowArrayIndexOutOfBoundsException(int32_t index)
103bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
104abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz
1052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // The number of array elements.
1062dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  int32_t length_;
1072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // Marker for the data (used by generated code)
1082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  uint32_t first_element_[0];
1092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DISALLOW_IMPLICIT_CONSTRUCTORS(Array);
1112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers};
1122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
113b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
1142dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass MANAGED PrimitiveArray : public Array {
1152dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers public:
1162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  typedef T ElementType;
1172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static PrimitiveArray<T>* Alloc(Thread* self, size_t length)
119bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
1202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
121440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light  static PrimitiveArray<T>* AllocateAndFill(Thread* self, const T* data, size_t length)
122440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_);
123440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
124440b5d9bffafa46366f58599414e0cff35ea3a6aAlex Light
125bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  const T* GetData() const ALWAYS_INLINE  REQUIRES_SHARED(Locks::mutator_lock_) {
126ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reinterpret_cast<const T*>(GetRawData(sizeof(T), 0));
1272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
129bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  T* GetData() ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
130ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reinterpret_cast<T*>(GetRawData(sizeof(T), 0));
1312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
133bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  T Get(int32_t i) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_);
134abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz
135bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  T GetWithoutChecks(int32_t i) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_) {
1360d5a281c671444bfa75d63caf1427a8c0e6e1177Roland Levillain    DCHECK(CheckIsValidIndex(i)) << "i=" << i << " length=" << GetLength();
1372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return GetData()[i];
1382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
140bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  void Set(int32_t i, T value) ALWAYS_INLINE REQUIRES_SHARED(Locks::mutator_lock_);
141d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
142d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // TODO fix thread safety analysis broken by the use of template. This should be
143bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  // REQUIRES_SHARED(Locks::mutator_lock_).
144d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  template<bool kTransactionActive, bool kCheckTransaction = true>
145b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  void Set(int32_t i, T value) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS;
1462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
147d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // TODO fix thread safety analysis broken by the use of template. This should be
148bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  // REQUIRES_SHARED(Locks::mutator_lock_).
1493b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe  template<bool kTransactionActive,
1503b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe           bool kCheckTransaction = true,
1513b45ef277e4a5f7e0314d5df7ef82e480156ba75Andreas Gampe           VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
152b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  void SetWithoutChecks(int32_t i, T value) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS;
153abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz
154ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  /*
155ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * Works like memmove(), except we guarantee not to allow tearing of array values (ie using
156ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * smaller than element size copies). Arguments are assumed to be within the bounds of the array
157ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * and the arrays non-null.
158ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   */
15931e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier  void Memmove(int32_t dst_pos, ObjPtr<PrimitiveArray<T>> src, int32_t src_pos, int32_t count)
160bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
161ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
162ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  /*
163ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * Works like memcpy(), except we guarantee not to allow tearing of array values (ie using
164ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * smaller than element size copies). Arguments are assumed to be within the bounds of the array
165ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * and the arrays non-null.
166ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   */
16731e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier  void Memcpy(int32_t dst_pos, ObjPtr<PrimitiveArray<T>> src, int32_t src_pos, int32_t count)
168bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
169ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
17031e88225b2ef68e7f32f11186acf922c74ddababMathieu Chartier  static void SetArrayClass(ObjPtr<Class> array_class);
1712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
172d6636d3440efc68e1fa43f437ffbe77581096399Mathieu Chartier  template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
173bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static Class* GetArrayClass() REQUIRES_SHARED(Locks::mutator_lock_) {
17494f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi    DCHECK(!array_class_.IsNull());
175d6636d3440efc68e1fa43f437ffbe77581096399Mathieu Chartier    return array_class_.Read<kReadBarrierOption>();
1762d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
1772d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static void ResetArrayClass() {
17994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi    CHECK(!array_class_.IsNull());
18094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi    array_class_ = GcRoot<Class>(nullptr);
1812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
183bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  static void VisitRoots(RootVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_);
184c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier
1852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers private:
18694f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi  static GcRoot<Class> array_class_;
1872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DISALLOW_IMPLICIT_CONSTRUCTORS(PrimitiveArray);
1892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers};
1902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1912722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampe// Declare the different primitive arrays. Instantiations will be in array.cc.
1922722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampeextern template class PrimitiveArray<uint8_t>;   // BooleanArray
1932722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampeextern template class PrimitiveArray<int8_t>;    // ByteArray
1942722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampeextern template class PrimitiveArray<uint16_t>;  // CharArray
1952722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampeextern template class PrimitiveArray<double>;    // DoubleArray
1962722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampeextern template class PrimitiveArray<float>;     // FloatArray
1972722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampeextern template class PrimitiveArray<int32_t>;   // IntArray
1982722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampeextern template class PrimitiveArray<int64_t>;   // LongArray
1992722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampeextern template class PrimitiveArray<int16_t>;   // ShortArray
2002722f380d6430be83a1c899a94999690a8ab26dfAndreas Gampe
201e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier// Either an IntArray or a LongArray.
202e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass PointerArray : public Array {
203e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier public:
204dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  template<typename T,
205dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier           VerifyObjectFlags kVerifyFlags = kVerifyNone,
206dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier           ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
207542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe  T GetElementPtrSize(uint32_t idx, PointerSize ptr_size)
208bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
209e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
2108c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier  void** ElementAddress(size_t index, PointerSize ptr_size) REQUIRES_SHARED(Locks::mutator_lock_) {
2118c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier    DCHECK_LT(index, static_cast<size_t>(GetLength()));
2128c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier    return reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(this) +
2138c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier                                    Array::DataOffset(static_cast<size_t>(ptr_size)).Uint32Value() +
2148c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier                                    static_cast<size_t>(ptr_size) * index);
2158c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier  }
2168c19d2431f45861ca11cf5ebc4fdaf10200f2458Mathieu Chartier
217d329a3b6a77148839171132eb779577fe4b16cddMathieu Chartier  template<bool kTransactionActive = false, bool kUnchecked = false>
218542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe  void SetElementPtrSize(uint32_t idx, uint64_t element, PointerSize ptr_size)
219bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
220e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  template<bool kTransactionActive = false, bool kUnchecked = false, typename T>
221542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe  void SetElementPtrSize(uint32_t idx, T* element, PointerSize ptr_size)
222bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
2234b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier
2244b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  // Fixup the pointers in the dest arrays by passing our pointers through the visitor. Only copies
2254b00d3415beb7a816a3b5948f43f3b2e4b856ea8Mathieu Chartier  // to dest if visitor(source_ptr) != source_ptr.
226dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier  template <VerifyObjectFlags kVerifyFlags = kVerifyNone,
227dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier            ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
228dfe02f6aafee264478d510b9742ee266ea52e8a8Mathieu Chartier            typename Visitor>
229542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe  void Fixup(mirror::PointerArray* dest, PointerSize pointer_size, const Visitor& visitor)
230bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
231a01de59eef990c07df9815376cd3c675e3acd481Alex Light
232a01de59eef990c07df9815376cd3c675e3acd481Alex Light  // Works like memcpy(), except we guarantee not to allow tearing of array values (ie using smaller
233a01de59eef990c07df9815376cd3c675e3acd481Alex Light  // than element size copies). Arguments are assumed to be within the bounds of the array and the
234a01de59eef990c07df9815376cd3c675e3acd481Alex Light  // arrays non-null. Cannot be called in an active transaction.
235a01de59eef990c07df9815376cd3c675e3acd481Alex Light  template<bool kUnchecked = false>
236a01de59eef990c07df9815376cd3c675e3acd481Alex Light  void Memcpy(int32_t dst_pos,
237a01de59eef990c07df9815376cd3c675e3acd481Alex Light              ObjPtr<PointerArray> src,
238a01de59eef990c07df9815376cd3c675e3acd481Alex Light              int32_t src_pos,
239a01de59eef990c07df9815376cd3c675e3acd481Alex Light              int32_t count,
240a01de59eef990c07df9815376cd3c675e3acd481Alex Light              PointerSize pointer_size)
241a01de59eef990c07df9815376cd3c675e3acd481Alex Light      REQUIRES_SHARED(Locks::mutator_lock_);
242e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier};
243e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier
2442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
2452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace art
2462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
247fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_ARRAY_H_
248