Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "oat_file_assistant.h"
     18 
     19 #include <algorithm>
     20 #include <fstream>
     21 #include <string>
     22 #include <vector>
     23 #include <sys/param.h>
     24 
     25 #include <backtrace/BacktraceMap.h>
     26 #include <gtest/gtest.h>
     27 
     28 #include "art_field-inl.h"
     29 #include "class_linker-inl.h"
     30 #include "common_runtime_test.h"
     31 #include "compiler_callbacks.h"
     32 #include "gc/space/image_space.h"
     33 #include "mem_map.h"
     34 #include "os.h"
     35 #include "scoped_thread_state_change.h"
     36 #include "thread-inl.h"
     37 #include "utils.h"
     38 
     39 namespace art {
     40 
     41 class OatFileAssistantTest : public CommonRuntimeTest {
     42  public:
     43   virtual void SetUp() {
     44     ReserveImageSpace();
     45     CommonRuntimeTest::SetUp();
     46 
     47     // Create a scratch directory to work from.
     48     scratch_dir_ = android_data_ + "/OatFileAssistantTest";
     49     ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700));
     50 
     51     // Create a subdirectory in scratch for odex files.
     52     odex_oat_dir_ = scratch_dir_ + "/oat";
     53     ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700));
     54 
     55     odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA));
     56     ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700));
     57 
     58 
     59     // Verify the environment is as we expect
     60     uint32_t checksum;
     61     std::string error_msg;
     62     ASSERT_TRUE(OS::FileExists(GetImageFile().c_str()))
     63       << "Expected pre-compiled boot image to be at: " << GetImageFile();
     64     ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str()))
     65       << "Expected dex file to be at: " << GetDexSrc1();
     66     ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str()))
     67       << "Expected stripped dex file to be at: " << GetStrippedDexSrc1();
     68     ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg))
     69       << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1();
     70     ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str()))
     71       << "Expected dex file to be at: " << GetDexSrc2();
     72 
     73     // GetMultiDexSrc2 should have the same primary dex checksum as
     74     // GetMultiDexSrc1, but a different secondary dex checksum.
     75     std::vector<std::unique_ptr<const DexFile>> multi1;
     76     ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(),
     77           GetMultiDexSrc1().c_str(), &error_msg, &multi1)) << error_msg;
     78     ASSERT_GT(multi1.size(), 1u);
     79 
     80     std::vector<std::unique_ptr<const DexFile>> multi2;
     81     ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(),
     82           GetMultiDexSrc2().c_str(), &error_msg, &multi2)) << error_msg;
     83     ASSERT_GT(multi2.size(), 1u);
     84 
     85     ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum());
     86     ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum());
     87   }
     88 
     89   virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
     90     // options->push_back(std::make_pair("-verbose:oat", nullptr));
     91 
     92     // Set up the image location.
     93     options->push_back(std::make_pair("-Ximage:" + GetImageLocation(),
     94           nullptr));
     95     // Make sure compilercallbacks are not set so that relocation will be
     96     // enabled.
     97     callbacks_.reset();
     98   }
     99 
    100   virtual void PreRuntimeCreate() {
    101     UnreserveImageSpace();
    102   }
    103 
    104   virtual void PostRuntimeCreate() {
    105     ReserveImageSpace();
    106   }
    107 
    108   virtual void TearDown() {
    109     ClearDirectory(odex_dir_.c_str());
    110     ASSERT_EQ(0, rmdir(odex_dir_.c_str()));
    111 
    112     ClearDirectory(odex_oat_dir_.c_str());
    113     ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str()));
    114 
    115     ClearDirectory(scratch_dir_.c_str());
    116     ASSERT_EQ(0, rmdir(scratch_dir_.c_str()));
    117 
    118     CommonRuntimeTest::TearDown();
    119   }
    120 
    121   void Copy(std::string src, std::string dst) {
    122     std::ifstream  src_stream(src, std::ios::binary);
    123     std::ofstream  dst_stream(dst, std::ios::binary);
    124 
    125     dst_stream << src_stream.rdbuf();
    126   }
    127 
    128   // Returns the directory where the pre-compiled core.art can be found.
    129   // TODO: We should factor out this into common tests somewhere rather than
    130   // re-hardcoding it here (This was copied originally from the elf writer
    131   // test).
    132   std::string GetImageDirectory() {
    133     if (IsHost()) {
    134       const char* host_dir = getenv("ANDROID_HOST_OUT");
    135       CHECK(host_dir != nullptr);
    136       return std::string(host_dir) + "/framework";
    137     } else {
    138       return std::string("/data/art-test");
    139     }
    140   }
    141 
    142   std::string GetImageLocation() {
    143     return GetImageDirectory() + "/core.art";
    144   }
    145 
    146   std::string GetImageFile() {
    147     return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA)
    148       + "/core.art";
    149   }
    150 
    151   std::string GetDexSrc1() {
    152     return GetTestDexFileName("Main");
    153   }
    154 
    155   // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex
    156   // file stripped.
    157   std::string GetStrippedDexSrc1() {
    158     return GetTestDexFileName("MainStripped");
    159   }
    160 
    161   std::string GetMultiDexSrc1() {
    162     return GetTestDexFileName("MultiDex");
    163   }
    164 
    165   // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but
    166   // with the contents of the secondary dex file changed.
    167   std::string GetMultiDexSrc2() {
    168     return GetTestDexFileName("MultiDexModifiedSecondary");
    169   }
    170 
    171   std::string GetDexSrc2() {
    172     return GetTestDexFileName("Nested");
    173   }
    174 
    175   // Scratch directory, for dex and odex files (oat files will go in the
    176   // dalvik cache).
    177   std::string GetScratchDir() {
    178     return scratch_dir_;
    179   }
    180 
    181   // Odex directory is the subdirectory in the scratch directory where odex
    182   // files should be located.
    183   std::string GetOdexDir() {
    184     return odex_dir_;
    185   }
    186 
    187   // Generate an odex file for the purposes of test.
    188   // If pic is true, generates a PIC odex.
    189   void GenerateOdexForTest(const std::string& dex_location,
    190                            const std::string& odex_location,
    191                            bool pic = false) {
    192     // For this operation, we temporarily redirect the dalvik cache so dex2oat
    193     // doesn't find the relocated image file.
    194     std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp";
    195     setenv("ANDROID_DATA", android_data_tmp.c_str(), 1);
    196     std::vector<std::string> args;
    197     args.push_back("--dex-file=" + dex_location);
    198     args.push_back("--oat-file=" + odex_location);
    199     if (pic) {
    200       args.push_back("--compile-pic");
    201     } else {
    202       args.push_back("--include-patch-information");
    203 
    204       // We need to use the quick compiler to generate non-PIC code, because
    205       // the optimizing compiler always generates PIC.
    206       args.push_back("--compiler-backend=Quick");
    207     }
    208     args.push_back("--runtime-arg");
    209     args.push_back("-Xnorelocate");
    210     std::string error_msg;
    211     ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
    212     setenv("ANDROID_DATA", android_data_.c_str(), 1);
    213   }
    214 
    215   void GeneratePicOdexForTest(const std::string& dex_location,
    216                               const std::string& odex_location) {
    217     GenerateOdexForTest(dex_location, odex_location, true);
    218   }
    219 
    220  private:
    221   // Reserve memory around where the image will be loaded so other memory
    222   // won't conflict when it comes time to load the image.
    223   // This can be called with an already loaded image to reserve the space
    224   // around it.
    225   void ReserveImageSpace() {
    226     MemMap::Init();
    227 
    228     // Ensure a chunk of memory is reserved for the image space.
    229     uintptr_t reservation_start = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MIN_DELTA;
    230     uintptr_t reservation_end = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MAX_DELTA
    231         // Include the main space that has to come right after the
    232         // image in case of the GSS collector.
    233         + 384 * MB;
    234 
    235     std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
    236     ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
    237     for (BacktraceMap::const_iterator it = map->begin();
    238         reservation_start < reservation_end && it != map->end(); ++it) {
    239       ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
    240       reservation_start = std::max(reservation_start, it->end);
    241     }
    242     ReserveImageSpaceChunk(reservation_start, reservation_end);
    243   }
    244 
    245   // Reserve a chunk of memory for the image space in the given range.
    246   // Only has effect for chunks with a positive number of bytes.
    247   void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
    248     if (start < end) {
    249       std::string error_msg;
    250       image_reservation_.push_back(std::unique_ptr<MemMap>(
    251           MemMap::MapAnonymous("image reservation",
    252               reinterpret_cast<uint8_t*>(start), end - start,
    253               PROT_NONE, false, false, &error_msg)));
    254       ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
    255       LOG(INFO) << "Reserved space for image " <<
    256         reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
    257         reinterpret_cast<void*>(image_reservation_.back()->End());
    258     }
    259   }
    260 
    261 
    262   // Unreserve any memory reserved by ReserveImageSpace. This should be called
    263   // before the image is loaded.
    264   void UnreserveImageSpace() {
    265     image_reservation_.clear();
    266   }
    267 
    268   std::string scratch_dir_;
    269   std::string odex_oat_dir_;
    270   std::string odex_dir_;
    271   std::vector<std::unique_ptr<MemMap>> image_reservation_;
    272 };
    273 
    274 class OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
    275  public:
    276   virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
    277     OatFileAssistantTest::SetUpRuntimeOptions(options);
    278     options->push_back(std::make_pair("-Xnodex2oat", nullptr));
    279   }
    280 };
    281 
    282 // Generate an oat file for the purposes of test, as opposed to testing
    283 // generation of oat files.
    284 static void GenerateOatForTest(const char* dex_location) {
    285   OatFileAssistant oat_file_assistant(dex_location, kRuntimeISA, false);
    286 
    287   std::string error_msg;
    288   ASSERT_TRUE(oat_file_assistant.GenerateOatFile(&error_msg)) << error_msg;
    289 }
    290 
    291 // Case: We have a DEX file, but no OAT file for it.
    292 // Expect: The status is kDex2OatNeeded.
    293 TEST_F(OatFileAssistantTest, DexNoOat) {
    294   std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
    295   Copy(GetDexSrc1(), dex_location);
    296 
    297   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    298 
    299   EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
    300 
    301   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    302   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    303   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    304   EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
    305   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    306   EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
    307   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    308   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    309   EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
    310   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    311   EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
    312   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    313 }
    314 
    315 // Case: We have no DEX file and no OAT file.
    316 // Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
    317 TEST_F(OatFileAssistantTest, NoDexNoOat) {
    318   std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
    319 
    320   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    321 
    322   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    323   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    324 
    325   // Trying to make the oat file up to date should not fail or crash.
    326   std::string error_msg;
    327   EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg));
    328 
    329   // Trying to get the best oat file should fail, but not crash.
    330   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    331   EXPECT_EQ(nullptr, oat_file.get());
    332 }
    333 
    334 // Case: We have a DEX file and up-to-date OAT file for it.
    335 // Expect: The status is kNoDexOptNeeded.
    336 TEST_F(OatFileAssistantTest, OatUpToDate) {
    337   std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
    338   Copy(GetDexSrc1(), dex_location);
    339   GenerateOatForTest(dex_location.c_str());
    340 
    341   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    342 
    343   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    344   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    345   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    346   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    347   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    348   EXPECT_TRUE(oat_file_assistant.OatFileExists());
    349   EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
    350   EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
    351   EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
    352   EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
    353   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    354 }
    355 
    356 // Case: We have a MultiDEX file and up-to-date OAT file for it.
    357 // Expect: The status is kNoDexOptNeeded and we load all dex files.
    358 TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
    359   std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
    360   Copy(GetMultiDexSrc1(), dex_location);
    361   GenerateOatForTest(dex_location.c_str());
    362 
    363   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    364   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    365   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    366 
    367   // Verify we can load both dex files.
    368   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    369   ASSERT_TRUE(oat_file.get() != nullptr);
    370   EXPECT_TRUE(oat_file->IsExecutable());
    371   std::vector<std::unique_ptr<const DexFile>> dex_files;
    372   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    373   EXPECT_EQ(2u, dex_files.size());
    374 }
    375 
    376 // Case: We have a MultiDEX file where the secondary dex file is out of date.
    377 // Expect: The status is kDex2OatNeeded.
    378 TEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
    379   std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
    380 
    381   // Compile code for GetMultiDexSrc1.
    382   Copy(GetMultiDexSrc1(), dex_location);
    383   GenerateOatForTest(dex_location.c_str());
    384 
    385   // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
    386   // is out of date.
    387   Copy(GetMultiDexSrc2(), dex_location);
    388 
    389   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    390   EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
    391   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    392 }
    393 
    394 // Case: We have a MultiDEX file and up-to-date OAT file for it with relative
    395 // encoded dex locations.
    396 // Expect: The oat file status is kNoDexOptNeeded.
    397 TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
    398   std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
    399   std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
    400 
    401   // Create the dex file
    402   Copy(GetMultiDexSrc1(), dex_location);
    403 
    404   // Create the oat file with relative encoded dex location.
    405   std::vector<std::string> args;
    406   args.push_back("--dex-file=" + dex_location);
    407   args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
    408   args.push_back("--oat-file=" + oat_location);
    409 
    410   std::string error_msg;
    411   ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
    412 
    413   // Verify we can load both dex files.
    414   OatFileAssistant oat_file_assistant(dex_location.c_str(),
    415                                       oat_location.c_str(),
    416                                       kRuntimeISA, true);
    417   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    418   ASSERT_TRUE(oat_file.get() != nullptr);
    419   EXPECT_TRUE(oat_file->IsExecutable());
    420   std::vector<std::unique_ptr<const DexFile>> dex_files;
    421   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    422   EXPECT_EQ(2u, dex_files.size());
    423 }
    424 
    425 // Case: We have a DEX file and out-of-date OAT file.
    426 // Expect: The status is kDex2OatNeeded.
    427 TEST_F(OatFileAssistantTest, OatOutOfDate) {
    428   std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
    429 
    430   // We create a dex, generate an oat for it, then overwrite the dex with a
    431   // different dex to make the oat out of date.
    432   Copy(GetDexSrc1(), dex_location);
    433   GenerateOatForTest(dex_location.c_str());
    434   Copy(GetDexSrc2(), dex_location);
    435 
    436   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    437   EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
    438 
    439   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    440   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    441   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    442   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    443   EXPECT_TRUE(oat_file_assistant.OatFileExists());
    444   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    445   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    446   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    447 }
    448 
    449 // Case: We have a DEX file and an ODEX file, but no OAT file.
    450 // Expect: The status is kPatchOatNeeded.
    451 TEST_F(OatFileAssistantTest, DexOdexNoOat) {
    452   std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
    453   std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
    454 
    455   // Create the dex and odex files
    456   Copy(GetDexSrc1(), dex_location);
    457   GenerateOdexForTest(dex_location, odex_location);
    458 
    459   // Verify the status.
    460   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    461 
    462   EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
    463 
    464   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    465   EXPECT_TRUE(oat_file_assistant.OdexFileExists());
    466   EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
    467   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    468   EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
    469   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    470   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    471   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    472   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    473 }
    474 
    475 // Case: We have a stripped DEX file and an ODEX file, but no OAT file.
    476 // Expect: The status is kPatchOatNeeded
    477 TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
    478   std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
    479   std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
    480 
    481   // Create the dex and odex files
    482   Copy(GetDexSrc1(), dex_location);
    483   GenerateOdexForTest(dex_location, odex_location);
    484 
    485   // Strip the dex file
    486   Copy(GetStrippedDexSrc1(), dex_location);
    487 
    488   // Verify the status.
    489   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    490 
    491   EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
    492 
    493   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    494   EXPECT_TRUE(oat_file_assistant.OdexFileExists());
    495   EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
    496   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    497   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    498   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    499   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    500   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    501 
    502   // Make the oat file up to date.
    503   std::string error_msg;
    504   ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
    505 
    506   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    507 
    508   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    509   EXPECT_TRUE(oat_file_assistant.OdexFileExists());
    510   EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
    511   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    512   EXPECT_TRUE(oat_file_assistant.OatFileExists());
    513   EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
    514   EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
    515   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    516 
    517   // Verify we can load the dex files from it.
    518   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    519   ASSERT_TRUE(oat_file.get() != nullptr);
    520   EXPECT_TRUE(oat_file->IsExecutable());
    521   std::vector<std::unique_ptr<const DexFile>> dex_files;
    522   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    523   EXPECT_EQ(1u, dex_files.size());
    524 }
    525 
    526 // Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file.
    527 // Expect: The status is kPatchOatNeeded.
    528 TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
    529   std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
    530   std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
    531 
    532   // Create the oat file from a different dex file so it looks out of date.
    533   Copy(GetDexSrc2(), dex_location);
    534   GenerateOatForTest(dex_location.c_str());
    535 
    536   // Create the odex file
    537   Copy(GetDexSrc1(), dex_location);
    538   GenerateOdexForTest(dex_location, odex_location);
    539 
    540   // Strip the dex file.
    541   Copy(GetStrippedDexSrc1(), dex_location);
    542 
    543   // Verify the status.
    544   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    545 
    546   EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
    547 
    548   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    549   EXPECT_TRUE(oat_file_assistant.OdexFileExists());
    550   EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
    551   EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
    552   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    553   EXPECT_TRUE(oat_file_assistant.OatFileExists());
    554   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    555   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    556   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    557 
    558   // Make the oat file up to date.
    559   std::string error_msg;
    560   ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
    561 
    562   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    563 
    564   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    565   EXPECT_TRUE(oat_file_assistant.OdexFileExists());
    566   EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
    567   EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation());
    568   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    569   EXPECT_TRUE(oat_file_assistant.OatFileExists());
    570   EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
    571   EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
    572   EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
    573   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    574 
    575   // Verify we can load the dex files from it.
    576   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    577   ASSERT_TRUE(oat_file.get() != nullptr);
    578   EXPECT_TRUE(oat_file->IsExecutable());
    579   std::vector<std::unique_ptr<const DexFile>> dex_files;
    580   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    581   EXPECT_EQ(1u, dex_files.size());
    582 }
    583 
    584 // Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
    585 // OAT file. Expect: The status is kNoDexOptNeeded.
    586 TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
    587   std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
    588 
    589   Copy(GetStrippedDexSrc1(), dex_location);
    590 
    591   // Verify the status.
    592   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    593 
    594   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    595 
    596   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    597   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    598   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    599   EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
    600   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    601   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    602   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    603   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    604   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    605 
    606   // Make the oat file up to date. This should have no effect.
    607   std::string error_msg;
    608   EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
    609 
    610   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    611 
    612   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    613   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    614   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    615   EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
    616   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    617   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    618   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    619   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    620   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    621 }
    622 
    623 // Case: We have a DEX file, no ODEX file and an OAT file that needs
    624 // relocation.
    625 // Expect: The status is kSelfPatchOatNeeded.
    626 TEST_F(OatFileAssistantTest, SelfRelocation) {
    627   std::string dex_location = GetScratchDir() + "/SelfRelocation.jar";
    628   std::string oat_location = GetOdexDir() + "/SelfRelocation.oat";
    629 
    630   // Create the dex and odex files
    631   Copy(GetDexSrc1(), dex_location);
    632   GenerateOdexForTest(dex_location, oat_location);
    633 
    634   OatFileAssistant oat_file_assistant(dex_location.c_str(),
    635       oat_location.c_str(), kRuntimeISA, true);
    636 
    637   EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
    638 
    639   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    640   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    641   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    642   EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
    643   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    644   EXPECT_TRUE(oat_file_assistant.OatFileExists());
    645   EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation());
    646   EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
    647   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    648   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    649 
    650   // Make the oat file up to date.
    651   std::string error_msg;
    652   ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
    653 
    654   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    655 
    656   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    657   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    658   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    659   EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation());
    660   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    661   EXPECT_TRUE(oat_file_assistant.OatFileExists());
    662   EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
    663   EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation());
    664   EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate());
    665   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    666 
    667   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    668   ASSERT_TRUE(oat_file.get() != nullptr);
    669   EXPECT_TRUE(oat_file->IsExecutable());
    670   std::vector<std::unique_ptr<const DexFile>> dex_files;
    671   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    672   EXPECT_EQ(1u, dex_files.size());
    673 }
    674 
    675 // Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
    676 // OAT files both have patch delta of 0.
    677 // Expect: It shouldn't crash, and status is kPatchOatNeeded.
    678 TEST_F(OatFileAssistantTest, OdexOatOverlap) {
    679   std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
    680   std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
    681   std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
    682 
    683   // Create the dex and odex files
    684   Copy(GetDexSrc1(), dex_location);
    685   GenerateOdexForTest(dex_location, odex_location);
    686 
    687   // Create the oat file by copying the odex so they are located in the same
    688   // place in memory.
    689   Copy(odex_location, oat_location);
    690 
    691   // Verify things don't go bad.
    692   OatFileAssistant oat_file_assistant(dex_location.c_str(),
    693       oat_location.c_str(), kRuntimeISA, true);
    694 
    695   EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded());
    696 
    697   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    698   EXPECT_TRUE(oat_file_assistant.OdexFileExists());
    699   EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
    700   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    701   EXPECT_TRUE(oat_file_assistant.OatFileExists());
    702   EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate());
    703   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    704   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    705 
    706   // Things aren't relocated, so it should fall back to interpreted.
    707   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    708   ASSERT_TRUE(oat_file.get() != nullptr);
    709 
    710   EXPECT_FALSE(oat_file->IsExecutable());
    711   std::vector<std::unique_ptr<const DexFile>> dex_files;
    712   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    713   EXPECT_EQ(1u, dex_files.size());
    714 
    715   // Add some extra checks to help diagnose apparently flaky test failures.
    716   Runtime* runtime = Runtime::Current();
    717   const gc::space::ImageSpace* image_space = runtime->GetHeap()->GetImageSpace();
    718   ASSERT_TRUE(image_space != nullptr);
    719   const ImageHeader& image_header = image_space->GetImageHeader();
    720   const OatHeader& oat_header = oat_file->GetOatHeader();
    721   EXPECT_FALSE(oat_file->IsPic());
    722   EXPECT_EQ(image_header.GetOatChecksum(), oat_header.GetImageFileLocationOatChecksum());
    723   EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
    724       oat_header.GetImageFileLocationOatDataBegin());
    725   EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta());
    726 }
    727 
    728 // Case: We have a DEX file and a PIC ODEX file, but no OAT file.
    729 // Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
    730 TEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
    731   std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
    732   std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
    733 
    734   // Create the dex and odex files
    735   Copy(GetDexSrc1(), dex_location);
    736   GeneratePicOdexForTest(dex_location, odex_location);
    737 
    738   // Verify the status.
    739   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    740 
    741   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    742 
    743   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    744   EXPECT_TRUE(oat_file_assistant.OdexFileExists());
    745   EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate());
    746   EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate());
    747   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    748   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    749   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    750   EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
    751 }
    752 
    753 // Case: We have a DEX file and up-to-date OAT file for it.
    754 // Expect: We should load an executable dex file.
    755 TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
    756   std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
    757 
    758   Copy(GetDexSrc1(), dex_location);
    759   GenerateOatForTest(dex_location.c_str());
    760 
    761   // Load the oat using an oat file assistant.
    762   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    763 
    764   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    765   ASSERT_TRUE(oat_file.get() != nullptr);
    766   EXPECT_TRUE(oat_file->IsExecutable());
    767   std::vector<std::unique_ptr<const DexFile>> dex_files;
    768   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    769   EXPECT_EQ(1u, dex_files.size());
    770 }
    771 
    772 // Case: We have a DEX file and up-to-date OAT file for it.
    773 // Expect: Loading non-executable should load the oat non-executable.
    774 TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
    775   std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
    776 
    777   Copy(GetDexSrc1(), dex_location);
    778   GenerateOatForTest(dex_location.c_str());
    779 
    780   // Load the oat using an oat file assistant.
    781   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    782 
    783   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    784   ASSERT_TRUE(oat_file.get() != nullptr);
    785   EXPECT_FALSE(oat_file->IsExecutable());
    786   std::vector<std::unique_ptr<const DexFile>> dex_files;
    787   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    788   EXPECT_EQ(1u, dex_files.size());
    789 }
    790 
    791 // Case: We have a DEX file.
    792 // Expect: We should load an executable dex file from an alternative oat
    793 // location.
    794 TEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
    795   std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
    796   std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
    797 
    798   Copy(GetDexSrc1(), dex_location);
    799 
    800   OatFileAssistant oat_file_assistant(
    801       dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
    802   std::string error_msg;
    803   ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg;
    804 
    805   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    806   ASSERT_TRUE(oat_file.get() != nullptr);
    807   EXPECT_TRUE(oat_file->IsExecutable());
    808   std::vector<std::unique_ptr<const DexFile>> dex_files;
    809   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    810   EXPECT_EQ(1u, dex_files.size());
    811 
    812   EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
    813 
    814   // Verify it didn't create an oat in the default location.
    815   OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false);
    816   EXPECT_FALSE(ofm.OatFileExists());
    817 }
    818 
    819 // Turn an absolute path into a path relative to the current working
    820 // directory.
    821 static std::string MakePathRelative(std::string target) {
    822   char buf[MAXPATHLEN];
    823   std::string cwd = getcwd(buf, MAXPATHLEN);
    824 
    825   // Split the target and cwd paths into components.
    826   std::vector<std::string> target_path;
    827   std::vector<std::string> cwd_path;
    828   Split(target, '/', &target_path);
    829   Split(cwd, '/', &cwd_path);
    830 
    831   // Reverse the path components, so we can use pop_back().
    832   std::reverse(target_path.begin(), target_path.end());
    833   std::reverse(cwd_path.begin(), cwd_path.end());
    834 
    835   // Drop the common prefix of the paths. Because we reversed the path
    836   // components, this becomes the common suffix of target_path and cwd_path.
    837   while (!target_path.empty() && !cwd_path.empty()
    838       && target_path.back() == cwd_path.back()) {
    839     target_path.pop_back();
    840     cwd_path.pop_back();
    841   }
    842 
    843   // For each element of the remaining cwd_path, add '..' to the beginning
    844   // of the target path. Because we reversed the path components, we add to
    845   // the end of target_path.
    846   for (unsigned int i = 0; i < cwd_path.size(); i++) {
    847     target_path.push_back("..");
    848   }
    849 
    850   // Reverse again to get the right path order, and join to get the result.
    851   std::reverse(target_path.begin(), target_path.end());
    852   return Join(target_path, '/');
    853 }
    854 
    855 // Case: Non-absolute path to Dex location.
    856 // Expect: Not sure, but it shouldn't crash.
    857 TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
    858   std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
    859   Copy(GetDexSrc1(), abs_dex_location);
    860 
    861   std::string dex_location = MakePathRelative(abs_dex_location);
    862   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    863 
    864   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    865   EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
    866   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    867   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    868   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    869   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    870   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    871   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    872 }
    873 
    874 // Case: Very short, non-existent Dex location.
    875 // Expect: kNoDexOptNeeded.
    876 TEST_F(OatFileAssistantTest, ShortDexLocation) {
    877   std::string dex_location = "/xx";
    878 
    879   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    880 
    881   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    882   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded());
    883   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    884   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    885   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    886   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    887   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    888   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    889   EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
    890 
    891   // Trying to make it up to date should have no effect.
    892   std::string error_msg;
    893   EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg));
    894   EXPECT_TRUE(error_msg.empty());
    895 }
    896 
    897 // Case: Non-standard extension for dex file.
    898 // Expect: The status is kDex2OatNeeded.
    899 TEST_F(OatFileAssistantTest, LongDexExtension) {
    900   std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
    901   Copy(GetDexSrc1(), dex_location);
    902 
    903   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
    904 
    905   EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded());
    906 
    907   EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
    908   EXPECT_FALSE(oat_file_assistant.OdexFileExists());
    909   EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate());
    910   EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate());
    911   EXPECT_FALSE(oat_file_assistant.OatFileExists());
    912   EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate());
    913   EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate());
    914 }
    915 
    916 // A task to generate a dex location. Used by the RaceToGenerate test.
    917 class RaceGenerateTask : public Task {
    918  public:
    919   explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
    920     : dex_location_(dex_location), oat_location_(oat_location),
    921       loaded_oat_file_(nullptr)
    922   {}
    923 
    924   void Run(Thread* self) {
    925     UNUSED(self);
    926 
    927     // Load the dex files, and save a pointer to the loaded oat file, so that
    928     // we can verify only one oat file was loaded for the dex location.
    929     ClassLinker* linker = Runtime::Current()->GetClassLinker();
    930     std::vector<std::unique_ptr<const DexFile>> dex_files;
    931     std::vector<std::string> error_msgs;
    932     dex_files = linker->OpenDexFilesFromOat(dex_location_.c_str(), oat_location_.c_str(), &error_msgs);
    933     CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
    934     CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
    935     loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
    936   }
    937 
    938   const OatFile* GetLoadedOatFile() const {
    939     return loaded_oat_file_;
    940   }
    941 
    942  private:
    943   std::string dex_location_;
    944   std::string oat_location_;
    945   const OatFile* loaded_oat_file_;
    946 };
    947 
    948 // Test the case where multiple processes race to generate an oat file.
    949 // This simulates multiple processes using multiple threads.
    950 //
    951 // We want only one Oat file to be loaded when there is a race to load, to
    952 // avoid using up the virtual memory address space.
    953 TEST_F(OatFileAssistantTest, RaceToGenerate) {
    954   std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
    955   std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
    956 
    957   // We use the lib core dex file, because it's large, and hopefully should
    958   // take a while to generate.
    959   Copy(GetLibCoreDexFileName(), dex_location);
    960 
    961   const int kNumThreads = 32;
    962   Thread* self = Thread::Current();
    963   ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
    964   std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
    965   for (int i = 0; i < kNumThreads; i++) {
    966     std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
    967     thread_pool.AddTask(self, task.get());
    968     tasks.push_back(std::move(task));
    969   }
    970   thread_pool.StartWorkers(self);
    971   thread_pool.Wait(self, true, false);
    972 
    973   // Verify every task got the same pointer.
    974   const OatFile* expected = tasks[0]->GetLoadedOatFile();
    975   for (auto& task : tasks) {
    976     EXPECT_EQ(expected, task->GetLoadedOatFile());
    977   }
    978 }
    979 
    980 // Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
    981 // disabled.
    982 // Expect: We should load the odex file non-executable.
    983 TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
    984   std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
    985   std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
    986 
    987   // Create the dex and odex files
    988   Copy(GetDexSrc1(), dex_location);
    989   GenerateOdexForTest(dex_location, odex_location);
    990 
    991   // Load the oat using an executable oat file assistant.
    992   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
    993 
    994   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
    995   ASSERT_TRUE(oat_file.get() != nullptr);
    996   EXPECT_FALSE(oat_file->IsExecutable());
    997   std::vector<std::unique_ptr<const DexFile>> dex_files;
    998   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
    999   EXPECT_EQ(1u, dex_files.size());
   1000 }
   1001 
   1002 // Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
   1003 // disabled.
   1004 // Expect: We should load the odex file non-executable.
   1005 TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
   1006   std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
   1007   std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
   1008 
   1009   // Create the dex and odex files
   1010   Copy(GetMultiDexSrc1(), dex_location);
   1011   GenerateOdexForTest(dex_location, odex_location);
   1012 
   1013   // Load the oat using an executable oat file assistant.
   1014   OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
   1015 
   1016   std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
   1017   ASSERT_TRUE(oat_file.get() != nullptr);
   1018   EXPECT_FALSE(oat_file->IsExecutable());
   1019   std::vector<std::unique_ptr<const DexFile>> dex_files;
   1020   dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
   1021   EXPECT_EQ(2u, dex_files.size());
   1022 }
   1023 
   1024 TEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) {
   1025   std::string error_msg;
   1026   std::string odex_file;
   1027 
   1028   EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
   1029         "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
   1030   EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
   1031 
   1032   EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename(
   1033         "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
   1034   EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
   1035 
   1036   EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
   1037         "nopath.jar", kArm, &odex_file, &error_msg));
   1038   EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename(
   1039         "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
   1040 }
   1041 
   1042 // Verify the dexopt status values from dalvik.system.DexFile
   1043 // match the OatFileAssistant::DexOptStatus values.
   1044 TEST_F(OatFileAssistantTest, DexOptStatusValues) {
   1045   ScopedObjectAccess soa(Thread::Current());
   1046   StackHandleScope<1> hs(soa.Self());
   1047   ClassLinker* linker = Runtime::Current()->GetClassLinker();
   1048   Handle<mirror::Class> dexfile(
   1049       hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
   1050   ASSERT_FALSE(dexfile.Get() == nullptr);
   1051   linker->EnsureInitialized(soa.Self(), dexfile, true, true);
   1052 
   1053   ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
   1054       soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
   1055   ASSERT_FALSE(no_dexopt_needed == nullptr);
   1056   EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
   1057   EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
   1058 
   1059   ArtField* dex2oat_needed = mirror::Class::FindStaticField(
   1060       soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
   1061   ASSERT_FALSE(dex2oat_needed == nullptr);
   1062   EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
   1063   EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
   1064 
   1065   ArtField* patchoat_needed = mirror::Class::FindStaticField(
   1066       soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
   1067   ASSERT_FALSE(patchoat_needed == nullptr);
   1068   EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
   1069   EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
   1070 
   1071   ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
   1072       soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
   1073   ASSERT_FALSE(self_patchoat_needed == nullptr);
   1074   EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
   1075   EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get()));
   1076 }
   1077 
   1078 // TODO: More Tests:
   1079 //  * Test class linker falls back to unquickened dex for DexNoOat
   1080 //  * Test class linker falls back to unquickened dex for MultiDexNoOat
   1081 //  * Test using secondary isa
   1082 //  * Test with profiling info?
   1083 //  * Test for status of oat while oat is being generated (how?)
   1084 //  * Test case where 32 and 64 bit boot class paths differ,
   1085 //      and we ask IsInBootClassPath for a class in exactly one of the 32 or
   1086 //      64 bit boot class paths.
   1087 //  * Test unexpected scenarios (?):
   1088 //    - Dex is stripped, don't have odex.
   1089 //    - Oat file corrupted after status check, before reload unexecutable
   1090 //    because it's unrelocated and no dex2oat
   1091 
   1092 }  // namespace art
   1093