summaryrefslogtreecommitdiff
path: root/runtime/runtime.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/runtime.cc')
-rw-r--r--runtime/runtime.cc106
1 files changed, 92 insertions, 14 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 370ee02790..433f564b2d 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -34,6 +34,7 @@
#include <cstdio>
#include <cstdlib>
#include <limits>
+#include <string.h>
#include <thread>
#include <unordered_set>
#include <vector>
@@ -1004,12 +1005,19 @@ bool Runtime::Start() {
!jit_options_->GetProfileSaverOptions().GetProfilePath().empty()) {
std::vector<std::string> dex_filenames;
Split(class_path_string_, ':', &dex_filenames);
- // It's ok to pass "" to the ref profile filename. It indicates we don't have
+
+ // We pass "" as the package name because at this point we don't know it. It could be the
+ // Zygote or it could be a dalvikvm cmd line execution. The package name will be re-set during
+ // post-fork or during RegisterAppInfo.
+ //
+ // Also, it's ok to pass "" to the ref profile filename. It indicates we don't have
// a reference profile.
RegisterAppInfo(
+ /*package_name=*/ "",
dex_filenames,
jit_options_->GetProfileSaverOptions().GetProfilePath(),
- /*ref_profile_filename=*/ "");
+ /*ref_profile_filename=*/ "",
+ kVMRuntimePrimaryApk);
}
return true;
@@ -1056,6 +1064,22 @@ void Runtime::InitNonZygoteOrPostFork(
DCHECK(!IsZygote());
if (is_system_server) {
+ // Register the system server code paths.
+ // TODO: Ideally this should be done by the VMRuntime#RegisterAppInfo. However, right now
+ // the method is only called when we set up the profile. It should be called all the time
+ // (simillar to the apps). Once that's done this manual registration can be removed.
+ const char* system_server_classpath = getenv("SYSTEMSERVERCLASSPATH");
+ if (system_server_classpath == nullptr || (strlen(system_server_classpath) == 0)) {
+ LOG(WARNING) << "System server class path not set";
+ } else {
+ std::vector<std::string> jars = android::base::Split(system_server_classpath, ":");
+ app_info_.RegisterAppInfo("android",
+ jars,
+ /*cur_profile_path=*/ "",
+ /*ref_profile_path=*/ "",
+ AppInfo::CodeType::kPrimaryApk);
+ }
+
// Set the system server package name to "android".
// This is used to tell the difference between samples provided by system server
// and samples generated by other apps when processing boot image profiles.
@@ -1101,6 +1125,8 @@ void Runtime::InitNonZygoteOrPostFork(
session_data.session_id = GetRandomNumber<int64_t>(1, std::numeric_limits<int64_t>::max());
// TODO: set session_data.compilation_reason and session_data.compiler_filter
metrics_reporter_->MaybeStartBackgroundThread(session_data);
+ // Also notify about any updates to the app info.
+ metrics_reporter_->NotifyAppInfoUpdated(&app_info_);
}
StartSignalCatcher();
@@ -1283,7 +1309,13 @@ void Runtime::InitializeApexVersions() {
if (info == apex_infos.end() || info->second->getIsFactory()) {
result += '/';
} else {
- android::base::StringAppendF(&result, "/%" PRIu64, info->second->getVersionCode());
+ // In case lastUpdateMillis field is populated in apex-info-list.xml, we
+ // prefer to use it as version scheme. If the field is missing we
+ // fallback to the version code of the APEX.
+ uint64_t version = info->second->hasLastUpdateMillis()
+ ? info->second->getLastUpdateMillis()
+ : info->second->getVersionCode();
+ android::base::StringAppendF(&result, "/%" PRIu64, version);
}
}
#endif
@@ -1308,6 +1340,12 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
// Reload all the flags value (from system properties and device configs).
ReloadAllFlags(__FUNCTION__);
+ deny_art_apex_data_files_ = runtime_options.Exists(Opt::DenyArtApexDataFiles);
+ if (deny_art_apex_data_files_) {
+ // We will run slower without those files if the system has taken an ART APEX update.
+ LOG(WARNING) << "ART APEX data files are untrusted.";
+ }
+
// Early override for logging output.
if (runtime_options.Exists(Opt::UseStderrLogger)) {
android::base::SetLogger(android::base::StderrLogger);
@@ -1316,6 +1354,7 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
MemMap::Init();
verifier_missing_kthrow_fatal_ = runtime_options.GetOrDefault(Opt::VerifierMissingKThrowFatal);
+ force_java_zygote_fork_loop_ = runtime_options.GetOrDefault(Opt::ForceJavaZygoteForkLoop);
perfetto_hprof_enabled_ = runtime_options.GetOrDefault(Opt::PerfettoHprof);
perfetto_javaheapprof_enabled_ = runtime_options.GetOrDefault(Opt::PerfettoJavaHeapStackProf);
@@ -1371,7 +1410,21 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
}
std::string system_oat_filename = ImageHeader::GetOatLocationFromImageLocation(
GetSystemImageFilename(image_location_.c_str(), instruction_set_));
- std::string system_oat_location = ImageHeader::GetOatLocationFromImageLocation(image_location_);
+ std::string system_oat_location = ImageHeader::GetOatLocationFromImageLocation(
+ image_location_);
+
+ if (deny_art_apex_data_files_ && (LocationIsOnArtApexData(system_oat_filename) ||
+ LocationIsOnArtApexData(system_oat_location))) {
+ // This code path exists for completeness, but we don't expect it to be hit.
+ //
+ // `deny_art_apex_data_files` defaults to false unless set at the command-line. The image
+ // locations come from the -Ximage argument and it would need to be specified as being on
+ // the ART APEX data directory. This combination of flags would say apexdata is compromised,
+ // use apexdata to load image files, which is obviously not a good idea.
+ LOG(ERROR) << "Could not open boot oat file from untrusted location: " << system_oat_filename;
+ return false;
+ }
+
std::string error_msg;
std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1,
system_oat_filename,
@@ -1761,6 +1814,14 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
}
}
+ // Now that the boot image space is set, cache the boot classpath checksums,
+ // to be used when validating oat files.
+ ArrayRef<gc::space::ImageSpace* const> image_spaces(GetHeap()->GetBootImageSpaces());
+ ArrayRef<const DexFile* const> bcp_dex_files(GetClassLinker()->GetBootClassPath());
+ boot_class_path_checksums_ = gc::space::ImageSpace::GetBootClassPathChecksums(image_spaces,
+ bcp_dex_files);
+
+ // Cache the apex versions.
InitializeApexVersions();
CHECK(class_linker_ != nullptr);
@@ -2037,6 +2098,10 @@ void Runtime::InitNativeMethods() {
// a regular JNI libraries with a regular JNI_OnLoad. Most JNI libraries can
// just use System.loadLibrary, but libcore can't because it's the library
// that implements System.loadLibrary!
+ //
+ // By setting calling class to java.lang.Object, the caller location for these
+ // JNI libs is core-oj.jar in the ART APEX, and hence they are loaded from the
+ // com_android_art linker namespace.
// libicu_jni has to be initialized before libopenjdk{d} due to runtime dependency from
// libopenjdk{d} to Icu4cMetadata native methods in libicu_jni. See http://b/143888405
@@ -2553,9 +2618,22 @@ void Runtime::ClearCalleeSaveMethods() {
}
}
-void Runtime::RegisterAppInfo(const std::vector<std::string>& code_paths,
+void Runtime::RegisterAppInfo(const std::string& package_name,
+ const std::vector<std::string>& code_paths,
const std::string& profile_output_filename,
- const std::string& ref_profile_filename) {
+ const std::string& ref_profile_filename,
+ int32_t code_type) {
+ app_info_.RegisterAppInfo(
+ package_name,
+ code_paths,
+ profile_output_filename,
+ ref_profile_filename,
+ AppInfo::FromVMRuntimeConstants(code_type));
+
+ if (metrics_reporter_ != nullptr) {
+ metrics_reporter_->NotifyAppInfoUpdated(&app_info_);
+ }
+
if (jit_.get() == nullptr) {
// We are not JITing. Nothing to do.
return;
@@ -3127,6 +3205,8 @@ void Runtime::NotifyStartupCompleted() {
return;
}
+ VLOG(startup) << app_info_;
+
VLOG(startup) << "Adding NotifyStartupCompleted task";
// Use the heap task processor since we want to be exclusive with the GC and we don't want to
// block the caller if the GC is running.
@@ -3138,18 +3218,16 @@ void Runtime::NotifyStartupCompleted() {
ProfileSaver::NotifyStartupCompleted();
if (metrics_reporter_ != nullptr) {
- std::string compilation_reason;
- CompilerFilter::Filter compiler_filter;
- if (oat_file_manager_->GetPrimaryOatFileInfo(&compilation_reason, &compiler_filter)) {
- metrics_reporter_->SetCompilationInfo(
- compilation_reason.empty() ? metrics::CompilationReasonFromName(compilation_reason)
- : metrics::CompilationReason::kUnknown,
- compiler_filter);
- }
metrics_reporter_->NotifyStartupCompleted();
}
}
+void Runtime::NotifyDexFileLoaded() {
+ if (metrics_reporter_ != nullptr) {
+ metrics_reporter_->NotifyAppInfoUpdated(&app_info_);
+ }
+}
+
bool Runtime::GetStartupCompleted() const {
return startup_completed_.load(std::memory_order_seq_cst);
}