12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
161f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_MIRROR_ARRAY_INL_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_MIRROR_ARRAY_INL_H_
191f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "array.h"
211f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom
222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "class.h"
233b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi#include "gc/heap-inl.h"
24967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi#include "thread.h"
25967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi#include "utils.h"
261f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom
271f87008b165d26541d832ff805250afdc89c253dBrian Carlstromnamespace art {
282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
3098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yanginline uint32_t Array::ClassSize() {
3198d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  uint32_t vtable_entries = Object::kVTableLength;
3298d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0);
3398d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang}
3498d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang
356e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
36ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Array::SizeOf() {
372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // This is safe from overflow because the array was already allocated, so we know it's sane.
389103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  size_t component_size =
396e83c172f385cb45dd13bbcf41d2df8e410828c6Hiroshi Yamauchi      GetClass<kVerifyFlags, kReadBarrierOption>()->template GetComponentSize<kReadBarrierOption>();
404e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  // Don't need to check this since we already check this in GetClass.
414e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  int32_t component_count =
424e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      GetLength<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>();
43aa866f51bccc2f017a2e65925748b7a1c701d3f6Hiroshi Yamauchi  size_t header_size = DataOffset(component_size).SizeValue();
442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  size_t data_size = component_count * component_size;
452dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return header_size + data_size;
462dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
472dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
48b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
49b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline bool Array::CheckIsValidIndex(int32_t index) {
50b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (UNLIKELY(static_cast<uint32_t>(index) >=
51b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers               static_cast<uint32_t>(GetLength<kVerifyFlags>()))) {
52b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    ThrowArrayIndexOutOfBoundsException(index);
53b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return false;
54b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
55b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return true;
56b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
57b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
583b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchistatic inline size_t ComputeArraySize(Thread* self, Class* array_class, int32_t component_count,
593b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi                                      size_t component_size)
603b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
61967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  DCHECK(array_class != NULL);
62967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  DCHECK_GE(component_count, 0);
63967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  DCHECK(array_class->IsArrayClass());
64967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
65aa866f51bccc2f017a2e65925748b7a1c701d3f6Hiroshi Yamauchi  size_t header_size = Array::DataOffset(component_size).SizeValue();
66967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  size_t data_size = component_count * component_size;
67967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  size_t size = header_size + data_size;
68967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
69967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  // Check for overflow and throw OutOfMemoryError if this was an unreasonable request.
70967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  size_t component_shift = sizeof(size_t) * 8 - 1 - CLZ(component_size);
71967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  if (UNLIKELY(data_size >> component_shift != size_t(component_count) || size < data_size)) {
72967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi    self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow",
73967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi                                             PrettyDescriptor(array_class).c_str(),
74967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi                                             component_count).c_str());
753b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi    return 0;  // failure
76967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  }
773b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  return size;
783b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi}
79967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
806fac447555dc94a935b78198479cce645c837b89Ian Rogers// Used for setting the array length in the allocation code path to ensure it is guarded by a
816fac447555dc94a935b78198479cce645c837b89Ian Rogers// StoreStore fence.
821febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartierclass SetLengthVisitor {
831febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier public:
841febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier  explicit SetLengthVisitor(int32_t length) : length_(length) {
851febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier  }
861febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier
876fac447555dc94a935b78198479cce645c837b89Ian Rogers  void operator()(Object* obj, size_t usable_size) const
886fac447555dc94a935b78198479cce645c837b89Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
896fac447555dc94a935b78198479cce645c837b89Ian Rogers    UNUSED(usable_size);
90ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    // Avoid AsArray as object is not yet in live bitmap or allocation stack.
91ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Array* array = down_cast<Array*>(obj);
92ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    // DCHECK(array->IsArrayInstance());
931febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier    array->SetLength(length_);
94967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  }
951febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier
961febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier private:
971febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier  const int32_t length_;
986fac447555dc94a935b78198479cce645c837b89Ian Rogers
996fac447555dc94a935b78198479cce645c837b89Ian Rogers  DISALLOW_COPY_AND_ASSIGN(SetLengthVisitor);
1006fac447555dc94a935b78198479cce645c837b89Ian Rogers};
1016fac447555dc94a935b78198479cce645c837b89Ian Rogers
1026fac447555dc94a935b78198479cce645c837b89Ian Rogers// Similar to SetLengthVisitor, used for setting the array length to fill the usable size of an
1036fac447555dc94a935b78198479cce645c837b89Ian Rogers// array.
1046fac447555dc94a935b78198479cce645c837b89Ian Rogersclass SetLengthToUsableSizeVisitor {
1056fac447555dc94a935b78198479cce645c837b89Ian Rogers public:
106a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers  SetLengthToUsableSizeVisitor(int32_t min_length, size_t header_size, size_t component_size) :
107a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers      minimum_length_(min_length), header_size_(header_size), component_size_(component_size) {
1086fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
1096fac447555dc94a935b78198479cce645c837b89Ian Rogers
1106fac447555dc94a935b78198479cce645c837b89Ian Rogers  void operator()(Object* obj, size_t usable_size) const
1116fac447555dc94a935b78198479cce645c837b89Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1126fac447555dc94a935b78198479cce645c837b89Ian Rogers    // Avoid AsArray as object is not yet in live bitmap or allocation stack.
1136fac447555dc94a935b78198479cce645c837b89Ian Rogers    Array* array = down_cast<Array*>(obj);
1146fac447555dc94a935b78198479cce645c837b89Ian Rogers    // DCHECK(array->IsArrayInstance());
115a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    int32_t length = (usable_size - header_size_) / component_size_;
116a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    DCHECK_GE(length, minimum_length_);
117a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    byte* old_end = reinterpret_cast<byte*>(array->GetRawData(component_size_, minimum_length_));
118a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    byte* new_end = reinterpret_cast<byte*>(array->GetRawData(component_size_, length));
119a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    // Ensure space beyond original allocation is zeroed.
120a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    memset(old_end, 0, new_end - old_end);
1216fac447555dc94a935b78198479cce645c837b89Ian Rogers    array->SetLength(length);
1226fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
1236fac447555dc94a935b78198479cce645c837b89Ian Rogers
1246fac447555dc94a935b78198479cce645c837b89Ian Rogers private:
125a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers  const int32_t minimum_length_;
1266fac447555dc94a935b78198479cce645c837b89Ian Rogers  const size_t header_size_;
1276fac447555dc94a935b78198479cce645c837b89Ian Rogers  const size_t component_size_;
1286fac447555dc94a935b78198479cce645c837b89Ian Rogers
1296fac447555dc94a935b78198479cce645c837b89Ian Rogers  DISALLOW_COPY_AND_ASSIGN(SetLengthToUsableSizeVisitor);
1301febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier};
131967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
132cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartiertemplate <bool kIsInstrumented>
133590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierinline Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count,
1346fac447555dc94a935b78198479cce645c837b89Ian Rogers                           size_t component_size, gc::AllocatorType allocator_type,
1356fac447555dc94a935b78198479cce645c837b89Ian Rogers                           bool fill_usable) {
1366fac447555dc94a935b78198479cce645c837b89Ian Rogers  DCHECK(allocator_type != gc::kAllocatorTypeLOS);
1373b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  size_t size = ComputeArraySize(self, array_class, component_count, component_size);
1383b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  if (UNLIKELY(size == 0)) {
139cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    return nullptr;
1403b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  }
1413b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  gc::Heap* heap = Runtime::Current()->GetHeap();
1426fac447555dc94a935b78198479cce645c837b89Ian Rogers  Array* result;
1436fac447555dc94a935b78198479cce645c837b89Ian Rogers  if (!fill_usable) {
1446fac447555dc94a935b78198479cce645c837b89Ian Rogers    SetLengthVisitor visitor(component_count);
1456fac447555dc94a935b78198479cce645c837b89Ian Rogers    result = down_cast<Array*>(
1466fac447555dc94a935b78198479cce645c837b89Ian Rogers        heap->AllocObjectWithAllocator<kIsInstrumented, true>(self, array_class, size,
1476fac447555dc94a935b78198479cce645c837b89Ian Rogers                                                              allocator_type, visitor));
1486fac447555dc94a935b78198479cce645c837b89Ian Rogers  } else {
149aa866f51bccc2f017a2e65925748b7a1c701d3f6Hiroshi Yamauchi    SetLengthToUsableSizeVisitor visitor(component_count, DataOffset(component_size).SizeValue(),
150a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers                                         component_size);
1516fac447555dc94a935b78198479cce645c837b89Ian Rogers    result = down_cast<Array*>(
1526fac447555dc94a935b78198479cce645c837b89Ian Rogers        heap->AllocObjectWithAllocator<kIsInstrumented, true>(self, array_class, size,
1536fac447555dc94a935b78198479cce645c837b89Ian Rogers                                                              allocator_type, visitor));
1546fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
1556fac447555dc94a935b78198479cce645c837b89Ian Rogers  if (kIsDebugBuild && result != nullptr && Runtime::Current()->IsStarted()) {
1568580154e01910459d99074ef10584b8d647d912fMathieu Chartier    array_class = result->GetClass();  // In case the array class moved.
157a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    CHECK_EQ(array_class->GetComponentSize(), component_size);
1586fac447555dc94a935b78198479cce645c837b89Ian Rogers    if (!fill_usable) {
1596fac447555dc94a935b78198479cce645c837b89Ian Rogers      CHECK_EQ(result->SizeOf(), size);
1606fac447555dc94a935b78198479cce645c837b89Ian Rogers    } else {
1616fac447555dc94a935b78198479cce645c837b89Ian Rogers      CHECK_GE(result->SizeOf(), size);
1626fac447555dc94a935b78198479cce645c837b89Ian Rogers    }
1636fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
1646fac447555dc94a935b78198479cce645c837b89Ian Rogers  return result;
165967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi}
166967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
167c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartiertemplate<class T>
16883c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartierinline void PrimitiveArray<T>::VisitRoots(RootCallback* callback, void* arg) {
16912f7423a2bb4bfab76700d84eb6d4338d211983aMathieu Chartier  array_class_.VisitRootIfNonNull(callback, arg, RootInfo(kRootStickyClass));
170c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier}
171c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier
17299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogerstemplate<typename T>
17399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogersinline PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
1744f1ebc2b86c8467d1ecb3ec655316e6d7ee8b8b5Hiroshi Yamauchi  Array* raw_array = Array::Alloc<true>(self, GetArrayClass(), length, sizeof(T),
17599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers                                        Runtime::Current()->GetHeap()->GetCurrentAllocator());
17699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  return down_cast<PrimitiveArray<T>*>(raw_array);
17799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers}
17899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers
179b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
180b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T PrimitiveArray<T>::Get(int32_t i) {
181b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (!CheckIsValidIndex(i)) {
182b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    DCHECK(Thread::Current()->IsExceptionPending());
183b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return T(0);
184b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
185b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetWithoutChecks(i);
186b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
187b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
188b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
189b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void PrimitiveArray<T>::Set(int32_t i, T value) {
190b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (Runtime::Current()->IsActiveTransaction()) {
191b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Set<true>(i, value);
192b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  } else {
193b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Set<false>(i, value);
194b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
195b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
196b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
197b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
198b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction>
199b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void PrimitiveArray<T>::Set(int32_t i, T value) {
200b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (CheckIsValidIndex(i)) {
201b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetWithoutChecks<kTransactionActive, kCheckTransaction>(i, value);
202b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  } else {
203b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    DCHECK(Thread::Current()->IsExceptionPending());
204b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
205b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
206b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
207b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
208b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction>
209b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void PrimitiveArray<T>::SetWithoutChecks(int32_t i, T value) {
210b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kCheckTransaction) {
211b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
212b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
213b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kTransactionActive) {
214b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteArray(this, i, GetWithoutChecks(i));
215b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
216b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  DCHECK(CheckIsValidIndex(i));
217b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  GetData()[i] = value;
218b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
21999cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers// Backward copy where elements are of aligned appropriately for T. Count is in T sized units.
22099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers// Copies are guaranteed not to tear when the sizeof T is less-than 64bit.
221ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<typename T>
222ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersstatic inline void ArrayBackwardCopy(T* d, const T* s, int32_t count) {
223ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  d += count;
224ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  s += count;
225ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  for (int32_t i = 0; i < count; ++i) {
226ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    d--;
227ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    s--;
228ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    *d = *s;
229ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
230ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
231ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
23299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers// Forward copy where elements are of aligned appropriately for T. Count is in T sized units.
23399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers// Copies are guaranteed not to tear when the sizeof T is less-than 64bit.
2346fac447555dc94a935b78198479cce645c837b89Ian Rogerstemplate<typename T>
23599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogersstatic inline void ArrayForwardCopy(T* d, const T* s, int32_t count) {
23699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  for (int32_t i = 0; i < count; ++i) {
23799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    *d = *s;
23899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    d++;
23999cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    s++;
24099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  }
2416fac447555dc94a935b78198479cce645c837b89Ian Rogers}
2426fac447555dc94a935b78198479cce645c837b89Ian Rogers
243ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<class T>
2446fac447555dc94a935b78198479cce645c837b89Ian Rogersinline void PrimitiveArray<T>::Memmove(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos,
2456fac447555dc94a935b78198479cce645c837b89Ian Rogers                                       int32_t count) {
246ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (UNLIKELY(count == 0)) {
247ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return;
248ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
249ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GE(dst_pos, 0);
250ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GE(src_pos, 0);
251ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GT(count, 0);
252ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK(src != nullptr);
253ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LT(dst_pos, GetLength());
254ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LE(dst_pos, GetLength() - count);
255ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LT(src_pos, src->GetLength());
256ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LE(src_pos, src->GetLength() - count);
257ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
258ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // Note for non-byte copies we can't rely on standard libc functions like memcpy(3) and memmove(3)
259ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // in our implementation, because they may copy byte-by-byte.
26099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  if (LIKELY(src != this)) {
26199cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    // Memcpy ok for guaranteed non-overlapping distinct arrays.
262ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Memcpy(dst_pos, src, src_pos, count);
263ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
26499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    // Handle copies within the same array using the appropriate direction copy.
265ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    void* dst_raw = GetRawData(sizeof(T), dst_pos);
266ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    const void* src_raw = src->GetRawData(sizeof(T), src_pos);
267ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    if (sizeof(T) == sizeof(uint8_t)) {
268ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      uint8_t* d = reinterpret_cast<uint8_t*>(dst_raw);
269ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      const uint8_t* s = reinterpret_cast<const uint8_t*>(src_raw);
27099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      memmove(d, s, count);
271ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    } else {
27299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= count);
27399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      if (sizeof(T) == sizeof(uint16_t)) {
27499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        uint16_t* d = reinterpret_cast<uint16_t*>(dst_raw);
27599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        const uint16_t* s = reinterpret_cast<const uint16_t*>(src_raw);
27699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        if (copy_forward) {
27799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayForwardCopy<uint16_t>(d, s, count);
27899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        } else {
27999cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayBackwardCopy<uint16_t>(d, s, count);
28099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        }
28199cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      } else if (sizeof(T) == sizeof(uint32_t)) {
28299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        uint32_t* d = reinterpret_cast<uint32_t*>(dst_raw);
28399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        const uint32_t* s = reinterpret_cast<const uint32_t*>(src_raw);
28499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        if (copy_forward) {
28599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayForwardCopy<uint32_t>(d, s, count);
28699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        } else {
28799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayBackwardCopy<uint32_t>(d, s, count);
28899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        }
28999cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      } else {
29099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        DCHECK_EQ(sizeof(T), sizeof(uint64_t));
29199cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        uint64_t* d = reinterpret_cast<uint64_t*>(dst_raw);
29299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        const uint64_t* s = reinterpret_cast<const uint64_t*>(src_raw);
29399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        if (copy_forward) {
29499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayForwardCopy<uint64_t>(d, s, count);
29599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        } else {
29699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayBackwardCopy<uint64_t>(d, s, count);
29799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        }
29899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      }
299ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    }
300ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
301ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
302ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
303ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<class T>
3046fac447555dc94a935b78198479cce645c837b89Ian Rogersinline void PrimitiveArray<T>::Memcpy(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos,
3056fac447555dc94a935b78198479cce645c837b89Ian Rogers                                      int32_t count) {
306ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (UNLIKELY(count == 0)) {
307ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return;
308ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
309ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GE(dst_pos, 0);
310ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GE(src_pos, 0);
311ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GT(count, 0);
312ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK(src != nullptr);
313ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LT(dst_pos, GetLength());
314ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LE(dst_pos, GetLength() - count);
315ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LT(src_pos, src->GetLength());
316ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LE(src_pos, src->GetLength() - count);
317ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
318ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // Note for non-byte copies we can't rely on standard libc functions like memcpy(3) and memmove(3)
319ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // in our implementation, because they may copy byte-by-byte.
320ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void* dst_raw = GetRawData(sizeof(T), dst_pos);
321ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  const void* src_raw = src->GetRawData(sizeof(T), src_pos);
322ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (sizeof(T) == sizeof(uint8_t)) {
323ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    memcpy(dst_raw, src_raw, count);
324ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else if (sizeof(T) == sizeof(uint16_t)) {
325ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uint16_t* d = reinterpret_cast<uint16_t*>(dst_raw);
326ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    const uint16_t* s = reinterpret_cast<const uint16_t*>(src_raw);
327ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    ArrayForwardCopy<uint16_t>(d, s, count);
328ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else if (sizeof(T) == sizeof(uint32_t)) {
329ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uint32_t* d = reinterpret_cast<uint32_t*>(dst_raw);
330ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    const uint32_t* s = reinterpret_cast<const uint32_t*>(src_raw);
331ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    ArrayForwardCopy<uint32_t>(d, s, count);
332ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
333ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    DCHECK_EQ(sizeof(T), sizeof(uint64_t));
334ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uint64_t* d = reinterpret_cast<uint64_t*>(dst_raw);
335ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    const uint64_t* s = reinterpret_cast<const uint64_t*>(src_raw);
336ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    ArrayForwardCopy<uint64_t>(d, s, count);
337ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
338ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
339ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
3402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
3411f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom}  // namespace art
3421f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom
343fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_ARRAY_INL_H_
344