blob: 57bd191ce2e9b6c38696a6c7e701fce44d35d249 [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
Alex Lighta9bbc082019-11-14 14:51:41 -080020#include "base/globals.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080021#include "object_array.h"
22
Andreas Gampe46ee31b2016-12-14 10:11:49 -080023#include <string>
24
25#include "android-base/stringprintf.h"
26
Ian Rogers7e70b002014-10-08 11:47:24 -070027#include "array-inl.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070028#include "class.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070029#include "obj_ptr-inl.h"
30#include "object-inl.h"
Vladimir Marko557fece2019-03-26 14:29:41 +000031#include "read_barrier-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070032#include "runtime.h"
Andreas Gampe52ecb652018-10-24 15:18:21 -070033#include "thread-current-inl.h"
Mathieu Chartier88ea61e2018-06-20 17:45:41 -070034#include "write_barrier-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080035
36namespace art {
37namespace mirror {
38
Mathieu Chartierfbc31082016-01-24 11:59:56 -080039template<class T> template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Vladimir Marko423bebb2019-03-26 15:17:21 +000040inline ObjPtr<T> ObjectArray<T>::Get(int32_t i) {
Vladimir Marko924ad502018-09-19 09:48:04 +010041 if (!CheckIsValidIndex<kVerifyFlags>(i)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +010042 DCHECK(Thread::Current()->IsExceptionPending());
Mathieu Chartier2cebb242015-04-21 16:50:40 -070043 return nullptr;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080044 }
Mathieu Chartierfbc31082016-01-24 11:59:56 -080045 return GetFieldObject<T, kVerifyFlags, kReadBarrierOption>(OffsetOfElement(i));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080046}
47
Mathieu Chartier4e305412014-02-19 10:54:44 -080048template<class T> template<VerifyObjectFlags kVerifyFlags>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070049inline bool ObjectArray<T>::CheckAssignable(ObjPtr<T> object) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -070050 if (object != nullptr) {
Vladimir Markoc524e9e2019-03-26 10:54:50 +000051 ObjPtr<Class> element_class = GetClass<kVerifyFlags>()->GetComponentType();
Sebastien Hertz6bdd8f42013-05-17 14:44:01 +020052 if (UNLIKELY(!object->InstanceOf(element_class))) {
53 ThrowArrayStoreException(object);
54 return false;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080055 }
Sebastien Hertz6bdd8f42013-05-17 14:44:01 +020056 }
57 return true;
58}
59
60template<class T>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070061inline void ObjectArray<T>::Set(int32_t i, ObjPtr<T> object) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010062 if (Runtime::Current()->IsActiveTransaction()) {
63 Set<true>(i, object);
64 } else {
65 Set<false>(i, object);
66 }
67}
68
69template<class T>
Mathieu Chartier4e305412014-02-19 10:54:44 -080070template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070071inline void ObjectArray<T>::Set(int32_t i, ObjPtr<T> object) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070072 if (CheckIsValidIndex(i) && CheckAssignable<kVerifyFlags>(object)) {
73 SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags>(OffsetOfElement(i), object);
Sebastien Hertz6bdd8f42013-05-17 14:44:01 +020074 } else {
75 DCHECK(Thread::Current()->IsExceptionPending());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080076 }
77}
78
79template<class T>
Mathieu Chartier4e305412014-02-19 10:54:44 -080080template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070081inline void ObjectArray<T>::SetWithoutChecks(int32_t i, ObjPtr<T> object) {
Mathieu Chartier4e305412014-02-19 10:54:44 -080082 DCHECK(CheckIsValidIndex<kVerifyFlags>(i));
83 DCHECK(CheckAssignable<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(object));
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070084 SetFieldObject<kTransactionActive, kCheckTransaction, kVerifyFlags>(OffsetOfElement(i), object);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080085}
86
87template<class T>
Mathieu Chartier4e305412014-02-19 10:54:44 -080088template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -070089inline void ObjectArray<T>::SetWithoutChecksAndWriteBarrier(int32_t i, ObjPtr<T> object) {
Mathieu Chartier4e305412014-02-19 10:54:44 -080090 DCHECK(CheckIsValidIndex<kVerifyFlags>(i));
Ian Rogersef7d42f2014-01-06 12:55:46 -080091 // TODO: enable this check. It fails when writing the image in ImageWriter::FixupObjectArray.
Sebastien Hertzabff6432014-01-27 18:01:39 +010092 // DCHECK(CheckAssignable(object));
Mathieu Chartier4e305412014-02-19 10:54:44 -080093 SetFieldObjectWithoutWriteBarrier<kTransactionActive, kCheckTransaction, kVerifyFlags>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070094 OffsetOfElement(i), object);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080095}
96
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -080097template<class T> template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
Vladimir Marko423bebb2019-03-26 15:17:21 +000098inline ObjPtr<T> ObjectArray<T>::GetWithoutChecks(int32_t i) {
Sebastien Hertzabff6432014-01-27 18:01:39 +010099 DCHECK(CheckIsValidIndex(i));
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800100 return GetFieldObject<T, kVerifyFlags, kReadBarrierOption>(OffsetOfElement(i));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800101}
102
103template<class T>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700104inline void ObjectArray<T>::AssignableMemmove(int32_t dst_pos,
105 ObjPtr<ObjectArray<T>> src,
106 int32_t src_pos,
107 int32_t count) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800108 if (kIsDebugBuild) {
109 for (int i = 0; i < count; ++i) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700110 // The get will perform the VerifyObject.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800111 src->GetWithoutChecks(src_pos + i);
112 }
113 }
114 // Perform the memmove using int memmove then perform the write barrier.
Roland Levillain33d69032015-06-18 18:20:59 +0100115 static_assert(sizeof(HeapReference<T>) == sizeof(uint32_t),
116 "art::mirror::HeapReference<T> and uint32_t have different sizes.");
Mathieu Chartierfec13d42016-10-07 12:59:33 -0700117 // TODO: Optimize this later?
118 // We can't use memmove since it does not handle read barriers and may do by per byte copying.
119 // See b/32012820.
120 const bool copy_forward = (src != this) || (dst_pos < src_pos) || (dst_pos - src_pos >= count);
121 if (copy_forward) {
122 // Forward copy.
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800123 bool baker_non_gray_case = false;
124 if (kUseReadBarrier && kUseBakerReadBarrier) {
125 uintptr_t fake_address_dependency;
126 if (!ReadBarrier::IsGray(src.Ptr(), &fake_address_dependency)) {
127 baker_non_gray_case = true;
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800128 DCHECK_EQ(fake_address_dependency, 0U);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800129 src.Assign(reinterpret_cast<ObjectArray<T>*>(
130 reinterpret_cast<uintptr_t>(src.Ptr()) | fake_address_dependency));
131 for (int i = 0; i < count; ++i) {
132 // We can skip the RB here because 'src' isn't gray.
Vladimir Marko423bebb2019-03-26 15:17:21 +0000133 ObjPtr<T> obj = src->template GetWithoutChecks<kDefaultVerifyFlags, kWithoutReadBarrier>(
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800134 src_pos + i);
135 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
136 }
137 }
138 }
139 if (!baker_non_gray_case) {
140 for (int i = 0; i < count; ++i) {
141 // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
Vladimir Marko423bebb2019-03-26 15:17:21 +0000142 ObjPtr<T> obj = src->GetWithoutChecks(src_pos + i);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800143 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
144 }
Hiroshi Yamauchi79719282014-04-10 12:46:22 -0700145 }
146 } else {
Mathieu Chartierfec13d42016-10-07 12:59:33 -0700147 // Backward copy.
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800148 bool baker_non_gray_case = false;
149 if (kUseReadBarrier && kUseBakerReadBarrier) {
150 uintptr_t fake_address_dependency;
151 if (!ReadBarrier::IsGray(src.Ptr(), &fake_address_dependency)) {
152 baker_non_gray_case = true;
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800153 DCHECK_EQ(fake_address_dependency, 0U);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800154 src.Assign(reinterpret_cast<ObjectArray<T>*>(
155 reinterpret_cast<uintptr_t>(src.Ptr()) | fake_address_dependency));
156 for (int i = count - 1; i >= 0; --i) {
157 // We can skip the RB here because 'src' isn't gray.
Vladimir Marko423bebb2019-03-26 15:17:21 +0000158 ObjPtr<T> obj = src->template GetWithoutChecks<kDefaultVerifyFlags, kWithoutReadBarrier>(
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800159 src_pos + i);
160 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
161 }
162 }
163 }
164 if (!baker_non_gray_case) {
165 for (int i = count - 1; i >= 0; --i) {
166 // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
Vladimir Marko423bebb2019-03-26 15:17:21 +0000167 ObjPtr<T> obj = src->GetWithoutChecks(src_pos + i);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800168 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
169 }
Mathieu Chartierfec13d42016-10-07 12:59:33 -0700170 }
Hiroshi Yamauchi79719282014-04-10 12:46:22 -0700171 }
Mathieu Chartier88ea61e2018-06-20 17:45:41 -0700172 WriteBarrier::ForArrayWrite(this, dst_pos, count);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800173 if (kIsDebugBuild) {
174 for (int i = 0; i < count; ++i) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700175 // The get will perform the VerifyObject.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800176 GetWithoutChecks(dst_pos + i);
177 }
178 }
179}
180
181template<class T>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700182inline void ObjectArray<T>::AssignableMemcpy(int32_t dst_pos,
183 ObjPtr<ObjectArray<T>> src,
184 int32_t src_pos,
185 int32_t count) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800186 if (kIsDebugBuild) {
187 for (int i = 0; i < count; ++i) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700188 // The get will perform the VerifyObject.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800189 src->GetWithoutChecks(src_pos + i);
190 }
191 }
192 // Perform the memmove using int memcpy then perform the write barrier.
Roland Levillain33d69032015-06-18 18:20:59 +0100193 static_assert(sizeof(HeapReference<T>) == sizeof(uint32_t),
194 "art::mirror::HeapReference<T> and uint32_t have different sizes.");
Mathieu Chartierfec13d42016-10-07 12:59:33 -0700195 // TODO: Optimize this later?
196 // We can't use memmove since it does not handle read barriers and may do by per byte copying.
197 // See b/32012820.
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800198 bool baker_non_gray_case = false;
199 if (kUseReadBarrier && kUseBakerReadBarrier) {
200 uintptr_t fake_address_dependency;
201 if (!ReadBarrier::IsGray(src.Ptr(), &fake_address_dependency)) {
202 baker_non_gray_case = true;
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800203 DCHECK_EQ(fake_address_dependency, 0U);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800204 src.Assign(reinterpret_cast<ObjectArray<T>*>(
205 reinterpret_cast<uintptr_t>(src.Ptr()) | fake_address_dependency));
206 for (int i = 0; i < count; ++i) {
207 // We can skip the RB here because 'src' isn't gray.
Vladimir Marko423bebb2019-03-26 15:17:21 +0000208 ObjPtr<Object> obj =
209 src->template GetWithoutChecks<kDefaultVerifyFlags, kWithoutReadBarrier>(src_pos + i);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800210 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
211 }
212 }
213 }
214 if (!baker_non_gray_case) {
215 for (int i = 0; i < count; ++i) {
216 // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
Vladimir Marko423bebb2019-03-26 15:17:21 +0000217 ObjPtr<T> obj = src->GetWithoutChecks(src_pos + i);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800218 SetWithoutChecksAndWriteBarrier<false>(dst_pos + i, obj);
219 }
Hiroshi Yamauchi79719282014-04-10 12:46:22 -0700220 }
Mathieu Chartier88ea61e2018-06-20 17:45:41 -0700221 WriteBarrier::ForArrayWrite(this, dst_pos, count);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800222 if (kIsDebugBuild) {
223 for (int i = 0; i < count; ++i) {
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700224 // The get will perform the VerifyObject.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800225 GetWithoutChecks(dst_pos + i);
226 }
227 }
228}
229
230template<class T>
Andreas Gampe85a098a2016-03-31 13:30:53 -0700231template<bool kTransactionActive>
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700232inline void ObjectArray<T>::AssignableCheckingMemcpy(int32_t dst_pos,
233 ObjPtr<ObjectArray<T>> src,
234 int32_t src_pos,
235 int32_t count,
Ian Rogersef7d42f2014-01-06 12:55:46 -0800236 bool throw_exception) {
237 DCHECK_NE(this, src)
238 << "This case should be handled with memmove that handles overlaps correctly";
239 // We want to avoid redundant IsAssignableFrom checks where possible, so we cache a class that
240 // we know is assignable to the destination array's component type.
Vladimir Markoc524e9e2019-03-26 10:54:50 +0000241 ObjPtr<Class> dst_class = GetClass()->GetComponentType();
242 ObjPtr<Class> lastAssignableElementClass = dst_class;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800243
Vladimir Markoc524e9e2019-03-26 10:54:50 +0000244 ObjPtr<T> o = nullptr;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800245 int i = 0;
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800246 bool baker_non_gray_case = false;
247 if (kUseReadBarrier && kUseBakerReadBarrier) {
248 uintptr_t fake_address_dependency;
249 if (!ReadBarrier::IsGray(src.Ptr(), &fake_address_dependency)) {
250 baker_non_gray_case = true;
Hiroshi Yamauchi6013f772016-11-16 13:30:17 -0800251 DCHECK_EQ(fake_address_dependency, 0U);
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800252 src.Assign(reinterpret_cast<ObjectArray<T>*>(
253 reinterpret_cast<uintptr_t>(src.Ptr()) | fake_address_dependency));
254 for (; i < count; ++i) {
255 // The follow get operations force the objects to be verified.
256 // We can skip the RB here because 'src' isn't gray.
257 o = src->template GetWithoutChecks<kDefaultVerifyFlags, kWithoutReadBarrier>(
258 src_pos + i);
259 if (o == nullptr) {
260 // Null is always assignable.
261 SetWithoutChecks<kTransactionActive>(dst_pos + i, nullptr);
262 } else {
263 // TODO: use the underlying class reference to avoid uncompression when not necessary.
Vladimir Markoc524e9e2019-03-26 10:54:50 +0000264 ObjPtr<Class> o_class = o->GetClass();
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800265 if (LIKELY(lastAssignableElementClass == o_class)) {
266 SetWithoutChecks<kTransactionActive>(dst_pos + i, o);
267 } else if (LIKELY(dst_class->IsAssignableFrom(o_class))) {
268 lastAssignableElementClass = o_class;
269 SetWithoutChecks<kTransactionActive>(dst_pos + i, o);
270 } else {
271 // Can't put this element into the array, break to perform write-barrier and throw
272 // exception.
273 break;
274 }
275 }
276 }
277 }
278 }
279 if (!baker_non_gray_case) {
280 for (; i < count; ++i) {
281 // The follow get operations force the objects to be verified.
282 // We need a RB here. ObjectArray::GetWithoutChecks() contains a RB.
283 o = src->GetWithoutChecks(src_pos + i);
284 if (o == nullptr) {
285 // Null is always assignable.
286 SetWithoutChecks<kTransactionActive>(dst_pos + i, nullptr);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800287 } else {
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800288 // TODO: use the underlying class reference to avoid uncompression when not necessary.
Vladimir Markodfc0de72019-04-01 10:57:55 +0100289 ObjPtr<Class> o_class = o->GetClass();
Hiroshi Yamauchie43b80e2016-11-14 13:42:50 -0800290 if (LIKELY(lastAssignableElementClass == o_class)) {
291 SetWithoutChecks<kTransactionActive>(dst_pos + i, o);
292 } else if (LIKELY(dst_class->IsAssignableFrom(o_class))) {
293 lastAssignableElementClass = o_class;
294 SetWithoutChecks<kTransactionActive>(dst_pos + i, o);
295 } else {
296 // Can't put this element into the array, break to perform write-barrier and throw
297 // exception.
298 break;
299 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800300 }
301 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800302 }
Mathieu Chartier88ea61e2018-06-20 17:45:41 -0700303 WriteBarrier::ForArrayWrite(this, dst_pos, count);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800304 if (UNLIKELY(i != count)) {
David Sehr709b0702016-10-13 09:12:37 -0700305 std::string actualSrcType(mirror::Object::PrettyTypeOf(o));
306 std::string dstType(PrettyTypeOf());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800307 Thread* self = Thread::Current();
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800308 std::string msg = android::base::StringPrintf(
309 "source[%d] of type %s cannot be stored in destination array of type %s",
310 src_pos + i,
311 actualSrcType.c_str(),
312 dstType.c_str());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800313 if (throw_exception) {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800314 self->ThrowNewException("Ljava/lang/ArrayStoreException;", msg.c_str());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800315 } else {
Andreas Gampe46ee31b2016-12-14 10:11:49 -0800316 LOG(FATAL) << msg;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800317 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800318 }
319}
320
321template<class T>
Ian Rogersef7d42f2014-01-06 12:55:46 -0800322inline MemberOffset ObjectArray<T>::OffsetOfElement(int32_t i) {
Mathieu Chartier1a5337f2016-10-13 13:48:23 -0700323 return MemberOffset(DataOffset(kHeapReferenceSize).Int32Value() + (i * kHeapReferenceSize));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800324}
325
Mathieu Chartier059ef3d2015-08-18 13:54:21 -0700326template<class T> template<typename Visitor>
Hiroshi Yamauchi723e6ce2015-10-28 20:59:47 -0700327inline void ObjectArray<T>::VisitReferences(const Visitor& visitor) {
Mathieu Chartier407f7022014-02-18 14:37:05 -0800328 const size_t length = static_cast<size_t>(GetLength());
329 for (size_t i = 0; i < length; ++i) {
330 visitor(this, OffsetOfElement(i), false);
331 }
332}
333
Alex Lighta9bbc082019-11-14 14:51:41 -0800334template <class T>
335inline ConstObjPtrArrayIter<T> ObjectArray<T>::cbegin() const {
336 return ConstObjPtrArrayIter<T>(this, 0);
337}
338template <class T>
339inline ConstObjPtrArrayIter<T> ObjectArray<T>::cend() const {
340 return ConstObjPtrArrayIter<T>(this, GetLength());
341}
342template <class T>
343inline ConstHandleArrayIter<T> ObjectArray<T>::cbegin(const Handle<ObjectArray<T>>& h_this) {
344 return ConstHandleArrayIter<T>(h_this, 0);
345}
346template <class T>
347inline ConstHandleArrayIter<T> ObjectArray<T>::cend(const Handle<ObjectArray<T>>& h_this) {
348 return ConstHandleArrayIter<T>(h_this, h_this->GetLength());
349}
350
351template <class T>
352inline ObjPtrArrayIter<T> ObjectArray<T>::begin() {
353 return ObjPtrArrayIter<T>(this, 0);
354}
355template <class T>
356inline ObjPtrArrayIter<T> ObjectArray<T>::end() {
357 return ObjPtrArrayIter<T>(this, GetLength());
358}
359template <class T>
360inline HandleArrayIter<T> ObjectArray<T>::begin(Handle<ObjectArray<T>>& h_this) {
361 return HandleArrayIter<T>(h_this, 0);
362}
363template <class T>
364inline HandleArrayIter<T> ObjectArray<T>::end(Handle<ObjectArray<T>>& h_this) {
365 return HandleArrayIter<T>(h_this, h_this->GetLength());
366}
367
368template<typename T, typename C>
369inline void ArrayIter<T, C>::CheckIdx() const {
370 if (kIsDebugBuild) {
371 Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
372 }
373 DCHECK_LE(0, idx_);
374 DCHECK_LE(idx_, array_->GetLength());
375}
376
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800377} // namespace mirror
378} // namespace art
379
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700380#endif // ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_