array-inl.h revision b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cf
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
309103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchitemplate<VerifyObjectFlags kVerifyFlags, bool kDoReadBarrier>
31ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersinline size_t Array::SizeOf() {
322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  // This is safe from overflow because the array was already allocated, so we know it's sane.
339103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi  size_t component_size =
349103c86a98524e9ddfd14f8cee56e919f68eee9bHiroshi Yamauchi      GetClass<kVerifyFlags, kDoReadBarrier>()->template GetComponentSize<kDoReadBarrier>();
354e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  // Don't need to check this since we already check this in GetClass.
364e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier  int32_t component_count =
374e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier      GetLength<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>();
38aa866f51bccc2f017a2e65925748b7a1c701d3f6Hiroshi Yamauchi  size_t header_size = DataOffset(component_size).SizeValue();
392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  size_t data_size = component_count * component_size;
402dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return header_size + data_size;
412dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
422dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
43b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<VerifyObjectFlags kVerifyFlags>
44b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline bool Array::CheckIsValidIndex(int32_t index) {
45b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (UNLIKELY(static_cast<uint32_t>(index) >=
46b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers               static_cast<uint32_t>(GetLength<kVerifyFlags>()))) {
47b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    ThrowArrayIndexOutOfBoundsException(index);
48b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return false;
49b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
50b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return true;
51b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
52b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
533b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchistatic inline size_t ComputeArraySize(Thread* self, Class* array_class, int32_t component_count,
543b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi                                      size_t component_size)
553b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
56967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  DCHECK(array_class != NULL);
57967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  DCHECK_GE(component_count, 0);
58967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  DCHECK(array_class->IsArrayClass());
59967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
60aa866f51bccc2f017a2e65925748b7a1c701d3f6Hiroshi Yamauchi  size_t header_size = Array::DataOffset(component_size).SizeValue();
61967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  size_t data_size = component_count * component_size;
62967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  size_t size = header_size + data_size;
63967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
64967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  // Check for overflow and throw OutOfMemoryError if this was an unreasonable request.
65967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  size_t component_shift = sizeof(size_t) * 8 - 1 - CLZ(component_size);
66967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  if (UNLIKELY(data_size >> component_shift != size_t(component_count) || size < data_size)) {
67967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi    self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow",
68967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi                                             PrettyDescriptor(array_class).c_str(),
69967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi                                             component_count).c_str());
703b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi    return 0;  // failure
71967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  }
723b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  return size;
733b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi}
74967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
756fac447555dc94a935b78198479cce645c837b89Ian Rogers// Used for setting the array length in the allocation code path to ensure it is guarded by a
766fac447555dc94a935b78198479cce645c837b89Ian Rogers// StoreStore fence.
771febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartierclass SetLengthVisitor {
781febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier public:
791febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier  explicit SetLengthVisitor(int32_t length) : length_(length) {
801febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier  }
811febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier
826fac447555dc94a935b78198479cce645c837b89Ian Rogers  void operator()(Object* obj, size_t usable_size) const
836fac447555dc94a935b78198479cce645c837b89Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
846fac447555dc94a935b78198479cce645c837b89Ian Rogers    UNUSED(usable_size);
85ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    // Avoid AsArray as object is not yet in live bitmap or allocation stack.
86ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Array* array = down_cast<Array*>(obj);
87ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    // DCHECK(array->IsArrayInstance());
881febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier    array->SetLength(length_);
89967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi  }
901febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier
911febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier private:
921febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier  const int32_t length_;
936fac447555dc94a935b78198479cce645c837b89Ian Rogers
946fac447555dc94a935b78198479cce645c837b89Ian Rogers  DISALLOW_COPY_AND_ASSIGN(SetLengthVisitor);
956fac447555dc94a935b78198479cce645c837b89Ian Rogers};
966fac447555dc94a935b78198479cce645c837b89Ian Rogers
976fac447555dc94a935b78198479cce645c837b89Ian Rogers// Similar to SetLengthVisitor, used for setting the array length to fill the usable size of an
986fac447555dc94a935b78198479cce645c837b89Ian Rogers// array.
996fac447555dc94a935b78198479cce645c837b89Ian Rogersclass SetLengthToUsableSizeVisitor {
1006fac447555dc94a935b78198479cce645c837b89Ian Rogers public:
101a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers  SetLengthToUsableSizeVisitor(int32_t min_length, size_t header_size, size_t component_size) :
102a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers      minimum_length_(min_length), header_size_(header_size), component_size_(component_size) {
1036fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
1046fac447555dc94a935b78198479cce645c837b89Ian Rogers
1056fac447555dc94a935b78198479cce645c837b89Ian Rogers  void operator()(Object* obj, size_t usable_size) const
1066fac447555dc94a935b78198479cce645c837b89Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1076fac447555dc94a935b78198479cce645c837b89Ian Rogers    // Avoid AsArray as object is not yet in live bitmap or allocation stack.
1086fac447555dc94a935b78198479cce645c837b89Ian Rogers    Array* array = down_cast<Array*>(obj);
1096fac447555dc94a935b78198479cce645c837b89Ian Rogers    // DCHECK(array->IsArrayInstance());
110a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    int32_t length = (usable_size - header_size_) / component_size_;
111a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    DCHECK_GE(length, minimum_length_);
112a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    byte* old_end = reinterpret_cast<byte*>(array->GetRawData(component_size_, minimum_length_));
113a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    byte* new_end = reinterpret_cast<byte*>(array->GetRawData(component_size_, length));
114a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    // Ensure space beyond original allocation is zeroed.
115a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    memset(old_end, 0, new_end - old_end);
1166fac447555dc94a935b78198479cce645c837b89Ian Rogers    array->SetLength(length);
1176fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
1186fac447555dc94a935b78198479cce645c837b89Ian Rogers
1196fac447555dc94a935b78198479cce645c837b89Ian Rogers private:
120a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers  const int32_t minimum_length_;
1216fac447555dc94a935b78198479cce645c837b89Ian Rogers  const size_t header_size_;
1226fac447555dc94a935b78198479cce645c837b89Ian Rogers  const size_t component_size_;
1236fac447555dc94a935b78198479cce645c837b89Ian Rogers
1246fac447555dc94a935b78198479cce645c837b89Ian Rogers  DISALLOW_COPY_AND_ASSIGN(SetLengthToUsableSizeVisitor);
1251febddf359ae500ef1bb01ab4883b076fcb56440Mathieu Chartier};
126967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
127cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartiertemplate <bool kIsInstrumented>
128590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierinline Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count,
1296fac447555dc94a935b78198479cce645c837b89Ian Rogers                           size_t component_size, gc::AllocatorType allocator_type,
1306fac447555dc94a935b78198479cce645c837b89Ian Rogers                           bool fill_usable) {
1316fac447555dc94a935b78198479cce645c837b89Ian Rogers  DCHECK(allocator_type != gc::kAllocatorTypeLOS);
1323b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  size_t size = ComputeArraySize(self, array_class, component_count, component_size);
1333b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  if (UNLIKELY(size == 0)) {
134cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier    return nullptr;
1353b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  }
1363b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi  gc::Heap* heap = Runtime::Current()->GetHeap();
1376fac447555dc94a935b78198479cce645c837b89Ian Rogers  Array* result;
1386fac447555dc94a935b78198479cce645c837b89Ian Rogers  if (!fill_usable) {
1396fac447555dc94a935b78198479cce645c837b89Ian Rogers    SetLengthVisitor visitor(component_count);
1406fac447555dc94a935b78198479cce645c837b89Ian Rogers    result = down_cast<Array*>(
1416fac447555dc94a935b78198479cce645c837b89Ian Rogers        heap->AllocObjectWithAllocator<kIsInstrumented, true>(self, array_class, size,
1426fac447555dc94a935b78198479cce645c837b89Ian Rogers                                                              allocator_type, visitor));
1436fac447555dc94a935b78198479cce645c837b89Ian Rogers  } else {
144aa866f51bccc2f017a2e65925748b7a1c701d3f6Hiroshi Yamauchi    SetLengthToUsableSizeVisitor visitor(component_count, DataOffset(component_size).SizeValue(),
145a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers                                         component_size);
1466fac447555dc94a935b78198479cce645c837b89Ian Rogers    result = down_cast<Array*>(
1476fac447555dc94a935b78198479cce645c837b89Ian Rogers        heap->AllocObjectWithAllocator<kIsInstrumented, true>(self, array_class, size,
1486fac447555dc94a935b78198479cce645c837b89Ian Rogers                                                              allocator_type, visitor));
1496fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
1506fac447555dc94a935b78198479cce645c837b89Ian Rogers  if (kIsDebugBuild && result != nullptr && Runtime::Current()->IsStarted()) {
1518580154e01910459d99074ef10584b8d647d912fMathieu Chartier    array_class = result->GetClass();  // In case the array class moved.
152a55cf41c9d1da7ee8b2f63974dedfb484042dd03Ian Rogers    CHECK_EQ(array_class->GetComponentSize(), component_size);
1536fac447555dc94a935b78198479cce645c837b89Ian Rogers    if (!fill_usable) {
1546fac447555dc94a935b78198479cce645c837b89Ian Rogers      CHECK_EQ(result->SizeOf(), size);
1556fac447555dc94a935b78198479cce645c837b89Ian Rogers    } else {
1566fac447555dc94a935b78198479cce645c837b89Ian Rogers      CHECK_GE(result->SizeOf(), size);
1576fac447555dc94a935b78198479cce645c837b89Ian Rogers    }
1586fac447555dc94a935b78198479cce645c837b89Ian Rogers  }
1596fac447555dc94a935b78198479cce645c837b89Ian Rogers  return result;
160967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi}
161967a0adf8b93a23d2a8fef82e06bd913db94ac19Hiroshi Yamauchi
162c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartiertemplate<class T>
16383c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartierinline void PrimitiveArray<T>::VisitRoots(RootCallback* callback, void* arg) {
164c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  if (array_class_ != nullptr) {
165815873ecc312b1d231acce71e1a16f42cdaf09f2Mathieu Chartier    callback(reinterpret_cast<mirror::Object**>(&array_class_), arg, 0, kRootStickyClass);
166c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier  }
167c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier}
168c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier
16999cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogerstemplate<typename T>
17099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogersinline PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
17199cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  DCHECK(array_class_ != NULL);
17299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  Array* raw_array = Array::Alloc<true>(self, array_class_, length, sizeof(T),
17399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers                                        Runtime::Current()->GetHeap()->GetCurrentAllocator());
17499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  return down_cast<PrimitiveArray<T>*>(raw_array);
17599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers}
17699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers
177b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
178b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline T PrimitiveArray<T>::Get(int32_t i) {
179b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (!CheckIsValidIndex(i)) {
180b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    DCHECK(Thread::Current()->IsExceptionPending());
181b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    return T(0);
182b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
183b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  return GetWithoutChecks(i);
184b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
185b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
186b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
187b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void PrimitiveArray<T>::Set(int32_t i, T value) {
188b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (Runtime::Current()->IsActiveTransaction()) {
189b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Set<true>(i, value);
190b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  } else {
191b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Set<false>(i, value);
192b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
193b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
194b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
195b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
196b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction>
197b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void PrimitiveArray<T>::Set(int32_t i, T value) {
198b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (CheckIsValidIndex(i)) {
199b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    SetWithoutChecks<kTransactionActive, kCheckTransaction>(i, value);
200b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  } else {
201b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    DCHECK(Thread::Current()->IsExceptionPending());
202b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
203b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
204b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers
205b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<typename T>
206b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogerstemplate<bool kTransactionActive, bool kCheckTransaction>
207b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogersinline void PrimitiveArray<T>::SetWithoutChecks(int32_t i, T value) {
208b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kCheckTransaction) {
209b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
210b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
211b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  if (kTransactionActive) {
212b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers    Runtime::Current()->RecordWriteArray(this, i, GetWithoutChecks(i));
213b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  }
214b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  DCHECK(CheckIsValidIndex(i));
215b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers  GetData()[i] = value;
216b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers}
21799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers// Backward copy where elements are of aligned appropriately for T. Count is in T sized units.
21899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers// Copies are guaranteed not to tear when the sizeof T is less-than 64bit.
219ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<typename T>
220ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogersstatic inline void ArrayBackwardCopy(T* d, const T* s, int32_t count) {
221ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  d += count;
222ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  s += count;
223ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  for (int32_t i = 0; i < count; ++i) {
224ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    d--;
225ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    s--;
226ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    *d = *s;
227ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
228ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
229ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
23099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers// Forward copy where elements are of aligned appropriately for T. Count is in T sized units.
23199cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers// Copies are guaranteed not to tear when the sizeof T is less-than 64bit.
2326fac447555dc94a935b78198479cce645c837b89Ian Rogerstemplate<typename T>
23399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogersstatic inline void ArrayForwardCopy(T* d, const T* s, int32_t count) {
23499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  for (int32_t i = 0; i < count; ++i) {
23599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    *d = *s;
23699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    d++;
23799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    s++;
23899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  }
2396fac447555dc94a935b78198479cce645c837b89Ian Rogers}
2406fac447555dc94a935b78198479cce645c837b89Ian Rogers
241ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<class T>
2426fac447555dc94a935b78198479cce645c837b89Ian Rogersinline void PrimitiveArray<T>::Memmove(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos,
2436fac447555dc94a935b78198479cce645c837b89Ian Rogers                                       int32_t count) {
244ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (UNLIKELY(count == 0)) {
245ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return;
246ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
247ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GE(dst_pos, 0);
248ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GE(src_pos, 0);
249ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GT(count, 0);
250ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK(src != nullptr);
251ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LT(dst_pos, GetLength());
252ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LE(dst_pos, GetLength() - count);
253ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LT(src_pos, src->GetLength());
254ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LE(src_pos, src->GetLength() - count);
255ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
256ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // Note for non-byte copies we can't rely on standard libc functions like memcpy(3) and memmove(3)
257ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // in our implementation, because they may copy byte-by-byte.
25899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers  if (LIKELY(src != this)) {
25999cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    // Memcpy ok for guaranteed non-overlapping distinct arrays.
260ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    Memcpy(dst_pos, src, src_pos, count);
261ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
26299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers    // Handle copies within the same array using the appropriate direction copy.
263ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    void* dst_raw = GetRawData(sizeof(T), dst_pos);
264ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    const void* src_raw = src->GetRawData(sizeof(T), src_pos);
265ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    if (sizeof(T) == sizeof(uint8_t)) {
266ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      uint8_t* d = reinterpret_cast<uint8_t*>(dst_raw);
267ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      const uint8_t* s = reinterpret_cast<const uint8_t*>(src_raw);
26899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      memmove(d, s, count);
269ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    } else {
27099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      const bool copy_forward = (dst_pos < src_pos) || (dst_pos - src_pos >= count);
27199cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      if (sizeof(T) == sizeof(uint16_t)) {
27299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        uint16_t* d = reinterpret_cast<uint16_t*>(dst_raw);
27399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        const uint16_t* s = reinterpret_cast<const uint16_t*>(src_raw);
27499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        if (copy_forward) {
27599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayForwardCopy<uint16_t>(d, s, count);
27699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        } else {
27799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayBackwardCopy<uint16_t>(d, s, count);
27899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        }
27999cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      } else if (sizeof(T) == sizeof(uint32_t)) {
28099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        uint32_t* d = reinterpret_cast<uint32_t*>(dst_raw);
28199cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        const uint32_t* s = reinterpret_cast<const uint32_t*>(src_raw);
28299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        if (copy_forward) {
28399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayForwardCopy<uint32_t>(d, s, count);
28499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        } else {
28599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayBackwardCopy<uint32_t>(d, s, count);
28699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        }
28799cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      } else {
28899cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        DCHECK_EQ(sizeof(T), sizeof(uint64_t));
28999cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        uint64_t* d = reinterpret_cast<uint64_t*>(dst_raw);
29099cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        const uint64_t* s = reinterpret_cast<const uint64_t*>(src_raw);
29199cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        if (copy_forward) {
29299cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayForwardCopy<uint64_t>(d, s, count);
29399cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        } else {
29499cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers          ArrayBackwardCopy<uint64_t>(d, s, count);
29599cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers        }
29699cb4eac56f8bd6336669f5fb9dc4b1f4061466cIan Rogers      }
297ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    }
298ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
299ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
300ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
301ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstemplate<class T>
3026fac447555dc94a935b78198479cce645c837b89Ian Rogersinline void PrimitiveArray<T>::Memcpy(int32_t dst_pos, PrimitiveArray<T>* src, int32_t src_pos,
3036fac447555dc94a935b78198479cce645c837b89Ian Rogers                                      int32_t count) {
304ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (UNLIKELY(count == 0)) {
305ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    return;
306ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
307ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GE(dst_pos, 0);
308ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GE(src_pos, 0);
309ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_GT(count, 0);
310ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK(src != nullptr);
311ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LT(dst_pos, GetLength());
312ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LE(dst_pos, GetLength() - count);
313ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LT(src_pos, src->GetLength());
314ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  DCHECK_LE(src_pos, src->GetLength() - count);
315ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
316ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // Note for non-byte copies we can't rely on standard libc functions like memcpy(3) and memmove(3)
317ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  // in our implementation, because they may copy byte-by-byte.
318ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void* dst_raw = GetRawData(sizeof(T), dst_pos);
319ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  const void* src_raw = src->GetRawData(sizeof(T), src_pos);
320ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  if (sizeof(T) == sizeof(uint8_t)) {
321ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    memcpy(dst_raw, src_raw, count);
322ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else if (sizeof(T) == sizeof(uint16_t)) {
323ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uint16_t* d = reinterpret_cast<uint16_t*>(dst_raw);
324ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    const uint16_t* s = reinterpret_cast<const uint16_t*>(src_raw);
325ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    ArrayForwardCopy<uint16_t>(d, s, count);
326ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else if (sizeof(T) == sizeof(uint32_t)) {
327ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uint32_t* d = reinterpret_cast<uint32_t*>(dst_raw);
328ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    const uint32_t* s = reinterpret_cast<const uint32_t*>(src_raw);
329ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    ArrayForwardCopy<uint32_t>(d, s, count);
330ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  } else {
331ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    DCHECK_EQ(sizeof(T), sizeof(uint64_t));
332ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uint64_t* d = reinterpret_cast<uint64_t*>(dst_raw);
333ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    const uint64_t* s = reinterpret_cast<const uint64_t*>(src_raw);
334ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    ArrayForwardCopy<uint64_t>(d, s, count);
335ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  }
336ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers}
337ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers
3382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
3391f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom}  // namespace art
3401f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom
341fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_MIRROR_ARRAY_INL_H_
342