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