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