diff options
author | 2023-05-02 19:14:55 +0000 | |
---|---|---|
committer | 2023-05-02 19:24:56 +0000 | |
commit | fa358c4160debc3620ddc95cb6630e446cb343ac (patch) | |
tree | 5ac9a9ecabb8f9ec21cad8c522d18871cb4f430c /runtime/mirror/array-inl.h | |
parent | 60fdcb2b277e878eb3b2326ec516fe5d3d801174 (diff) |
Don't access component_type_ for obj-array's SizeOf
For object arrays the component-type class could be allocated in the
higher address than the object array. This causes problems in
userfaultfd GC as it frees from-space pages as the compaction
progresses.
Fortunately, for object arrays we recognize them using the class-flags
and therefore when calling SizeOf() on it in VisitRefsForCompaction(),
we can calculate component-size-shift without accessing component-type
class. For primitive object arrays it's not a problem as the
component-type class is either in boot/zygote images or in lower address
in the moving space.
Bug: 160737021
Bug: 272272332
Bug: 274327217
Test: install module and check of tombstones/ANR due to NPE in GC thread
Change-Id: Ic657ec95aed8b3642c62b82945ffabf947ee5ad7
Diffstat (limited to 'runtime/mirror/array-inl.h')
-rw-r--r-- | runtime/mirror/array-inl.h | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index 2bdf8277cd..8f81ae5c1a 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -36,11 +36,15 @@ inline uint32_t Array::ClassSize(PointerSize pointer_size) { return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size); } -template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption> +template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption, bool kIsObjArray> inline size_t Array::SizeOf() { - size_t component_size_shift = - GetClass<kVerifyFlags, kReadBarrierOption>() - ->template GetComponentSizeShift<kReadBarrierOption>(); + // When we are certain that this is a object array, then don't fetch shift + // from component_type_ as that doesn't work well with userfaultfd GC as the + // component-type class may be allocated at a higher address than the array. + size_t component_size_shift = kIsObjArray ? + Primitive::ComponentSizeShift(Primitive::kPrimNot) : + GetClass<kVerifyFlags, kReadBarrierOption>() + ->template GetComponentSizeShift<kReadBarrierOption>(); // Don't need to check this since we already check this in GetClass. int32_t component_count = GetLength<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>(); |