oat_file_assistant_test.cc revision d91b8a2464b99625efe03caf7d30c8372bc378ed
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 <algorithm> 2066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <fstream> 2166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <string> 2266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <vector> 2366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/param.h> 2466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <backtrace/BacktraceMap.h> 2666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <gtest/gtest.h> 2766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 28c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h" 293481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h" 3066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "common_runtime_test.h" 31bb9c6b1c55e9e2308b4f5892a398a8837231fdbdAndreas Gampe#include "compiler_callbacks.h" 32f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler#include "gc/space/image_space.h" 3366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "mem_map.h" 34f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier#include "oat_file_manager.h" 3566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "os.h" 3623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler#include "scoped_thread_state_change.h" 3766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "thread-inl.h" 3866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "utils.h" 3966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 4066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlernamespace art { 4166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 4266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantTest : public CommonRuntimeTest { 4366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public: 4466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler virtual void SetUp() { 4566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ReserveImageSpace(); 4666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CommonRuntimeTest::SetUp(); 4766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 4866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create a scratch directory to work from. 4966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler scratch_dir_ = android_data_ + "/OatFileAssistantTest"; 5066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700)); 5166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 526343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler // Create a subdirectory in scratch for odex files. 536343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler odex_oat_dir_ = scratch_dir_ + "/oat"; 546343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700)); 556343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler 566343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA)); 576343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700)); 586343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler 5966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 6066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the environment is as we expect 6166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler uint32_t checksum; 6266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 6366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(OS::FileExists(GetImageFile().c_str())) 6466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << "Expected pre-compiled boot image to be at: " << GetImageFile(); 6566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str())) 6666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << "Expected dex file to be at: " << GetDexSrc1(); 6766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str())) 6866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << "Expected stripped dex file to be at: " << GetStrippedDexSrc1(); 69b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg)) 7066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1(); 7166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str())) 7266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler << "Expected dex file to be at: " << GetDexSrc2(); 7367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 7467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // GetMultiDexSrc2 should have the same primary dex checksum as 7567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // GetMultiDexSrc1, but a different secondary dex checksum. 7667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler std::vector<std::unique_ptr<const DexFile>> multi1; 7767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(), 78b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin GetMultiDexSrc1().c_str(), &error_msg, &multi1)) << error_msg; 7967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler ASSERT_GT(multi1.size(), 1u); 8067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 8167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler std::vector<std::unique_ptr<const DexFile>> multi2; 8267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(), 83b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin GetMultiDexSrc2().c_str(), &error_msg, &multi2)) << error_msg; 8467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler ASSERT_GT(multi2.size(), 1u); 8567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 8667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum()); 8767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum()); 8866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 8966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 9066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler virtual void SetUpRuntimeOptions(RuntimeOptions* options) { 91892fc96694b51ac7a896dacd75af5b235f955825Richard Uhler // options->push_back(std::make_pair("-verbose:oat", nullptr)); 9266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 9366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Set up the image location. 9466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler options->push_back(std::make_pair("-Ximage:" + GetImageLocation(), 9566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler nullptr)); 9666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Make sure compilercallbacks are not set so that relocation will be 9766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // enabled. 98bb9c6b1c55e9e2308b4f5892a398a8837231fdbdAndreas Gampe callbacks_.reset(); 9966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 10066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler virtual void PreRuntimeCreate() { 10266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler UnreserveImageSpace(); 10366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 10466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler virtual void PostRuntimeCreate() { 10666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ReserveImageSpace(); 10766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 10866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler virtual void TearDown() { 1106343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler ClearDirectory(odex_dir_.c_str()); 1116343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler ASSERT_EQ(0, rmdir(odex_dir_.c_str())); 1126343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler 1136343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler ClearDirectory(odex_oat_dir_.c_str()); 1146343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str())); 11566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 11666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ClearDirectory(scratch_dir_.c_str()); 11766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_EQ(0, rmdir(scratch_dir_.c_str())); 11866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 11966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CommonRuntimeTest::TearDown(); 12066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 12166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 12266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler void Copy(std::string src, std::string dst) { 12366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::ifstream src_stream(src, std::ios::binary); 12466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::ofstream dst_stream(dst, std::ios::binary); 12566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 12666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dst_stream << src_stream.rdbuf(); 12766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 12866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 12966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Returns the directory where the pre-compiled core.art can be found. 13066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // TODO: We should factor out this into common tests somewhere rather than 13166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // re-hardcoding it here (This was copied originally from the elf writer 13266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // test). 13366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string GetImageDirectory() { 13466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler if (IsHost()) { 13566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const char* host_dir = getenv("ANDROID_HOST_OUT"); 1362cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(host_dir != nullptr); 13766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return std::string(host_dir) + "/framework"; 13866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } else { 13966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return std::string("/data/art-test"); 14066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 14166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 14266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 14366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string GetImageLocation() { 14466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return GetImageDirectory() + "/core.art"; 14566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 14666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 14766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string GetImageFile() { 14866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA) 14966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler + "/core.art"; 15066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 15166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 15266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string GetDexSrc1() { 15366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return GetTestDexFileName("Main"); 15466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 15566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 15666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex 15766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // file stripped. 15866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string GetStrippedDexSrc1() { 15966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return GetTestDexFileName("MainStripped"); 16066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 16166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 16266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string GetMultiDexSrc1() { 16366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return GetTestDexFileName("MultiDex"); 16466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 16566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 16667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but 16767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // with the contents of the secondary dex file changed. 16867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler std::string GetMultiDexSrc2() { 16967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler return GetTestDexFileName("MultiDexModifiedSecondary"); 17067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler } 17167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 17266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string GetDexSrc2() { 17366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return GetTestDexFileName("Nested"); 17466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 17566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 17666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Scratch directory, for dex and odex files (oat files will go in the 17766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // dalvik cache). 17866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string GetScratchDir() { 17966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return scratch_dir_; 18066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 18166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1826343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler // Odex directory is the subdirectory in the scratch directory where odex 18366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // files should be located. 1846343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string GetOdexDir() { 1856343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler return odex_dir_; 18666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 18766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 18893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // Generate a non-PIC odex file for the purposes of test. 18994f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler // The generated odex file will be un-relocated. 19066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler void GenerateOdexForTest(const std::string& dex_location, 19193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler const std::string& odex_location) { 19293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // To generate an un-relocated odex file, we first compile a relocated 19393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // version of the file, then manually call patchoat to make it look as if 19493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // it is unrelocated. 19593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler std::string relocated_odex_location = odex_location + ".relocated"; 19693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler std::vector<std::string> args; 19793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler args.push_back("--dex-file=" + dex_location); 19893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler args.push_back("--oat-file=" + relocated_odex_location); 19993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler args.push_back("--include-patch-information"); 20093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 20193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // We need to use the quick compiler to generate non-PIC code, because 20293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // the optimizing compiler always generates PIC. 20393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler args.push_back("--compiler-backend=Quick"); 20493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 20593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler std::string error_msg; 20693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 20793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 20893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // Use patchoat to unrelocate the relocated odex file. 20993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler Runtime* runtime = Runtime::Current(); 21093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler std::vector<std::string> argv; 21193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler argv.push_back(runtime->GetPatchoatExecutable()); 21293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA))); 21393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler argv.push_back("--input-oat-file=" + relocated_odex_location); 21493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler argv.push_back("--output-oat-file=" + odex_location); 21593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler argv.push_back("--base-offset-delta=0x00008000"); 21693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler std::string command_line(Join(argv, ' ')); 21793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler ASSERT_TRUE(Exec(argv, &error_msg)) << error_msg; 21893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 21993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // Verify the odex file was generated as expected and really is 22093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // unrelocated. 22193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler std::unique_ptr<OatFile> odex_file(OatFile::Open( 22293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, 22393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler false, dex_location.c_str(), &error_msg)); 22493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; 22593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 226dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao const std::vector<gc::space::ImageSpace*> image_spaces = 227dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao runtime->GetHeap()->GetBootImageSpaces(); 228dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr); 229dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao const ImageHeader& image_header = image_spaces[0]->GetImageHeader(); 23093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler const OatHeader& oat_header = odex_file->GetOatHeader(); 23193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler EXPECT_FALSE(odex_file->IsPic()); 23293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler EXPECT_EQ(image_header.GetOatChecksum(), oat_header.GetImageFileLocationOatChecksum()); 23393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()), 23493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler oat_header.GetImageFileLocationOatDataBegin()); 23593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta()); 23693aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler } 23793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 23893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler void GeneratePicOdexForTest(const std::string& dex_location, 23993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler const std::string& odex_location) { 24093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // Temporarily redirect the dalvik cache so dex2oat doesn't find the 24193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // relocated image file. 24266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp"; 24366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler setenv("ANDROID_DATA", android_data_tmp.c_str(), 1); 24466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> args; 24566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler args.push_back("--dex-file=" + dex_location); 24666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler args.push_back("--oat-file=" + odex_location); 24793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler args.push_back("--compile-pic"); 24866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler args.push_back("--runtime-arg"); 24966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler args.push_back("-Xnorelocate"); 25066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 251b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 25266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler setenv("ANDROID_DATA", android_data_.c_str(), 1); 25394f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler 25494f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler // Verify the odex file was generated as expected. 25594f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler std::unique_ptr<OatFile> odex_file(OatFile::Open( 25694f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, 257b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin false, dex_location.c_str(), &error_msg)); 25894f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; 25993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler EXPECT_TRUE(odex_file->IsPic()); 26066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 26166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 262ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil void GenerateExtractOnlyOdexForTest(const std::string& dex_location, 263d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle const std::string& odex_location) { 264ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil std::vector<std::string> args; 265ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil args.push_back("--dex-file=" + dex_location); 266ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil args.push_back("--oat-file=" + odex_location); 267ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil args.push_back("--compiler-filter=verify-at-runtime"); 268ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil std::string error_msg; 269ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 270ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 271ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil // Verify the odex file was generated as expected. 272ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil std::unique_ptr<OatFile> odex_file(OatFile::Open( 273ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, 274ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil false, dex_location.c_str(), &error_msg)); 275ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; 276ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(odex_file->IsExtractOnly()); 277ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_EQ(odex_file->GetOatHeader().GetImageFileLocationOatChecksum(), 0u); 278ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_EQ(odex_file->GetOatHeader().GetImageFileLocationOatDataBegin(), 0u); 279ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_EQ(odex_file->GetOatHeader().GetImagePatchDelta(), 0); 280d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle } 281d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 282d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle void GenerateProfileGuideOdexForTest(const std::string& dex_location, 283d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle const std::string& odex_location) { 284d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle std::vector<std::string> args; 285d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle args.push_back("--dex-file=" + dex_location); 286d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle args.push_back("--oat-file=" + odex_location); 287d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ScratchFile profile_file; 288d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle args.push_back("--profile-file=" + profile_file.GetFilename()); 289d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle std::string error_msg; 290d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 291d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 292d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle // Verify the odex file was generated as expected. 293d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle std::unique_ptr<OatFile> odex_file(OatFile::Open( 294d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle odex_location.c_str(), odex_location.c_str(), nullptr, nullptr, 295d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle false, dex_location.c_str(), &error_msg)); 296d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle printf("error %s", error_msg.c_str()); 297d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; 298d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(odex_file->IsProfileGuideCompiled()); 299d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle } 300ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 30166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private: 30266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Reserve memory around where the image will be loaded so other memory 30366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // won't conflict when it comes time to load the image. 30466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // This can be called with an already loaded image to reserve the space 30566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // around it. 30666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler void ReserveImageSpace() { 30766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler MemMap::Init(); 30866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 30966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Ensure a chunk of memory is reserved for the image space. 31066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler uintptr_t reservation_start = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MIN_DELTA; 31166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler uintptr_t reservation_end = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MAX_DELTA 3123dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi // Include the main space that has to come right after the 3133dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi // image in case of the GSS collector. 3143dbf23412481c4da51f0ebe32bec5d300c36834bHiroshi Yamauchi + 384 * MB; 31566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 31666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true)); 31766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map"; 31866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (BacktraceMap::const_iterator it = map->begin(); 31966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler reservation_start < reservation_end && it != map->end(); ++it) { 3203efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end)); 3213efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler reservation_start = std::max(reservation_start, it->end); 3223efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler } 3233efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler ReserveImageSpaceChunk(reservation_start, reservation_end); 3243efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler } 32566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 3263efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler // Reserve a chunk of memory for the image space in the given range. 3273efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler // Only has effect for chunks with a positive number of bytes. 3283efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) { 3293efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler if (start < end) { 3303efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler std::string error_msg; 33166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler image_reservation_.push_back(std::unique_ptr<MemMap>( 33266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler MemMap::MapAnonymous("image reservation", 3333efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler reinterpret_cast<uint8_t*>(start), end - start, 334b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin PROT_NONE, false, false, &error_msg))); 33566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg; 33666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler LOG(INFO) << "Reserved space for image " << 33766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" << 33866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler reinterpret_cast<void*>(image_reservation_.back()->End()); 33966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 34066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 34166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 34266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 34366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Unreserve any memory reserved by ReserveImageSpace. This should be called 34466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // before the image is loaded. 34566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler void UnreserveImageSpace() { 34666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler image_reservation_.clear(); 34766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 34866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 34966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string scratch_dir_; 3506343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_oat_dir_; 3516343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_dir_; 35266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<MemMap>> image_reservation_; 35366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}; 35466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 35566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantNoDex2OatTest : public OatFileAssistantTest { 35666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public: 35766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler virtual void SetUpRuntimeOptions(RuntimeOptions* options) { 35866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler OatFileAssistantTest::SetUpRuntimeOptions(options); 35966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler options->push_back(std::make_pair("-Xnodex2oat", nullptr)); 36066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 36166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}; 36266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 36366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Generate an oat file for the purposes of test, as opposed to testing 36466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// generation of oat files. 36566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic void GenerateOatForTest(const char* dex_location) { 366d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location, 367d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 36866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 36966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 370b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_TRUE(oat_file_assistant.GenerateOatFile(&error_msg)) << error_msg; 37166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 37266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 37366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, but no OAT file for it. 37495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded. 37566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexNoOat) { 37666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/DexNoOat.jar"; 37766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 37866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 379d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 380d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 38166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 38295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded()); 38366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 38466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 38566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 38666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 38766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 38866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 38995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); 39066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 39166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 39266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 39366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 39495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); 3959b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 39666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 39766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 39866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have no DEX file and no OAT file. 3999b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash. 40066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NoDexNoOat) { 40166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar"; 40266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 403d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 404d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 40566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 4069b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 4079b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 4089b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 4099b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Trying to make the oat file up to date should not fail or crash. 4109b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler std::string error_msg; 411b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)); 4129b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 4139b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Trying to get the best oat file should fail, but not crash. 41466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 41566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(nullptr, oat_file.get()); 41666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 41766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 41866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it. 41995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded. 42066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatUpToDate) { 42166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/OatUpToDate.jar"; 42266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 42366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOatForTest(dex_location.c_str()); 42466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 425d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 426d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 42766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 42895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 42966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 43066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 43166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 43266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 43366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 43466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 43566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 43666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 43795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); 4389b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 43966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 44066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 44166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it. 44295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded and we load all dex files. 44366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, MultiDexOatUpToDate) { 44466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar"; 44566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetMultiDexSrc1(), dex_location); 44666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOatForTest(dex_location.c_str()); 44766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 448d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 449d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 45095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 4519b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 45295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 45395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler // Verify we can load both dex files. 454e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 455e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 456e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 457e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 458e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 459e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler EXPECT_EQ(2u, dex_files.size()); 460e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler} 461e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 46267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Case: We have a MultiDEX file where the secondary dex file is out of date. 46367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Expect: The status is kDex2OatNeeded. 46467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard UhlerTEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) { 46567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar"; 46667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 46767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // Compile code for GetMultiDexSrc1. 46867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler Copy(GetMultiDexSrc1(), dex_location); 46967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler GenerateOatForTest(dex_location.c_str()); 47067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 47167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum 47267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // is out of date. 47367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler Copy(GetMultiDexSrc2(), dex_location); 47467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 475d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 476d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 47767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded()); 4789b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 47967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler} 48067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 481e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it with relative 482e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// encoded dex locations. 48395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The oat file status is kNoDexOptNeeded. 484e5fed03772144595c0904faf3d6974cc55214c8cRichard UhlerTEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) { 485e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar"; 4866343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat"; 487e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 488e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // Create the dex file 489e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler Copy(GetMultiDexSrc1(), dex_location); 490e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 491e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // Create the oat file with relative encoded dex location. 492e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::vector<std::string> args; 493e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler args.push_back("--dex-file=" + dex_location); 494e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar")); 495e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler args.push_back("--oat-file=" + oat_location); 496e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 497e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::string error_msg; 498b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 499e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 500e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // Verify we can load both dex files. 501e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler OatFileAssistant oat_file_assistant(dex_location.c_str(), 502e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler oat_location.c_str(), 503d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, 504e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler kRuntimeISA, true); 505e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 50666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 50766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 50866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 509e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 51066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(2u, dex_files.size()); 51166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 51266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 51395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file and out-of-date OAT file. 51495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded. 51566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatOutOfDate) { 51666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar"; 51766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 51866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // We create a dex, generate an oat for it, then overwrite the dex with a 51966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // different dex to make the oat out of date. 52066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 52166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOatForTest(dex_location.c_str()); 52266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc2(), dex_location); 52366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 524d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 525d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 52695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded()); 52766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 52866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 52966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 53066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 53166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 53266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 53366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 53466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 5359b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 53666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 53766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 53866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, but no OAT file. 53995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded. 54066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexOdexNoOat) { 54166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar"; 5426343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex"; 54366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 54466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 54566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 54666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOdexForTest(dex_location, odex_location); 54766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 54866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the status. 549d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 550d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 55166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 55295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded()); 55366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 55466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 55566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 55666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 55766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 55866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 55966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 56066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 56166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 5629b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 5635f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler 5645f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler // We should still be able to get the non-executable odex file to run from. 5655f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 5665f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 56766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 56866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 56966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a stripped DEX file and an ODEX file, but no OAT file. 57095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded 57166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) { 57266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar"; 5736343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex"; 57466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 57566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 57666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 57766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOdexForTest(dex_location, odex_location); 57866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 57966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Strip the dex file 58066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetStrippedDexSrc1(), dex_location); 58166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 58266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the status. 583d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 584d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 58566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 58695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded()); 58766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 58866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 58966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 59066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 59166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 59266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 59366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 59466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 5959b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 59666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 59766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Make the oat file up to date. 59866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 599b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg; 60066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 60195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 60266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 60366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 60466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 60566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 60666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 60766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 60866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 60966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 6109b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 61166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 61266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify we can load the dex files from it. 61366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 61466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 61566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 61666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 61766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 61866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 61966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 62066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 62195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file. 62295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded. 62366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexOat) { 62466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar"; 6256343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex"; 62666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 62766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the oat file from a different dex file so it looks out of date. 62866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc2(), dex_location); 62966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOatForTest(dex_location.c_str()); 63066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 63166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the odex file 63266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 63366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOdexForTest(dex_location, odex_location); 63466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 63566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Strip the dex file. 63666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetStrippedDexSrc1(), dex_location); 63766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 63866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the status. 639d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 640d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 64166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 64295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded()); 64366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 64466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 64566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 64666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 64766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 64866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 64966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 65066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 65166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 6529b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 65366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 65466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Make the oat file up to date. 65566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 656b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg; 65766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 65895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 65966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 66066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 66166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 66266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 66366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 66466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 66566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 66666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 66766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 66866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 6699b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 67066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 67166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify we can load the dex files from it. 67266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 67366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 67466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 67566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 67666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 67766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 67866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 67966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 6809b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no 6819b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// OAT file. Expect: The status is kNoDexOptNeeded. 6829b994ea841eaaefbdda652251894a74db9cefcc8Richard UhlerTEST_F(OatFileAssistantTest, ResourceOnlyDex) { 6839b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar"; 6849b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6859b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler Copy(GetStrippedDexSrc1(), dex_location); 6869b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6879b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Verify the status. 688d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 689d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 6909b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6919b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 6929b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6939b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 6949b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 6959b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 6969b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 6979b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 6989b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 6999b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 7009b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 7019b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 7029b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 7039b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Make the oat file up to date. This should have no effect. 7049b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler std::string error_msg; 705b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg; 7069b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 7079b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 7089b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 7099b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 7109b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 7119b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 7129b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 7139b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 7149b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 7159b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 7169b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 7179b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 7189b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler} 7199b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 72095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs 72195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// relocation. 72295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kSelfPatchOatNeeded. 72395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerTEST_F(OatFileAssistantTest, SelfRelocation) { 72495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::string dex_location = GetScratchDir() + "/SelfRelocation.jar"; 72595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::string oat_location = GetOdexDir() + "/SelfRelocation.oat"; 72695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 72795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler // Create the dex and odex files 72895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler Copy(GetDexSrc1(), dex_location); 72995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler GenerateOdexForTest(dex_location, oat_location); 73095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 73195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler OatFileAssistant oat_file_assistant(dex_location.c_str(), 732d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle oat_location.c_str(), OatFileAssistant::kFullCompilation, kRuntimeISA, true); 73395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 73495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, oat_file_assistant.GetDexOptNeeded()); 73595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 73695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 73795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 73895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 73995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 74095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 74195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 74295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation()); 74395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 74495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 7459b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 74695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 74795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler // Make the oat file up to date. 74895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::string error_msg; 749b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg; 75095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 75195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 75295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 75395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 75495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 75595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 75695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 75795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 75895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 75995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 76095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 76195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 7629b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 76395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 76495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 76595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 76695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 76795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 76895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 76995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(1u, dex_files.size()); 77095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler} 77195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 77266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and 77366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// OAT files both have patch delta of 0. 77495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: It shouldn't crash, and status is kPatchOatNeeded. 77566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OdexOatOverlap) { 77666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar"; 7776343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex"; 7786343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat"; 77966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 78066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 78166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 78266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOdexForTest(dex_location, odex_location); 78366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 78466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the oat file by copying the odex so they are located in the same 78566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // place in memory. 78666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(odex_location, oat_location); 78766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 78866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify things don't go bad. 78966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler OatFileAssistant oat_file_assistant(dex_location.c_str(), 790d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle oat_location.c_str(), OatFileAssistant::kFullCompilation, kRuntimeISA, true); 79166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 79295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, oat_file_assistant.GetDexOptNeeded()); 79366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 79466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 79566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 79666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 79766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 79866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 79966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 80066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 8019b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 80266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 80366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Things aren't relocated, so it should fall back to interpreted. 80466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 80566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 806f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler 80766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file->IsExecutable()); 80866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 80966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 81066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 81166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 81266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 81366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and a PIC ODEX file, but no OAT file. 81495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation. 81566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexPicOdexNoOat) { 81666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar"; 8176343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex"; 81866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 81966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 82066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 82166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GeneratePicOdexForTest(dex_location, odex_location); 82266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 82366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the status. 824d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 825d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 82666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 82795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 82866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 82966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 830ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 831ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 832ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate()); 833ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_FALSE(oat_file_assistant.OatFileExists()); 834ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 835ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 836ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 837ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil} 838ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 839ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil// Case: We have a DEX file and a ExtractOnly ODEX file, but no OAT file. 840ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil// Expect: The status is kNoDexOptNeeded, because ExtractOnly contains no code. 841ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid BrazdilTEST_F(OatFileAssistantTest, DexExtractOnlyOdexNoOat) { 842ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil std::string dex_location = GetScratchDir() + "/DexExtractOnlyOdexNoOat.jar"; 843ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil std::string odex_location = GetOdexDir() + "/DexExtractOnlyOdexNoOat.odex"; 844ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 845ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil // Create the dex and odex files 846ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil Copy(GetDexSrc1(), dex_location); 847ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil GenerateExtractOnlyOdexForTest(dex_location, odex_location); 848ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 849ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil // Verify the status. 850d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 851d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation | OatFileAssistant::kExtractOnly, 852d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle kRuntimeISA, false); 853ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 854ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 855ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 856ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 85766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 85866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 85966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate()); 86066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 86166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 86266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 8639b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 86466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 86566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 86666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it. 86766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file. 86866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadOatUpToDate) { 86966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar"; 87066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 87166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 87266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOatForTest(dex_location.c_str()); 87366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 87466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the oat using an oat file assistant. 875d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 876d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 87766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 87866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 87966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 88066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 88166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 88266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 88366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 88466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 88566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 88666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it. 88766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Loading non-executable should load the oat non-executable. 88866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) { 88966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar"; 89066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 89166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 89266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOatForTest(dex_location.c_str()); 89366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 89466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the oat using an oat file assistant. 895d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 896d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 89766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 89866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 89966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 90066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file->IsExecutable()); 90166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 90266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 90366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 90466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 90566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 90666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file. 90766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file from an alternative oat 90866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// location. 90966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) { 91066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar"; 91166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat"; 91266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 91366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 91466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 91566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler OatFileAssistant oat_file_assistant( 916d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle dex_location.c_str(), oat_location.c_str(), 917d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 91866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 919b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)) << error_msg; 92066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 92166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 92266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 92366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 92466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 92566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 92666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 92766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 92866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(OS::FileExists(oat_location.c_str())); 92966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 93066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify it didn't create an oat in the default location. 931d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant ofm(dex_location.c_str(), 932d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 93366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(ofm.OatFileExists()); 93466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 93566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 9368327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We have a DEX file but can't write the oat file. 9378327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to make the oat file up to date. 9388327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) { 9398327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar"; 9408327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9418327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler // Make the oat location unwritable by inserting some non-existent 9428327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler // intermediate directories. 9438327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat"; 9448327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9458327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler Copy(GetDexSrc1(), dex_location); 9468327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9478327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler OatFileAssistant oat_file_assistant( 948d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle dex_location.c_str(), oat_location.c_str(), 949d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 9508327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string error_msg; 9518327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler ASSERT_FALSE(oat_file_assistant.MakeUpToDate(&error_msg)); 9528327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9538327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 9548327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler ASSERT_TRUE(oat_file.get() == nullptr); 9558327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler} 9568327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9578327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We don't have a DEX file and can't write the oat file. 9588327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to generate the oat file without crashing. 9598327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, GenNoDex) { 9608327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string dex_location = GetScratchDir() + "/GenNoDex.jar"; 9618327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string oat_location = GetScratchDir() + "/GenNoDex.oat"; 9628327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9638327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler OatFileAssistant oat_file_assistant( 964d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle dex_location.c_str(), oat_location.c_str(), 965d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 9668327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string error_msg; 9678327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler ASSERT_FALSE(oat_file_assistant.GenerateOatFile(&error_msg)); 9688327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler} 9698327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 97066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Turn an absolute path into a path relative to the current working 97166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// directory. 97266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic std::string MakePathRelative(std::string target) { 97366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler char buf[MAXPATHLEN]; 97466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string cwd = getcwd(buf, MAXPATHLEN); 97566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 97666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Split the target and cwd paths into components. 97766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> target_path; 97866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> cwd_path; 97966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Split(target, '/', &target_path); 98066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Split(cwd, '/', &cwd_path); 98166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 98266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Reverse the path components, so we can use pop_back(). 98366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::reverse(target_path.begin(), target_path.end()); 98466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::reverse(cwd_path.begin(), cwd_path.end()); 98566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 98666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Drop the common prefix of the paths. Because we reversed the path 98766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // components, this becomes the common suffix of target_path and cwd_path. 98866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler while (!target_path.empty() && !cwd_path.empty() 98966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler && target_path.back() == cwd_path.back()) { 99066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler target_path.pop_back(); 99166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cwd_path.pop_back(); 99266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 99366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 99466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // For each element of the remaining cwd_path, add '..' to the beginning 99566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // of the target path. Because we reversed the path components, we add to 99666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // the end of target_path. 99766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (unsigned int i = 0; i < cwd_path.size(); i++) { 99866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler target_path.push_back(".."); 99966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 100066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 100166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Reverse again to get the right path order, and join to get the result. 100266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::reverse(target_path.begin(), target_path.end()); 100366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return Join(target_path, '/'); 100466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 100566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 100666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-absolute path to Dex location. 100766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Not sure, but it shouldn't crash. 100866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) { 100966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar"; 101066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), abs_dex_location); 101166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 101266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = MakePathRelative(abs_dex_location); 1013d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 1014d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 101566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 101666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 101795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded()); 101866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 101966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 102066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 102166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 102266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 102366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 102466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 102566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 102666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Very short, non-existent Dex location. 10279b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: kNoDexOptNeeded. 102866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, ShortDexLocation) { 102966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = "/xx"; 103066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1031d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 1032d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 103366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 103466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 10359b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded()); 103666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 103766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 103866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 103966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 104066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 104166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 10429b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 104366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10449b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Trying to make it up to date should have no effect. 104566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 1046b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin EXPECT_TRUE(oat_file_assistant.MakeUpToDate(&error_msg)); 10479b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(error_msg.empty()); 104866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 104966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 105066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-standard extension for dex file. 105195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded. 105266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LongDexExtension) { 105366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx"; 105466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 105566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1056d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 1057d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 105866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 105995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, oat_file_assistant.GetDexOptNeeded()); 106066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 106166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 106266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 106366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 106466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 106566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 106666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 106766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 106866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 106966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 107066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// A task to generate a dex location. Used by the RaceToGenerate test. 107166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass RaceGenerateTask : public Task { 107266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public: 107366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location) 107466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler : dex_location_(dex_location), oat_location_(oat_location), 107566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler loaded_oat_file_(nullptr) 107666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler {} 107766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10784b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain void Run(Thread* self ATTRIBUTE_UNUSED) { 107966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the dex files, and save a pointer to the loaded oat file, so that 108066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // we can verify only one oat file was loaded for the dex location. 108166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 108266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> error_msgs; 1083e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier const OatFile* oat_file = nullptr; 1084f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat( 1085f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier dex_location_.c_str(), 1086f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier oat_location_.c_str(), 1087fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*class_loader*/nullptr, 1088fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*dex_elements*/nullptr, 1089e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier &oat_file, 1090f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier &error_msgs); 109166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(!dex_files.empty()) << Join(error_msgs, '\n'); 109207b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation(); 109307b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile(); 1094e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier CHECK_EQ(loaded_oat_file_, oat_file); 109566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 109666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 109766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* GetLoadedOatFile() const { 109866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return loaded_oat_file_; 109966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 110066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 110166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private: 110266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location_; 110366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string oat_location_; 110466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* loaded_oat_file_; 110566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}; 110666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 110766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Test the case where multiple processes race to generate an oat file. 110866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// This simulates multiple processes using multiple threads. 110966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// 1110f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// We want unique Oat files to be loaded even when there is a race to load. 1111f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// TODO: The test case no longer tests locking the way it was intended since we now get multiple 1112f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// copies of the same Oat files mapped at different locations. 111366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, RaceToGenerate) { 111466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar"; 11156343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat"; 111666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 111766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // We use the lib core dex file, because it's large, and hopefully should 111866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // take a while to generate. 1119d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath Copy(GetLibCoreDexFileNames()[0], dex_location); 112066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 112166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const int kNumThreads = 32; 112266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Thread* self = Thread::Current(); 112366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads); 112466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<RaceGenerateTask>> tasks; 112566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (int i = 0; i < kNumThreads; i++) { 112666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location)); 112766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler thread_pool.AddTask(self, task.get()); 112866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler tasks.push_back(std::move(task)); 112966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 113066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler thread_pool.StartWorkers(self); 113166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler thread_pool.Wait(self, true, false); 113266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1133f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Verify every task got a unique oat file. 1134f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::set<const OatFile*> oat_files; 113566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (auto& task : tasks) { 1136f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const OatFile* oat_file = task->GetLoadedOatFile(); 1137f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end()); 1138f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier oat_files.insert(oat_file); 113966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 114066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 114166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 114266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is 114366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled. 114466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable. 114566d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) { 114666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar"; 11476343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex"; 114866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 114966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 115066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 115166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOdexForTest(dex_location, odex_location); 115266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 115366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the oat using an executable oat file assistant. 1154d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 1155d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 115666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 115766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 115866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 115966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file->IsExecutable()); 116066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 116166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 116266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 116366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 116466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 116566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is 116666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled. 116766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable. 116866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) { 116966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar"; 11706343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex"; 117166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 117266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 117366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetMultiDexSrc1(), dex_location); 117466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler GenerateOdexForTest(dex_location, odex_location); 117566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 117666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the oat using an executable oat file assistant. 1177d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant oat_file_assistant(dex_location.c_str(), 1178d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, true); 117966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 118066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 118166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 118266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file->IsExecutable()); 118366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 118466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 118566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(2u, dex_files.size()); 118666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 118766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 118866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) { 118966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 119066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string odex_file; 119166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 119266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename( 1193b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg; 11946343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file); 119566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 119666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename( 1197b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg; 11986343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file); 119966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 120066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename( 1201b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin "nopath.jar", kArm, &odex_file, &error_msg)); 120266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename( 1203b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin "/foo/bar/baz_noext", kArm, &odex_file, &error_msg)); 120466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 120566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1206d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle// Case: We have a DEX file, extract-only ODEX, and fully compiled OAT. 1207d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle// Expect: The status depends on the target compilation type mask. 1208d91b8a2464b99625efe03caf7d30c8372bc378edCalin JuravleTEST_F(OatFileAssistantTest, TargetCompilationType) { 1209d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle std::string dex_location = GetScratchDir() + "/TargetCompilationType.jar"; 1210d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle std::string odex_location = GetOdexDir() + "/TargetCompilationType.odex"; 1211d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle Copy(GetDexSrc1(), dex_location); 1212d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle GenerateExtractOnlyOdexForTest(dex_location, odex_location); 1213d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle GenerateOatForTest(dex_location.c_str()); 1214d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 1215d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant ofa_full(dex_location.c_str(), 1216d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation, kRuntimeISA, false); 1217d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, ofa_full.GetDexOptNeeded()); 1218d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_FALSE(ofa_full.IsInBootClassPath()); 1219d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(ofa_full.OdexFileIsOutOfDate()); 1220d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(ofa_full.OatFileIsUpToDate()); 1221d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 1222d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant ofa_extract(dex_location.c_str(), 1223d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kExtractOnly, kRuntimeISA, false); 1224d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, ofa_extract.GetDexOptNeeded()); 1225d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_FALSE(ofa_extract.IsInBootClassPath()); 1226d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(ofa_extract.OdexFileIsUpToDate()); 1227d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(ofa_extract.OatFileIsOutOfDate()); 1228d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 1229d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant ofa_profile(dex_location.c_str(), 1230d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kProfileGuideCompilation, kRuntimeISA, false); 1231d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, ofa_profile.GetDexOptNeeded()); 1232d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_FALSE(ofa_profile.IsInBootClassPath()); 1233d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(ofa_profile.OdexFileIsOutOfDate()); 1234d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(ofa_profile.OatFileIsOutOfDate()); 1235d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 1236d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant ofa_extract_full(dex_location.c_str(), 1237d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle OatFileAssistant::kFullCompilation | OatFileAssistant::kExtractOnly, 1238d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle kRuntimeISA, false); 1239d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, ofa_extract_full.GetDexOptNeeded()); 1240d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_FALSE(ofa_extract_full.IsInBootClassPath()); 1241d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(ofa_extract_full.OdexFileIsUpToDate()); 1242d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_TRUE(ofa_extract_full.OatFileIsUpToDate()); 1243d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle} 1244d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 124523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// Verify the dexopt status values from dalvik.system.DexFile 124623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// match the OatFileAssistant::DexOptStatus values. 124723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard UhlerTEST_F(OatFileAssistantTest, DexOptStatusValues) { 124823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ScopedObjectAccess soa(Thread::Current()); 124923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler StackHandleScope<1> hs(soa.Self()); 125023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ClassLinker* linker = Runtime::Current()->GetClassLinker(); 125123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler Handle<mirror::Class> dexfile( 125223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;"))); 125323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(dexfile.Get() == nullptr); 125423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler linker->EnsureInitialized(soa.Self(), dexfile, true, true); 125523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler 1256c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* no_dexopt_needed = mirror::Class::FindStaticField( 125723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I"); 125823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(no_dexopt_needed == nullptr); 125923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 126023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get())); 126123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler 1262c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* dex2oat_needed = mirror::Class::FindStaticField( 126323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler soa.Self(), dexfile, "DEX2OAT_NEEDED", "I"); 126423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(dex2oat_needed == nullptr); 126523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 126623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get())); 126723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler 1268c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* patchoat_needed = mirror::Class::FindStaticField( 126923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler soa.Self(), dexfile, "PATCHOAT_NEEDED", "I"); 127023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(patchoat_needed == nullptr); 127123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 127223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get())); 127323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler 1274c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* self_patchoat_needed = mirror::Class::FindStaticField( 127523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I"); 127623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(self_patchoat_needed == nullptr); 127723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 127823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get())); 1279d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 1280d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ArtField* compilation_type_full = mirror::Class::FindStaticField( 1281d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle soa.Self(), dexfile, "COMPILATION_TYPE_FULL", "I"); 1282d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ASSERT_FALSE(compilation_type_full == nullptr); 1283d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(compilation_type_full->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 1284d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(OatFileAssistant::kFullCompilation, compilation_type_full->GetInt(dexfile.Get())); 1285d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 1286d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ArtField* compilation_type_profile_guide = mirror::Class::FindStaticField( 1287d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle soa.Self(), dexfile, "COMPILATION_TYPE_PROFILE_GUIDE", "I"); 1288d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ASSERT_FALSE(compilation_type_profile_guide == nullptr); 1289d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(compilation_type_profile_guide->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 1290d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(OatFileAssistant::kProfileGuideCompilation, 1291d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle compilation_type_profile_guide->GetInt(dexfile.Get())); 1292d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle 1293d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ArtField* compilation_type_extract_only = mirror::Class::FindStaticField( 1294d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle soa.Self(), dexfile, "COMPILATION_TYPE_EXTRACT_ONLY", "I"); 1295d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle ASSERT_FALSE(compilation_type_extract_only == nullptr); 1296d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(compilation_type_extract_only->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 1297d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle EXPECT_EQ(OatFileAssistant::kExtractOnly, compilation_type_extract_only->GetInt(dexfile.Get())); 129823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler} 129966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 130066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// TODO: More Tests: 130166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test class linker falls back to unquickened dex for DexNoOat 130266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test class linker falls back to unquickened dex for MultiDexNoOat 130366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test using secondary isa 130466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test for status of oat while oat is being generated (how?) 130566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test case where 32 and 64 bit boot class paths differ, 130666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// and we ask IsInBootClassPath for a class in exactly one of the 32 or 130766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// 64 bit boot class paths. 130866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test unexpected scenarios (?): 130966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// - Dex is stripped, don't have odex. 131066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// - Oat file corrupted after status check, before reload unexecutable 131166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// because it's unrelocated and no dex2oat 1312d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle// * Test unrelocated specific target compilation type can be relocated to 1313d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle// make it up to date. 131466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 131566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} // namespace art 1316