oat_file_assistant.cc revision a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931
166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler/* 266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Copyright (C) 2014 The Android Open Source Project 366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * 466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Licensed under the Apache License, Version 2.0 (the "License"); 566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * you may not use this file except in compliance with the License. 666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * You may obtain a copy of the License at 766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * 866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * http://www.apache.org/licenses/LICENSE-2.0 966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * 1066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * Unless required by applicable law or agreed to in writing, software 1166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * distributed under the License is distributed on an "AS IS" BASIS, 1266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * See the License for the specific language governing permissions and 1466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler * limitations under the License. 1566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler */ 1666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "oat_file_assistant.h" 1866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <fcntl.h> 2066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#ifdef __linux__ 2166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/sendfile.h> 2266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#else 2366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/socket.h> 2466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#endif 2566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/types.h> 2666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/stat.h> 2766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <unistd.h> 2866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <set> 3066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 3166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "base/logging.h" 3266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "base/stringprintf.h" 3366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "class_linker.h" 3466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "gc/heap.h" 3566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "gc/space/image_space.h" 3666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "image.h" 3766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "oat.h" 3866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "os.h" 3966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "runtime.h" 40fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier#include "scoped_thread_state_change.h" 4166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "ScopedFd.h" 4266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "utils.h" 4366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 4466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlernamespace art { 4566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 4666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerOatFileAssistant::OatFileAssistant(const char* dex_location, 4766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const InstructionSet isa, 48a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler bool profile_changed, 4966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler bool load_executable) 50a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler : OatFileAssistant(dex_location, nullptr, isa, profile_changed, load_executable) 51b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle{ } 5266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 5366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerOatFileAssistant::OatFileAssistant(const char* dex_location, 5466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const char* oat_location, 5566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const InstructionSet isa, 56a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler bool profile_changed, 5766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler bool load_executable) 58a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler : isa_(isa), profile_changed_(profile_changed), load_executable_(load_executable) { 59740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler CHECK(dex_location != nullptr) << "OatFileAssistant: null dex location"; 60740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler dex_location_.assign(dex_location); 61740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler 6266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (load_executable_ && isa != kRuntimeISA) { 6366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler LOG(WARNING) << "OatFileAssistant: Load executable specified, " 6466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << "but isa is not kRuntimeISA. Will not attempt to load executable."; 6566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler load_executable_ = false; 6666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 6766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 6866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // If the user gave a target oat location, save that as the cached oat 6966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // location now so we won't try to construct the default location later. 7066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (oat_location != nullptr) { 7166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_name_ = std::string(oat_location); 7266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_name_attempted_ = true; 7366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_name_found_ = true; 7466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 7566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 7666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 7766d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerOatFileAssistant::~OatFileAssistant() { 7866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Clean up the lock file. 79581f4e9065b9b7f788315d3ea1a45e51ae168589Richard Uhler if (flock_.HasFile()) { 80581f4e9065b9b7f788315d3ea1a45e51ae168589Richard Uhler TEMP_FAILURE_RETRY(unlink(flock_.GetFile()->GetPath().c_str())); 8166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 8266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 8366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 8466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::IsInBootClassPath() { 8566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Note: We check the current boot class path, regardless of the ISA 8666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // specified by the user. This is okay, because the boot class path should 8766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // be the same for all ISAs. 8866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // TODO: Can we verify the boot class path is the same for all ISAs? 8966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Runtime* runtime = Runtime::Current(); 9066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ClassLinker* class_linker = runtime->GetClassLinker(); 9166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const auto& boot_class_path = class_linker->GetBootClassPath(); 9266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (size_t i = 0; i < boot_class_path.size(); i++) { 93740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler if (boot_class_path[i]->GetLocation() == dex_location_) { 9466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler VLOG(oat) << "Dex location " << dex_location_ << " is in boot class path"; 9566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return true; 9666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 9766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 9866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 9966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 10066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::Lock(std::string* error_msg) { 10266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(error_msg != nullptr); 103581f4e9065b9b7f788315d3ea1a45e51ae168589Richard Uhler CHECK(!flock_.HasFile()) << "OatFileAssistant::Lock already acquired"; 10466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OatFileName() == nullptr) { 10666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *error_msg = "Failed to determine lock file"; 10766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 10866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 10966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string lock_file_name = *OatFileName() + ".flock"; 11066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 111581f4e9065b9b7f788315d3ea1a45e51ae168589Richard Uhler if (!flock_.Init(lock_file_name.c_str(), error_msg)) { 11266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler TEMP_FAILURE_RETRY(unlink(lock_file_name.c_str())); 11366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 11466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 11566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return true; 11666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 11766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 118a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhlerbool OatFileAssistant::OatFileCompilerFilterIsOkay(CompilerFilter::Filter target) { 119a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler const OatFile* oat_file = GetOatFile(); 120a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (oat_file != nullptr) { 121a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler CompilerFilter::Filter current = oat_file->GetCompilerFilter(); 122a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return CompilerFilter::IsAsGoodAs(current, target); 123a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 124a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return false; 125b077e15d2d11b7c81aacbcd4a46c2b1e9c9ba20dCalin Juravle} 12666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 127a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhlerbool OatFileAssistant::OdexFileCompilerFilterIsOkay(CompilerFilter::Filter target) { 128a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler const OatFile* odex_file = GetOdexFile(); 129a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (odex_file != nullptr) { 130a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler CompilerFilter::Filter current = odex_file->GetCompilerFilter(); 131a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return CompilerFilter::IsAsGoodAs(current, target); 13295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler } 133a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return false; 134a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler} 13595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 136a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard UhlerOatFileAssistant::DexOptNeeded OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target) { 137a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler bool compilation_desired = CompilerFilter::IsCompilationEnabled(target); 138a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler 139a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // See if the oat file is in good shape as is. 140a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler bool oat_okay = OatFileCompilerFilterIsOkay(target); 141a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (oat_okay) { 142a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (compilation_desired) { 143a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (OatFileIsUpToDate()) { 144a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return kNoDexOptNeeded; 145a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 146a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } else { 147a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (!OatFileIsOutOfDate()) { 148a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return kNoDexOptNeeded; 149a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 150a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 151a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 152a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler 153a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // See if the odex file is in good shape as is. 154a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler bool odex_okay = OdexFileCompilerFilterIsOkay(target); 155a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (odex_okay) { 156a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (compilation_desired) { 157a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (OdexFileIsUpToDate()) { 158a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return kNoDexOptNeeded; 159a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 160a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } else { 161a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (!OdexFileIsOutOfDate()) { 162a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return kNoDexOptNeeded; 163a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 164a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 16595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler } 16695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 167a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // See if we can get an up-to-date file by running patchoat. 168a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (compilation_desired) { 169a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (odex_okay && OdexFileNeedsRelocation()) { 170a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // TODO: don't return kPatchOatNeeded if the odex file contains no 171a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // patch information. 172a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return kPatchOatNeeded; 173a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 174a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler 175a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (oat_okay && OatFileNeedsRelocation()) { 176a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // TODO: don't return kSelfPatchOatNeeded if the oat file contains no 177a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // patch information. 178a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return kSelfPatchOatNeeded; 179a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 18066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 18195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 182a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // We can only run dex2oat if there are original dex files. 1839b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler return HasOriginalDexFiles() ? kDex2OatNeeded : kNoDexOptNeeded; 18466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 18566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 186a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhlerbool OatFileAssistant::MakeUpToDate(CompilerFilter::Filter target, std::string* error_msg) { 187a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler switch (GetDexOptNeeded(target)) { 18895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler case kNoDexOptNeeded: return true; 189a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler case kDex2OatNeeded: return GenerateOatFile(target, error_msg); 19095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler case kPatchOatNeeded: return RelocateOatFile(OdexFileName(), error_msg); 19195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler case kSelfPatchOatNeeded: return RelocateOatFile(OatFileName(), error_msg); 19266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 19366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler UNREACHABLE(); 19466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 19566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 19666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstd::unique_ptr<OatFile> OatFileAssistant::GetBestOatFile() { 1975f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler // The best oat files are, in descending order of bestness: 1985f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler // 1. Properly relocated files. These may be opened executable. 1995f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler // 2. Not out-of-date files that are already opened non-executable. 2005f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler // 3. Not out-of-date files that we must reopen non-executable. 2015f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler 20266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OatFileIsUpToDate()) { 20366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_file_released_ = true; 20466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return std::move(cached_oat_file_); 20566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 20666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 20766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OdexFileIsUpToDate()) { 20866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_file_released_ = true; 20966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return std::move(cached_odex_file_); 21066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 21166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2125f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler VLOG(oat) << "Oat File Assistant: No relocated oat file found," 2135f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler << " attempting to fall back to interpreting oat file instead."; 2145f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler 2155f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler if (!OatFileIsOutOfDate() && !OatFileIsExecutable()) { 2165f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler oat_file_released_ = true; 2175f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler return std::move(cached_oat_file_); 2185f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler } 2195f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler 2205f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler if (!OdexFileIsOutOfDate() && !OdexFileIsExecutable()) { 2215f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler oat_file_released_ = true; 2225f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler return std::move(cached_odex_file_); 2235f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler } 22466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2255f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler if (!OatFileIsOutOfDate()) { 2265f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler load_executable_ = false; 2275f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler ClearOatFileCache(); 22866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!OatFileIsOutOfDate()) { 2295f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler CHECK(!OatFileIsExecutable()); 2305f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler oat_file_released_ = true; 2315f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler return std::move(cached_oat_file_); 23266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 2335f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler } 23466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2355f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler if (!OdexFileIsOutOfDate()) { 2365f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler load_executable_ = false; 2375f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler ClearOdexFileCache(); 23866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!OdexFileIsOutOfDate()) { 2395f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler CHECK(!OdexFileIsExecutable()); 2405f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler oat_file_released_ = true; 2415f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler return std::move(cached_odex_file_); 24266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 24366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 24466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 24566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return std::unique_ptr<OatFile>(); 24666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 24766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 24866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstd::vector<std::unique_ptr<const DexFile>> OatFileAssistant::LoadDexFiles( 24966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile& oat_file, const char* dex_location) { 25066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 25166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 25266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the primary dex file. 25366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 25466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile::OatDexFile* oat_dex_file = oat_file.GetOatDexFile( 25566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_location, nullptr, false); 25666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (oat_dex_file == nullptr) { 25766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler LOG(WARNING) << "Attempt to load out-of-date oat file " 25866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << oat_file.GetLocation() << " for dex location " << dex_location; 25966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return std::vector<std::unique_ptr<const DexFile>>(); 26066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 26166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 262b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error_msg); 26366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (dex_file.get() == nullptr) { 26466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler LOG(WARNING) << "Failed to open dex file from oat dex file: " << error_msg; 26566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return std::vector<std::unique_ptr<const DexFile>>(); 26666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 26766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files.push_back(std::move(dex_file)); 26866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 26966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load secondary multidex files 27090e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe for (size_t i = 1; ; i++) { 27190e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe std::string secondary_dex_location = DexFile::GetMultiDexLocation(i, dex_location); 27266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_dex_file = oat_file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false); 2732cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (oat_dex_file == nullptr) { 27466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // There are no more secondary dex files to load. 27566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler break; 27666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 27766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 278b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin dex_file = oat_dex_file->OpenDexFile(&error_msg); 27966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (dex_file.get() == nullptr) { 28066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler LOG(WARNING) << "Failed to open dex file from oat dex file: " << error_msg; 28166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return std::vector<std::unique_ptr<const DexFile>>(); 28266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 28366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files.push_back(std::move(dex_file)); 28466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 28566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return dex_files; 28666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 28766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2889b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhlerbool OatFileAssistant::HasOriginalDexFiles() { 2899b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Ensure GetRequiredDexChecksum has been run so that 2909b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // has_original_dex_files_ is initialized. We don't care about the result of 2919b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // GetRequiredDexChecksum. 2929b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler GetRequiredDexChecksum(); 2939b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler return has_original_dex_files_; 2949b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler} 2959b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 29666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst std::string* OatFileAssistant::OdexFileName() { 29766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!cached_odex_file_name_attempted_) { 29866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_odex_file_name_attempted_ = true; 29966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 30066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 30166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_odex_file_name_found_ = DexFilenameToOdexFilename( 302b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin dex_location_, isa_, &cached_odex_file_name_, &error_msg); 30366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!cached_odex_file_name_found_) { 30466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // If we can't figure out the odex file, we treat it as if the odex 30566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // file was inaccessible. 30666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler LOG(WARNING) << "Failed to determine odex file name: " << error_msg; 30766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 30866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 30966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return cached_odex_file_name_found_ ? &cached_odex_file_name_ : nullptr; 31066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 31166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 31266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OdexFileExists() { 31366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return GetOdexFile() != nullptr; 31466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 31566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 31695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerOatFileAssistant::OatStatus OatFileAssistant::OdexFileStatus() { 31766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OdexFileIsOutOfDate()) { 31895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatOutOfDate; 31966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 32066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OdexFileIsUpToDate()) { 32195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatUpToDate; 32266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 32395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatNeedsRelocation; 32466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 32566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 32666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OdexFileIsOutOfDate() { 32766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!odex_file_is_out_of_date_attempted_) { 32866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler odex_file_is_out_of_date_attempted_ = true; 32966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* odex_file = GetOdexFile(); 33066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (odex_file == nullptr) { 33166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_odex_file_is_out_of_date_ = true; 33266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 33366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_odex_file_is_out_of_date_ = GivenOatFileIsOutOfDate(*odex_file); 33466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 33566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 33666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return cached_odex_file_is_out_of_date_; 33766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 33866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 33966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OdexFileNeedsRelocation() { 34095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return OdexFileStatus() == kOatNeedsRelocation; 34166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 34266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 34366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OdexFileIsUpToDate() { 34466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!odex_file_is_up_to_date_attempted_) { 34566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler odex_file_is_up_to_date_attempted_ = true; 34666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* odex_file = GetOdexFile(); 34766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (odex_file == nullptr) { 34866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_odex_file_is_up_to_date_ = false; 34966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 35066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_odex_file_is_up_to_date_ = GivenOatFileIsUpToDate(*odex_file); 35166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 35266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 35366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return cached_odex_file_is_up_to_date_; 35466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 35566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 356fbc31087932a65e036a153afab3049dc5298656aMathieu Chartierstd::string OatFileAssistant::ArtFileName(const OatFile* oat_file) const { 357fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier const std::string oat_file_location = oat_file->GetLocation(); 358fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // Replace extension with .art 359fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier const size_t last_ext = oat_file_location.find_last_of('.'); 360fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (last_ext == std::string::npos) { 361fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier LOG(ERROR) << "No extension in oat file " << oat_file_location; 362fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier return std::string(); 363fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 364fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier return oat_file_location.substr(0, last_ext) + ".art"; 365fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier} 366fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier 36766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst std::string* OatFileAssistant::OatFileName() { 36866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!cached_oat_file_name_attempted_) { 36966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_name_attempted_ = true; 37066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 37166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Compute the oat file name from the dex location. 37266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // TODO: The oat file assistant should be the definitive place for 37366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // determining the oat file name from the dex location, not 37466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // GetDalvikCacheFilename. 37566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string cache_dir = StringPrintf("%s%s", 37666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler DalvikCacheDirectory().c_str(), GetInstructionSetString(isa_)); 37766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 378740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler cached_oat_file_name_found_ = GetDalvikCacheFilename(dex_location_.c_str(), 379b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin cache_dir.c_str(), &cached_oat_file_name_, &error_msg); 38066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!cached_oat_file_name_found_) { 38166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // If we can't determine the oat file name, we treat the oat file as 38266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // inaccessible. 38366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler LOG(WARNING) << "Failed to determine oat file name for dex location " 38466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << dex_location_ << ": " << error_msg; 38566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 38666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 38766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return cached_oat_file_name_found_ ? &cached_oat_file_name_ : nullptr; 38866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 38966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 39066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OatFileExists() { 39166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return GetOatFile() != nullptr; 39266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 39366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 39495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerOatFileAssistant::OatStatus OatFileAssistant::OatFileStatus() { 39566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OatFileIsOutOfDate()) { 39695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatOutOfDate; 39766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 39866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OatFileIsUpToDate()) { 39995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatUpToDate; 40066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 40195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatNeedsRelocation; 40266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 40366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 40466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OatFileIsOutOfDate() { 40566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!oat_file_is_out_of_date_attempted_) { 40666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_file_is_out_of_date_attempted_ = true; 40766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* oat_file = GetOatFile(); 40866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (oat_file == nullptr) { 40966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_is_out_of_date_ = true; 41066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 41166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_is_out_of_date_ = GivenOatFileIsOutOfDate(*oat_file); 41266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 41366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 41466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return cached_oat_file_is_out_of_date_; 41566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 41666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 41766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OatFileNeedsRelocation() { 41895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return OatFileStatus() == kOatNeedsRelocation; 41966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 42066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 42166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::OatFileIsUpToDate() { 42266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!oat_file_is_up_to_date_attempted_) { 42366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_file_is_up_to_date_attempted_ = true; 42466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* oat_file = GetOatFile(); 42566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (oat_file == nullptr) { 42666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_is_up_to_date_ = false; 42766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 42866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_is_up_to_date_ = GivenOatFileIsUpToDate(*oat_file); 42966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 43066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 43166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return cached_oat_file_is_up_to_date_; 43266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 43366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 43495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerOatFileAssistant::OatStatus OatFileAssistant::GivenOatFileStatus(const OatFile& file) { 43566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // TODO: This could cause GivenOatFileIsOutOfDate to be called twice, which 43666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // is more work than we need to do. If performance becomes a concern, and 43766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // this method is actually called, this should be fixed. 43866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (GivenOatFileIsOutOfDate(file)) { 43995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatOutOfDate; 44066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 44166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (GivenOatFileIsUpToDate(file)) { 44295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatUpToDate; 44366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 44495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return kOatNeedsRelocation; 44566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 44666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 44766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::GivenOatFileIsOutOfDate(const OatFile& file) { 44866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the dex checksum. 4492cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Note: GetOatDexFile will return null if the dex checksum doesn't match 45066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // what we provide, which verifies the primary dex checksum for us. 45166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const uint32_t* dex_checksum_pointer = GetRequiredDexChecksum(); 45266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile::OatDexFile* oat_dex_file = file.GetOatDexFile( 453740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler dex_location_.c_str(), dex_checksum_pointer, false); 4542cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (oat_dex_file == nullptr) { 45566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return true; 45666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 45766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 45866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the dex checksums for any secondary multidex files 45990e34043ff7bf8926e8fe6a6d5011a9daa68d320Andreas Gampe for (size_t i = 1; ; i++) { 46066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string secondary_dex_location 461740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler = DexFile::GetMultiDexLocation(i, dex_location_.c_str()); 46266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile::OatDexFile* secondary_oat_dex_file 46366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler = file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false); 4642cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (secondary_oat_dex_file == nullptr) { 46566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // There are no more secondary dex files to check. 46666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler break; 46766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 46866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 46966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 47066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler uint32_t expected_secondary_checksum = 0; 47166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (DexFile::GetChecksum(secondary_dex_location.c_str(), 472b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin &expected_secondary_checksum, &error_msg)) { 47366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler uint32_t actual_secondary_checksum 47466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler = secondary_oat_dex_file->GetDexFileLocationChecksum(); 47566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (expected_secondary_checksum != actual_secondary_checksum) { 47666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler VLOG(oat) << "Dex checksum does not match for secondary dex: " 47766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << secondary_dex_location 47866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << ". Expected: " << expected_secondary_checksum 47966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << ", Actual: " << actual_secondary_checksum; 48067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler return true; 48166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 48266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 48366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // If we can't get the checksum for the secondary location, we assume 48466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // the dex checksum is up to date for this and all other secondary dex 48566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // files. 48666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler break; 48766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 48866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 48966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 490a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler CompilerFilter::Filter current_compiler_filter = file.GetCompilerFilter(); 491a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "Compiler filter for " << file.GetLocation() << " is " << current_compiler_filter; 492ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 49366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the image checksum 494a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (CompilerFilter::DependsOnImageChecksum(current_compiler_filter)) { 495a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler const ImageInfo* image_info = GetImageInfo(); 496a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (image_info == nullptr) { 497a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "No image for oat image checksum to match against."; 498a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return true; 499a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 500a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler 501a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (file.GetOatHeader().GetImageFileLocationOatChecksum() != image_info->oat_checksum) { 502a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "Oat image checksum does not match image checksum."; 503a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return true; 504a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 505a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } else { 506a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "Image checksum test skipped for compiler filter " << current_compiler_filter; 50766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 50866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 509a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // Verify the profile hasn't changed recently. 510a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // TODO: Move this check to OatFileCompilerFilterIsOkay? Nothing bad should 511a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // happen if we use an oat file compiled with an out-of-date profile. 512a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (CompilerFilter::DependsOnProfile(current_compiler_filter)) { 513a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (profile_changed_) { 514a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "The profile has changed recently."; 515a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return true; 516a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 517a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } else { 518a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "Profile check skipped for compiler filter " << current_compiler_filter; 51966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 52066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 521a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // Everything looks good; the dex file is not out of date. 52266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 52366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 52466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 52566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::GivenOatFileNeedsRelocation(const OatFile& file) { 52695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler return GivenOatFileStatus(file) == kOatNeedsRelocation; 52766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 52866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 52966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::GivenOatFileIsUpToDate(const OatFile& file) { 53066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (GivenOatFileIsOutOfDate(file)) { 53166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 53266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 53366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 534a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler CompilerFilter::Filter current_compiler_filter = file.GetCompilerFilter(); 53566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 536a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // Don't consider an oat file as up-to-date with compiled code unless 537a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // compilation is enabled. This ensures we fall back to a non-executable oat 538a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // file if there is no compiled code. 539a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (!CompilerFilter::IsCompilationEnabled(current_compiler_filter)) { 540a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "Compilation not enabled for " << current_compiler_filter; 54166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 54266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 54366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 544a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (!file.IsPic()) { 545a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler const ImageInfo* image_info = GetImageInfo(); 546a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (image_info == nullptr) { 547a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "No image to check oat relocation against."; 548a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return false; 549a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 55066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 551a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // Verify the oat_data_begin recorded for the image in the oat file matches 552a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // the actual oat_data_begin for boot.oat in the image. 553a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler const OatHeader& oat_header = file.GetOatHeader(); 554a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler uintptr_t oat_data_begin = oat_header.GetImageFileLocationOatDataBegin(); 555a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (oat_data_begin != image_info->oat_data_begin) { 556a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << file.GetLocation() << 557a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler ": Oat file image oat_data_begin (" << oat_data_begin << ")" 558a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler << " does not match actual image oat_data_begin (" 559a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler << image_info->oat_data_begin << ")"; 560a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return false; 561a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 562a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler 563a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // Verify the oat_patch_delta recorded for the image in the oat file matches 564a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // the actual oat_patch_delta for the image. 565a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler int32_t oat_patch_delta = oat_header.GetImagePatchDelta(); 566a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler if (oat_patch_delta != image_info->patch_delta) { 567a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << file.GetLocation() << 568a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler ": Oat file image patch delta (" << oat_patch_delta << ")" 569a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler << " does not match actual image patch delta (" 570a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler << image_info->patch_delta << ")"; 571a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler return false; 572a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } 573a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler } else { 574a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // Oat files compiled in PIC mode do not require relocation and extract-only 575a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // oat files do not contain any compiled code. Skip the relocation test. 576a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler VLOG(oat) << "Oat relocation test skipped for PIC oat file"; 57766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 57866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return true; 57966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 58066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 58195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhlerbool OatFileAssistant::RelocateOatFile(const std::string* input_file, 58295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::string* error_msg) { 58366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(error_msg != nullptr); 58466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 58595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler if (input_file == nullptr) { 586740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler *error_msg = "Patching of oat file for dex location " + dex_location_ 58795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler + " not attempted because the input file name could not be determined."; 58866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 58966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 59095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler const std::string& input_file_name = *input_file; 59166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 59266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OatFileName() == nullptr) { 593740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler *error_msg = "Patching of oat file for dex location " + dex_location_ 59466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler + " not attempted because the oat file name could not be determined."; 59566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 59666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 59766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const std::string& oat_file_name = *OatFileName(); 59866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 59966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const ImageInfo* image_info = GetImageInfo(); 60066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Runtime* runtime = Runtime::Current(); 60166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (image_info == nullptr) { 60266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *error_msg = "Patching of oat file " + oat_file_name 60366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler + " not attempted because no image location was found."; 60466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 60566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 60666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 60766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!runtime->IsDex2OatEnabled()) { 60866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *error_msg = "Patching of oat file " + oat_file_name 60966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler + " not attempted because dex2oat is disabled"; 61066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 61166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 61266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 61366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> argv; 61466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back(runtime->GetPatchoatExecutable()); 61566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(isa_))); 61695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler argv.push_back("--input-oat-file=" + input_file_name); 61766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--output-oat-file=" + oat_file_name); 61866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--patched-image-location=" + image_info->location); 61966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 62066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string command_line(Join(argv, ' ')); 62166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!Exec(argv, error_msg)) { 62266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Manually delete the file. This ensures there is no garbage left over if 62366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // the process unexpectedly died. 62466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler TEMP_FAILURE_RETRY(unlink(oat_file_name.c_str())); 62566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 62666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 62766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 62866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Mark that the oat file has changed and we should try to reload. 62966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ClearOatFileCache(); 63066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return true; 63166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 63266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 633a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhlerbool OatFileAssistant::GenerateOatFile(CompilerFilter::Filter target, std::string* error_msg) { 63466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(error_msg != nullptr); 63566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 6368327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler Runtime* runtime = Runtime::Current(); 6378327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler if (!runtime->IsDex2OatEnabled()) { 638740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler *error_msg = "Generation of oat file for dex location " + dex_location_ 6398327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler + " not attempted because dex2oat is disabled."; 64066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 64166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 64266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 6438327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler if (OatFileName() == nullptr) { 6448327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler *error_msg = "Generation of oat file for dex location " + dex_location_ 6458327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler + " not attempted because the oat file name could not be determined."; 64666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 64766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 6488327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler const std::string& oat_file_name = *OatFileName(); 64966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 65066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // dex2oat ignores missing dex files and doesn't report an error. 65166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Check explicitly here so we can detect the error properly. 65266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // TODO: Why does dex2oat behave that way? 653740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler if (!OS::FileExists(dex_location_.c_str())) { 654740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler *error_msg = "Dex location " + dex_location_ + " does not exists."; 65566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 65666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 65766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 6588327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::unique_ptr<File> oat_file; 6598327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler oat_file.reset(OS::CreateEmptyFile(oat_file_name.c_str())); 6608327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler if (oat_file.get() == nullptr) { 6618327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler *error_msg = "Generation of oat file " + oat_file_name 6628327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler + " not attempted because the oat file could not be created."; 6638327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler return false; 6648327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler } 6658327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 6668327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler if (fchmod(oat_file->Fd(), 0644) != 0) { 6678327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler *error_msg = "Generation of oat file " + oat_file_name 6688327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler + " not attempted because the oat file could not be made world readable."; 6698327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler oat_file->Erase(); 6708327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler return false; 6718327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler } 6728327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 6738327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::vector<std::string> args; 6748327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler args.push_back("--dex-file=" + dex_location_); 6758327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler args.push_back("--oat-fd=" + std::to_string(oat_file->Fd())); 6768327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler args.push_back("--oat-location=" + oat_file_name); 677a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(target)); 6788327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 67966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!Dex2Oat(args, error_msg)) { 68066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Manually delete the file. This ensures there is no garbage left over if 68166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // the process unexpectedly died. 6828327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler oat_file->Erase(); 6838327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler TEMP_FAILURE_RETRY(unlink(oat_file_name.c_str())); 6848327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler return false; 6858327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler } 6868327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 6878327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler if (oat_file->FlushCloseOrErase() != 0) { 6888327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler *error_msg = "Unable to close oat file " + oat_file_name; 68966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler TEMP_FAILURE_RETRY(unlink(oat_file_name.c_str())); 69066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 69166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 69266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 69366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Mark that the oat file has changed and we should try to reload. 69466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ClearOatFileCache(); 69566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return true; 69666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 69766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 69866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::Dex2Oat(const std::vector<std::string>& args, 69966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string* error_msg) { 70066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Runtime* runtime = Runtime::Current(); 70166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string image_location = ImageLocation(); 70266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (image_location.empty()) { 70366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *error_msg = "No image location found for Dex2Oat."; 70466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 70566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 70666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 70766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> argv; 70866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back(runtime->GetCompilerExecutable()); 70966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--runtime-arg"); 71066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("-classpath"); 71166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--runtime-arg"); 71266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back(runtime->GetClassPathString()); 7137a4d0157eb690266928902a67922f346e290f4c6Nicolas Geoffray if (runtime->IsDebuggable()) { 7140de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz argv.push_back("--debuggable"); 7150de1133ba600f299b3d67938f650720d9f859eb2Sebastien Hertz } 716b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv); 71766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 71866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!runtime->IsVerificationEnabled()) { 71966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--compiler-filter=verify-none"); 72066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 72166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 72266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (runtime->MustRelocateIfPossible()) { 72366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--runtime-arg"); 72466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("-Xrelocate"); 72566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 72666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--runtime-arg"); 72766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("-Xnorelocate"); 72866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 72966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 73066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!kIsTargetBuild) { 73166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--host"); 73266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 73366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 73466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.push_back("--boot-image=" + image_location); 73566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 73666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> compiler_options = runtime->GetCompilerOptions(); 73766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.insert(argv.end(), compiler_options.begin(), compiler_options.end()); 73866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 73966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler argv.insert(argv.end(), args.begin(), args.end()); 74066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 74166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string command_line(Join(argv, ' ')); 74266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return Exec(argv, error_msg); 74366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 74466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 74566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerbool OatFileAssistant::DexFilenameToOdexFilename(const std::string& location, 74666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler InstructionSet isa, std::string* odex_filename, std::string* error_msg) { 74766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(odex_filename != nullptr); 74866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(error_msg != nullptr); 74966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 75066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // The odex file name is formed by replacing the dex_location extension with 7516343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler // .odex and inserting an oat/<isa> directory. For example: 75266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // location = /foo/bar/baz.jar 7536343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler // odex_location = /foo/bar/oat/<isa>/baz.odex 75466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 7556343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler // Find the directory portion of the dex location and add the oat/<isa> 7566343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler // directory. 75766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler size_t pos = location.rfind('/'); 75866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (pos == std::string::npos) { 75966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *error_msg = "Dex location " + location + " has no directory."; 76066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 76166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 76266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dir = location.substr(0, pos+1); 7636343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler dir += "oat/" + std::string(GetInstructionSetString(isa)); 76466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 76566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Find the file portion of the dex location. 76666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string file; 76766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (pos == std::string::npos) { 76866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler file = location; 76966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 77066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler file = location.substr(pos+1); 77166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 77266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 77366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Get the base part of the file without the extension. 77466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler pos = file.rfind('.'); 77566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (pos == std::string::npos) { 77666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *error_msg = "Dex location " + location + " has no extension."; 77766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return false; 77866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 77966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string base = file.substr(0, pos); 78066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 78166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler *odex_filename = dir + "/" + base + ".odex"; 78266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return true; 78366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 78466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 78566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstd::string OatFileAssistant::DalvikCacheDirectory() { 78666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Note: We don't cache this, because it will only be called once by 787a62d2f04a6ecf804f8a78e722a6ca8ccb2dfa931Richard Uhler // OatFileName. 78866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 78966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // TODO: The work done in GetDalvikCache is overkill for what we need. 79066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Ideally a new API for getting the DalvikCacheDirectory the way we want 79166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // (without existence testing, creation, or death) is provided with the rest 79266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // of the GetDalvikCache family of functions. Until such an API is in place, 79366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // we use GetDalvikCache to avoid duplicating the logic for determining the 79466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // dalvik cache directory. 79566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string result; 79666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler bool have_android_data; 79766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler bool dalvik_cache_exists; 79866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler bool is_global_cache; 79966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GetDalvikCache("", false, &result, &have_android_data, &dalvik_cache_exists, &is_global_cache); 80066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return result; 80166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 80266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 80366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstd::string OatFileAssistant::ImageLocation() { 80466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Runtime* runtime = Runtime::Current(); 8058994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe const std::vector<gc::space::ImageSpace*>& image_spaces = 8068994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe runtime->GetHeap()->GetBootImageSpaces(); 8078994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe if (image_spaces.empty()) { 8088994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe return ""; 8098994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe } 8108994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe return image_spaces[0]->GetImageLocation(); 81166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 81266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 81366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst uint32_t* OatFileAssistant::GetRequiredDexChecksum() { 8149b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler if (!required_dex_checksum_attempted_) { 8159b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler required_dex_checksum_attempted_ = true; 8169b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler required_dex_checksum_found_ = false; 81766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 818740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler if (DexFile::GetChecksum(dex_location_.c_str(), &cached_required_dex_checksum_, &error_msg)) { 8199b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler required_dex_checksum_found_ = true; 8209b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler has_original_dex_files_ = true; 82166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 82266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // This can happen if the original dex file has been stripped from the 82366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // apk. 82466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler VLOG(oat) << "OatFileAssistant: " << error_msg; 8259b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler has_original_dex_files_ = false; 82666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 82766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Get the checksum from the odex if we can. 82866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* odex_file = GetOdexFile(); 82966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (odex_file != nullptr) { 83066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile::OatDexFile* odex_dex_file = odex_file->GetOatDexFile( 831740eec92a7f63e8ddff1e007ae624d548a4e5a16Richard Uhler dex_location_.c_str(), nullptr, false); 83266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (odex_dex_file != nullptr) { 8339b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler cached_required_dex_checksum_ = odex_dex_file->GetDexFileLocationChecksum(); 8349b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler required_dex_checksum_found_ = true; 83566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 83666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 83766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 83866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 8399b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler return required_dex_checksum_found_ ? &cached_required_dex_checksum_ : nullptr; 84066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 84166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 84266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst OatFile* OatFileAssistant::GetOdexFile() { 84366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(!oat_file_released_) << "OdexFile called after oat file released."; 84466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!odex_file_load_attempted_) { 84566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler odex_file_load_attempted_ = true; 84666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OdexFileName() != nullptr) { 84766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const std::string& odex_file_name = *OdexFileName(); 84866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 84966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_odex_file_.reset(OatFile::Open(odex_file_name.c_str(), 8500b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier odex_file_name.c_str(), 8510b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier nullptr, 8520b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier nullptr, 8530b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier load_executable_, 8540b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier /*low_4gb*/false, 8550b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier dex_location_.c_str(), 8560b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier &error_msg)); 85766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (cached_odex_file_.get() == nullptr) { 85866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler VLOG(oat) << "OatFileAssistant test for existing pre-compiled oat file " 85966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << odex_file_name << ": " << error_msg; 86066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 86166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 86266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 86366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return cached_odex_file_.get(); 86466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 86566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 8665f946da9c362216e9144b142ec0e5b90073b836dRichard Uhlerbool OatFileAssistant::OdexFileIsExecutable() { 8675f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler const OatFile* odex_file = GetOdexFile(); 8685f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler return (odex_file != nullptr && odex_file->IsExecutable()); 8695f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler} 8705f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler 87166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlervoid OatFileAssistant::ClearOdexFileCache() { 87266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler odex_file_load_attempted_ = false; 87366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_odex_file_.reset(); 87466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler odex_file_is_out_of_date_attempted_ = false; 87566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler odex_file_is_up_to_date_attempted_ = false; 87666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 87766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 87866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst OatFile* OatFileAssistant::GetOatFile() { 87966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(!oat_file_released_) << "OatFile called after oat file released."; 88066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!oat_file_load_attempted_) { 88166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_file_load_attempted_ = true; 88266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (OatFileName() != nullptr) { 88366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const std::string& oat_file_name = *OatFileName(); 88466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 88566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_.reset(OatFile::Open(oat_file_name.c_str(), 8860b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier oat_file_name.c_str(), 8870b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier nullptr, 8880b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier nullptr, 8890b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier load_executable_, 8900b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier /*low_4gb*/false, 8910b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier dex_location_.c_str(), 8920b4cbd0c2a75b47ae09d21e5d73d2b1709cb5b9eMathieu Chartier &error_msg)); 89366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (cached_oat_file_.get() == nullptr) { 89466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler VLOG(oat) << "OatFileAssistant test for existing oat file " 89566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << oat_file_name << ": " << error_msg; 89666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 89766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 89866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 89966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return cached_oat_file_.get(); 90066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 90166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 9025f946da9c362216e9144b142ec0e5b90073b836dRichard Uhlerbool OatFileAssistant::OatFileIsExecutable() { 9035f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler const OatFile* oat_file = GetOatFile(); 9045f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler return (oat_file != nullptr && oat_file->IsExecutable()); 9055f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler} 9065f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler 90766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlervoid OatFileAssistant::ClearOatFileCache() { 90866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_file_load_attempted_ = false; 90966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_oat_file_.reset(); 91066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_file_is_out_of_date_attempted_ = false; 91166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler oat_file_is_up_to_date_attempted_ = false; 91266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 91366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 91466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerconst OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() { 91566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (!image_info_load_attempted_) { 91666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler image_info_load_attempted_ = true; 91766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 91866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Runtime* runtime = Runtime::Current(); 919dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao std::vector<gc::space::ImageSpace*> image_spaces = runtime->GetHeap()->GetBootImageSpaces(); 920dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao if (!image_spaces.empty()) { 921dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao cached_image_info_.location = image_spaces[0]->GetImageLocation(); 92266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 92366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (isa_ == kRuntimeISA) { 924dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao const ImageHeader& image_header = image_spaces[0]->GetImageHeader(); 92566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_image_info_.oat_checksum = image_header.GetOatChecksum(); 926073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>( 927073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier image_header.GetOatDataBegin()); 92866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_image_info_.patch_delta = image_header.GetPatchDelta(); 92966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 93066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<ImageHeader> image_header( 93166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler gc::space::ImageSpace::ReadImageHeaderOrDie( 93266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_image_info_.location.c_str(), isa_)); 93366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_image_info_.oat_checksum = image_header->GetOatChecksum(); 934073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>( 935073b16c8429d302d5413e8ffc488b03b8f770780Mathieu Chartier image_header->GetOatDataBegin()); 93666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cached_image_info_.patch_delta = image_header->GetPatchDelta(); 93766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 93866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 939dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao image_info_load_succeeded_ = (!image_spaces.empty()); 94066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 94166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return image_info_load_succeeded_ ? &cached_image_info_ : nullptr; 94266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 94366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 944fbc31087932a65e036a153afab3049dc5298656aMathieu Chartiergc::space::ImageSpace* OatFileAssistant::OpenImageSpace(const OatFile* oat_file) { 945fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier DCHECK(oat_file != nullptr); 946fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier std::string art_file = ArtFileName(oat_file); 947fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier if (art_file.empty()) { 948fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier return nullptr; 949fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 950fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier std::string error_msg; 951fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier ScopedObjectAccess soa(Thread::Current()); 952fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier gc::space::ImageSpace* ret = gc::space::ImageSpace::CreateFromAppImage(art_file.c_str(), 953fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier oat_file, 954fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier &error_msg); 955e778fc7332238534b173c2c3e0c4502d12f58da3Mathieu Chartier if (ret == nullptr && (VLOG_IS_ON(image) || OS::FileExists(art_file.c_str()))) { 956fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier LOG(INFO) << "Failed to open app image " << art_file.c_str() << " " << error_msg; 957fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier } 958fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier return ret; 959fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier} 960fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier 96166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} // namespace art 96266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 963