From 024d69fb9936ca5a0031d35c9f248853cbc25d3f Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Thu, 13 Jun 2019 10:52:32 +0100 Subject: Use cleared JNI weak sentinel from boot image. We were already adding the sentinel to the boot image, so we may as well reuse the boot image copy. Also move pre-allocated objects from class roots to the boot image live objects. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: aosp_taimen-userdebug boots. Change-Id: I635dcdd146ca2c6b55d187e9a545a9990b0b35ca --- compiler/optimizing/intrinsic_objects.cc | 67 +++++++++++--------------------- 1 file changed, 22 insertions(+), 45 deletions(-) (limited to 'compiler/optimizing/intrinsic_objects.cc') diff --git a/compiler/optimizing/intrinsic_objects.cc b/compiler/optimizing/intrinsic_objects.cc index c345624a7a..5f6f562161 100644 --- a/compiler/optimizing/intrinsic_objects.cc +++ b/compiler/optimizing/intrinsic_objects.cc @@ -17,18 +17,18 @@ #include "intrinsic_objects.h" #include "art_field-inl.h" +#include "base/casts.h" #include "base/logging.h" -#include "class_root.h" -#include "handle.h" +#include "image.h" #include "obj_ptr-inl.h" -#include "mirror/object_array-alloc-inl.h" -#include "mirror/object_array-inl.h" namespace art { -static ObjPtr> LookupIntegerCache(Thread* self, - ClassLinker* class_linker) - REQUIRES_SHARED(Locks::mutator_lock_) { +static constexpr size_t kIntrinsicObjectsOffset = + enum_cast(ImageHeader::kIntrinsicObjectsStart); + +ObjPtr> IntrinsicObjects::LookupIntegerCache( + Thread* self, ClassLinker* class_linker) { ObjPtr integer_cache_class = class_linker->LookupClass( self, "Ljava/lang/Integer$IntegerCache;", /* class_loader= */ nullptr); if (integer_cache_class == nullptr || !integer_cache_class->IsInitialized()) { @@ -44,47 +44,24 @@ static ObjPtr> LookupIntegerCache(Thread* se return integer_cache; } -ObjPtr> IntrinsicObjects::AllocateBootImageLiveObjects( - Thread* self, - ClassLinker* class_linker) REQUIRES_SHARED(Locks::mutator_lock_) { - // The objects used for the Integer.valueOf() intrinsic must remain live even if references - // to them are removed using reflection. Image roots are not accessible through reflection, - // so the array we construct here shall keep them alive. - StackHandleScope<1> hs(self); - Handle> integer_cache = - hs.NewHandle(LookupIntegerCache(self, class_linker)); - size_t live_objects_size = - (integer_cache != nullptr) ? (/* cache */ 1u + integer_cache->GetLength()) : 0u; - ObjPtr> live_objects = - mirror::ObjectArray::Alloc( - self, GetClassRoot>(class_linker), live_objects_size); - int32_t index = 0; - if (integer_cache != nullptr) { - live_objects->Set(index++, integer_cache.Get()); - for (int32_t i = 0, length = integer_cache->GetLength(); i != length; ++i) { - live_objects->Set(index++, integer_cache->Get(i)); - } - } - CHECK_EQ(index, live_objects->GetLength()); - - if (kIsDebugBuild && integer_cache != nullptr) { - CHECK_EQ(integer_cache.Get(), GetIntegerValueOfCache(live_objects)); - for (int32_t i = 0, len = integer_cache->GetLength(); i != len; ++i) { - CHECK_EQ(integer_cache->GetWithoutChecks(i), GetIntegerValueOfObject(live_objects, i)); - } - } - return live_objects; +static bool HasIntrinsicObjects( + ObjPtr> boot_image_live_objects) + REQUIRES_SHARED(Locks::mutator_lock_) { + DCHECK(boot_image_live_objects != nullptr); + uint32_t length = static_cast(boot_image_live_objects->GetLength()); + DCHECK_GE(length, kIntrinsicObjectsOffset); + return length != kIntrinsicObjectsOffset; } ObjPtr> IntrinsicObjects::GetIntegerValueOfCache( ObjPtr> boot_image_live_objects) { - DCHECK(boot_image_live_objects != nullptr); - if (boot_image_live_objects->GetLength() == 0u) { + if (!HasIntrinsicObjects(boot_image_live_objects)) { return nullptr; // No intrinsic objects. } // No need for read barrier for boot image object or for verifying the value that was just stored. ObjPtr result = - boot_image_live_objects->GetWithoutChecks(0); + boot_image_live_objects->GetWithoutChecks( + kIntrinsicObjectsOffset); DCHECK(result != nullptr); DCHECK(result->IsObjectArray()); DCHECK(result->GetClass()->DescriptorEquals("[Ljava/lang/Integer;")); @@ -94,15 +71,14 @@ ObjPtr> IntrinsicObjects::GetIntegerValueOfC ObjPtr IntrinsicObjects::GetIntegerValueOfObject( ObjPtr> boot_image_live_objects, uint32_t index) { - DCHECK(boot_image_live_objects != nullptr); - DCHECK_NE(boot_image_live_objects->GetLength(), 0); + DCHECK(HasIntrinsicObjects(boot_image_live_objects)); DCHECK_LT(index, static_cast(GetIntegerValueOfCache(boot_image_live_objects)->GetLength())); // No need for read barrier for boot image object or for verifying the value that was just stored. ObjPtr result = boot_image_live_objects->GetWithoutChecks( - /* skip the IntegerCache.cache */ 1u + index); + kIntrinsicObjectsOffset + /* skip the IntegerCache.cache */ 1u + index); DCHECK(result != nullptr); DCHECK(result->GetClass()->DescriptorEquals("Ljava/lang/Integer;")); return result; @@ -110,8 +86,9 @@ ObjPtr IntrinsicObjects::GetIntegerValueOfObject( MemberOffset IntrinsicObjects::GetIntegerValueOfArrayDataOffset( ObjPtr> boot_image_live_objects) { - DCHECK_NE(boot_image_live_objects->GetLength(), 0); - MemberOffset result = mirror::ObjectArray::OffsetOfElement(1u); + DCHECK(HasIntrinsicObjects(boot_image_live_objects)); + MemberOffset result = + mirror::ObjectArray::OffsetOfElement(kIntrinsicObjectsOffset + 1u); DCHECK_EQ(GetIntegerValueOfObject(boot_image_live_objects, 0u), (boot_image_live_objects ->GetFieldObject(result))); -- cgit v1.2.3-59-g8ed1b