From c37e3a0a532fb89b62753d0478c1ba3c9fc87bb3 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Tue, 22 Mar 2022 15:44:57 +0000 Subject: Add clinit checks at entry for some boot image methods. Look at the list of preloaded classes to know whether the class will be initialized. If it's not in the list, add explicit clinit checks at entry. Update FixupStaticTrampolines to only update the entrypoint if it is the resolution stub. This adds two pages to current on-device boot classpath oat files. Test: imgdiag Bug: 162110941 Change-Id: Ic7b0b01a772444bc615b62cdb9305a1ef555c780 --- compiler/driver/compiler_options.cc | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'compiler/driver/compiler_options.cc') diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index 51cd999b6d..b55e32b59d 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -23,6 +23,7 @@ #include "arch/instruction_set.h" #include "arch/instruction_set_features.h" +#include "art_method-inl.h" #include "base/runtime_debug.h" #include "base/string_view_cpp20.h" #include "base/variant_map.h" @@ -146,14 +147,37 @@ bool CompilerOptions::ParseCompilerOptions(const std::vector& optio bool CompilerOptions::IsImageClass(const char* descriptor) const { // Historical note: We used to hold the set indirectly and there was a distinction between an - // empty set and a null, null meaning to include all classes. However, the distiction has been + // empty set and a null, null meaning to include all classes. However, the distinction has been // removed; if we don't have a profile, we treat it as an empty set of classes. b/77340429 return image_classes_.find(std::string_view(descriptor)) != image_classes_.end(); } +bool CompilerOptions::IsPreloadedClass(const char* pretty_descriptor) const { + return preloaded_classes_.find(std::string_view(pretty_descriptor)) != preloaded_classes_.end(); +} + const VerificationResults* CompilerOptions::GetVerificationResults() const { DCHECK(Runtime::Current()->IsAotCompiler()); return verification_results_; } +bool CompilerOptions::ShouldCompileWithClinitCheck(ArtMethod* method) const { + if (method->IsStatic() && + !method->IsConstructor() && + // Compiled code for native methods never do a clinit check, so we may put the resolution + // trampoline for native methods. This means that it's possible post zygote fork for the + // entry to be dirtied. We could resolve this by either: + // - Make these methods use the generic JNI entrypoint, but that's not + // desirable for a method that is in the profile. + // - Ensure the declaring class of such native methods are always in the + // preloaded-classes list. + // - Emit the clinit check in the compiled code of native methods. + !method->IsNative()) { + ScopedObjectAccess soa(Thread::Current()); + ObjPtr cls = method->GetDeclaringClass(); + return cls->IsInBootImageAndNotInPreloadedClasses(); + } + return false; +} + } // namespace art -- cgit v1.2.3-59-g8ed1b