summaryrefslogtreecommitdiff
path: root/runtime/mirror/array-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mirror/array-inl.h')
-rw-r--r--runtime/mirror/array-inl.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index 7f974d0cf0..bc8d34815f 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -40,6 +40,16 @@ inline size_t Array::SizeOf() {
return header_size + data_size;
}
+template<VerifyObjectFlags kVerifyFlags>
+inline bool Array::CheckIsValidIndex(int32_t index) {
+ if (UNLIKELY(static_cast<uint32_t>(index) >=
+ static_cast<uint32_t>(GetLength<kVerifyFlags>()))) {
+ ThrowArrayIndexOutOfBoundsException(index);
+ return false;
+ }
+ return true;
+}
+
static inline size_t ComputeArraySize(Thread* self, Class* array_class, int32_t component_count,
size_t component_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -164,6 +174,46 @@ inline PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length)
return down_cast<PrimitiveArray<T>*>(raw_array);
}
+template<typename T>
+inline T PrimitiveArray<T>::Get(int32_t i) {
+ if (!CheckIsValidIndex(i)) {
+ DCHECK(Thread::Current()->IsExceptionPending());
+ return T(0);
+ }
+ return GetWithoutChecks(i);
+}
+
+template<typename T>
+inline void PrimitiveArray<T>::Set(int32_t i, T value) {
+ if (Runtime::Current()->IsActiveTransaction()) {
+ Set<true>(i, value);
+ } else {
+ Set<false>(i, value);
+ }
+}
+
+template<typename T>
+template<bool kTransactionActive, bool kCheckTransaction>
+inline void PrimitiveArray<T>::Set(int32_t i, T value) {
+ if (CheckIsValidIndex(i)) {
+ SetWithoutChecks<kTransactionActive, kCheckTransaction>(i, value);
+ } else {
+ DCHECK(Thread::Current()->IsExceptionPending());
+ }
+}
+
+template<typename T>
+template<bool kTransactionActive, bool kCheckTransaction>
+inline void PrimitiveArray<T>::SetWithoutChecks(int32_t i, T value) {
+ if (kCheckTransaction) {
+ DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
+ }
+ if (kTransactionActive) {
+ Runtime::Current()->RecordWriteArray(this, i, GetWithoutChecks(i));
+ }
+ DCHECK(CheckIsValidIndex(i));
+ GetData()[i] = value;
+}
// Backward copy where elements are of aligned appropriately for T. Count is in T sized units.
// Copies are guaranteed not to tear when the sizeof T is less-than 64bit.
template<typename T>