diff options
author | 2023-11-09 12:14:07 +0000 | |
---|---|---|
committer | 2023-11-10 11:37:51 +0000 | |
commit | 87fb6c91839b094d5937e79023d9204d37f46d2d (patch) | |
tree | d1c541bb108fd252b99038d7eaa57ea7bee998b5 /compiler/optimizing/intrinsics.cc | |
parent | 039154ecfaea7f7e61ba2bbcee8c0d77a57cd47d (diff) |
Introduce boxed primitive caches in WellKnownClasses.
Test: test.py
Change-Id: Ia8d2f03dea8dd01eeb337d4bc2e31c778b9543a2
Diffstat (limited to 'compiler/optimizing/intrinsics.cc')
-rw-r--r-- | compiler/optimizing/intrinsics.cc | 78 |
1 files changed, 22 insertions, 56 deletions
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index b3615e6110..0849c4fa89 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -32,7 +32,7 @@ #include "obj_ptr-inl.h" #include "scoped_thread_state_change-inl.h" #include "thread-current-inl.h" -#include "well_known_classes.h" +#include "well_known_classes-inl.h" namespace art HIDDEN { @@ -53,7 +53,6 @@ std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) { static const char kIntegerCacheDescriptor[] = "Ljava/lang/Integer$IntegerCache;"; static const char kIntegerDescriptor[] = "Ljava/lang/Integer;"; -static const char kIntegerArrayDescriptor[] = "[Ljava/lang/Integer;"; static const char kLowFieldName[] = "low"; static const char kHighFieldName[] = "high"; static const char kValueFieldName[] = "value"; @@ -72,21 +71,9 @@ static ObjPtr<mirror::ObjectArray<mirror::Object>> GetBootImageLiveObjects() return boot_image_live_objects; } -static ObjPtr<mirror::Class> LookupInitializedClass(Thread* self, - ClassLinker* class_linker, - const char* descriptor) - REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Class> klass = - class_linker->LookupClass(self, descriptor, /* class_loader= */ nullptr); - DCHECK(klass != nullptr); - DCHECK(klass->IsInitialized()); - return klass; -} - static ObjPtr<mirror::ObjectArray<mirror::Object>> GetIntegerCacheArray( ObjPtr<mirror::Class> cache_class) REQUIRES_SHARED(Locks::mutator_lock_) { - ArtField* cache_field = cache_class->FindDeclaredStaticField("cache", kIntegerArrayDescriptor); - DCHECK(cache_field != nullptr); + ArtField* cache_field = WellKnownClasses::java_lang_Integer_IntegerCache_cache; return ObjPtr<mirror::ObjectArray<mirror::Object>>::DownCast(cache_field->GetObject(cache_class)); } @@ -97,19 +84,17 @@ static int32_t GetIntegerCacheField(ObjPtr<mirror::Class> cache_class, const cha return field->GetInt(cache_class); } -static bool CheckIntegerCache(Thread* self, - ClassLinker* class_linker, - ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects, +static bool CheckIntegerCache(ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects, ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_cache) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(boot_image_cache != nullptr); // Since we have a cache in the boot image, both java.lang.Integer and // java.lang.Integer$IntegerCache must be initialized in the boot image. - ObjPtr<mirror::Class> cache_class = - LookupInitializedClass(self, class_linker, kIntegerCacheDescriptor); - ObjPtr<mirror::Class> integer_class = - LookupInitializedClass(self, class_linker, kIntegerDescriptor); + ObjPtr<mirror::Class> cache_class = WellKnownClasses::java_lang_Integer_IntegerCache.Get(); + DCHECK(cache_class->IsInitialized()); + ObjPtr<mirror::Class> integer_class = WellKnownClasses::java_lang_Integer.Get(); + DCHECK(integer_class->IsInitialized()); // Check that the current cache is the same as the `boot_image_cache`. ObjPtr<mirror::ObjectArray<mirror::Object>> current_cache = GetIntegerCacheArray(cache_class); @@ -176,23 +161,11 @@ void IntrinsicVisitor::ComputeIntegerValueOfLocations(HInvoke* invoke, !compiler_options.IsImageClass(kIntegerDescriptor)) { return; } - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - Thread* self = Thread::Current(); - ScopedObjectAccess soa(self); - ObjPtr<mirror::Class> cache_class = class_linker->LookupClass( - self, kIntegerCacheDescriptor, /* class_loader= */ nullptr); - DCHECK(cache_class != nullptr); - if (UNLIKELY(!cache_class->IsInitialized())) { - LOG(WARNING) << "Image class " << cache_class->PrettyDescriptor() << " is uninitialized."; - return; - } - ObjPtr<mirror::Class> integer_class = - class_linker->LookupClass(self, kIntegerDescriptor, /* class_loader= */ nullptr); - DCHECK(integer_class != nullptr); - if (UNLIKELY(!integer_class->IsInitialized())) { - LOG(WARNING) << "Image class " << integer_class->PrettyDescriptor() << " is uninitialized."; - return; - } + ScopedObjectAccess soa(Thread::Current()); + ObjPtr<mirror::Class> cache_class = WellKnownClasses::java_lang_Integer_IntegerCache.Get(); + DCHECK(cache_class->IsInitialized()); + ObjPtr<mirror::Class> integer_class = WellKnownClasses::java_lang_Integer.Get(); + DCHECK(integer_class->IsInitialized()); int32_t low = GetIntegerCacheField(cache_class, kLowFieldName); int32_t high = GetIntegerCacheField(cache_class, kHighFieldName); if (kIsDebugBuild) { @@ -216,9 +189,7 @@ void IntrinsicVisitor::ComputeIntegerValueOfLocations(HInvoke* invoke, } } } else { - Runtime* runtime = Runtime::Current(); - Thread* self = Thread::Current(); - ScopedObjectAccess soa(self); + ScopedObjectAccess soa(Thread::Current()); ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects = GetBootImageLiveObjects(); ObjPtr<mirror::ObjectArray<mirror::Object>> cache = IntrinsicObjects::GetIntegerValueOfCache(boot_image_live_objects); @@ -226,12 +197,12 @@ void IntrinsicVisitor::ComputeIntegerValueOfLocations(HInvoke* invoke, return; // No cache in the boot image. } if (compiler_options.IsJitCompiler()) { - if (!CheckIntegerCache(self, runtime->GetClassLinker(), boot_image_live_objects, cache)) { + if (!CheckIntegerCache(boot_image_live_objects, cache)) { return; // The cache was somehow messed up, probably by using reflection. } } else { DCHECK(compiler_options.IsAotCompiler()); - DCHECK(CheckIntegerCache(self, runtime->GetClassLinker(), boot_image_live_objects, cache)); + DCHECK(CheckIntegerCache(boot_image_live_objects, cache)); if (input->IsIntConstant()) { int32_t value = input->AsIntConstant()->GetValue(); // Retrieve the `value` from the lowest cached Integer. @@ -264,10 +235,9 @@ void IntrinsicVisitor::ComputeIntegerValueOfLocations(HInvoke* invoke, } } -static int32_t GetIntegerCacheLowFromIntegerCache(Thread* self, ClassLinker* class_linker) - REQUIRES_SHARED(Locks::mutator_lock_) { - ObjPtr<mirror::Class> cache_class = - LookupInitializedClass(self, class_linker, kIntegerCacheDescriptor); +static int32_t GetIntegerCacheLowFromIntegerCache() REQUIRES_SHARED(Locks::mutator_lock_) { + ObjPtr<mirror::Class> cache_class = WellKnownClasses::java_lang_Integer_IntegerCache.Get(); + DCHECK(cache_class->IsInitialized()); return GetIntegerCacheField(cache_class, kLowFieldName); } @@ -289,10 +259,7 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo // we need to provide data that shall not lead to a crash even if the fields were // modified through reflection since ComputeIntegerValueOfLocations() when JITting. - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - Thread* self = Thread::Current(); - ScopedObjectAccess soa(self); - + ScopedObjectAccess soa(Thread::Current()); IntegerValueOfInfo info; if (compiler_options.IsBootImage()) { ObjPtr<mirror::Class> integer_class = invoke->GetResolvedMethod()->GetDeclaringClass(); @@ -300,8 +267,7 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo ArtField* value_field = integer_class->FindDeclaredInstanceField(kValueFieldName, "I"); DCHECK(value_field != nullptr); info.value_offset = value_field->GetOffset().Uint32Value(); - ObjPtr<mirror::Class> cache_class = - LookupInitializedClass(self, class_linker, kIntegerCacheDescriptor); + ObjPtr<mirror::Class> cache_class = WellKnownClasses::java_lang_Integer_IntegerCache.Get(); info.low = GetIntegerCacheField(cache_class, kLowFieldName); int32_t high = GetIntegerCacheField(cache_class, kHighFieldName); info.length = dchecked_integral_cast<uint32_t>(high - info.low + 1); @@ -331,11 +297,11 @@ IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo if (compiler_options.IsJitCompiler()) { // Use the current `IntegerCache.low` for JIT to avoid truly surprising behavior if the // code messes up the `value` field in the lowest cached Integer using reflection. - info.low = GetIntegerCacheLowFromIntegerCache(self, class_linker); + info.low = GetIntegerCacheLowFromIntegerCache(); } else { // For app AOT, the `low_integer->value` should be the same as `IntegerCache.low`. info.low = value_field->GetInt(low_integer); - DCHECK_EQ(info.low, GetIntegerCacheLowFromIntegerCache(self, class_linker)); + DCHECK_EQ(info.low, GetIntegerCacheLowFromIntegerCache()); } // Do not look at `IntegerCache.high`, use the immutable length of the cache array instead. info.length = dchecked_integral_cast<uint32_t>( |