summaryrefslogtreecommitdiff
path: root/runtime/mirror/array-inl.h
diff options
context:
space:
mode:
author Lokesh Gidra <lokeshgidra@google.com> 2023-05-02 19:14:55 +0000
committer Lokesh Gidra <lokeshgidra@google.com> 2023-05-02 19:24:56 +0000
commitfa358c4160debc3620ddc95cb6630e446cb343ac (patch)
tree5ac9a9ecabb8f9ec21cad8c522d18871cb4f430c /runtime/mirror/array-inl.h
parent60fdcb2b277e878eb3b2326ec516fe5d3d801174 (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.h12
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)>();