array.h revision 0cd81352a7c06e381951cea1b104fd73516f4341
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"
232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art {
25b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
26eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartiertemplate<class T> class Handle;
27b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass MANAGED Array : public Object {
312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers public:
326fac447555dc94a935b78198479cce645c837b89Ian Rogers  // Allocates an array with the given properties, if fill_usable is true the array will be of at
336fac447555dc94a935b78198479cce645c837b89Ian Rogers  // least component_count size, however, if there's usable space at the end of the allocation the
346fac447555dc94a935b78198479cce645c837b89Ian Rogers  // array will fill it.
35cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  template <bool kIsInstrumented>
36cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier  static Array* Alloc(Thread* self, Class* array_class, int32_t component_count,
376fac447555dc94a935b78198479cce645c837b89Ian Rogers                      size_t component_size, gc::AllocatorType allocator_type,
386fac447555dc94a935b78198479cce645c837b89Ian Rogers                      bool fill_usable = false)
39cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
410cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier  static Array* CreateMultiArray(Thread* self, Handle<Class> element_class,
420cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier                                 Handle<IntArray> dimensions)
432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
456e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
466e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi           ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
47ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  size_t SizeOf() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
484e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
49ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  int32_t GetLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
50b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Array, length_));
512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
53ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void SetLength(int32_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    CHECK_GE(length, 0);
55d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    // We use non transactional version since we can't undo this write. We also disable checking
56d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz    // since it would fail during a transaction.
57b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetField32<false, false, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Array, length_), length);
582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static MemberOffset LengthOffset() {
612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return OFFSET_OF_OBJECT_MEMBER(Array, length_);
622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
632dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
642dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static MemberOffset DataOffset(size_t component_size) {
652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    if (component_size != sizeof(int64_t)) {
662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      return OFFSET_OF_OBJECT_MEMBER(Array, first_element_);
672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    } else {
682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      // Align longs and doubles.
692dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      return MemberOffset(OFFSETOF_MEMBER(Array, first_element_) + 4);
702dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    }
712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
73ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void* GetRawData(size_t component_size, int32_t index)
74ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
75ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value() +
76ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        + (index * component_size);
772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return reinterpret_cast<void*>(data);
782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
80ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  const void* GetRawData(size_t component_size, int32_t index) const {
81ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value() +
82ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        + (index * component_size);
83ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reinterpret_cast<void*>(data);
842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
86abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz  // Returns true if the index is valid. If not, throws an ArrayIndexOutOfBoundsException and
87abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz  // returns false.
884e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
89b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  bool CheckIsValidIndex(int32_t index) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers protected:
92ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void ThrowArrayStoreException(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers private:
95ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void ThrowArrayIndexOutOfBoundsException(int32_t index)
96abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
97abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz
982dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // The number of array elements.
992dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  int32_t length_;
1002dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // Marker for the data (used by generated code)
1012dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  uint32_t first_element_[0];
1022dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1032dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DISALLOW_IMPLICIT_CONSTRUCTORS(Array);
1042dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers};
1052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
106b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
1072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass MANAGED PrimitiveArray : public Array {
1082dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers public:
1092dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  typedef T ElementType;
1102dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static PrimitiveArray<T>* Alloc(Thread* self, size_t length)
1122dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1132dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
114b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  const T* GetData() const ALWAYS_INLINE  SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
115ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reinterpret_cast<const T*>(GetRawData(sizeof(T), 0));
1162dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
118b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  T* GetData() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
119ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return reinterpret_cast<T*>(GetRawData(sizeof(T), 0));
1202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
122b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  T Get(int32_t i) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
123abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz
124b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  T GetWithoutChecks(int32_t i) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
125abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz    DCHECK(CheckIsValidIndex(i));
1262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    return GetData()[i];
1272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
129b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  void Set(int32_t i, T value) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
130d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz
131d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // TODO fix thread safety analysis broken by the use of template. This should be
132d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // SHARED_LOCKS_REQUIRED(Locks::mutator_lock_).
133d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  template<bool kTransactionActive, bool kCheckTransaction = true>
134b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  void Set(int32_t i, T value) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS;
1352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
136d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // TODO fix thread safety analysis broken by the use of template. This should be
137d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  // SHARED_LOCKS_REQUIRED(Locks::mutator_lock_).
138d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  template<bool kTransactionActive, bool kCheckTransaction = true>
139b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  void SetWithoutChecks(int32_t i, T value) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS;
140abff6439db28fbbed95490bfff7e24d1fdf5b771Sebastien Hertz
141ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  /*
142ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * Works like memmove(), except we guarantee not to allow tearing of array values (ie using
143ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * smaller than element size copies). Arguments are assumed to be within the bounds of the array
144ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * and the arrays non-null.
145ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   */
146ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void Memmove(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos, int32_t count)
147ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
148ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
149ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  /*
150ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * Works like memcpy(), except we guarantee not to allow tearing of array values (ie using
151ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * smaller than element size copies). Arguments are assumed to be within the bounds of the array
152ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   * and the arrays non-null.
153ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers   */
154ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void Memcpy(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos, int32_t count)
155ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
156ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
1572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static void SetArrayClass(Class* array_class) {
1582d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(array_class_ == nullptr);
1592d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(array_class != nullptr);
1602dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    array_class_ = array_class;
1612dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1632d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  static Class* GetArrayClass() {
1642d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    DCHECK(array_class_ != nullptr);
1652d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    return array_class_;
1662d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers  }
1672d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers
1682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static void ResetArrayClass() {
1692d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    CHECK(array_class_ != nullptr);
1702d10b206f9d0b97396b7dadb9a6415cd39efd341Ian Rogers    array_class_ = nullptr;
1712dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  }
1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
17383c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier  static void VisitRoots(RootCallback* callback, void* arg)
174c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
175c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier
1762dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers private:
1772dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static Class* array_class_;
1782dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  DISALLOW_IMPLICIT_CONSTRUCTORS(PrimitiveArray);
1802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers};
1812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
1822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
1832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace art
1842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
185fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_ARRAY_H_
186