summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jiakai Zhang <jiakaiz@google.com> 2021-09-15 08:56:56 +0000
committer Jiakai Zhang <jiakaiz@google.com> 2021-09-22 05:30:53 +0000
commit7fa70866414df11ef0c9d8eca3e6c23788e8c9d8 (patch)
tree2220f0057661852e53239319156f4161730096b5
parente3e01845d2643916699f1ee15149ed360b14ebeb (diff)
Update ART runtime to recognize artifacts on /system for APEX.
Context: go/location-for-compilation-artifacts-of-apex-jars This change enables ART runtime to use the artifacts generated by aosp/1821984. Bug: 194150908 Test: atest art_standalone_libartbase_tests Test: manual - 1. Patch aosp/1828115. 2. Build a system image and flash it into a device. 3. adb root && adb shell grep "/system/framework/oat" /proc/`adb shell pidof system_server`/maps 4. See "/system/framework/oat/x86_64/apex@..." in the output. Change-Id: I74cb21433d63b1f3ed4d096ab0c86f09bced4b97
-rw-r--r--libartbase/base/file_utils.cc29
-rw-r--r--libartbase/base/file_utils.h4
-rw-r--r--libartbase/base/file_utils_test.cc9
-rw-r--r--runtime/oat_file_assistant.cc12
4 files changed, 51 insertions, 3 deletions
diff --git a/libartbase/base/file_utils.cc b/libartbase/base/file_utils.cc
index 5650457268..c6c1b50a71 100644
--- a/libartbase/base/file_utils.cc
+++ b/libartbase/base/file_utils.cc
@@ -42,9 +42,9 @@
#include <sstream>
#include "android-base/file.h"
+#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
-
#include "base/bit_utils.h"
#include "base/globals.h"
#include "base/os.h"
@@ -403,8 +403,12 @@ void GetDalvikCache(const char* subdir, const bool create_if_absent, std::string
#endif
}
-bool GetDalvikCacheFilename(const char* location, const char* cache_location,
- std::string* filename, std::string* error_msg) {
+// Returns a path formed by encoding the dex location into the filename. The path returned will be
+// rooted at `cache_location`.
+static bool GetLocationEncodedFilename(const char* location,
+ const char* cache_location,
+ std::string* filename,
+ std::string* error_msg) {
if (location[0] != '/') {
*error_msg = StringPrintf("Expected path in location to be absolute: %s", location);
return false;
@@ -421,6 +425,13 @@ bool GetDalvikCacheFilename(const char* location, const char* cache_location,
return true;
}
+bool GetDalvikCacheFilename(const char* location,
+ const char* cache_location,
+ std::string* filename,
+ std::string* error_msg) {
+ return GetLocationEncodedFilename(location, cache_location, filename, error_msg);
+}
+
static std::string GetApexDataDalvikCacheDirectory(InstructionSet isa) {
if (isa != InstructionSet::kNone) {
return GetDalvikCacheDirectory(GetArtApexData(), GetInstructionSetString(isa));
@@ -489,6 +500,18 @@ std::string GetVdexFilename(const std::string& oat_location) {
return ReplaceFileExtension(oat_location, "vdex");
}
+std::string GetSystemOdexFilenameForApex(std::string_view location, InstructionSet isa) {
+ DCHECK(LocationIsOnApex(location));
+ std::string dir = GetAndroidRoot() + "/framework/oat/" + GetInstructionSetString(isa);
+ std::string result, error_msg;
+ bool ret =
+ GetLocationEncodedFilename(std::string{location}.c_str(), dir.c_str(), &result, &error_msg);
+ // This should never fail. The function fails only if the location is not absolute, and a location
+ // on /apex is always absolute.
+ DCHECK(ret) << error_msg;
+ return ReplaceFileExtension(result, "odex");
+}
+
static void InsertIsaDirectory(const InstructionSet isa, std::string* filename) {
// in = /foo/bar/baz
// out = /foo/bar/<isa>/baz
diff --git a/libartbase/base/file_utils.h b/libartbase/base/file_utils.h
index 337640e4a2..3c11ac3c7b 100644
--- a/libartbase/base/file_utils.h
+++ b/libartbase/base/file_utils.h
@@ -119,6 +119,10 @@ std::string GetSystemImageFilename(const char* location, InstructionSet isa);
// Returns the vdex filename for the given oat filename.
std::string GetVdexFilename(const std::string& oat_filename);
+// Returns the odex location on /system for a DEX file on /apex. The caller must make sure that
+// `location` is on /apex.
+std::string GetSystemOdexFilenameForApex(std::string_view location, InstructionSet isa);
+
// Returns `filename` with the text after the last occurrence of '.' replaced with
// `extension`. If `filename` does not contain a period, returns a string containing `filename`,
// a period, and `new_extension`.
diff --git a/libartbase/base/file_utils_test.cc b/libartbase/base/file_utils_test.cc
index e9093b249c..a0b3325648 100644
--- a/libartbase/base/file_utils_test.cc
+++ b/libartbase/base/file_utils_test.cc
@@ -271,4 +271,13 @@ TEST_F(FileUtilsTest, GetApexDataDalvikCacheFilename) {
CHECK_EQ(vdex_filename, ReplaceFileExtension(art_filename, "vdex"));
}
+TEST_F(FileUtilsTest, GetSystemOdexFilenameForApex) {
+ ScopedUnsetEnvironmentVariable android_root("ANDROID_ROOT");
+
+ const std::string apex_jar = std::string {kAndroidArtApexDefaultPath} + "/javalib/some.jar";
+ EXPECT_EQ(
+ GetAndroidRoot() + "/framework/oat/arm/apex@com.android.art@javalib@some.jar@classes.odex",
+ GetSystemOdexFilenameForApex(apex_jar.c_str(), InstructionSet::kArm));
+}
+
} // namespace art
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 109769c590..a0b0055e36 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -523,6 +523,18 @@ bool OatFileAssistant::DexLocationToOdexFilename(const std::string& location,
CHECK(odex_filename != nullptr);
CHECK(error_msg != nullptr);
+ // For a DEX file on /apex, check if there is an odex file on /system. If so, and the file exists,
+ // use it.
+ if (LocationIsOnApex(location)) {
+ const std::string system_file = GetSystemOdexFilenameForApex(location, isa);
+ if (OS::FileExists(system_file.c_str(), /*check_file_type=*/true)) {
+ *odex_filename = system_file;
+ return true;
+ } else if (errno != ENOENT) {
+ PLOG(ERROR) << "Could not check odex file " << system_file;
+ }
+ }
+
// The odex file name is formed by replacing the dex_location extension with
// .odex and inserting an oat/<isa> directory. For example:
// location = /foo/bar/baz.jar