diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
new file mode 100644
index 0000000..f87fa4f
--- /dev/null
+++ b/runtime/oat_file_assistant.cc
@@ -0,0 +1,952 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "oat_file_assistant.h"
+
+#include <fcntl.h>
+#ifdef __linux__
+#include <sys/sendfile.h>
+#else
+#include <sys/socket.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <set>
+
+#include "base/logging.h"
+#include "base/stringprintf.h"
+#include "class_linker.h"
+#include "gc/heap.h"
+#include "gc/space/image_space.h"
+#include "image.h"
+#include "oat.h"
+#include "os.h"
+#include "profiler.h"
+#include "runtime.h"
+#include "ScopedFd.h"
+#include "utils.h"
+
+namespace art {
+
+OatFileAssistant::OatFileAssistant(const char* dex_location,
+                                   const InstructionSet isa,
+                                   bool load_executable)
+    : OatFileAssistant(dex_location, nullptr, isa, load_executable, nullptr) { }
+
+OatFileAssistant::OatFileAssistant(const char* dex_location,
+                                   const char* oat_location,
+                                   const InstructionSet isa,
+                                   bool load_executable)
+    : OatFileAssistant(dex_location, oat_location, isa, load_executable, nullptr) { }
+
+OatFileAssistant::OatFileAssistant(const char* dex_location,
+                                   const InstructionSet isa,
+                                   bool load_executable,
+                                   const char* package_name)
+    : OatFileAssistant(dex_location, nullptr, isa, load_executable, package_name) { }
+
+OatFileAssistant::OatFileAssistant(const char* dex_location,
+                                   const char* oat_location,
+                                   const InstructionSet isa,
+                                   bool load_executable,
+                                   const char* package_name)
+    : dex_location_(dex_location), isa_(isa),
+      package_name_(package_name), load_executable_(load_executable) {
+  if (load_executable_ && isa != kRuntimeISA) {
+    LOG(WARNING) << "OatFileAssistant: Load executable specified, "
+      << "but isa is not kRuntimeISA. Will not attempt to load executable.";
+    load_executable_ = false;
+  }
+
+  // If the user gave a target oat location, save that as the cached oat
+  // location now so we won't try to construct the default location later.
+  if (oat_location != nullptr) {
+    cached_oat_file_name_ = std::string(oat_location);
+    cached_oat_file_name_attempted_ = true;
+    cached_oat_file_name_found_ = true;
+  }
+
+  // If there is no package name given, we will not be able to find any
+  // profiles associated with this dex location. Preemptively mark that to
+  // be the case, rather than trying to find and load the profiles later.
+  // Similarly, if profiling is disabled.
+  if (package_name == nullptr
+      || !Runtime::Current()->GetProfilerOptions().IsEnabled()) {
+    profile_load_attempted_ = true;
+    profile_load_succeeded_ = false;
+    old_profile_load_attempted_ = true;
+    old_profile_load_succeeded_ = false;
+  }
+}
+
+OatFileAssistant::~OatFileAssistant() {
+  // Clean up the lock file.
+  if (lock_file_.get() != nullptr) {
+    lock_file_->Erase();
+    TEMP_FAILURE_RETRY(unlink(lock_file_->GetPath().c_str()));
+  }
+}
+
+bool OatFileAssistant::IsInBootClassPath() {
+  // Note: We check the current boot class path, regardless of the ISA
+  // specified by the user. This is okay, because the boot class path should
+  // be the same for all ISAs.
+  // TODO: Can we verify the boot class path is the same for all ISAs?
+  Runtime* runtime = Runtime::Current();
+  ClassLinker* class_linker = runtime->GetClassLinker();
+  const auto& boot_class_path = class_linker->GetBootClassPath();
+  for (size_t i = 0; i < boot_class_path.size(); i++) {
+    if (boot_class_path[i]->GetLocation() == std::string(dex_location_)) {
+      VLOG(oat) << "Dex location " << dex_location_ << " is in boot class path";
+      return true;
+    }
+  }
+  return false;
+}
+
+bool OatFileAssistant::Lock(std::string* error_msg) {
+  CHECK(error_msg != nullptr);
+  CHECK(lock_file_.get() == nullptr) << "OatFileAssistant::Lock already acquired";
+
+  if (OatFileName() == nullptr) {
+    *error_msg = "Failed to determine lock file";
+    return false;
+  }
+  std::string lock_file_name = *OatFileName() + ".flock";
+
+  lock_file_.reset(OS::CreateEmptyFile(lock_file_name.c_str()));
+  if (lock_file_.get() == nullptr) {
+    *error_msg = "Failed to create lock file " + lock_file_name;
+    return false;
+  }
+
+  if (!flock_.Init(lock_file_.get(), error_msg)) {
+    TEMP_FAILURE_RETRY(unlink(lock_file_name.c_str()));
+    return false;
+  }
+  return true;
+}
+
+OatFileAssistant::Status OatFileAssistant::GetStatus() {
+  // TODO: If the profiling code is ever restored, it's worth considering
+  // whether we should check to see if the profile is out of date here.
+
+  if (OdexFileIsOutOfDate()) {
+    // The DEX file is not pre-compiled.
+    // TODO: What if the oat file is not out of date? Could we relocate it
+    // from itself?
+    return OatFileIsUpToDate() ? kUpToDate : kOutOfDate;
+  } else {
+    // The DEX file is pre-compiled. If the oat file isn't up to date, we can
+    // patch the pre-compiled version rather than recompiling.
+    if (OatFileIsUpToDate() || OdexFileIsUpToDate()) {
+      return kUpToDate;
+    } else {
+      return kNeedsRelocation;
+    }
+  }
+}
+
+bool OatFileAssistant::MakeUpToDate(std::string* error_msg) {
+  switch (GetStatus()) {
+    case kUpToDate: return true;
+    case kNeedsRelocation: return RelocateOatFile(error_msg);
+    case kOutOfDate: return GenerateOatFile(error_msg);
+  }
+  UNREACHABLE();
+}
+
+std::unique_ptr<OatFile> OatFileAssistant::GetBestOatFile() {
+  if (OatFileIsUpToDate()) {
+    oat_file_released_ = true;
+    return std::move(cached_oat_file_);
+  }
+
+  if (OdexFileIsUpToDate()) {
+    oat_file_released_ = true;
+    return std::move(cached_odex_file_);
+  }
+
+  if (load_executable_) {
+    VLOG(oat) << "Oat File Assistant: No relocated oat file found,"
+      << " attempting to fall back to interpreting oat file instead.";
+
+    if (!OatFileIsOutOfDate()) {
+      load_executable_ = false;
+      ClearOatFileCache();
+      if (!OatFileIsOutOfDate()) {
+        oat_file_released_ = true;
+        return std::move(cached_oat_file_);
+      }
+    }
+
+    if (!OdexFileIsOutOfDate()) {
+      load_executable_ = false;
+      ClearOdexFileCache();
+      if (!OdexFileIsOutOfDate()) {
+        oat_file_released_ = true;
+        return std::move(cached_odex_file_);
+      }
+    }
+  }
+
+  return std::unique_ptr<OatFile>();
+}
+
+std::vector<std::unique_ptr<const DexFile>> OatFileAssistant::LoadDexFiles(
+    const OatFile& oat_file, const char* dex_location) {
+  std::vector<std::unique_ptr<const DexFile>> dex_files;
+
+  // Load the primary dex file.
+  std::string error_msg;
+  const OatFile::OatDexFile* oat_dex_file = oat_file.GetOatDexFile(
+      dex_location, nullptr, false);
+  if (oat_dex_file == nullptr) {
+    LOG(WARNING) << "Attempt to load out-of-date oat file "
+      << oat_file.GetLocation() << " for dex location " << dex_location;
+    return std::vector<std::unique_ptr<const DexFile>>();
+  }
+
+  std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error_msg);
+  if (dex_file.get() == nullptr) {
+    LOG(WARNING) << "Failed to open dex file from oat dex file: " << error_msg;
+    return std::vector<std::unique_ptr<const DexFile>>();
+  }
+  dex_files.push_back(std::move(dex_file));
+
+  // Load secondary multidex files
+  for (int i = 1; ; i++) {
+    std::string secondary_dex_location = DexFile::GetMultiDexClassesDexName(i, dex_location);
+    oat_dex_file = oat_file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false);
+    if (oat_dex_file == NULL) {
+      // There are no more secondary dex files to load.
+      break;
+    }
+
+    dex_file = oat_dex_file->OpenDexFile(&error_msg);
+    if (dex_file.get() == nullptr) {
+      LOG(WARNING) << "Failed to open dex file from oat dex file: " << error_msg;
+      return std::vector<std::unique_ptr<const DexFile>>();
+    }
+    dex_files.push_back(std::move(dex_file));
+  }
+  return dex_files;
+}
+
+const std::string* OatFileAssistant::OdexFileName() {
+  if (!cached_odex_file_name_attempted_) {
+    CHECK(dex_location_ != nullptr) << "OatFileAssistant: null dex location";
+    cached_odex_file_name_attempted_ = true;
+
+    std::string error_msg;
+    cached_odex_file_name_found_ = DexFilenameToOdexFilename(
+        dex_location_, isa_, &cached_odex_file_name_, &error_msg);
+    if (!cached_odex_file_name_found_) {
+      // If we can't figure out the odex file, we treat it as if the odex
+      // file was inaccessible.
+      LOG(WARNING) << "Failed to determine odex file name: " << error_msg;
+    }
+  }
+  return cached_odex_file_name_found_ ? &cached_odex_file_name_ : nullptr;
+}
+
+bool OatFileAssistant::OdexFileExists() {
+  return GetOdexFile() != nullptr;
+}
+
+OatFileAssistant::Status OatFileAssistant::OdexFileStatus() {
+  if (OdexFileIsOutOfDate()) {
+    return kOutOfDate;
+  }
+  if (OdexFileIsUpToDate()) {
+    return kUpToDate;
+  }
+  return kNeedsRelocation;
+}
+
+bool OatFileAssistant::OdexFileIsOutOfDate() {
+  if (!odex_file_is_out_of_date_attempted_) {
+    odex_file_is_out_of_date_attempted_ = true;
+    const OatFile* odex_file = GetOdexFile();
+    if (odex_file == nullptr) {
+      cached_odex_file_is_out_of_date_ = true;
+    } else {
+      cached_odex_file_is_out_of_date_ = GivenOatFileIsOutOfDate(*odex_file);
+    }
+  }
+  return cached_odex_file_is_out_of_date_;
+}
+
+bool OatFileAssistant::OdexFileNeedsRelocation() {
+  return OdexFileStatus() == kNeedsRelocation;
+}
+
+bool OatFileAssistant::OdexFileIsUpToDate() {
+  if (!odex_file_is_up_to_date_attempted_) {
+    odex_file_is_up_to_date_attempted_ = true;
+    const OatFile* odex_file = GetOdexFile();
+    if (odex_file == nullptr) {
+      cached_odex_file_is_up_to_date_ = false;
+    } else {
+      cached_odex_file_is_up_to_date_ = GivenOatFileIsUpToDate(*odex_file);
+    }
+  }
+  return cached_odex_file_is_up_to_date_;
+}
+
+const std::string* OatFileAssistant::OatFileName() {
+  if (!cached_oat_file_name_attempted_) {
+    cached_oat_file_name_attempted_ = true;
+
+    // Compute the oat file name from the dex location.
+    CHECK(dex_location_ != nullptr) << "OatFileAssistant: null dex location";
+
+    // TODO: The oat file assistant should be the definitive place for
+    // determining the oat file name from the dex location, not
+    // GetDalvikCacheFilename.
+    std::string cache_dir = StringPrintf("%s%s",
+        DalvikCacheDirectory().c_str(), GetInstructionSetString(isa_));
+    std::string error_msg;
+    cached_oat_file_name_found_ = GetDalvikCacheFilename(dex_location_,
+        cache_dir.c_str(), &cached_oat_file_name_, &error_msg);
+    if (!cached_oat_file_name_found_) {
+      // If we can't determine the oat file name, we treat the oat file as
+      // inaccessible.
+      LOG(WARNING) << "Failed to determine oat file name for dex location "
+        << dex_location_ << ": " << error_msg;
+    }
+  }
+  return cached_oat_file_name_found_ ? &cached_oat_file_name_ : nullptr;
+}
+
+bool OatFileAssistant::OatFileExists() {
+  return GetOatFile() != nullptr;
+}
+
+OatFileAssistant::Status OatFileAssistant::OatFileStatus() {
+  if (OatFileIsOutOfDate()) {
+    return kOutOfDate;
+  }
+  if (OatFileIsUpToDate()) {
+    return kUpToDate;
+  }
+  return kNeedsRelocation;
+}
+
+bool OatFileAssistant::OatFileIsOutOfDate() {
+  if (!oat_file_is_out_of_date_attempted_) {
+    oat_file_is_out_of_date_attempted_ = true;
+    const OatFile* oat_file = GetOatFile();
+    if (oat_file == nullptr) {
+      cached_oat_file_is_out_of_date_ = true;
+    } else {
+      cached_oat_file_is_out_of_date_ = GivenOatFileIsOutOfDate(*oat_file);
+    }
+  }
+  return cached_oat_file_is_out_of_date_;
+}
+
+bool OatFileAssistant::OatFileNeedsRelocation() {
+  return OatFileStatus() == kNeedsRelocation;
+}
+
+bool OatFileAssistant::OatFileIsUpToDate() {
+  if (!oat_file_is_up_to_date_attempted_) {
+    oat_file_is_up_to_date_attempted_ = true;
+    const OatFile* oat_file = GetOatFile();
+    if (oat_file == nullptr) {
+      cached_oat_file_is_up_to_date_ = false;
+    } else {
+      cached_oat_file_is_up_to_date_ = GivenOatFileIsUpToDate(*oat_file);
+    }
+  }
+  return cached_oat_file_is_up_to_date_;
+}
+
+OatFileAssistant::Status OatFileAssistant::GivenOatFileStatus(const OatFile& file) {
+  // TODO: This could cause GivenOatFileIsOutOfDate to be called twice, which
+  // is more work than we need to do. If performance becomes a concern, and
+  // this method is actually called, this should be fixed.
+  if (GivenOatFileIsOutOfDate(file)) {
+    return kOutOfDate;
+  }
+  if (GivenOatFileIsUpToDate(file)) {
+    return kUpToDate;
+  }
+  return kNeedsRelocation;
+}
+
+bool OatFileAssistant::GivenOatFileIsOutOfDate(const OatFile& file) {
+  // Verify the dex checksum.
+  // Note: GetOatDexFile will return NULL if the dex checksum doesn't match
+  // what we provide, which verifies the primary dex checksum for us.
+  const uint32_t* dex_checksum_pointer = GetRequiredDexChecksum();
+  const OatFile::OatDexFile* oat_dex_file = file.GetOatDexFile(
+      dex_location_, dex_checksum_pointer, false);
+  if (oat_dex_file == NULL) {
+    return true;
+  }
+
+  // Verify the dex checksums for any secondary multidex files
+  for (int i = 1; ; i++) {
+    std::string secondary_dex_location
+      = DexFile::GetMultiDexClassesDexName(i, dex_location_);
+    const OatFile::OatDexFile* secondary_oat_dex_file
+      = file.GetOatDexFile(secondary_dex_location.c_str(), nullptr, false);
+    if (secondary_oat_dex_file == NULL) {
+      // There are no more secondary dex files to check.
+      break;
+    }
+
+    std::string error_msg;
+    uint32_t expected_secondary_checksum = 0;
+    if (DexFile::GetChecksum(secondary_dex_location.c_str(),
+          &expected_secondary_checksum, &error_msg)) {
+      uint32_t actual_secondary_checksum
+        = secondary_oat_dex_file->GetDexFileLocationChecksum();
+      if (expected_secondary_checksum != actual_secondary_checksum) {
+        VLOG(oat) << "Dex checksum does not match for secondary dex: "
+          << secondary_dex_location
+          << ". Expected: " << expected_secondary_checksum
+          << ", Actual: " << actual_secondary_checksum;
+        return false;
+      }
+    } else {
+      // If we can't get the checksum for the secondary location, we assume
+      // the dex checksum is up to date for this and all other secondary dex
+      // files.
+      break;
+    }
+  }
+
+  // Verify the image checksum
+  const ImageInfo* image_info = GetImageInfo();
+  if (image_info == nullptr) {
+    VLOG(oat) << "No image for oat image checksum to match against.";
+    return true;
+  }
+
+  if (file.GetOatHeader().GetImageFileLocationOatChecksum() != image_info->oat_checksum) {
+    VLOG(oat) << "Oat image checksum does not match image checksum.";
+    return true;
+  }
+
+  // The checksums are all good; the dex file is not out of date.
+  return false;
+}
+
+bool OatFileAssistant::GivenOatFileNeedsRelocation(const OatFile& file) {
+  return GivenOatFileStatus(file) == kNeedsRelocation;
+}
+
+bool OatFileAssistant::GivenOatFileIsUpToDate(const OatFile& file) {
+  if (GivenOatFileIsOutOfDate(file)) {
+    return false;
+  }
+
+  if (file.IsPic()) {
+    return true;
+  }
+
+  const ImageInfo* image_info = GetImageInfo();
+  if (image_info == nullptr) {
+    VLOG(oat) << "No image for to check oat relocation against.";
+    return false;
+  }
+
+  // Verify the oat_data_begin recorded for the image in the oat file matches
+  // the actual oat_data_begin for boot.oat in the image.
+  const OatHeader& oat_header = file.GetOatHeader();
+  uintptr_t oat_data_begin = oat_header.GetImageFileLocationOatDataBegin();
+  if (oat_data_begin != image_info->oat_data_begin) {
+    VLOG(oat) << file.GetLocation() <<
+      ": Oat file image oat_data_begin (" << oat_data_begin << ")"
+      << " does not match actual image oat_data_begin ("
+      << image_info->oat_data_begin << ")";
+    return false;
+  }
+
+  // Verify the oat_patch_delta recorded for the image in the oat file matches
+  // the actual oat_patch_delta for the image.
+  int32_t oat_patch_delta = oat_header.GetImagePatchDelta();
+  if (oat_patch_delta != image_info->patch_delta) {
+    VLOG(oat) << file.GetLocation() <<
+      ": Oat file image patch delta (" << oat_patch_delta << ")"
+      << " does not match actual image patch delta ("
+      << image_info->patch_delta << ")";
+    return false;
+  }
+  return true;
+}
+
+bool OatFileAssistant::ProfileExists() {
+  return GetProfile() != nullptr;
+}
+
+bool OatFileAssistant::OldProfileExists() {
+  return GetOldProfile() != nullptr;
+}
+
+// TODO: The IsProfileChangeSignificant implementation was copied from likely
+// bit-rotted code.
+bool OatFileAssistant::IsProfileChangeSignificant() {
+  ProfileFile* profile = GetProfile();
+  if (profile == nullptr) {
+    return false;
+  }
+
+  ProfileFile* old_profile = GetOldProfile();
+  if (old_profile == nullptr) {
+    return false;
+  }
+
+  // TODO: The following code to compare two profile files should live with
+  // the rest of the profiler code, not the oat file assistant code.
+
+  // A change in profile is considered significant if X% (change_thr property)
+  // of the top K% (compile_thr property) samples has changed.
+  const ProfilerOptions& options = Runtime::Current()->GetProfilerOptions();
+  const double top_k_threshold = options.GetTopKThreshold();
+  const double change_threshold = options.GetTopKChangeThreshold();
+  std::set<std::string> top_k, old_top_k;
+  profile->GetTopKSamples(top_k, top_k_threshold);
+  old_profile->GetTopKSamples(old_top_k, top_k_threshold);
+  std::set<std::string> diff;
+  std::set_difference(top_k.begin(), top_k.end(), old_top_k.begin(),
+      old_top_k.end(), std::inserter(diff, diff.end()));
+
+  // TODO: consider using the usedPercentage instead of the plain diff count.
+  double change_percent = 100.0 * static_cast<double>(diff.size())
+                                / static_cast<double>(top_k.size());
+  std::set<std::string>::iterator end = diff.end();
+  for (std::set<std::string>::iterator it = diff.begin(); it != end; it++) {
+    VLOG(oat) << "Profile new in topK: " << *it;
+  }
+
+  if (change_percent > change_threshold) {
+      VLOG(oat) << "Oat File Assistant: Profile for " << dex_location_
+        << "has changed significantly: (top "
+        << top_k_threshold << "% samples changed in proportion of "
+        << change_percent << "%)";
+      return true;
+  }
+  return false;
+}
+
+// TODO: The CopyProfileFile implementation was copied from likely bit-rotted
+// code.
+void OatFileAssistant::CopyProfileFile() {
+  if (!ProfileExists()) {
+    return;
+  }
+
+  std::string profile_name = ProfileFileName();
+  std::string old_profile_name = OldProfileFileName();
+
+  ScopedFd src(open(old_profile_name.c_str(), O_RDONLY));
+  if (src.get() == -1) {
+    PLOG(WARNING) << "Failed to open profile file " << old_profile_name
+      << ". My uid:gid is " << getuid() << ":" << getgid();
+    return;
+  }
+
+  struct stat stat_src;
+  if (fstat(src.get(), &stat_src) == -1) {
+    PLOG(WARNING) << "Failed to get stats for profile file  " << old_profile_name
+      << ". My uid:gid is " << getuid() << ":" << getgid();
+    return;
+  }
+
+  // Create the copy with rw------- (only accessible by system)
+  ScopedFd dst(open(profile_name.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0600));
+  if (dst.get()  == -1) {
+    PLOG(WARNING) << "Failed to create/write prev profile file " << profile_name
+      << ".  My uid:gid is " << getuid() << ":" << getgid();
+    return;
+  }
+
+#ifdef __linux__
+  if (sendfile(dst.get(), src.get(), nullptr, stat_src.st_size) == -1) {
+#else
+  off_t len;
+  if (sendfile(dst.get(), src.get(), 0, &len, nullptr, 0) == -1) {
+#endif
+    PLOG(WARNING) << "Failed to copy profile file " << old_profile_name
+      << " to " << profile_name << ". My uid:gid is " << getuid()
+      << ":" << getgid();
+  }
+}
+
+bool OatFileAssistant::RelocateOatFile(std::string* error_msg) {
+  CHECK(error_msg != nullptr);
+
+  if (OdexFileName() == nullptr) {
+    *error_msg = "Patching of oat file for dex location "
+      + std::string(dex_location_)
+      + " not attempted because the odex file name could not be determined.";
+    return false;
+  }
+  const std::string& odex_file_name = *OdexFileName();
+
+  if (OatFileName() == nullptr) {
+    *error_msg = "Patching of oat file for dex location "
+      + std::string(dex_location_)
+      + " not attempted because the oat file name could not be determined.";
+    return false;
+  }
+  const std::string& oat_file_name = *OatFileName();
+
+  const ImageInfo* image_info = GetImageInfo();
+  Runtime* runtime = Runtime::Current();
+  if (image_info == nullptr) {
+    *error_msg = "Patching of oat file " + oat_file_name
+      + " not attempted because no image location was found.";
+    return false;
+  }
+
+  if (!runtime->IsDex2OatEnabled()) {
+    *error_msg = "Patching of oat file " + oat_file_name
+      + " not attempted because dex2oat is disabled";
+    return false;
+  }
+
+  std::vector<std::string> argv;
+  argv.push_back(runtime->GetPatchoatExecutable());
+  argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(isa_)));
+  argv.push_back("--input-oat-file=" + odex_file_name);
+  argv.push_back("--output-oat-file=" + oat_file_name);
+  argv.push_back("--patched-image-location=" + image_info->location);
+
+  std::string command_line(Join(argv, ' '));
+  if (!Exec(argv, error_msg)) {
+    // Manually delete the file. This ensures there is no garbage left over if
+    // the process unexpectedly died.
+    TEMP_FAILURE_RETRY(unlink(oat_file_name.c_str()));
+    return false;
+  }
+
+  // Mark that the oat file has changed and we should try to reload.
+  ClearOatFileCache();
+  return true;
+}
+
+bool OatFileAssistant::GenerateOatFile(std::string* error_msg) {
+  CHECK(error_msg != nullptr);
+
+  if (OatFileName() == nullptr) {
+    *error_msg = "Generation of oat file for dex location "
+      + std::string(dex_location_)
+      + " not attempted because the oat file name could not be determined.";
+    return false;
+  }
+  const std::string& oat_file_name = *OatFileName();
+
+  Runtime* runtime = Runtime::Current();
+  if (!runtime->IsDex2OatEnabled()) {
+    *error_msg = "Generation of oat file " + oat_file_name
+      + " not attempted because dex2oat is disabled";
+    return false;
+  }
+
+  std::vector<std::string> args;
+  args.push_back("--dex-file=" + std::string(dex_location_));
+  args.push_back("--oat-file=" + oat_file_name);
+
+  // dex2oat ignores missing dex files and doesn't report an error.
+  // Check explicitly here so we can detect the error properly.
+  // TODO: Why does dex2oat behave that way?
+  if (!OS::FileExists(dex_location_)) {
+    *error_msg = "Dex location " + std::string(dex_location_) + " does not exists.";
+    return false;
+  }
+
+  if (!Dex2Oat(args, error_msg)) {
+    // Manually delete the file. This ensures there is no garbage left over if
+    // the process unexpectedly died.
+    TEMP_FAILURE_RETRY(unlink(oat_file_name.c_str()));
+    return false;
+  }
+
+  // Mark that the oat file has changed and we should try to reload.
+  ClearOatFileCache();
+  return true;
+}
+
+bool OatFileAssistant::Dex2Oat(const std::vector<std::string>& args,
+                               std::string* error_msg) {
+  Runtime* runtime = Runtime::Current();
+  std::string image_location = ImageLocation();
+  if (image_location.empty()) {
+    *error_msg = "No image location found for Dex2Oat.";
+    return false;
+  }
+
+  std::vector<std::string> argv;
+  argv.push_back(runtime->GetCompilerExecutable());
+  argv.push_back("--runtime-arg");
+  argv.push_back("-classpath");
+  argv.push_back("--runtime-arg");
+  argv.push_back(runtime->GetClassPathString());
+  runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
+
+  if (!runtime->IsVerificationEnabled()) {
+    argv.push_back("--compiler-filter=verify-none");
+  }
+
+  if (runtime->MustRelocateIfPossible()) {
+    argv.push_back("--runtime-arg");
+    argv.push_back("-Xrelocate");
+  } else {
+    argv.push_back("--runtime-arg");
+    argv.push_back("-Xnorelocate");
+  }
+
+  if (!kIsTargetBuild) {
+    argv.push_back("--host");
+  }
+
+  argv.push_back("--boot-image=" + image_location);
+
+  std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
+  argv.insert(argv.end(), compiler_options.begin(), compiler_options.end());
+
+  argv.insert(argv.end(), args.begin(), args.end());
+
+  std::string command_line(Join(argv, ' '));
+  return Exec(argv, error_msg);
+}
+
+bool OatFileAssistant::DexFilenameToOdexFilename(const std::string& location,
+    InstructionSet isa, std::string* odex_filename, std::string* error_msg) {
+  CHECK(odex_filename != nullptr);
+  CHECK(error_msg != nullptr);
+
+  // The odex file name is formed by replacing the dex_location extension with
+  // .odex and inserting an isa directory. For example:
+  //   location = /foo/bar/baz.jar
+  //   odex_location = /foo/bar/<isa>/baz.odex
+
+  // Find the directory portion of the dex location and add the isa directory.
+  size_t pos = location.rfind('/');
+  if (pos == std::string::npos) {
+    *error_msg = "Dex location " + location + " has no directory.";
+    return false;
+  }
+  std::string dir = location.substr(0, pos+1);
+  dir += std::string(GetInstructionSetString(isa));
+
+  // Find the file portion of the dex location.
+  std::string file;
+  if (pos == std::string::npos) {
+    file = location;
+  } else {
+    file = location.substr(pos+1);
+  }
+
+  // Get the base part of the file without the extension.
+  pos = file.rfind('.');
+  if (pos == std::string::npos) {
+    *error_msg = "Dex location " + location + " has no extension.";
+    return false;
+  }
+  std::string base = file.substr(0, pos);
+
+  *odex_filename = dir + "/" + base + ".odex";
+  return true;
+}
+
+std::string OatFileAssistant::DalvikCacheDirectory() {
+  // Note: We don't cache this, because it will only be called once by
+  // OatFileName, and we don't care about the performance of the profiling
+  // code, which isn't used in practice.
+
+  // TODO: The work done in GetDalvikCache is overkill for what we need.
+  // Ideally a new API for getting the DalvikCacheDirectory the way we want
+  // (without existence testing, creation, or death) is provided with the rest
+  // of the GetDalvikCache family of functions. Until such an API is in place,
+  // we use GetDalvikCache to avoid duplicating the logic for determining the
+  // dalvik cache directory.
+  std::string result;
+  bool have_android_data;
+  bool dalvik_cache_exists;
+  bool is_global_cache;
+  GetDalvikCache("", false, &result, &have_android_data, &dalvik_cache_exists, &is_global_cache);
+  return result;
+}
+
+std::string OatFileAssistant::ProfileFileName() {
+  if (package_name_ != nullptr) {
+    return DalvikCacheDirectory() + std::string("profiles/") + package_name_;
+  }
+  return "";
+}
+
+std::string OatFileAssistant::OldProfileFileName() {
+  std::string profile_name = ProfileFileName();
+  if (profile_name.empty()) {
+    return "";
+  }
+  return profile_name + "@old";
+}
+
+std::string OatFileAssistant::ImageLocation() {
+  Runtime* runtime = Runtime::Current();
+  const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
+  if (image_space == nullptr) {
+    return "";
+  }
+  return image_space->GetImageLocation();
+}
+
+const uint32_t* OatFileAssistant::GetRequiredDexChecksum() {
+  if (!required_dex_checksum_attempted) {
+    required_dex_checksum_attempted = true;
+    required_dex_checksum_found = false;
+    std::string error_msg;
+    CHECK(dex_location_ != nullptr) << "OatFileAssistant provided no dex location";
+    if (DexFile::GetChecksum(dex_location_, &cached_required_dex_checksum, &error_msg)) {
+      required_dex_checksum_found = true;
+    } else {
+      // This can happen if the original dex file has been stripped from the
+      // apk.
+      VLOG(oat) << "OatFileAssistant: " << error_msg;
+
+      // Get the checksum from the odex if we can.
+      const OatFile* odex_file = GetOdexFile();
+      if (odex_file != nullptr) {
+        const OatFile::OatDexFile* odex_dex_file = odex_file->GetOatDexFile(
+            dex_location_, nullptr, false);
+        if (odex_dex_file != nullptr) {
+          cached_required_dex_checksum = odex_dex_file->GetDexFileLocationChecksum();
+          required_dex_checksum_found = true;
+        }
+      }
+    }
+  }
+  return required_dex_checksum_found ? &cached_required_dex_checksum : nullptr;
+}
+
+const OatFile* OatFileAssistant::GetOdexFile() {
+  CHECK(!oat_file_released_) << "OdexFile called after oat file released.";
+  if (!odex_file_load_attempted_) {
+    odex_file_load_attempted_ = true;
+    if (OdexFileName() != nullptr) {
+      const std::string& odex_file_name = *OdexFileName();
+      std::string error_msg;
+      cached_odex_file_.reset(OatFile::Open(odex_file_name.c_str(),
+            odex_file_name.c_str(), nullptr, nullptr, load_executable_,
+            &error_msg));
+      if (cached_odex_file_.get() == nullptr) {
+        VLOG(oat) << "OatFileAssistant test for existing pre-compiled oat file "
+          << odex_file_name << ": " << error_msg;
+      }
+    }
+  }
+  return cached_odex_file_.get();
+}
+
+void OatFileAssistant::ClearOdexFileCache() {
+  odex_file_load_attempted_ = false;
+  cached_odex_file_.reset();
+  odex_file_is_out_of_date_attempted_ = false;
+  odex_file_is_up_to_date_attempted_ = false;
+}
+
+const OatFile* OatFileAssistant::GetOatFile() {
+  CHECK(!oat_file_released_) << "OatFile called after oat file released.";
+  if (!oat_file_load_attempted_) {
+    oat_file_load_attempted_ = true;
+    if (OatFileName() != nullptr) {
+      const std::string& oat_file_name = *OatFileName();
+      std::string error_msg;
+      cached_oat_file_.reset(OatFile::Open(oat_file_name.c_str(),
+            oat_file_name.c_str(), nullptr, nullptr, load_executable_, &error_msg));
+      if (cached_oat_file_.get() == nullptr) {
+        VLOG(oat) << "OatFileAssistant test for existing oat file "
+          << oat_file_name << ": " << error_msg;
+      }
+    }
+  }
+  return cached_oat_file_.get();
+}
+
+void OatFileAssistant::ClearOatFileCache() {
+  oat_file_load_attempted_ = false;
+  cached_oat_file_.reset();
+  oat_file_is_out_of_date_attempted_ = false;
+  oat_file_is_up_to_date_attempted_ = false;
+}
+
+const OatFileAssistant::ImageInfo* OatFileAssistant::GetImageInfo() {
+  if (!image_info_load_attempted_) {
+    image_info_load_attempted_ = true;
+
+    Runtime* runtime = Runtime::Current();
+    const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
+    if (image_space != nullptr) {
+      cached_image_info_.location = image_space->GetImageLocation();
+
+      if (isa_ == kRuntimeISA) {
+        const ImageHeader& image_header = image_space->GetImageHeader();
+        cached_image_info_.oat_checksum = image_header.GetOatChecksum();
+        cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin());
+        cached_image_info_.patch_delta = image_header.GetPatchDelta();
+      } else {
+        std::unique_ptr<ImageHeader> image_header(
+            gc::space::ImageSpace::ReadImageHeaderOrDie(
+                cached_image_info_.location.c_str(), isa_));
+        cached_image_info_.oat_checksum = image_header->GetOatChecksum();
+        cached_image_info_.oat_data_begin = reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin());
+        cached_image_info_.patch_delta = image_header->GetPatchDelta();
+      }
+    }
+    image_info_load_succeeded_ = (image_space != nullptr);
+  }
+  return image_info_load_succeeded_ ? &cached_image_info_ : nullptr;
+}
+
+ProfileFile* OatFileAssistant::GetProfile() {
+  if (!profile_load_attempted_) {
+    CHECK(package_name_ != nullptr)
+      << "pakage_name_ is nullptr: "
+      << "profile_load_attempted_ should have been true";
+    profile_load_attempted_ = true;
+    std::string profile_name = ProfileFileName();
+    if (!profile_name.empty()) {
+      profile_load_succeeded_ = cached_profile_.LoadFile(profile_name);
+    }
+  }
+  return profile_load_succeeded_ ? &cached_profile_ : nullptr;
+}
+
+ProfileFile* OatFileAssistant::GetOldProfile() {
+  if (!old_profile_load_attempted_) {
+    CHECK(package_name_ != nullptr)
+      << "pakage_name_ is nullptr: "
+      << "old_profile_load_attempted_ should have been true";
+    old_profile_load_attempted_ = true;
+    std::string old_profile_name = OldProfileFileName();
+    if (!old_profile_name.empty()) {
+      old_profile_load_succeeded_ = cached_old_profile_.LoadFile(old_profile_name);
+    }
+  }
+  return old_profile_load_succeeded_ ? &cached_old_profile_ : nullptr;
+}
+
+}  // namespace art
+
