diff options
| author | 2012-06-19 23:13:22 -0700 | |
|---|---|---|
| committer | 2012-06-25 10:32:02 -0700 | |
| commit | 46b8a62388f6ac5209371515e48915c32e6d62b9 (patch) | |
| tree | 4df6cb385addbc71bea7cbf8ce55bb27febb7da6 | |
| parent | 4e181288cc6bd67baa1024e2fdb7201dde3d100e (diff) | |
Compare checksum in oat files adjacent to jar/apk to support oat in system image
Change-Id: I45554c9fa5c369a0f47830623b6dbe7f9c691a08
| -rw-r--r-- | Android.mk | 6 | ||||
| -rw-r--r-- | src/class_linker.cc | 88 | ||||
| -rw-r--r-- | src/class_linker.h | 4 |
3 files changed, 65 insertions, 33 deletions
diff --git a/Android.mk b/Android.mk index 9c422b9c3b..14a7679109 100644 --- a/Android.mk +++ b/Android.mk @@ -233,7 +233,11 @@ OAT_TARGET_TARGETS := # $(1): input jar or apk target location define declare-oat-target-target +ifneq (,$(filter $(1),$(addprefix system/app/,$(addsuffix .apk,$(PRODUCT_DEX_PREOPT_PACKAGES_IN_DATA))))) OUT_OAT_FILE := $(call art-cache-out,$(1).oat) +else +OUT_OAT_FILE := $(PRODUCT_OUT)/$(1).oat +endif ifeq ($(ONE_SHOT_MAKEFILE),) .PHONY: oat-target-$(1) @@ -254,7 +258,7 @@ endef $(foreach file,\ $(filter-out\ - $(TARGET_BOOT_DEX),\ + $(addprefix $(TARGET_OUT_JAVA_LIBRARIES)/,$(addsuffix .jar,$(TARGET_BOOT_JARS))),\ $(wildcard $(TARGET_OUT_APPS)/*.apk) $(wildcard $(TARGET_OUT_JAVA_LIBRARIES)/*.jar)),\ $(eval $(call declare-oat-target-target,$(subst $(PRODUCT_OUT)/,,$(file))))) diff --git a/src/class_linker.cc b/src/class_linker.cc index f891913770..b18b31f65d 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -741,6 +741,40 @@ const DexFile* ClassLinker::FindOrCreateOatFileForDexLocation(const std::string& return oat_dex_file->OpenDexFile(); } +const DexFile* ClassLinker::VerifyOatFileChecksums(const OatFile* oat_file, + const std::string& dex_location, + uint32_t dex_location_checksum) { + Runtime* runtime = Runtime::Current(); + const ImageHeader& image_header = runtime->GetHeap()->GetImageSpace()->GetImageHeader(); + uint32_t image_checksum = image_header.GetOatChecksum(); + bool image_check = (oat_file->GetOatHeader().GetImageFileLocationChecksum() == image_checksum); + + const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location); + CHECK(oat_dex_file != NULL) << oat_file->GetLocation() << " " << dex_location; + bool dex_check = (dex_location_checksum == oat_dex_file->GetDexFileLocationChecksum()); + + if (image_check && dex_check) { + RegisterOatFileLocked(*oat_file); + return oat_file->GetOatDexFile(dex_location)->OpenDexFile(); + } + + if (!image_check) { + std::string image_file(image_header.GetImageRoot( + ImageHeader::kOatLocation)->AsString()->ToModifiedUtf8()); + LOG(WARNING) << ".oat file " << oat_file->GetLocation() + << " checksum ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum() + << ") mismatch with " << image_file + << " (" << std::hex << image_checksum << ")"; + } + if (!dex_check) { + LOG(WARNING) << ".oat file " << oat_file->GetLocation() + << " checksum ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum() + << ") mismatch with " << dex_location + << " (" << std::hex << dex_location_checksum << ")"; + } + return NULL; +} + const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::string& dex_location) { MutexLock mu(dex_lock_); @@ -749,14 +783,26 @@ const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::strin return open_oat_file->GetOatDexFile(dex_location)->OpenDexFile(); } - // Look for an existing file next to dex, assuming its up-to-date if found + // Look for an existing file next to dex. for example, for + // /foo/bar/baz.jar, look for /foo/bar/baz.jar.oat. std::string oat_filename(OatFile::DexFilenameToOatFilename(dex_location)); const OatFile* oat_file = FindOatFileFromOatLocation(oat_filename); if (oat_file != NULL) { - const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location); - CHECK(oat_dex_file != NULL) << oat_filename << " " << dex_location; - RegisterOatFileLocked(*oat_file); - return oat_dex_file->OpenDexFile(); + uint32_t dex_location_checksum; + if (!DexFile::GetChecksum(dex_location, dex_location_checksum)) { + // If no classes.dex found in dex_location, it has been stripped, assume oat is up-to-date. + // This is the common case in user builds for jar's and apk's in the /system directory. + const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location); + CHECK(oat_dex_file != NULL) << oat_filename << " " << dex_location; + RegisterOatFileLocked(*oat_file); + return oat_dex_file->OpenDexFile(); + } + const DexFile* dex_file = VerifyOatFileChecksums(oat_file, + dex_location, + dex_location_checksum); + if (dex_file != NULL) { + return dex_file; + } } // Look for an existing file in the art-cache, validating the result if found // not found in /foo/bar/baz.oat? try /data/art-cache/foo@bar@baz.oat @@ -768,33 +814,11 @@ const DexFile* ClassLinker::FindDexFileInOatFileFromDexLocation(const std::strin LOG(WARNING) << "Failed to compute checksum: " << dex_location; return NULL; } - - Runtime* runtime = Runtime::Current(); - const ImageHeader& image_header = runtime->GetHeap()->GetImageSpace()->GetImageHeader(); - uint32_t image_checksum = image_header.GetOatChecksum(); - bool image_check = (oat_file->GetOatHeader().GetImageFileLocationChecksum() == image_checksum); - - const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_location); - CHECK(oat_dex_file != NULL) << oat_filename << " " << dex_location; - bool dex_check = (dex_location_checksum == oat_dex_file->GetDexFileLocationChecksum()); - - if (image_check && dex_check) { - RegisterOatFileLocked(*oat_file); - return oat_file->GetOatDexFile(dex_location)->OpenDexFile(); - } - if (!image_check) { - std::string image_file(image_header.GetImageRoot( - ImageHeader::kOatLocation)->AsString()->ToModifiedUtf8()); - LOG(WARNING) << ".oat file " << oat_file->GetLocation() - << " checksum ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum() - << ") mismatch with " << image_file - << " (" << std::hex << image_checksum << ")--- regenerating"; - } - if (!dex_check) { - LOG(WARNING) << ".oat file " << oat_file->GetLocation() - << " checksum ( " << std::hex << oat_dex_file->GetDexFileLocationChecksum() - << ") mismatch with " << dex_location - << " (" << std::hex << dex_location_checksum << ")--- regenerating"; + const DexFile* dex_file = VerifyOatFileChecksums(oat_file, + dex_location, + dex_location_checksum); + if (dex_file != NULL) { + return dex_file; } if (TEMP_FAILURE_RETRY(unlink(oat_file->GetLocation().c_str())) != 0) { PLOG(FATAL) << "Failed to remove obsolete .oat file " << oat_file->GetLocation(); diff --git a/src/class_linker.h b/src/class_linker.h index 293e3abe71..01c1051864 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -404,6 +404,10 @@ class ClassLinker { const OatFile* FindOpenedOatFileForDexFile(const DexFile& dex_file); const OatFile* FindOpenedOatFileFromDexLocation(const std::string& dex_location); const OatFile* FindOpenedOatFileFromOatLocation(const std::string& oat_location); + const DexFile* VerifyOatFileChecksums(const OatFile* oat_file, + const std::string& dex_location, + uint32_t dex_location_checksum) + EXCLUSIVE_LOCKS_REQUIRED(dex_lock_); Method* CreateProxyConstructor(SirtRef<Class>& klass, Class* proxy_class); Method* CreateProxyMethod(SirtRef<Class>& klass, SirtRef<Method>& prototype); |