diff options
| author | 2021-09-15 08:56:56 +0000 | |
|---|---|---|
| committer | 2021-09-22 05:30:53 +0000 | |
| commit | 7fa70866414df11ef0c9d8eca3e6c23788e8c9d8 (patch) | |
| tree | 2220f0057661852e53239319156f4161730096b5 | |
| parent | e3e01845d2643916699f1ee15149ed360b14ebeb (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.cc | 29 | ||||
| -rw-r--r-- | libartbase/base/file_utils.h | 4 | ||||
| -rw-r--r-- | libartbase/base/file_utils_test.cc | 9 | ||||
| -rw-r--r-- | runtime/oat_file_assistant.cc | 12 |
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 |