From a5001fed23788c966fd87048d7f17ba8c0b51914 Mon Sep 17 00:00:00 2001 From: Hans Boehm Date: Fri, 26 Jul 2024 13:09:10 -0700 Subject: Object.clone() allocates more movable objects Make Object.clone() allocate an unmovable object only if the original was specifically allocated as nonmovable. Or at least get much closer to that. In the process, we stop allocated nonmovable objects in LargeObjectsSpace, so that we can better identifty them. Objects in image space cannot have been allocated as nonmovable: newNonMovableArray() involves JNI call, and this will cause a transaction failure. This is good, since the act of including the object in an ImageSpace would move it. The ZygoteSpace is allocated by copying objects into nonmoving space. To avoid having clone() treat the whole ZygoteSpace as nonmovable, we explicitly remember the non-class objects that were already there. Currently we use a std::set data structure for this. This seems a bit suboptimal; a sorted array may be an improvement. But empirically the set only contains a dozen or two elements for AOSP. We do implicitly allocate classes using the nonnmoving allocator. But those cannot be cloned. Thus we do not bother tracking them. For Array::CopyOf, we DCHECK that the argument was movable, and fix one of the callers to fail in a more appropriate way if we would otherwise violate that. Prevent jvmti from resizing a nonmovable array. I don't think anything good could have come of that anyway. This should prevent us from creating unrequested nonmovable objects, except as a result of the CC collector using that as a backup when it otherwise runs out of space during copying. Rename IsMovableObject() to somewhat clarify that it queries an implementation property, where IsNonMovable() is a query about intended object semantics, NOT implementation artifacts. Various drive-by documentation fixes for issues I encountered while trying to understand the code. Bug: 355291033 Bug: 354087169 Test: Build and boot AOSP Change-Id: Ia24dd1c2623d3d588c397332f87be45cc0f4bf27 --- runtime/mirror/object_array-alloc-inl.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'runtime/mirror/object_array-alloc-inl.h') diff --git a/runtime/mirror/object_array-alloc-inl.h b/runtime/mirror/object_array-alloc-inl.h index e79d154f84..d3688762a4 100644 --- a/runtime/mirror/object_array-alloc-inl.h +++ b/runtime/mirror/object_array-alloc-inl.h @@ -66,9 +66,8 @@ inline ObjPtr> ObjectArray::CopyOf(Handle> h_th int32_t new_length) { DCHECK_GE(new_length, 0); gc::Heap* heap = Runtime::Current()->GetHeap(); - gc::AllocatorType allocator_type = heap->IsMovableObject(h_this.Get()) - ? heap->GetCurrentAllocator() - : heap->GetCurrentNonMovingAllocator(); + DCHECK(heap->PossiblyAllocatedMovable(h_this.Get())); + gc::AllocatorType allocator_type = heap->GetCurrentAllocator(); ObjPtr> new_array = Alloc(self, h_this->GetClass(), new_length, allocator_type); if (LIKELY(new_array != nullptr)) { new_array->AssignableMemcpy(0, h_this.Get(), 0, std::min(h_this->GetLength(), new_length)); -- cgit v1.2.3-59-g8ed1b