oat_file_assistant_test.cc revision 0e4a2f0d6b526d398b71a54395c3071a8e78e503
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 <algorithm> 1866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <fstream> 1966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <string> 2066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <vector> 2166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <sys/param.h> 2266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <backtrace/BacktraceMap.h> 2466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include <gtest/gtest.h> 2566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 26c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h" 273481ba2c4e4f3aa80d8c6d50a9f85dacb56b508bVladimir Marko#include "class_linker-inl.h" 2866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "common_runtime_test.h" 29bb9c6b1c55e9e2308b4f5892a398a8837231fdbdAndreas Gampe#include "compiler_callbacks.h" 3025a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "dex2oat_environment_test.h" 31f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler#include "gc/space/image_space.h" 3266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler#include "mem_map.h" 3325a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe#include "oat_file_assistant.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 4225a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampeclass OatFileAssistantTest : public Dex2oatEnvironmentTest { 4366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public: 4425a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe virtual void SetUp() OVERRIDE { 4566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ReserveImageSpace(); 4625a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe Dex2oatEnvironmentTest::SetUp(); 4766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 4866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 497dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler // Pre-Relocate the image to a known non-zero offset so we don't have to 507dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler // deal with the runtime randomly relocating the image by 0 and messing up 517dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler // the expected results of the tests. 527dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler bool PreRelocateImage(std::string* error_msg) { 537dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler std::string image; 547dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler if (!GetCachedImageFile(&image, error_msg)) { 557dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler return false; 567dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler } 577dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler 587dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler std::string patchoat = GetAndroidRoot(); 597dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler patchoat += kIsDebugBuild ? "/bin/patchoatd" : "/bin/patchoat"; 607dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler 617dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler std::vector<std::string> argv; 627dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler argv.push_back(patchoat); 637dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler argv.push_back("--input-image-location=" + GetImageLocation()); 647dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler argv.push_back("--output-image-file=" + image); 657dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA))); 667dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler argv.push_back("--base-offset-delta=0x00008000"); 677dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler return Exec(argv, error_msg); 687dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler } 697dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler 7066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler virtual void PreRuntimeCreate() { 717dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler std::string error_msg; 727dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler ASSERT_TRUE(PreRelocateImage(&error_msg)) << error_msg; 737dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler 7466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler UnreserveImageSpace(); 7566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 7666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 7725a9abe3cd9594a60d353c0277b4f9e49a71a40aAndreas Gampe virtual void PostRuntimeCreate() OVERRIDE { 7866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ReserveImageSpace(); 7966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 8066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 8193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // Generate a non-PIC odex file for the purposes of test. 8294f5bda4828255b290c7b1472f38929f3b901e58Richard Uhler // The generated odex file will be un-relocated. 8366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler void GenerateOdexForTest(const std::string& dex_location, 847bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe const std::string& odex_location, 857dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler CompilerFilter::Filter filter, 867dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler bool pic = false, 877dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler bool with_patch_info = true) { 887dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler // Temporarily redirect the dalvik cache so dex2oat doesn't find the 897dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler // relocated image file. 900e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr std::string dalvik_cache = GetDalvikCache(GetInstructionSetString(kRuntimeISA)); 910e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr std::string dalvik_cache_tmp = dalvik_cache + ".redirected"; 920e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr ASSERT_EQ(0, rename(dalvik_cache.c_str(), dalvik_cache_tmp.c_str())) << strerror(errno); 930e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr 9493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler std::vector<std::string> args; 9593aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler args.push_back("--dex-file=" + dex_location); 967dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler args.push_back("--oat-file=" + odex_location); 977bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); 987dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler args.push_back("--runtime-arg"); 997dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler args.push_back("-Xnorelocate"); 10093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 1017dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler if (pic) { 1027dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler args.push_back("--compile-pic"); 1037dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler } 1047dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler 1057dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler if (with_patch_info) { 1067dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler args.push_back("--include-patch-information"); 1077dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler } 10893aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 10993aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler std::string error_msg; 11093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 1110e4a2f0d6b526d398b71a54395c3071a8e78e503David Sehr ASSERT_EQ(0, rename(dalvik_cache_tmp.c_str(), dalvik_cache.c_str())) << strerror(errno); 11293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 11393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // Verify the odex file was generated as expected and really is 11493aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler // unrelocated. 115bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), 116bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier odex_location.c_str(), 117bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier nullptr, 118bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier nullptr, 119bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier false, 120bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier /*low_4gb*/false, 121bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier dex_location.c_str(), 122bcb6a72569a1401b36a3ad3b6aa4d13e29966cf0Mathieu Chartier &error_msg)); 12393aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; 1247dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler EXPECT_EQ(pic, odex_file->IsPic()); 1257dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler EXPECT_EQ(with_patch_info, odex_file->HasPatchInfo()); 1267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(filter, odex_file->GetCompilerFilter()); 12793aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 1288c185bf0c6f18a5349bc87a7e3751ba06d90f461Vladimir Marko if (CompilerFilter::IsBytecodeCompilationEnabled(filter)) { 1297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe const std::vector<gc::space::ImageSpace*> image_spaces = 1307dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler Runtime::Current()->GetHeap()->GetBootImageSpaces(); 1317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr); 1327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe const ImageHeader& image_header = image_spaces[0]->GetImageHeader(); 1337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe const OatHeader& oat_header = odex_file->GetOatHeader(); 1344f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum(); 1354f351aae00f43dd4e3290976f249d3664cc47091Jeff Hao EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum()); 1367bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()), 1377bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_header.GetImageFileLocationOatDataBegin()); 1387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta()); 1397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe } 14093aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler } 14193aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler 14293aa210bd8bfa5e1e64eca329115617b3ab76faeRichard Uhler void GeneratePicOdexForTest(const std::string& dex_location, 1437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe const std::string& odex_location, 1447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe CompilerFilter::Filter filter) { 1457dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler GenerateOdexForTest(dex_location, odex_location, filter, true, false); 146d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle } 147ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 1481c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler // Generate a non-PIC odex file without patch information for the purposes 1491c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler // of test. The generated odex file will be un-relocated. 1501c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler void GenerateNoPatchOdexForTest(const std::string& dex_location, 1511c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler const std::string& odex_location, 1521c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler CompilerFilter::Filter filter) { 1537dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler GenerateOdexForTest(dex_location, odex_location, filter, false, false); 1541c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler } 1551c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler 15666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private: 15766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Reserve memory around where the image will be loaded so other memory 15866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // won't conflict when it comes time to load the image. 15966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // This can be called with an already loaded image to reserve the space 16066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // around it. 16166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler void ReserveImageSpace() { 16266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler MemMap::Init(); 16366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 16466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Ensure a chunk of memory is reserved for the image space. 1657dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler // The reservation_end includes room for the main space that has to come 1667dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler // right after the image in case of the GSS collector. 1677dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler uintptr_t reservation_start = ART_BASE_ADDRESS; 1687dfe5de0c83a4b7e8f34ae2d5ea47105e620257dRichard Uhler uintptr_t reservation_end = ART_BASE_ADDRESS + 384 * MB; 16966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 17066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true)); 17166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map"; 17266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (BacktraceMap::const_iterator it = map->begin(); 17366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler reservation_start < reservation_end && it != map->end(); ++it) { 1743efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end)); 1753efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler reservation_start = std::max(reservation_start, it->end); 1763efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler } 1773efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler ReserveImageSpaceChunk(reservation_start, reservation_end); 1783efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler } 17966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1803efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler // Reserve a chunk of memory for the image space in the given range. 1813efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler // Only has effect for chunks with a positive number of bytes. 1823efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) { 1833efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler if (start < end) { 1843efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler std::string error_msg; 18566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler image_reservation_.push_back(std::unique_ptr<MemMap>( 18666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler MemMap::MapAnonymous("image reservation", 1873efe979d4292330c8fab1708a4361e58681a88cbRichard Uhler reinterpret_cast<uint8_t*>(start), end - start, 188b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin PROT_NONE, false, false, &error_msg))); 18966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg; 19066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler LOG(INFO) << "Reserved space for image " << 19166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" << 19266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler reinterpret_cast<void*>(image_reservation_.back()->End()); 19366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 19466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 19566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 19666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 19766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Unreserve any memory reserved by ReserveImageSpace. This should be called 19866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // before the image is loaded. 19966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler void UnreserveImageSpace() { 20066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler image_reservation_.clear(); 20166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 20266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 20366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<MemMap>> image_reservation_; 20466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}; 20566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 20666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass OatFileAssistantNoDex2OatTest : public OatFileAssistantTest { 20766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public: 20866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler virtual void SetUpRuntimeOptions(RuntimeOptions* options) { 20966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler OatFileAssistantTest::SetUpRuntimeOptions(options); 21066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler options->push_back(std::make_pair("-Xnodex2oat", nullptr)); 21166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 21266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}; 21366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 21466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Generate an oat file for the purposes of test, as opposed to testing 21566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// generation of oat files. 2167bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampestatic void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) { 2177bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe // Use an oat file assistant to find the proper oat location. 2187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant ofa(dex_location, kRuntimeISA, false, false); 2197bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe const std::string* oat_location = ofa.OatFileName(); 2207bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe ASSERT_TRUE(oat_location != nullptr); 22166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2227bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::vector<std::string> args; 2237bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe args.push_back("--dex-file=" + std::string(dex_location)); 2247bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe args.push_back("--oat-file=" + *oat_location); 2257bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); 2267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe args.push_back("--runtime-arg"); 2277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe args.push_back("-Xnorelocate"); 22866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 2297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 2307bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 2317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe // Verify the oat file was generated as expected. 2327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location->c_str(), 2337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_location->c_str(), 2347bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe nullptr, 2357bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe nullptr, 2367bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe false, 2377bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe /*low_4gb*/false, 2387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe dex_location, 2397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe &error_msg)); 2407bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe ASSERT_TRUE(oat_file.get() != nullptr) << error_msg; 2417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(filter, oat_file->GetCompilerFilter()); 24266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 24366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 24466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, but no OAT file for it. 24595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded. 24666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexNoOat) { 24766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/DexNoOat.jar"; 24866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 24966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 25166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 2537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 2547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 2557bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 2567bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 2577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile)); 2587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 2597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 26066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 26166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 26266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 26366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 26466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 26566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 26695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); 26766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 26866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 26966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 27066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 27195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); 2729b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 27366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 27466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 27566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have no DEX file and no OAT file. 2769b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash. 27766d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NoDexNoOat) { 27866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar"; 27966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2807bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 28166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 2827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 2837bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 2849b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 2859b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 2869b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Trying to make the oat file up to date should not fail or crash. 2879b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler std::string error_msg; 288ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, 289ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)); 2909b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 2919b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Trying to get the best oat file should fail, but not crash. 29266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 29366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(nullptr, oat_file.get()); 29466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 29566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 29666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it. 29795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded. 29866d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatUpToDate) { 29966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/OatUpToDate.jar"; 30066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 3017bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 30266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 3037bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 3047bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 3057bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 3067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 3077bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 3087bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 3097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 3107bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 3117bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 3127bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 31366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 31466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 31566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 31666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 31766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 31866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 31966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 32066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 32166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 32295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); 3239b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 32466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 32566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 3267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and speed-profile OAT file for it. 3277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDexOptNeeded if the profile hasn't changed. 3287bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, ProfileOatUpToDate) { 3297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar"; 3307bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe Copy(GetDexSrc1(), dex_location); 3317bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile); 3327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 3337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 3347bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 3357bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 3367bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile)); 3377bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 3387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 3397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 3407bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 3417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 3427bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 3437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 3447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file_assistant.OatFileExists()); 3457bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 3467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 3477bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 3487bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); 3497bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 3507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe} 3517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 3527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and speed-profile OAT file for it. 3537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDex2OatNeeded if the profile has changed. 3547bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, ProfileOatOutOfDate) { 3557bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::string dex_location = GetScratchDir() + "/ProfileOatOutOfDate.jar"; 3567bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe Copy(GetDexSrc1(), dex_location); 3577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile); 3587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 3597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true, false); 3607bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 3617bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 3627bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile)); 3637bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 3647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 3657bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 3667bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 3677bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 3687bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 3697bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 3707bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file_assistant.OatFileExists()); 3717bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 3727bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 3737bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 3747bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); 3757bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 3767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe} 3777bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 37866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it. 37995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded and we load all dex files. 38066d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, MultiDexOatUpToDate) { 38166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar"; 38266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetMultiDexSrc1(), dex_location); 3837bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 38466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 3857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 3867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 3877bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 3889b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 38995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 39095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler // Verify we can load both dex files. 391e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 392e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 393e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 394e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 395e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 396e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler EXPECT_EQ(2u, dex_files.size()); 397e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler} 398e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 39967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Case: We have a MultiDEX file where the secondary dex file is out of date. 40067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler// Expect: The status is kDex2OatNeeded. 40167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard UhlerTEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) { 40267ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar"; 40367ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 40467ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // Compile code for GetMultiDexSrc1. 40567ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler Copy(GetMultiDexSrc1(), dex_location); 4067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 40767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 40867ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum 40967ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler // is out of date. 41067ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler Copy(GetMultiDexSrc2(), dex_location); 41167ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 4127bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 4137bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 4147bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 4159b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 41667ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler} 41767ff7d1fd7bcaf4b6b73ecdab6011c8636562b58Richard Uhler 418e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// Case: We have a MultiDEX file and up-to-date OAT file for it with relative 419e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler// encoded dex locations. 42095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The oat file status is kNoDexOptNeeded. 421e5fed03772144595c0904faf3d6974cc55214c8cRichard UhlerTEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) { 422e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar"; 4236343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat"; 424e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 425e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // Create the dex file 426e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler Copy(GetMultiDexSrc1(), dex_location); 427e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 428e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // Create the oat file with relative encoded dex location. 429e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::vector<std::string> args; 430e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler args.push_back("--dex-file=" + dex_location); 431e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar")); 432e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler args.push_back("--oat-file=" + oat_location); 4337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe args.push_back("--compiler-filter=speed"); 434e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 435e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::string error_msg; 436b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 437e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler 438e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler // Verify we can load both dex files. 439e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler OatFileAssistant oat_file_assistant(dex_location.c_str(), 440e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler oat_location.c_str(), 4417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe kRuntimeISA, false, true); 442e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 44366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 44466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 44566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 446e5fed03772144595c0904faf3d6974cc55214c8cRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 44766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(2u, dex_files.size()); 44866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 44966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 45095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file and out-of-date OAT file. 45195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded. 45266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OatOutOfDate) { 45366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar"; 45466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 45566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // We create a dex, generate an oat for it, then overwrite the dex with a 45666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // different dex to make the oat out of date. 45766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 4587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 45966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc2(), dex_location); 46066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 4617bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 4627bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 4637bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 4647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 4657bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 46666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 46766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 46866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 46966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 47066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 47166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 47266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 47366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 4749b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 47566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 47666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 47766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, but no OAT file. 47895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded. 47966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexOdexNoOat) { 48066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar"; 4816343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex"; 48266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 48366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 48466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 4857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 48666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 48766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the status. 4887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 48966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 4907bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 4917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 4927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, 4937bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 49466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 49566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 49666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 49766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 49866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 49966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 50066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 50166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 50266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 5039b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 5045f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler 5055f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler // We should still be able to get the non-executable odex file to run from. 5065f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 5075f946da9c362216e9144b142ec0e5b90073b836dRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 50866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 50966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 51066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a stripped DEX file and an ODEX file, but no OAT file. 51195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded 51266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) { 51366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar"; 5146343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex"; 51566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 51666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 51766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 5187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 51966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 52066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Strip the dex file 52166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetStrippedDexSrc1(), dex_location); 52266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 52366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the status. 5247bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 52566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 5267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, 5277bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 52866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 52966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 53066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 53166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 53266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 53366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 53466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 53566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 5369b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 53766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 53866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Make the oat file up to date. 53966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 540ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 541ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 54266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 5437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 5447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 54566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 54666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 54766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 54866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 54966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 55066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 55166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 55266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 5539b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 55466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 55566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify we can load the dex files from it. 55666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 55766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 55866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 55966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 56066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 56166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 56266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 56366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 56495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file. 56595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kPatchOatNeeded. 56666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, StrippedDexOdexOat) { 56766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar"; 5686343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex"; 56966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 57066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the oat file from a different dex file so it looks out of date. 57166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc2(), dex_location); 5727bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 57366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 57466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the odex file 57566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 5767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 57766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 57866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Strip the dex file. 57966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetStrippedDexSrc1(), dex_location); 58066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 58166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the status. 5827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 58366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 5847bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 5857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 5867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, 5877bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 5887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped. 5897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 59066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 59166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 59266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 59366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 59466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 59566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 59666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 59766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 59866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 5999b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 60066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 60166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Make the oat file up to date. 60266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 603ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 604ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 60566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 6067bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 6077bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 6087bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped. 6097bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 61066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 61166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 61266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 61366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 61466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 61566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 61666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 61766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 61866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 61966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 6209b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 62166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 62266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify we can load the dex files from it. 62366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 62466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 62566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 62666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 62766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 62866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 62966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 63066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 6319b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no 6329b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// OAT file. Expect: The status is kNoDexOptNeeded. 6339b994ea841eaaefbdda652251894a74db9cefcc8Richard UhlerTEST_F(OatFileAssistantTest, ResourceOnlyDex) { 6349b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar"; 6359b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6369b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler Copy(GetStrippedDexSrc1(), dex_location); 6379b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6389b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Verify the status. 6397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 6409b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 6427bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 6437bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 6447bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 6457bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 6467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 6479b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6489b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 6499b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 6509b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 6519b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 6529b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 6539b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 6549b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 6559b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 6569b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 6579b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6589b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Make the oat file up to date. This should have no effect. 6599b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler std::string error_msg; 660ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, 661ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 6629b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6637bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 6647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 6659b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 6669b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 6679b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 6689b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 6699b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 6709b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 6719b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 6729b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 6739b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 6749b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 6759b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler} 6769b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler 67795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs 67895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// relocation. 67995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kSelfPatchOatNeeded. 68095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard UhlerTEST_F(OatFileAssistantTest, SelfRelocation) { 68195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::string dex_location = GetScratchDir() + "/SelfRelocation.jar"; 68295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::string oat_location = GetOdexDir() + "/SelfRelocation.oat"; 68395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 68495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler // Create the dex and odex files 68595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler Copy(GetDexSrc1(), dex_location); 6867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed); 68795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 68895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler OatFileAssistant oat_file_assistant(dex_location.c_str(), 6897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_location.c_str(), kRuntimeISA, false, true); 69095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 6917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 6927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 6937bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, 6947bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 6957bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 6967bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 69795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 69895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 69995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 70095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 70195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 70295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 70395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 70495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation()); 70595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 70695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 7079b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 70895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 70995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler // Make the oat file up to date. 71095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::string error_msg; 711ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 712ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 71395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 7147bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 7157bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 71695abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 71795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 71895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 71995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 72095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 72195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 72295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 72395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 72495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 72595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 7269b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 72795abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 72895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 72995abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 73095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 73195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 73295abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 73395abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler EXPECT_EQ(1u, dex_files.size()); 73495abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler} 73595abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler 7361c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// Case: We have a DEX file, no ODEX file and an OAT file that needs 7371c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// relocation but doesn't have patch info. 7381c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler// Expect: The status is kDex2OatNeeded, because we can't run patchoat. 7391c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard UhlerTEST_F(OatFileAssistantTest, NoSelfRelocation) { 7401c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler std::string dex_location = GetScratchDir() + "/NoSelfRelocation.jar"; 7411c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler std::string oat_location = GetOdexDir() + "/NoSelfRelocation.oat"; 7421c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler 7431c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler // Create the dex and odex files 7441c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler Copy(GetDexSrc1(), dex_location); 7451c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler GenerateNoPatchOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed); 7461c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler 7471c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler OatFileAssistant oat_file_assistant(dex_location.c_str(), 7481c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler oat_location.c_str(), kRuntimeISA, false, true); 7491c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler 7501c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 7511c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 7521c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler 7531c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler // Make the oat file up to date. 7541c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler std::string error_msg; 755ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 756ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 7571c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 7581c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 7591c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler 7601c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 7611c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 7621c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 7631c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 7641c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 7651c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler EXPECT_EQ(1u, dex_files.size()); 7661c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler} 7671c4eb04b6cb1427f96e9587bd425ee269b8c8479Richard Uhler 76866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and 76966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// OAT files both have patch delta of 0. 77095abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: It shouldn't crash, and status is kPatchOatNeeded. 77166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, OdexOatOverlap) { 77266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar"; 7736343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex"; 7746343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat"; 77566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 77666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 77766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 7787bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 77966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 78066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the oat file by copying the odex so they are located in the same 78166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // place in memory. 78266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(odex_location, oat_location); 78366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 78466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify things don't go bad. 78566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler OatFileAssistant oat_file_assistant(dex_location.c_str(), 7867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_location.c_str(), kRuntimeISA, false, true); 78766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 7887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, 7897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 79066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 79166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 79266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 79366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 79466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 79566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileExists()); 79666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 79766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 7989b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 79966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 80066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Things aren't relocated, so it should fall back to interpreted. 80166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 80266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 803f16d5727f9062379519043bc063a2c0527c59eb8Richard Uhler 80466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file->IsExecutable()); 80566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 80666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 80766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 80866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 80966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 81066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and a PIC ODEX file, but no OAT file. 81195abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation. 81266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, DexPicOdexNoOat) { 81366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar"; 8146343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex"; 81566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 81666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 81766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 8187bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 81966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 82066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify the status. 8217bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 82266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 8237bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 8247bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 8257bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 8267bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 82766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 82866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 829ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 830ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 831ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate()); 832ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_FALSE(oat_file_assistant.OatFileExists()); 833ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 834ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 835ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 836ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil} 837ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 8387bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file. 8397bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code. 8407bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) { 8417bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar"; 8427bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex"; 843ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 844ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil // Create the dex and odex files 845ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil Copy(GetDexSrc1(), dex_location); 8467bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime); 847ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 848ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil // Verify the status. 8497bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 850ce4b0ba4d762775a86b3529ac76cb89199c0cc1eDavid Brazdil 8517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 8527bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 8537bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 8547bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 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); 8727bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 87366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 87466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the oat using an oat file assistant. 8757bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 8767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 8777bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 8787bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe ASSERT_TRUE(oat_file.get() != nullptr); 8797bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_TRUE(oat_file->IsExecutable()); 8807bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::vector<std::unique_ptr<const DexFile>> dex_files; 8817bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 8827bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(1u, dex_files.size()); 8837bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe} 8847bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 8857bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Case: We have a DEX file and up-to-date interpret-only OAT file for it. 8867bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// Expect: We should still load the oat file as executable. 8877bcfcb80a31f57a84d754e00bca8698829365208Andreas GampeTEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) { 8887bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar"; 8897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 8907bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe Copy(GetDexSrc1(), dex_location); 8917bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly); 8927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe 8937bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe // Load the oat using an oat file assistant. 8947bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 89566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 89666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 89766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 89866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 89966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 90066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 90166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 90266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 90366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 90466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and up-to-date OAT file for it. 90566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Loading non-executable should load the oat non-executable. 90666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) { 90766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar"; 90866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 90966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 9107bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 91166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 91266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the oat using an oat file assistant. 9137bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 91466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 91566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 91666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 91766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file->IsExecutable()); 91866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 91966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 92066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 92166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 92266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 92366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file. 92466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load an executable dex file from an alternative oat 92566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// location. 92666d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) { 92766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar"; 92866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat"; 92966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 93066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 93166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 93266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler OatFileAssistant oat_file_assistant( 9337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true); 93466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 935ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 936ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 93766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 93866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 93966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 94066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file->IsExecutable()); 94166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 94266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 94366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 94466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 94566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(OS::FileExists(oat_location.c_str())); 94666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 94766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Verify it didn't create an oat in the default location. 9487bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false, false); 94966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(ofm.OatFileExists()); 95066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 95166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 9528327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We have a DEX file but can't write the oat file. 9538327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to make the oat file up to date. 9548327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) { 9558327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar"; 9568327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9578327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler // Make the oat location unwritable by inserting some non-existent 9588327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler // intermediate directories. 9598327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat"; 9608327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9618327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler Copy(GetDexSrc1(), dex_location); 9628327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9638327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler OatFileAssistant oat_file_assistant( 9647bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true); 9658327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string error_msg; 966ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler ASSERT_EQ(OatFileAssistant::kUpdateNotAttempted, 967ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)); 9688327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9698327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 9708327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler ASSERT_TRUE(oat_file.get() == nullptr); 9718327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler} 9728327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9738327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Case: We don't have a DEX file and can't write the oat file. 9748327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler// Expect: We should fail to generate the oat file without crashing. 9758327cf74d5f87bd64572b56bb8b77bd701adb976Richard UhlerTEST_F(OatFileAssistantTest, GenNoDex) { 9768327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string dex_location = GetScratchDir() + "/GenNoDex.jar"; 9778327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string oat_location = GetScratchDir() + "/GenNoDex.oat"; 9788327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 9798327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler OatFileAssistant oat_file_assistant( 9807bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true); 9818327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler std::string error_msg; 982ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted, 983ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.GenerateOatFile(CompilerFilter::kSpeed, &error_msg)); 9848327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler} 9858327cf74d5f87bd64572b56bb8b77bd701adb976Richard Uhler 98666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Turn an absolute path into a path relative to the current working 98766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// directory. 98866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerstatic std::string MakePathRelative(std::string target) { 98966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler char buf[MAXPATHLEN]; 99066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string cwd = getcwd(buf, MAXPATHLEN); 99166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 99266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Split the target and cwd paths into components. 99366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> target_path; 99466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> cwd_path; 99566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Split(target, '/', &target_path); 99666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Split(cwd, '/', &cwd_path); 99766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 99866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Reverse the path components, so we can use pop_back(). 99966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::reverse(target_path.begin(), target_path.end()); 100066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::reverse(cwd_path.begin(), cwd_path.end()); 100166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 100266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Drop the common prefix of the paths. Because we reversed the path 100366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // components, this becomes the common suffix of target_path and cwd_path. 100466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler while (!target_path.empty() && !cwd_path.empty() 100566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler && target_path.back() == cwd_path.back()) { 100666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler target_path.pop_back(); 100766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler cwd_path.pop_back(); 100866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 100966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 101066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // For each element of the remaining cwd_path, add '..' to the beginning 101166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // of the target path. Because we reversed the path components, we add to 101266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // the end of target_path. 101366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (unsigned int i = 0; i < cwd_path.size(); i++) { 101466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler target_path.push_back(".."); 101566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 101666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 101766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Reverse again to get the right path order, and join to get the result. 101866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::reverse(target_path.begin(), target_path.end()); 101966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return Join(target_path, '/'); 102066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 102166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 102266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-absolute path to Dex location. 102366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: Not sure, but it shouldn't crash. 102466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) { 102566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar"; 102666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), abs_dex_location); 102766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 102866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = MakePathRelative(abs_dex_location); 10297bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 103066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 103166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 10327bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 10337bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 103466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 103566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 103666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 103766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 103866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 103966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 104066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 104166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 104266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Very short, non-existent Dex location. 10439b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler// Expect: kNoDexOptNeeded. 104466d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, ShortDexLocation) { 104566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = "/xx"; 104666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10477bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 104866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 104966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 10507bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 10517bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 105266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 105366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 105466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 105566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 105666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 105766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 10589b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 105966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10609b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler // Trying to make it up to date should have no effect. 106166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 1062ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, 1063ff0274bd8a67e3512ff85cc05b77fd01df368638Richard Uhler oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)); 10649b994ea841eaaefbdda652251894a74db9cefcc8Richard Uhler EXPECT_TRUE(error_msg.empty()); 106566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 106666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 106766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: Non-standard extension for dex file. 106895abd04d211470ea4b9b9191b96dd0f32e7ce3a4Richard Uhler// Expect: The status is kDex2OatNeeded. 106966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, LongDexExtension) { 107066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx"; 107166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 107266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10737bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 107466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10757bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 10767bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 107766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 107866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 107966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 108066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 108166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 108266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileExists()); 108366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 108466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 108566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 108666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 108766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// A task to generate a dex location. Used by the RaceToGenerate test. 108866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhlerclass RaceGenerateTask : public Task { 108966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler public: 109066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location) 10915872d7cd6ceffe67550d0b021191ec66f1a34c5dJeff Hao : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr) 109266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler {} 109366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 10944b8f1ecd3aa5a29ec1463ff88fee9db365f257dcRoland Levillain void Run(Thread* self ATTRIBUTE_UNUSED) { 109566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the dex files, and save a pointer to the loaded oat file, so that 109666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // we can verify only one oat file was loaded for the dex location. 109766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 109866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::string> error_msgs; 1099e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier const OatFile* oat_file = nullptr; 1100f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat( 1101f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier dex_location_.c_str(), 1102f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier oat_location_.c_str(), 1103fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*class_loader*/nullptr, 1104fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier /*dex_elements*/nullptr, 1105e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier &oat_file, 1106f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier &error_msgs); 110766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler CHECK(!dex_files.empty()) << Join(error_msgs, '\n'); 110807b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation(); 110907b3c2351bb527ea91c084dc19434600af9ae66bRichard Uhler loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile(); 1110e58991b3b2282b5761f1a6023a16c803e1c4eb45Mathieu Chartier CHECK_EQ(loaded_oat_file_, oat_file); 111166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 111266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 111366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* GetLoadedOatFile() const { 111466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler return loaded_oat_file_; 111566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 111666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 111766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler private: 111866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location_; 111966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string oat_location_; 112066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const OatFile* loaded_oat_file_; 112166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler}; 112266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 112366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Test the case where multiple processes race to generate an oat file. 112466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// This simulates multiple processes using multiple threads. 112566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// 1126f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// We want unique Oat files to be loaded even when there is a race to load. 1127f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// TODO: The test case no longer tests locking the way it was intended since we now get multiple 1128f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier// copies of the same Oat files mapped at different locations. 112966d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantTest, RaceToGenerate) { 113066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar"; 11316343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat"; 113266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 113366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // We use the lib core dex file, because it's large, and hopefully should 113466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // take a while to generate. 1135d1ef4362bf799f9f5d50e5edef8433664b503051Narayan Kamath Copy(GetLibCoreDexFileNames()[0], dex_location); 113666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 113766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler const int kNumThreads = 32; 113866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Thread* self = Thread::Current(); 113966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads); 114066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<RaceGenerateTask>> tasks; 114166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (int i = 0; i < kNumThreads; i++) { 114266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location)); 114366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler thread_pool.AddTask(self, task.get()); 114466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler tasks.push_back(std::move(task)); 114566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 114666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler thread_pool.StartWorkers(self); 114766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler thread_pool.Wait(self, true, false); 114866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 1149f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // Verify every task got a unique oat file. 1150f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::set<const OatFile*> oat_files; 115166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler for (auto& task : tasks) { 1152f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier const OatFile* oat_file = task->GetLoadedOatFile(); 1153f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end()); 1154f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier oat_files.insert(oat_file); 115566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler } 115666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 115766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 115866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is 115966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled. 116066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable. 116166d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) { 116266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar"; 11636343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex"; 116466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 116566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 116666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetDexSrc1(), dex_location); 11677bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 116866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 116966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the oat using an executable oat file assistant. 11707bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 117166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 117266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 117366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 117466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file->IsExecutable()); 117566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 117666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 117766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(1u, dex_files.size()); 117866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 117966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 118066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is 118166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// disabled. 118266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// Expect: We should load the odex file non-executable. 118366d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) { 118466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar"; 11856343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex"; 118666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 118766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Create the dex and odex files 118866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler Copy(GetMultiDexSrc1(), dex_location); 11897bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 119066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 119166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler // Load the oat using an executable oat file assistant. 11927bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 119366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 119466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 119566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler ASSERT_TRUE(oat_file.get() != nullptr); 119666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(oat_file->IsExecutable()); 119766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::vector<std::unique_ptr<const DexFile>> dex_files; 119866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 119966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_EQ(2u, dex_files.size()); 120066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 120166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 120266d874d96d5699bb090c59f47a5a528956ca053eRichard UhlerTEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) { 120366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string error_msg; 120466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler std::string odex_file; 120566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 120666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename( 1207b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg; 12086343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file); 120966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 121066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename( 1211b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg; 12126343411e52d2a59cd716cb47a85ebd0d68e61a3cRichard Uhler EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file); 121366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 121466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename( 1215b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin "nopath.jar", kArm, &odex_file, &error_msg)); 121666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename( 1217b1d8c314b55bb2df2b2bb72a3daaf5db65b7ebc7Igor Murashkin "/foo/bar/baz_noext", kArm, &odex_file, &error_msg)); 121866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} 121966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 122023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// Verify the dexopt status values from dalvik.system.DexFile 122123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler// match the OatFileAssistant::DexOptStatus values. 122223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard UhlerTEST_F(OatFileAssistantTest, DexOptStatusValues) { 122323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ScopedObjectAccess soa(Thread::Current()); 122423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler StackHandleScope<1> hs(soa.Self()); 122523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ClassLinker* linker = Runtime::Current()->GetClassLinker(); 122623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler Handle<mirror::Class> dexfile( 122723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;"))); 122823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(dexfile.Get() == nullptr); 122923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler linker->EnsureInitialized(soa.Self(), dexfile, true, true); 123023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler 1231c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* no_dexopt_needed = mirror::Class::FindStaticField( 123223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I"); 123323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(no_dexopt_needed == nullptr); 123423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 123523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get())); 123623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler 1237c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* dex2oat_needed = mirror::Class::FindStaticField( 123823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler soa.Self(), dexfile, "DEX2OAT_NEEDED", "I"); 123923cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(dex2oat_needed == nullptr); 124023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 124123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get())); 124223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler 1243c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* patchoat_needed = mirror::Class::FindStaticField( 124423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler soa.Self(), dexfile, "PATCHOAT_NEEDED", "I"); 124523cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(patchoat_needed == nullptr); 124623cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 124723cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get())); 124823cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler 1249c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* self_patchoat_needed = mirror::Class::FindStaticField( 125023cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I"); 125123cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler ASSERT_FALSE(self_patchoat_needed == nullptr); 125223cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 125323cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get())); 125423cedd20e76bdbbdaa3f44a1b83f30698d04fa3fRichard Uhler} 125566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 125666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// TODO: More Tests: 12577bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// * Image checksum change is out of date for kIntepretOnly, but not 12587bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// kVerifyAtRuntime. But target of kVerifyAtRuntime still says current 12597bcfcb80a31f57a84d754e00bca8698829365208Andreas Gampe// kInterpretOnly is out of date. 126066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test class linker falls back to unquickened dex for DexNoOat 126166d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test class linker falls back to unquickened dex for MultiDexNoOat 126266d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test using secondary isa 126366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test for status of oat while oat is being generated (how?) 126466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test case where 32 and 64 bit boot class paths differ, 126566d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// and we ask IsInBootClassPath for a class in exactly one of the 32 or 126666d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// 64 bit boot class paths. 126766d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// * Test unexpected scenarios (?): 126866d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// - Dex is stripped, don't have odex. 126966d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// - Oat file corrupted after status check, before reload unexecutable 127066d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler// because it's unrelocated and no dex2oat 1271d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle// * Test unrelocated specific target compilation type can be relocated to 1272d91b8a2464b99625efe03caf7d30c8372bc378edCalin Juravle// make it up to date. 127366d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler 127466d874d96d5699bb090c59f47a5a528956ca053eRichard Uhler} // namespace art 1275