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