blob: 1d2f47f86ab7cfc914b527975b4b57f0e3122b06 [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_
18#define ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
20#include "object_array.h"
21
Andreas Gampe46ee31b2016-12-14 10:11:49 -080022#include <string>
23
24#include "android-base/stringprintf.h"
25
Ian Rogers7e70b002014-10-08 11:47:24 -070026#include "array-inl.h"
David Sehrc431b9d2018-03-02 12:01:51 -080027#include "base/utils.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070028#include "class.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070029#include "gc/heap.h"
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070030#include "handle_scope-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070031#include "obj_ptr-inl.h"
32#include "object-inl.h"
33#include "runtime.h"
Sebastien Hertz6bdd8f42013-05-17 14:44:01 +020034#include "thread.h"
Mathieu Chartier88ea61e2018-06-20 17:45:41 -070035#include "write_barrier-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080036
37namespace art {
38namespace mirror {
39
40template<class T>
Vladimir Markobcf17522018-06-01 13:14:32 +010041inline ObjPtr<ObjectArray<T>> ObjectArray<T>::Alloc(Thread* self,
42 ObjPtr<Class> object_array_class,
43 int32_t length,
44 gc::AllocatorType allocator_type) {
45 ObjPtr<Array> array = Array::Alloc<true>(self,
46 object_array_class,
47 length,
48 ComponentSizeShiftWidth(kHeapReferenceSize),
49 allocator_type);
Mathieu Chartiercbb2d202013-11-14 17:45:16 -080050 if (UNLIKELY(array == nullptr)) {
51 return nullptr;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080052 }
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070053 DCHECK_EQ(array->GetClass()->GetComponentSizeShift(),
54 ComponentSizeShiftWidth(kHeapReferenceSize));
55 return array->AsObjectArray<T>();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080056}
57
58template<class T>
Vladimir Markobcf17522018-06-01 13:14:32 +010059inline ObjPtr<ObjectArray<T>> ObjectArray<T>::Alloc(Thread* self,
60 ObjPtr<Class> object_array_class,
61 int32_t length) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070062 return Alloc(self,
63 object_array_class,
64 length,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -080065 Runtime::Current()->GetHeap()->GetCurrentAllocator());
66}
67
Mathieu Chartierfbc31082016-01-24 11:59:56 -080068template<class T> template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -080069inline T* ObjectArray<T>::Get(int32_t i) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070070 if (!CheckIsValidIndex(i)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +010071 DCHECK(Thread::Current()->IsExceptionPending());
Mathieu Chartier2cebb242015-04-21 16:50:40 -070072 return nullptr;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080073 }
Mathieu Chartierfbc31082016-01-24 11:59:56 -080074 return GetFieldObject<T, kVerifyFlags, kReadBarrierOption>(OffsetOfElement(i));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080075}
76
Mathieu Chartier4e305412014-02-19 10:54:44 -080077template<class T> template<VerifyObjectFlags kVerifyFlags>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070078inline bool ObjectArray<T>::CheckAssignable(ObjPtr<T> object) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070079 if (object != nullptr) {
Mathieu Chartier4e305412014-02-19 10:54:44 -080080 Class* element_class = GetClass<kVerifyFlags>()->GetComponentType();
Sebastien Hertz6bdd8f42013-05-17 14:44:01 +020081 if (UNLIKELY(!object->InstanceOf(element_class))) {
82 ThrowArrayStoreException(object);
83 return false;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080084 }
Sebastien Hertz6bdd8f42013-05-17 14:44:01 +020085 }
86 return true;
87}
88
89template<class T>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070090inline void ObjectArray<T>::Set(int32_t i, ObjPtr<T> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010091 if (Runtime::Current()->IsActiveTransaction()) {
92 Set<true>(i, object);
93 } else {
94 Set<false>(i, object);
95 }
96}
97
98template<class T>
Mathieu Chartier4e305412014-02-19 10:54:44 -080099template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700100inline void ObjectArray<T>::Set(int32_t i, ObjPtr<T> object) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700101 if (CheckIsValidIndex(i) && CheckAssignable<kVerifyFlags>(object)) {
102 SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags>(OffsetOfElement(i), object);
Sebastien Hertz6bdd8f42013-05-17 14:44:01 +0200103 } else {
104 DCHECK(Thread::Current()->IsExceptionPending());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800105 }
106}
107
108template<class T>
Mathieu Chartier4e305412014-02-19 10:54:44 -0800109template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700110inline void ObjectArray<T>::SetWithoutChecks(int32_t i, ObjPtr<T> object) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800111 DCHECK(CheckIsValidIndex<kVerifyFlags>(i));
112 DCHECK(CheckAssignable<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(object));
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700113 SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags>(OffsetOfElement(i), object);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800114}
115
116template<class T>
Mathieu Chartier4e305412014-02-19 10:54:44 -0800117template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700118inline void ObjectArray<T>::SetWithoutChecksAndWriteBarrier(int32_t i, ObjPtr<T> object) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800119 DCHECK(CheckIsValidIndex<kVerifyFlags>(i));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800120 // TODO: enable this check. It fails when writing the image in ImageWriter::FixupObjectArray.
Sebastien Hertzabff6432014-01-27 18:01:39 +0100121 // DCHECK(CheckAssignable(object));
Mathieu Chartier4e305412014-02-19 10:54:44 -0800122 SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700123 OffsetOfElement(i), object);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800124}
125
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800126template<class T> template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800127inline T* ObjectArray<T>::GetWithoutChecks(int32_t i) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100128 DCHECK(CheckIsValidIndex(i));
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800129 return GetFieldObject<T, kVerifyFlags, kReadBarrierOption>(OffsetOfElement(i));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800130}
131
132template<class T>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700133inline void ObjectArray<T>::AssignableMemmove(int32_t dst_pos,
134 ObjPtr<ObjectArray<T>> src,
135 int32_t src_pos,
136 int32_t count) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800137 if (kIsDebugBuild) {
138 for (int i = 0; i < count; ++i) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700139 // The get will perform the VerifyObject.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800140 src->GetWithoutChecks(src_pos + i);
141 }
142 }
143 // Perform the memmove using int memmove then perform the write barrier.
Roland Levillain33d69032015-06-18 18:20:59 +0100144 static_assert(sizeof(HeapReference<T>) == sizeof(uint32_t),
145 "art::mirror::HeapReference<T> and uint32_t have different sizes.");
Mathieu Chartierfec13d42016-10-07 12:59:33 -0700146 // TODO: Optimize this later?
147 // We can't use memmove since it does not handle read barriers and may do by per byte copying.
148 // See b/32012820.
149 const bool copy_forward = (src != this) || (dst_pos < src_pos) || (dst_pos - src_pos >= count);
150 if (copy_forward) {
151 // Forward copy.
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800152 bool baker_non_gray_case = false;
153 if (kUseReadBarrier && kUseBakerReadBarrier) {
154 uintptr_t fake_address_dependency;
155 if (!ReadBarrier::IsGray(src.Ptr(), &fake_address_dependency)) {
156 baker_non_gray_case = true;
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800157 DCHECK_EQ(fake_address_dependency, 0U);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800158 src.Assign(reinterpret_cast<ObjectArray<T>*>(
159 reinterpret_cast<uintptr_t>(src.Ptr()) | fake_address_dependency));
160 for (int i = 0; i < count; ++i) {
161 // We can skip the RB here because 'src' isn't gray.
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800162 T* obj = src->template GetWithoutChecks<kDefaultVerifyFlags, kWithoutReadBarrier>(
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800163 src_pos + i);
164 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
165 }
166 }
167 }
168 if (!baker_non_gray_case) {
169 for (int i = 0; i < count; ++i) {
170 // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800171 T* obj = src->GetWithoutChecks(src_pos + i);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800172 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
173 }
Hiroshi Yamauchi79719282014-04-10 12:46:22 -0700174 }
175 } else {
Mathieu Chartierfec13d42016-10-07 12:59:33 -0700176 // Backward copy.
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800177 bool baker_non_gray_case = false;
178 if (kUseReadBarrier && kUseBakerReadBarrier) {
179 uintptr_t fake_address_dependency;
180 if (!ReadBarrier::IsGray(src.Ptr(), &fake_address_dependency)) {
181 baker_non_gray_case = true;
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800182 DCHECK_EQ(fake_address_dependency, 0U);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800183 src.Assign(reinterpret_cast<ObjectArray<T>*>(
184 reinterpret_cast<uintptr_t>(src.Ptr()) | fake_address_dependency));
185 for (int i = count - 1; i >= 0; --i) {
186 // We can skip the RB here because 'src' isn't gray.
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800187 T* obj = src->template GetWithoutChecks<kDefaultVerifyFlags, kWithoutReadBarrier>(
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800188 src_pos + i);
189 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
190 }
191 }
192 }
193 if (!baker_non_gray_case) {
194 for (int i = count - 1; i >= 0; --i) {
195 // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800196 T* obj = src->GetWithoutChecks(src_pos + i);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800197 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
198 }
Mathieu Chartierfec13d42016-10-07 12:59:33 -0700199 }
Hiroshi Yamauchi79719282014-04-10 12:46:22 -0700200 }
Mathieu Chartier88ea61e2018-06-20 17:45:41 -0700201 WriteBarrier::ForArrayWrite(this, dst_pos, count);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800202 if (kIsDebugBuild) {
203 for (int i = 0; i < count; ++i) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700204 // The get will perform the VerifyObject.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800205 GetWithoutChecks(dst_pos + i);
206 }
207 }
208}
209
210template<class T>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700211inline void ObjectArray<T>::AssignableMemcpy(int32_t dst_pos,
212 ObjPtr<ObjectArray<T>> src,
213 int32_t src_pos,
214 int32_t count) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800215 if (kIsDebugBuild) {
216 for (int i = 0; i < count; ++i) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700217 // The get will perform the VerifyObject.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800218 src->GetWithoutChecks(src_pos + i);
219 }
220 }
221 // Perform the memmove using int memcpy then perform the write barrier.
Roland Levillain33d69032015-06-18 18:20:59 +0100222 static_assert(sizeof(HeapReference<T>) == sizeof(uint32_t),
223 "art::mirror::HeapReference<T> and uint32_t have different sizes.");
Mathieu Chartierfec13d42016-10-07 12:59:33 -0700224 // TODO: Optimize this later?
225 // We can't use memmove since it does not handle read barriers and may do by per byte copying.
226 // See b/32012820.
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800227 bool baker_non_gray_case = false;
228 if (kUseReadBarrier && kUseBakerReadBarrier) {
229 uintptr_t fake_address_dependency;
230 if (!ReadBarrier::IsGray(src.Ptr(), &fake_address_dependency)) {
231 baker_non_gray_case = true;
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800232 DCHECK_EQ(fake_address_dependency, 0U);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800233 src.Assign(reinterpret_cast<ObjectArray<T>*>(
234 reinterpret_cast<uintptr_t>(src.Ptr()) | fake_address_dependency));
235 for (int i = 0; i < count; ++i) {
236 // We can skip the RB here because 'src' isn't gray.
237 Object* obj = src->template GetWithoutChecks<kDefaultVerifyFlags, kWithoutReadBarrier>(
238 src_pos + i);
239 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
240 }
241 }
242 }
243 if (!baker_non_gray_case) {
244 for (int i = 0; i < count; ++i) {
245 // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
246 T* obj = src->GetWithoutChecks(src_pos + i);
247 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
248 }
Hiroshi Yamauchi79719282014-04-10 12:46:22 -0700249 }
Mathieu Chartier88ea61e2018-06-20 17:45:41 -0700250 WriteBarrier::ForArrayWrite(this, dst_pos, count);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800251 if (kIsDebugBuild) {
252 for (int i = 0; i < count; ++i) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700253 // The get will perform the VerifyObject.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800254 GetWithoutChecks(dst_pos + i);
255 }
256 }
257}
258
259template<class T>
Andreas Gampe85a098a2016-03-31 13:30:53 -0700260template<bool kTransactionActive>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700261inline void ObjectArray<T>::AssignableCheckingMemcpy(int32_t dst_pos,
262 ObjPtr<ObjectArray<T>> src,
263 int32_t src_pos,
264 int32_t count,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800265 bool throw_exception) {
266 DCHECK_NE(this, src)
267 << "This case should be handled with memmove that handles overlaps correctly";
268 // We want to avoid redundant IsAssignableFrom checks where possible, so we cache a class that
269 // we know is assignable to the destination array's component type.
270 Class* dst_class = GetClass()->GetComponentType();
271 Class* lastAssignableElementClass = dst_class;
272
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800273 T* o = nullptr;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800274 int i = 0;
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800275 bool baker_non_gray_case = false;
276 if (kUseReadBarrier && kUseBakerReadBarrier) {
277 uintptr_t fake_address_dependency;
278 if (!ReadBarrier::IsGray(src.Ptr(), &fake_address_dependency)) {
279 baker_non_gray_case = true;
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800280 DCHECK_EQ(fake_address_dependency, 0U);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800281 src.Assign(reinterpret_cast<ObjectArray<T>*>(
282 reinterpret_cast<uintptr_t>(src.Ptr()) | fake_address_dependency));
283 for (; i < count; ++i) {
284 // The follow get operations force the objects to be verified.
285 // We can skip the RB here because 'src' isn't gray.
286 o = src->template GetWithoutChecks<kDefaultVerifyFlags, kWithoutReadBarrier>(
287 src_pos + i);
288 if (o == nullptr) {
289 // Null is always assignable.
290 SetWithoutChecks<kTransactionActive>(dst_pos + i, nullptr);
291 } else {
292 // TODO: use the underlying class reference to avoid uncompression when not necessary.
293 Class* o_class = o->GetClass();
294 if (LIKELY(lastAssignableElementClass == o_class)) {
295 SetWithoutChecks<kTransactionActive>(dst_pos + i, o);
296 } else if (LIKELY(dst_class->IsAssignableFrom(o_class))) {
297 lastAssignableElementClass = o_class;
298 SetWithoutChecks<kTransactionActive>(dst_pos + i, o);
299 } else {
300 // Can't put this element into the array, break to perform write-barrier and throw
301 // exception.
302 break;
303 }
304 }
305 }
306 }
307 }
308 if (!baker_non_gray_case) {
309 for (; i < count; ++i) {
310 // The follow get operations force the objects to be verified.
311 // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
312 o = src->GetWithoutChecks(src_pos + i);
313 if (o == nullptr) {
314 // Null is always assignable.
315 SetWithoutChecks<kTransactionActive>(dst_pos + i, nullptr);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800316 } else {
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800317 // TODO: use the underlying class reference to avoid uncompression when not necessary.
318 Class* o_class = o->GetClass();
319 if (LIKELY(lastAssignableElementClass == o_class)) {
320 SetWithoutChecks<kTransactionActive>(dst_pos + i, o);
321 } else if (LIKELY(dst_class->IsAssignableFrom(o_class))) {
322 lastAssignableElementClass = o_class;
323 SetWithoutChecks<kTransactionActive>(dst_pos + i, o);
324 } else {
325 // Can't put this element into the array, break to perform write-barrier and throw
326 // exception.
327 break;
328 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800329 }
330 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800331 }
Mathieu Chartier88ea61e2018-06-20 17:45:41 -0700332 WriteBarrier::ForArrayWrite(this, dst_pos, count);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800333 if (UNLIKELY(i != count)) {
David Sehr709b0702016-10-13 09:12:37 -0700334 std::string actualSrcType(mirror::Object::PrettyTypeOf(o));
335 std::string dstType(PrettyTypeOf());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800336 Thread* self = Thread::Current();
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800337 std::string msg = android::base::StringPrintf(
338 "source[%d] of type %s cannot be stored in destination array of type %s",
339 src_pos + i,
340 actualSrcType.c_str(),
341 dstType.c_str());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800342 if (throw_exception) {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800343 self->ThrowNewException("Ljava/lang/ArrayStoreException;", msg.c_str());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800344 } else {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800345 LOG(FATAL) << msg;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800346 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800347 }
348}
349
350template<class T>
Vladimir Markobcf17522018-06-01 13:14:32 +0100351inline ObjPtr<ObjectArray<T>> ObjectArray<T>::CopyOf(Thread* self, int32_t new_length) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800352 DCHECK_GE(new_length, 0);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700353 // We may get copied by a compacting GC.
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700354 StackHandleScope<1> hs(self);
Ian Rogers700a4022014-05-19 16:49:03 -0700355 Handle<ObjectArray<T>> h_this(hs.NewHandle(this));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800356 gc::Heap* heap = Runtime::Current()->GetHeap();
357 gc::AllocatorType allocator_type = heap->IsMovableObject(this) ? heap->GetCurrentAllocator() :
358 heap->GetCurrentNonMovingAllocator();
Vladimir Markobcf17522018-06-01 13:14:32 +0100359 ObjPtr<ObjectArray<T>> new_array = Alloc(self, GetClass(), new_length, allocator_type);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700360 if (LIKELY(new_array != nullptr)) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700361 new_array->AssignableMemcpy(0, h_this.Get(), 0, std::min(h_this->GetLength(), new_length));
Ian Rogersa436fde2013-08-27 23:34:06 -0700362 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800363 return new_array;
364}
365
Ian Rogersef7d42f2014-01-06 12:55:46 -0800366template<class T>
367inline MemberOffset ObjectArray<T>::OffsetOfElement(int32_t i) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700368 return MemberOffset(DataOffset(kHeapReferenceSize).Int32Value() + (i * kHeapReferenceSize));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800369}
370
Mathieu Chartier059ef3d2015-08-18 13:54:21 -0700371template<class T> template<typename Visitor>
Hiroshi Yamauchi723e6ce2015-10-28 20:59:47 -0700372inline void ObjectArray<T>::VisitReferences(const Visitor& visitor) {
Mathieu Chartier407f7022014-02-18 14:37:05 -0800373 const size_t length = static_cast<size_t>(GetLength());
374 for (size_t i = 0; i < length; ++i) {
375 visitor(this, OffsetOfElement(i), false);
376 }
377}
378
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800379} // namespace mirror
380} // namespace art
381
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700382#endif // ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_