Fix ART code around JIT zygote.
- The right image location for it now ends with a profile
- Add profile locations to image spaces, so the JIT knows what to
compile
- Remove now deprecated ApexImage related code.
Bug:119800099
Test: boots, methods from framework gets compiled by zygote
Change-Id: Ie31b62d0a25f1b50e266c1537c43307d7b29e138
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index a43390a..c05ff89 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -74,7 +74,6 @@
kBootImage, // Creating boot image.
kBootImageExtension, // Creating boot image extension.
kAppImage, // Creating app image.
- kApexBootImageExtension, // Creating JIT-zygote boot image extension (b/119800099).
};
CompilerOptions();
@@ -197,14 +196,9 @@
return image_type_ == ImageType::kBootImage;
}
- bool IsApexBootImageExtension() const {
- return image_type_ == ImageType::kApexBootImageExtension;
- }
-
// Are we compiling a boot image extension?
bool IsBootImageExtension() const {
- return image_type_ == ImageType::kBootImageExtension
- || image_type_ == ImageType::kApexBootImageExtension;
+ return image_type_ == ImageType::kBootImageExtension;
}
bool IsBaseline() const {
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 4ce5335..3073f5f 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -830,13 +830,10 @@
DCHECK(compiler_options_->image_type_ == CompilerOptions::ImageType::kNone);
if (!image_filenames_.empty() || image_fd_ != -1) {
// If no boot image is provided, then dex2oat is compiling the primary boot image,
- // otherwise it is compiling the boot image extension. In the case of JIT-zygote
- // extension the primary boot image has a special name "apex.art".
+ // otherwise it is compiling the boot image extension.
compiler_options_->image_type_ = boot_image_filename_.empty()
? CompilerOptions::ImageType::kBootImage
- : android::base::EndsWith(boot_image_filename_, "apex.art")
- ? CompilerOptions::ImageType::kApexBootImageExtension
- : CompilerOptions::ImageType::kBootImageExtension;
+ : CompilerOptions::ImageType::kBootImageExtension;
}
if (app_image_fd_ != -1 || !app_image_file_name_.empty()) {
if (compiler_options_->IsBootImage() || compiler_options_->IsBootImageExtension()) {
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc
index 94391eb..c0d1999 100644
--- a/dex2oat/driver/compiler_driver.cc
+++ b/dex2oat/driver/compiler_driver.cc
@@ -933,14 +933,6 @@
}
bool CompilerDriver::ShouldCompileBasedOnProfile(const MethodReference& method_ref) const {
- // If compiling the apex image, filter out methods not in an apex file (the profile used
- // for boot classpath is the same between the apex image and the boot image, so it includes
- /// framewkro methods).
- if (compiler_options_->IsApexBootImageExtension() &&
- !android::base::StartsWith(method_ref.dex_file->GetLocation(), "/apex")) {
- return false;
- }
-
// Profile compilation info may be null if no profile is passed.
if (!CompilerFilter::DependsOnProfile(compiler_options_->GetCompilerFilter())) {
// Use the compiler filter instead of the presence of profile_compilation_info_ since
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index b749bb8..1343f3d 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4835,20 +4835,6 @@
const OatDexFile* oat_dex_file = dex_file.GetOatDexFile();
// In case we run without an image there won't be a backing oat file.
if (oat_dex_file == nullptr || oat_dex_file->GetOatFile() == nullptr) {
- if (!kIsDebugBuild && klass->GetClassLoader() == nullptr) {
- // For boot classpath classes in the case we're not using a default boot image:
- // we don't have the infrastructure yet to query verification data on individual
- // boot vdex files, so it's simpler for now to consider all boot classpath classes
- // verified. This should be taken into account when measuring boot time and app
- // startup compare to the (current) production system where both:
- // 1) updatable boot classpath classes, and
- // 2) classes in /system referencing updatable classes
- // will be verified at runtime.
- if (Runtime::Current()->IsUsingApexBootImageLocation()) {
- oat_file_class_status = ClassStatus::kVerified;
- return true;
- }
- }
return false;
}
diff --git a/runtime/gc/collector/immune_spaces_test.cc b/runtime/gc/collector/immune_spaces_test.cc
index b3a14e2..b1a21d4 100644
--- a/runtime/gc/collector/immune_spaces_test.cc
+++ b/runtime/gc/collector/immune_spaces_test.cc
@@ -46,6 +46,7 @@
MemMap&& oat_map)
: ImageSpace("DummyImageSpace",
/*image_location=*/"",
+ /*profile_file=*/"",
std::move(map),
std::move(live_bitmap),
map.End()),
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index d762e31..9e3d201 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -78,6 +78,7 @@
ImageSpace::ImageSpace(const std::string& image_filename,
const char* image_location,
+ const char* profile_file,
MemMap&& mem_map,
accounting::ContinuousSpaceBitmap&& live_bitmap,
uint8_t* end)
@@ -89,7 +90,8 @@
kGcRetentionPolicyNeverCollect),
live_bitmap_(std::move(live_bitmap)),
oat_file_non_owned_(nullptr),
- image_location_(image_location) {
+ image_location_(image_location),
+ profile_file_(profile_file) {
DCHECK(live_bitmap_.IsValid());
}
@@ -769,6 +771,7 @@
return Init(file.get(),
image_filename,
image_location,
+ /* profile_file=*/ "",
oat_file,
/*allow_direct_mapping=*/ true,
logger,
@@ -779,6 +782,7 @@
static std::unique_ptr<ImageSpace> Init(File* file,
const char* image_filename,
const char* image_location,
+ const char* profile_file,
const OatFile* oat_file,
bool allow_direct_mapping,
TimingLogger* logger,
@@ -914,6 +918,7 @@
// We only want the mirror object, not the ArtFields and ArtMethods.
std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename,
image_location,
+ profile_file,
std::move(map),
std::move(bitmap),
image_end));
@@ -1505,6 +1510,7 @@
struct ImageChunk {
std::string base_location;
std::string base_filename;
+ std::string profile_file;
size_t start_index;
uint32_t component_count;
uint32_t image_space_count;
@@ -2144,6 +2150,7 @@
ImageChunk chunk;
chunk.base_location = base_location;
chunk.base_filename = base_filename;
+ chunk.profile_file = profile_filename;
chunk.start_index = bcp_index;
chunk.component_count = header.GetComponentCount();
chunk.image_space_count = header.GetImageSpaceCount();
@@ -2877,6 +2884,7 @@
std::unique_ptr<ImageSpace> Load(const std::string& image_location,
const std::string& image_filename,
+ const std::string& profile_file,
android::base::unique_fd art_fd,
TimingLogger* logger,
/*inout*/MemMap* image_reservation,
@@ -2892,6 +2900,7 @@
std::unique_ptr<ImageSpace> result = Loader::Init(&image_file,
image_filename.c_str(),
image_location.c_str(),
+ profile_file.c_str(),
/*oat_file=*/ nullptr,
/*allow_direct_mapping=*/ false,
logger,
@@ -3119,6 +3128,7 @@
for (size_t i = 0u, size = locations.size(); i != size; ++i) {
spaces->push_back(Load(locations[i],
filenames[i],
+ chunk.profile_file,
std::move(chunk.art_fd),
logger,
image_reservation,
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index ab31be8..cf23e75 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -171,6 +171,10 @@
return image_location_;
}
+ const std::string GetProfileFile() const {
+ return profile_file_;
+ }
+
accounting::ContinuousSpaceBitmap* GetLiveBitmap() override {
return &live_bitmap_;
}
@@ -289,6 +293,7 @@
ImageSpace(const std::string& name,
const char* image_location,
+ const char* profile_file,
MemMap&& mem_map,
accounting::ContinuousSpaceBitmap&& live_bitmap,
uint8_t* end);
@@ -303,6 +308,7 @@
const OatFile* oat_file_non_owned_;
const std::string image_location_;
+ const std::string profile_file_;
friend class Space;
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 180eb8d..363fe25 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -873,29 +873,29 @@
void Run(Thread* self) override {
Runtime* runtime = Runtime::Current();
- std::string profile_file;
- for (const std::string& option : runtime->GetImageCompilerOptions()) {
- if (android::base::StartsWith(option, "--profile-file=")) {
- profile_file = option.substr(strlen("--profile-file="));
- break;
- }
- }
-
- const std::vector<const DexFile*>& boot_class_path =
- runtime->GetClassLinker()->GetBootClassPath();
- ScopedNullHandle<mirror::ClassLoader> null_handle;
- std::string boot_profile = GetBootProfileFile(profile_file);
- // We add to the queue for zygote so that we can fork processes in-between
- // compilations.
uint32_t added_to_queue = 0;
- if (Runtime::Current()->IsPrimaryZygote()) {
- // We avoid doing compilation at boot for the secondary zygote, as apps
- // forked from it are not critical for boot.
- added_to_queue += runtime->GetJit()->CompileMethodsFromBootProfile(
- self, boot_class_path, boot_profile, null_handle, /* add_to_queue= */ true);
+ for (gc::space::ImageSpace* space : Runtime::Current()->GetHeap()->GetBootImageSpaces()) {
+ const std::string& profile_file = space->GetProfileFile();
+ if (profile_file.empty()) {
+ continue;
+ }
+ LOG(INFO) << "JIT Zygote looking at profile " << profile_file;
+
+ const std::vector<const DexFile*>& boot_class_path =
+ runtime->GetClassLinker()->GetBootClassPath();
+ ScopedNullHandle<mirror::ClassLoader> null_handle;
+ // We add to the queue for zygote so that we can fork processes in-between
+ // compilations.
+ if (Runtime::Current()->IsPrimaryZygote()) {
+ std::string boot_profile = GetBootProfileFile(profile_file);
+ // We avoid doing compilation at boot for the secondary zygote, as apps
+ // forked from it are not critical for boot.
+ added_to_queue += runtime->GetJit()->CompileMethodsFromBootProfile(
+ self, boot_class_path, boot_profile, null_handle, /* add_to_queue= */ true);
+ }
+ added_to_queue += runtime->GetJit()->CompileMethodsFromProfile(
+ self, boot_class_path, profile_file, null_handle, /* add_to_queue= */ true);
}
- added_to_queue += runtime->GetJit()->CompileMethodsFromProfile(
- self, boot_class_path, profile_file, null_handle, /* add_to_queue= */ true);
JitCodeCache* code_cache = runtime->GetJit()->GetCodeCache();
code_cache->GetZygoteMap()->Initialize(added_to_queue);
@@ -1128,7 +1128,7 @@
Start();
Runtime* runtime = Runtime::Current();
- if (runtime->IsZygote() && runtime->IsUsingApexBootImageLocation() && UseJitCompilation()) {
+ if (runtime->IsZygote() && runtime->IsRunningJitZygote() && UseJitCompilation()) {
// If we're not using the default boot image location, request a JIT task to
// compile all methods in the boot image profile.
thread_pool_->AddTask(Thread::Current(), new ZygoteTask());
@@ -1209,7 +1209,7 @@
return;
}
Runtime* runtime = Runtime::Current();
- if (runtime->IsSystemServer() && runtime->IsUsingApexBootImageLocation() && UseJitCompilation()) {
+ if (runtime->IsSystemServer() && runtime->IsRunningJitZygote() && UseJitCompilation()) {
thread_pool_->AddTask(Thread::Current(), new JitProfileTask(dex_files, class_loader));
}
}
@@ -1465,7 +1465,7 @@
if (UseJitCompilation()) {
if (old_count == 0 &&
method->IsNative() &&
- Runtime::Current()->IsUsingApexBootImageLocation()) {
+ Runtime::Current()->IsRunningJitZygote()) {
// jitzygote: Compile JNI stub on first use to avoid the expensive generic stub.
CompileMethod(method, self, /* baseline= */ false, /* osr= */ false, /* prejit= */ false);
return true;
@@ -1640,7 +1640,7 @@
Runtime* const runtime = Runtime::Current();
// For child zygote, we instead query IsCompilationNotified() post zygote fork.
- if (!is_zygote && runtime->IsUsingApexBootImageLocation() && fd_methods_ != -1) {
+ if (!is_zygote && runtime->IsRunningJitZygote() && fd_methods_ != -1) {
// Create a thread that will poll the status of zygote compilation, and map
// the private mapping of boot image methods.
zygote_mapping_methods_.ResetInForkedProcess();
@@ -1668,7 +1668,7 @@
code_cache_->SetGarbageCollectCode(!jit_compiler_->GenerateDebugInfo() &&
!Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled());
- if (is_system_server && Runtime::Current()->IsUsingApexBootImageLocation()) {
+ if (is_system_server && Runtime::Current()->IsRunningJitZygote()) {
// Disable garbage collection: we don't want it to delete methods we're compiling
// through boot and system server profiles.
// TODO(ngeoffray): Fix this so we still collect deoptimized and unused code.
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 717b2a3..fb11a05 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -340,7 +340,7 @@
}
const void* JitCodeCache::GetSavedEntryPointOfPreCompiledMethod(ArtMethod* method) {
- if (Runtime::Current()->IsUsingApexBootImageLocation() && method->IsPreCompiled()) {
+ if (method->IsPreCompiled()) {
const void* code_ptr = nullptr;
if (method->GetDeclaringClass()->GetClassLoader() == nullptr) {
code_ptr = zygote_map_.GetCodeFor(method);
@@ -723,7 +723,6 @@
} else if (NeedsClinitCheckBeforeCall(method) &&
!method->GetDeclaringClass()->IsVisiblyInitialized()) {
// This situation currently only occurs in the jit-zygote mode.
- DCHECK(Runtime::Current()->IsUsingApexBootImageLocation());
DCHECK(!garbage_collect_code_);
DCHECK(method->IsPreCompiled());
// The shared region can easily be queried. For the private region, we
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index ee37528..dce34d9 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -34,7 +34,6 @@
#include "dex/utf.h"
#include "index_bss_mapping.h"
#include "mirror/object.h"
-#include "runtime.h"
namespace art {
@@ -481,12 +480,6 @@
// May return null if the OatDexFile only contains a type lookup table. This case only happens
// for the compiler to speed up compilation, or in jitzygote.
const OatFile* GetOatFile() const {
- // Avoid pulling in runtime.h in the header file.
- if (kIsDebugBuild && oat_file_ == nullptr) {
- if (!Runtime::Current()->IsUsingApexBootImageLocation()) {
- AssertAotCompiler();
- }
- }
return oat_file_;
}
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index fcfe797..615e37e 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -196,9 +196,6 @@
// barrier config.
static constexpr double kExtraDefaultHeapGrowthMultiplier = kUseReadBarrier ? 1.0 : 0.0;
-static constexpr const char* kApexBootImageLocation =
- "/apex/com.android.art/javalib/apex.art:/system/framework/apex-framework.art";
-
Runtime* Runtime::instance_ = nullptr;
struct TraceConfig {
@@ -1130,13 +1127,6 @@
continue;
}
bool verify = Runtime::Current()->IsVerificationEnabled();
- // In the case we're using the apex boot image, we don't have support yet
- // on reading vdex files of boot classpath. So just assume all boot classpath
- // dex files have been verified (this should always be the case as the default boot
- // image has been generated at build time).
- if (Runtime::Current()->IsUsingApexBootImageLocation() && !kIsDebugBuild) {
- verify = false;
- }
if (!dex_file_loader.Open(dex_filename,
dex_location,
verify,
@@ -1244,10 +1234,6 @@
runtime_options.GetOrDefault(Opt::StackDumpLockProfThreshold));
image_location_ = runtime_options.GetOrDefault(Opt::Image);
- {
- std::string error_msg;
- is_using_apex_boot_image_location_ = (image_location_ == kApexBootImageLocation);
- }
SetInstructionSet(runtime_options.GetOrDefault(Opt::ImageInstructionSet));
boot_class_path_ = runtime_options.ReleaseOrDefault(Opt::BootClassPath);
diff --git a/runtime/runtime.h b/runtime/runtime.h
index a988fa7..3e618fa 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -30,6 +30,7 @@
#include "base/locks.h"
#include "base/macros.h"
#include "base/mem_map.h"
+#include "base/string_view_cpp20.h"
#include "deoptimization_kind.h"
#include "dex/dex_file_types.h"
#include "experimental_flags.h"
@@ -213,10 +214,6 @@
return image_location_;
}
- bool IsUsingApexBootImageLocation() const {
- return is_using_apex_boot_image_location_;
- }
-
// Starts a runtime, which may cause threads to be started and code to run.
bool Start() UNLOCK_FUNCTION(Locks::mutator_lock_);
@@ -982,6 +979,11 @@
// Return true if we should load oat files as executable or not.
bool GetOatFilesExecutable() const;
+ bool IsRunningJitZygote() const {
+ // TODO: This should be better specified.
+ return EndsWith(image_location_, "boot-image.prof");
+ }
+
private:
static void InitPlatformSignalHandlers();
@@ -1062,7 +1064,6 @@
std::vector<std::string> compiler_options_;
std::vector<std::string> image_compiler_options_;
std::string image_location_;
- bool is_using_apex_boot_image_location_;
std::vector<std::string> boot_class_path_;
std::vector<std::string> boot_class_path_locations_;