oat_file_assistant_test.cc revision ff0274bd8a67e3512ff85cc05b77fd01df368638
18d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes/* 28d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Copyright (C) 2014 The Android Open Source Project 38d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 48d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 58d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * you may not use this file except in compliance with the License. 68d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * You may obtain a copy of the License at 78d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 88d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 98d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * 108d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * Unless required by applicable law or agreed to in writing, software 118d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 128d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * See the License for the specific language governing permissions and 148d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes * limitations under the License. 158d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes */ 160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#include "oat_file_assistant.h" 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom 190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include <algorithm> 2002b48d1dae0c3adc01ef6668226fb648fb52990aElliott Hughes#include <fstream> 21306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers#include <string> 22a09576416788b916095739e43a16917e7948f3a4Elliott Hughes#include <vector> 23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <sys/param.h> 24700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers 258ce6b9040747054b444a7fa706503cd257801936Dave Allison#include <backtrace/BacktraceMap.h> 268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <gtest/gtest.h> 27b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 284dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang#include "art_field-inl.h" 29d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "class_linker-inl.h" 30b8e087e0dfd619df90cbb56534478a60bc859ebfIan Rogers#include "common_runtime_test.h" 31761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "compiler_callbacks.h" 32719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "gc/space/image_space.h" 33848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers#include "mem_map.h" 34848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers#include "oat_file_manager.h" 357655f29fabc0a12765de828914a18314382e5a35Ian Rogers#include "os.h" 36578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "scoped_thread_state_change.h" 37eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier#include "thread-inl.h" 38956af0f0cb05422e38c1d22cbef309d16b8a1a12Elliott Hughes#include "utils.h" 39306057fd278d75bf3794bd5243a3b6652c487d18Ian Rogers 4083c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartiernamespace art { 41578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom 429d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughesclass OatFileAssistantTest : public CommonRuntimeTest { 4368e76526e98432625464022cb26f66b9ef6f5af4Elliott Hughes public: 442dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers virtual void SetUp() { 45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ReserveImageSpace(); 460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro CommonRuntimeTest::SetUp(); 470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 4815d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier // Create a scratch directory to work from. 4915d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier scratch_dir_ = android_data_ + "/OatFileAssistantTest"; 5098d1cc8033251c93786e2fa8c59a2e555a9493beMingyao Yang ASSERT_EQ(0, mkdir(scratch_dir_.c_str(), 0700)); 5115d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier 5215d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier // Create a subdirectory in scratch for odex files. 5315d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier odex_oat_dir_ = scratch_dir_ + "/oat"; 542dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ASSERT_EQ(0, mkdir(odex_oat_dir_.c_str(), 0700)); 55848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers 56848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers odex_dir_ = odex_oat_dir_ + "/" + std::string(GetInstructionSetString(kRuntimeISA)); 57848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers ASSERT_EQ(0, mkdir(odex_dir_.c_str(), 0700)); 58848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers 59848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers 60848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers // Verify the environment is as we expect 61848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers uint32_t checksum; 62848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers std::string error_msg; 6380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko ASSERT_TRUE(OS::FileExists(GetImageFile().c_str())) 64848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers << "Expected pre-compiled boot image to be at: " << GetImageFile(); 652dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers ASSERT_TRUE(OS::FileExists(GetDexSrc1().c_str())) 6612d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier << "Expected dex file to be at: " << GetDexSrc1(); 6712d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier ASSERT_TRUE(OS::FileExists(GetStrippedDexSrc1().c_str())) 6812d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier << "Expected stripped dex file to be at: " << GetStrippedDexSrc1(); 6912d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier ASSERT_FALSE(DexFile::GetChecksum(GetStrippedDexSrc1().c_str(), &checksum, &error_msg)) 7012d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier << "Expected stripped dex file to be stripped: " << GetStrippedDexSrc1(); 71e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ASSERT_TRUE(OS::FileExists(GetDexSrc2().c_str())) 722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers << "Expected dex file to be at: " << GetDexSrc2(); 732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 747a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers // GetMultiDexSrc2 should have the same primary dex checksum as 75bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // GetMultiDexSrc1, but a different secondary dex checksum. 761b09b094a85e03f6ef5f687f58bb91c433273ba1Ian Rogers std::vector<std::unique_ptr<const DexFile>> multi1; 77f795869da0a1fa006fdcdacd8afb6149a63fc1a7Sebastien Hertz ASSERT_TRUE(DexFile::Open(GetMultiDexSrc1().c_str(), 7881d425b0b232962441616f8b14f73620bffef5e5Ian Rogers GetMultiDexSrc1().c_str(), &error_msg, &multi1)) << error_msg; 79b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers ASSERT_GT(multi1.size(), 1u); 8081d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 818daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes std::vector<std::unique_ptr<const DexFile>> multi2; 82b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ASSERT_TRUE(DexFile::Open(GetMultiDexSrc2().c_str(), 832b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier GetMultiDexSrc2().c_str(), &error_msg, &multi2)) << error_msg; 84f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chien ASSERT_GT(multi2.size(), 1u); 85597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz 86f795869da0a1fa006fdcdacd8afb6149a63fc1a7Sebastien Hertz ASSERT_EQ(multi1[0]->GetLocationChecksum(), multi2[0]->GetLocationChecksum()); 8740381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom ASSERT_NE(multi1[1]->GetLocationChecksum(), multi2[1]->GetLocationChecksum()); 8840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom } 890e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 9034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes virtual void SetUpRuntimeOptions(RuntimeOptions* options) { 9134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes // options->push_back(std::make_pair("-verbose:oat", nullptr)); 9234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes 9334e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes // Set up the image location. 9434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes options->push_back(std::make_pair("-Ximage:" + GetImageLocation(), 9534e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes nullptr)); 9634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes // Make sure compilercallbacks are not set so that relocation will be 97fc1d9f581592d54cc14240b9909824af38656931Elliott Hughes // enabled. 98474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers callbacks_.reset(); 9950ffee20ced9c0c7ac68889c86be8844cf120cf2Ian Rogers } 10050ffee20ced9c0c7ac68889c86be8844cf120cf2Ian Rogers 10162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void PreRuntimeCreate() { 102474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers UnreserveImageSpace(); 103474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers } 104f795869da0a1fa006fdcdacd8afb6149a63fc1a7Sebastien Hertz 1051f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang virtual void PostRuntimeCreate() { 1061f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang ReserveImageSpace(); 1071f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang } 1081f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 109e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers virtual void TearDown() { 110e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers ClearDirectory(odex_dir_.c_str()); 111648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ASSERT_EQ(0, rmdir(odex_dir_.c_str())); 112648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 113648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ClearDirectory(odex_oat_dir_.c_str()); 114648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ASSERT_EQ(0, rmdir(odex_oat_dir_.c_str())); 115648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 116648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ClearDirectory(scratch_dir_.c_str()); 117648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ASSERT_EQ(0, rmdir(scratch_dir_.c_str())); 118648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 119648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison CommonRuntimeTest::TearDown(); 120648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 121648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 122648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison void Copy(std::string src, std::string dst) { 123648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison std::ifstream src_stream(src, std::ios::binary); 124648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison std::ofstream dst_stream(dst, std::ios::binary); 125648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 126648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison dst_stream << src_stream.rdbuf(); 127648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 128648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 129648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // Returns the directory where the pre-compiled core.art can be found. 130648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // TODO: We should factor out this into common tests somewhere rather than 131648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // re-hardcoding it here (This was copied originally from the elf writer 132648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison // test). 133648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison std::string GetImageDirectory() { 134648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison if (IsHost()) { 135648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison const char* host_dir = getenv("ANDROID_HOST_OUT"); 136648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison CHECK(host_dir != nullptr); 137648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison return std::string(host_dir) + "/framework"; 138648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } else { 139dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return std::string("/data/art-test"); 14034e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes } 141f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison } 142f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison 143f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison std::string GetImageLocation() { 144f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison return GetImageDirectory() + "/core.art"; 145648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison } 1467ea6f79bbddd69d5db86a8656a31aaaf64ae2582Andreas Gampe 147f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison std::string GetImageFile() { 148462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes return GetImageDirectory() + "/" + GetInstructionSetString(kRuntimeISA) 149462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes + "/core.art"; 15052673ffae0025d86f4023735581f19ebcc477487Ian Rogers } 15161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 152462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes std::string GetDexSrc1() { 153462c94449720e0dc6b93d7138d835d345ccf67aeElliott Hughes return GetTestDexFileName("Main"); 154664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier } 155664bebf92eb2151b9b570ccd42ac4b6056c3ea9cMathieu Chartier 156b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro // Returns the path to a dex file equivalent to GetDexSrc1, but with the dex 157caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom // file stripped. 158caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom std::string GetStrippedDexSrc1() { 159caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom return GetTestDexFileName("MainStripped"); 1606f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers } 1616f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers 1626f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers std::string GetMultiDexSrc1() { 16302ed4c04468ca5f5540c5b704ac3e2f30eb9e8f4Ian Rogers return GetTestDexFileName("MultiDex"); 1640e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1657b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers 1667b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers // Returns the path to a multidex file equivalent to GetMultiDexSrc2, but 1677b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers // with the contents of the secondary dex file changed. 1687b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers std::string GetMultiDexSrc2() { 1697b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers return GetTestDexFileName("MultiDexModifiedSecondary"); 1707b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers } 1712b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier 1722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers std::string GetDexSrc2() { 173a77f0f68a59870ff027dad654fe31eb3fdaf3d5djeffhao return GetTestDexFileName("Nested"); 174b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers } 175b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers 1762b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier // Scratch directory, for dex and odex files (oat files will go in the 177a77f0f68a59870ff027dad654fe31eb3fdaf3d5djeffhao // dalvik cache). 178b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers std::string GetScratchDir() { 179b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers return scratch_dir_; 1808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes } 18128fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes 182dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Odex directory is the subdirectory in the scratch directory where odex 183dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // files should be located. 18428fa76d17d741238da86dbdb47f721ae97c9eac8Elliott Hughes std::string GetOdexDir() { 18500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return odex_dir_; 18600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 18700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 18800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Generate a non-PIC odex file for the purposes of test. 18900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // The generated odex file will be un-relocated. 190b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers void GenerateOdexForTest(const std::string& dex_location, 191b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers const std::string& odex_location, 192a09576416788b916095739e43a16917e7948f3a4Elliott Hughes CompilerFilter::Filter filter) { 193c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier // To generate an un-relocated odex file, we first compile a relocated 194c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier // version of the file, then manually call patchoat to make it look as if 195c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier // it is unrelocated. 196c751fdcc9491c1b60c3db517fbc41bb98e92441fMathieu Chartier std::string relocated_odex_location = odex_location + ".relocated"; 1972cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier std::vector<std::string> args; 198abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes args.push_back("--dex-file=" + dex_location); 19900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers args.push_back("--oat-file=" + relocated_odex_location); 200cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); 201cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers 202abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes // We need to use the quick compiler to generate non-PIC code, because 203474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers // the optimizing compiler always generates PIC. 204dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--compiler-backend=Quick"); 205dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--include-patch-information"); 206dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 2070aded089f565008ba5908e395e5914ca4f91f2deDave Allison std::string error_msg; 2080aded089f565008ba5908e395e5914ca4f91f2deDave Allison ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 209474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers 2108d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes // Use patchoat to unrelocate the relocated odex file. 21181d425b0b232962441616f8b14f73620bffef5e5Ian Rogers Runtime* runtime = Runtime::Current(); 212dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::vector<std::string> argv; 21352673ffae0025d86f4023735581f19ebcc477487Ian Rogers argv.push_back(runtime->GetPatchoatExecutable()); 21452673ffae0025d86f4023735581f19ebcc477487Ian Rogers argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA))); 21581d425b0b232962441616f8b14f73620bffef5e5Ian Rogers argv.push_back("--input-oat-file=" + relocated_odex_location); 216dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers argv.push_back("--output-oat-file=" + odex_location); 21700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers argv.push_back("--base-offset-delta=0x00008000"); 21800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers std::string command_line(Join(argv, ' ')); 219858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier ASSERT_TRUE(Exec(argv, &error_msg)) << error_msg; 22059cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman 221dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Verify the odex file was generated as expected and really is 222858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier // unrelocated. 223858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), 22400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers odex_location.c_str(), 22500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers nullptr, 22601ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers nullptr, 227b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers false, 22800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers /*low_4gb*/false, 229d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers dex_location.c_str(), 230d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers &error_msg)); 231858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; 2322cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXPECT_FALSE(odex_file->IsPic()); 2332cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXPECT_TRUE(odex_file->HasPatchInfo()); 2342cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXPECT_EQ(filter, odex_file->GetCompilerFilter()); 23500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 23600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (CompilerFilter::IsCompilationEnabled(filter)) { 2379da7f59c9059397182b9a97e898a42ec06d4d646Ian Rogers const std::vector<gc::space::ImageSpace*> image_spaces = 238b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers runtime->GetHeap()->GetBootImageSpaces(); 239b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr); 24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const ImageHeader& image_header = image_spaces[0]->GetImageHeader(); 24100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers const OatHeader& oat_header = odex_file->GetOatHeader(); 24200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXPECT_EQ(image_header.GetOatChecksum(), oat_header.GetImageFileLocationOatChecksum()); 243b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()), 244693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers oat_header.GetImageFileLocationOatDataBegin()); 2451ffa32f0be7becec4907b26ead353e4b17e1219cIan Rogers EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta()); 24600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 24700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 24800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 24900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void GeneratePicOdexForTest(const std::string& dex_location, 250b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers const std::string& odex_location, 251693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers CompilerFilter::Filter filter) { 2521ffa32f0be7becec4907b26ead353e4b17e1219cIan Rogers // Temporarily redirect the dalvik cache so dex2oat doesn't find the 253038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes // relocated image file. 2540399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp"; 25552673ffae0025d86f4023735581f19ebcc477487Ian Rogers setenv("ANDROID_DATA", android_data_tmp.c_str(), 1); 256590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier std::vector<std::string> args; 2572cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier args.push_back("--dex-file=" + dex_location); 258dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--oat-file=" + odex_location); 259dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); 260dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--compile-pic"); 261590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier args.push_back("--runtime-arg"); 262590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier args.push_back("-Xnorelocate"); 263590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier std::string error_msg; 264590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 26552673ffae0025d86f4023735581f19ebcc477487Ian Rogers setenv("ANDROID_DATA", android_data_.c_str(), 1); 26652673ffae0025d86f4023735581f19ebcc477487Ian Rogers 2670399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Verify the odex file was generated as expected. 26852673ffae0025d86f4023735581f19ebcc477487Ian Rogers std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), 269590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier odex_location.c_str(), 270dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers nullptr, 271dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers nullptr, 272dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers false, 273dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers /*low_4gb*/false, 274590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier dex_location.c_str(), 2750399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers &error_msg)); 27600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; 27700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXPECT_TRUE(odex_file->IsPic()); 2780399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers EXPECT_EQ(filter, odex_file->GetCompilerFilter()); 27900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 280dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 28100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Generate a non-PIC odex file without patch information for the purposes 28200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // of test. The generated odex file will be un-relocated. 283dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // TODO: This won't work correctly if we depend on the boot image being 2845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // randomly relocated by a non-zero amount. We should have a better solution 2858daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // for avoiding that flakiness and duplicating code to generate odex and oat 2868daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // files for test. 2878daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes void GenerateNoPatchOdexForTest(const std::string& dex_location, 2888daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes const std::string& odex_location, 2898daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes CompilerFilter::Filter filter) { 2908daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Temporarily redirect the dalvik cache so dex2oat doesn't find the 2918daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // relocated image file. 2928daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes std::string android_data_tmp = GetScratchDir() + "AndroidDataTmp"; 2938daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes setenv("ANDROID_DATA", android_data_tmp.c_str(), 1); 2948daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes std::vector<std::string> args; 2958daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes args.push_back("--dex-file=" + dex_location); 2968daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes args.push_back("--oat-file=" + odex_location); 2978daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); 2988daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes args.push_back("--runtime-arg"); 2998daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes args.push_back("-Xnorelocate"); 3008daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes std::string error_msg; 301d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 302dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers setenv("ANDROID_DATA", android_data_.c_str(), 1); 303b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 304b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro // Verify the odex file was generated as expected. 305d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(), 306dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers odex_location.c_str(), 307d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes nullptr, 308e27955ca3ca960928d4dbd6cb79711fce06950b3Elliott Hughes nullptr, 3092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier false, 3102b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier /*low_4gb*/false, 311b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers dex_location.c_str(), 312899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes &error_msg)); 313ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; 314ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes EXPECT_FALSE(odex_file->IsPic()); 315ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes EXPECT_FALSE(odex_file->HasPatchInfo()); 316ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes EXPECT_EQ(filter, odex_file->GetCompilerFilter()); 317899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes } 318b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers 319fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes private: 32057dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao // Reserve memory around where the image will be loaded so other memory 32157dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao // won't conflict when it comes time to load the image. 32257dac6ed61a0a25c14d4e2fabc84435578d42360Jeff Hao // This can be called with an already loaded image to reserve the space 3232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers // around it. 324dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers void ReserveImageSpace() { 325dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers MemMap::Init(); 3268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 3278daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes // Ensure a chunk of memory is reserved for the image space. 32800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers uintptr_t reservation_start = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MIN_DELTA; 329dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers uintptr_t reservation_end = ART_BASE_ADDRESS + ART_BASE_ADDRESS_MAX_DELTA 33000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Include the main space that has to come right after the 33100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // image in case of the GSS collector. 3329d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes + 384 * MB; 333dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 3349d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true)); 3359d5ccec86d60c9ddd811836b9a2bc28d0b3d11feElliott Hughes ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map"; 3367dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes for (BacktraceMap::const_iterator it = map->begin(); 3377dc5166ea740359d381097a7ab382c1dd404055fElliott Hughes reservation_start < reservation_end && it != map->end(); ++it) { 3380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end)); 339dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers reservation_start = std::max(reservation_start, it->end); 3400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 3410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro ReserveImageSpaceChunk(reservation_start, reservation_end); 34214691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray } 343dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 3440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // Reserve a chunk of memory for the image space in the given range. 3450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // Only has effect for chunks with a positive number of bytes. 346d9efea646485fe996c967f4680a3fc4cdc40b251Andreas Gampe void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) { 347a61894d88fabe45677f491c9f6bde30059a49026Mathieu Chartier if (start < end) { 34800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers std::string error_msg; 3498d7672e476a526aa6205a008b5a06c8216342ac6Mathieu Chartier image_reservation_.push_back(std::unique_ptr<MemMap>( 35000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers MemMap::MapAnonymous("image reservation", 35114691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray reinterpret_cast<uint8_t*>(start), end - start, 35262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers PROT_NONE, false, false, &error_msg))); 3532cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg; 354474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers LOG(INFO) << "Reserved space for image " << 355dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" << 3560cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers reinterpret_cast<void*>(image_reservation_.back()->End()); 3570cfe1fb7060576d047f7f894fc0d8b87de84fcabIan Rogers } 358a309d76d4c9f4e5564b09708004bf4b2e3401bb3Serguei Katkov } 359dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 36094d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao 36194d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao // Unreserve any memory reserved by ReserveImageSpace. This should be called 362bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // before the image is loaded. 363794ad76e8d5b5b9132819d5b08a0570e27615644Andreas Gampe void UnreserveImageSpace() { 364bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers image_reservation_.clear(); 365bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 3660399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 3674dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang std::string scratch_dir_; 3684dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang std::string odex_oat_dir_; 3694dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang std::string odex_dir_; 3704dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang std::vector<std::unique_ptr<MemMap>> image_reservation_; 3714dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang}; 3724dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang 3734dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yangclass OatFileAssistantNoDex2OatTest : public OatFileAssistantTest { 3744dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang public: 3754dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang virtual void SetUpRuntimeOptions(RuntimeOptions* options) { 3764dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang OatFileAssistantTest::SetUpRuntimeOptions(options); 3774dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang options->push_back(std::make_pair("-Xnodex2oat", nullptr)); 3784dcfc4329d2d481b738e3be183dfa2a785738df2Mingyao Yang } 379dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers}; 3801a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao 3811a18c8c1c0e4ea1ff06177e93c7ff703376dcee2Shih-wei Liao// Generate an oat file for the purposes of test, as opposed to testing 3826ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampe// generation of oat files. 3836ec8ebd178ed39aa09e4c7fad194900114c4121aAndreas Gampestatic void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) { 384e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier // Use an oat file assistant to find the proper oat location. 385b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers OatFileAssistant ofa(dex_location, kRuntimeISA, false, false); 3860399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers const std::string* oat_location = ofa.OatFileName(); 3877642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray ASSERT_TRUE(oat_location != nullptr); 3887642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray 3897642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray std::vector<std::string> args; 3907642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray args.push_back("--dex-file=" + std::string(dex_location)); 3917642cfc90fc9c3ebfd8e3b5041915705c93b5cf0Nicolas Geoffray args.push_back("--oat-file=" + *oat_location); 392e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); 393dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--runtime-arg"); 3940e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro args.push_back("-Xnorelocate"); 3950e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro std::string error_msg; 39611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 397dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 39811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao // Verify the oat file was generated as expected. 39911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location->c_str(), 4000399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers oat_location->c_str(), 401dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers nullptr, 402dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers nullptr, 403bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers false, 404bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers /*low_4gb*/false, 4052cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier dex_location, 4060aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray &error_msg)); 407b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers ASSERT_TRUE(oat_file.get() != nullptr) << error_msg; 4085cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes EXPECT_EQ(filter, oat_file->GetCompilerFilter()); 4092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier} 410a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott Hughes 4110aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray// Case: We have a DEX file, but no OAT file for it. 412b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers// Expect: The status is kDex2OatNeeded. 413a4f94740f9d66b21f4bcd3a225c434aa29cfa323Elliott HughesTEST_F(OatFileAssistantTest, DexNoOat) { 4140aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray std::string dex_location = GetScratchDir() + "/DexNoOat.jar"; 4150aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray Copy(GetDexSrc1(), dex_location); 416b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers 417a5b897eae4b6f9f9608faa9eada7ddf42bf1bfd2Elliott Hughes OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 4180aa50ce2fb75bfc2e815a0c33adf9b049561923bNicolas Geoffray 419b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 4204a2b41793d18d402286ae37e9de4fd392bc75a08Elliott Hughes oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 4212ced6a534157d5d963693346904389c19775d2daElliott Hughes EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 4228a8b9cbe158ee13477f2381f164c519762a06fefElliott Hughes oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 423120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 42479082e367845bbd68ec44ef2ddd1be8ef0e1550fElliott Hughes oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile)); 425be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 426038a806df72f884d22283a84a31c9a1d35ba1fdfElliott Hughes oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 427c1674ed06662420213441ff2b818f2f71f9098dcElliott Hughes 428b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 429b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 43069f5bc6759f256a146eefd8a7141d39fcc3b0421Elliott Hughes EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 431dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 432b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 433b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus()); 434408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers EXPECT_FALSE(oat_file_assistant.OatFileExists()); 4352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 436b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 437a6e7f0872c42009ecbee82d7fbe452deef9ae65bMathieu Chartier EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 438dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); 439dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 440dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 441a6e7f0872c42009ecbee82d7fbe452deef9ae65bMathieu Chartier 442dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have no DEX file and no OAT file. 443dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash. 444dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, NoDexNoOat) { 4458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar"; 446dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 4478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 448dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 449dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 450dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 451dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 452dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 453dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Trying to make the oat file up to date should not fail or crash. 454dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string error_msg; 455dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, 456dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)); 457dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 458dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Trying to get the best oat file should fail, but not crash. 459dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 460dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(nullptr, oat_file.get()); 461dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 462dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 463dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file and up-to-date OAT file for it. 464dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kNoDexOptNeeded. 465dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, OatUpToDate) { 466dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = GetScratchDir() + "/OatUpToDate.jar"; 467dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 468dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 469dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 470dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 471dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 472dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 473dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 474dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 475dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 476dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 477dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 478dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 479dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 480dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 481dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 482dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 483dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 484dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 485dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileExists()); 486dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 4875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 48868d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 489dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); 490c143c55718342519db5398e41dda31422cf16c79buzbee EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 491c143c55718342519db5398e41dda31422cf16c79buzbee} 49268d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers 493c143c55718342519db5398e41dda31422cf16c79buzbee// Case: We have a DEX file and speed-profile OAT file for it. 494aaa208006d7c8cc0f381c4aa9b525be24066c495Ian Rogers// Expect: The status is kNoDexOptNeeded if the profile hasn't changed. 495ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien HertzTEST_F(OatFileAssistantTest, ProfileOatUpToDate) { 496ee1d79a603c77c0667b27c075a983579d5c51f7eSebastien Hertz std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar"; 4972b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier Copy(GetDexSrc1(), dex_location); 498b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile); 49901158d7a57c8321370667a6045220237d16e0da8Elliott Hughes 50001158d7a57c8321370667a6045220237d16e0da8Elliott Hughes OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 5012cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier 5022cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 50301158d7a57c8321370667a6045220237d16e0da8Elliott Hughes oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile)); 5042b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 5052b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 5062b7c4d196c8abe32f4ca633534917da9de53c359Mathieu Chartier 50753b8b09fc80329539585dcf43657bc5f4ecefdffIan Rogers EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 50855df06be4369f5d8ab5eb61a5d22809255171036Shih-wei Liao EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 509bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 5106f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 5114e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier EXPECT_TRUE(oat_file_assistant.OatFileExists()); 512250455229aa0cc07bbd18174efe510bd52631a99jeffhao EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 513be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 514be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 515be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus()); 516be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 517dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 518dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 519dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file and speed-profile OAT file for it. 520dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kNoDex2OatNeeded if the profile has changed. 521dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, ProfileOatOutOfDate) { 522dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = GetScratchDir() + "/ProfileOatOutOfDate.jar"; 523dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 524dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile); 525dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 526dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true, false); 527dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 528dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 529dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile)); 530dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 531dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 532dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 533dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 534dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 535dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 536dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 537dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileExists()); 538dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 539dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 540dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 541dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus()); 542dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 543dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 544dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 545dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a MultiDEX file and up-to-date OAT file for it. 546dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kNoDexOptNeeded and we load all dex files. 547dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, MultiDexOatUpToDate) { 548dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar"; 549dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetMultiDexSrc1(), dex_location); 550dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 551dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 552848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 553848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 554848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 555848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 556848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 557848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Verify we can load both dex files. 558848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 559848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao ASSERT_TRUE(oat_file.get() != nullptr); 560848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao EXPECT_TRUE(oat_file->IsExecutable()); 561848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao std::vector<std::unique_ptr<const DexFile>> dex_files; 562dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 563dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(2u, dex_files.size()); 564dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 565dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 566dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a MultiDEX file where the secondary dex file is out of date. 567dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kDex2OatNeeded. 568dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) { 569dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar"; 570dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 571dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Compile code for GetMultiDexSrc1. 572be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes Copy(GetMultiDexSrc1(), dex_location); 573be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 574dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 575dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum 576dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // is out of date. 577dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetMultiDexSrc2(), dex_location); 578be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 579be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 580dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 581dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 582dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 583be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes} 584be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 585dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a MultiDEX file and up-to-date OAT file for it with relative 586dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// encoded dex locations. 587dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The oat file status is kNoDexOptNeeded. 588be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott HughesTEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) { 589be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar"; 590dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat"; 591dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 592dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Create the dex file 593be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes Copy(GetMultiDexSrc1(), dex_location); 594be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 595dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Create the oat file with relative encoded dex location. 596dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::vector<std::string> args; 597dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--dex-file=" + dex_location); 598dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar")); 599dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--oat-file=" + oat_location); 600dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers args.push_back("--compiler-filter=speed"); 601dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 602dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string error_msg; 603dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; 604dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 605b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison // Verify we can load both dex files. 606b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison OatFileAssistant oat_file_assistant(dex_location.c_str(), 607e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi oat_location.c_str(), 608e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi kRuntimeISA, false, true); 609e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 610e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi ASSERT_TRUE(oat_file.get() != nullptr); 611e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi EXPECT_TRUE(oat_file->IsExecutable()); 612e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi std::vector<std::unique_ptr<const DexFile>> dex_files; 613e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 614e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi EXPECT_EQ(2u, dex_files.size()); 615e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi} 616e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi 617e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi// Case: We have a DEX file and out-of-date OAT file. 618e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi// Expect: The status is kDex2OatNeeded. 619e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi YamauchiTEST_F(OatFileAssistantTest, OatOutOfDate) { 620e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar"; 621e01a520fe0010f8abd344b5ed7120787d7ed1d71Hiroshi Yamauchi 622932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // We create a dex, generate an oat for it, then overwrite the dex with a 623d752132c73072084a3def9257cca4fcee76047b6jeffhao // different dex to make the oat out of date. 624dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 625932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 626932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers Copy(GetDexSrc2(), dex_location); 62713735955f39b3b304c37d2b2840663c131262c18Ian Rogers 628535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 629535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 630535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 631535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 632535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 633535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray 634535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 635535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 636535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 63713735955f39b3b304c37d2b2840663c131262c18Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 638dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileExists()); 639d752132c73072084a3def9257cca4fcee76047b6jeffhao EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 640d752132c73072084a3def9257cca4fcee76047b6jeffhao EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 641932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 642b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers} 643932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 644932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers// Case: We have a DEX file and an ODEX file, but no OAT file. 645b090a18e4292dc339a3b2668bf6dc855928dee3aDave Allison// Expect: The status is kPatchOatNeeded. 646932746a4f22951abcba7b7c4c94c27b1bf164272Ian RogersTEST_F(OatFileAssistantTest, DexOdexNoOat) { 647932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar"; 648b090a18e4292dc339a3b2668bf6dc855928dee3aDave Allison std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex"; 649932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers 650932746a4f22951abcba7b7c4c94c27b1bf164272Ian Rogers // Create the dex and odex files 651f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison Copy(GetDexSrc1(), dex_location); 652648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 653f943914730db8ad2ff03d49a2cacd31885d08fd7Dave Allison 654120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers // Verify the status. 655dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 656120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers 657120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 658dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 659dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, 660dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 661dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 662be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 663be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 664dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 665dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 666dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 667dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileExists()); 668be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 669be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 670dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 671dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 672dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // We should still be able to get the non-executable odex file to run from. 673dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 674dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ASSERT_TRUE(oat_file.get() != nullptr); 675be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes} 676be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 6770399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers// Case: We have a stripped DEX file and an ODEX file, but no OAT file. 678dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kPatchOatNeeded 6790399dde18753aa9bd2bd0d7cf60beef154d164a4Ian RogersTEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) { 6800399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar"; 6810399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex"; 6820399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 683dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Create the dex and odex files 6840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers Copy(GetDexSrc1(), dex_location); 6850399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 686dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 687bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Strip the dex file 688bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers Copy(GetStrippedDexSrc1(), dex_location); 6890399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers 690dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Verify the status. 691de479be99328d2113bf483e082c9ecf235a34d69TDYa OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 692de479be99328d2113bf483e082c9ecf235a34d69TDYa 693de479be99328d2113bf483e082c9ecf235a34d69TDYa EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, 694dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 695de479be99328d2113bf483e082c9ecf235a34d69TDYa 696f7ad17e108b9357d7c94c6218a8521140a667f3dLogan Chien EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 697dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 698dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 699dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 700dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileExists()); 701dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 702d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 703d668a06b5dcc3b0f7f788da4d756cd4ee6f1d0faTDYa EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 704ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 705ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // Make the oat file up to date. 706dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string error_msg; 7070399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 7080399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 709eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier 710eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 7110399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 712eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier 713ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 714eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 715c8ccf68b805c92674545f63e0341ba47e8d9701cAndreas Gampe EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 7160399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 7170399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileExists()); 718eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 7190399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 720bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 72183c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier 7220399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Verify we can load the dex files from it. 723eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 724eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier ASSERT_TRUE(oat_file.get() != nullptr); 7251f5393447b9f45be7918042d9ee7b521376de866Ian Rogers EXPECT_TRUE(oat_file->IsExecutable()); 7261f5393447b9f45be7918042d9ee7b521376de866Ian Rogers std::vector<std::unique_ptr<const DexFile>> dex_files; 727eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 72859c07060a6fbb93e455b44f00098cafb8e7e26ccIan Rogers EXPECT_EQ(1u, dex_files.size()); 729eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier} 730eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier 731eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file. 732eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Expect: The status is kPatchOatNeeded. 733eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu ChartierTEST_F(OatFileAssistantTest, StrippedDexOdexOat) { 734eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar"; 735eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex"; 736eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier 7371f5393447b9f45be7918042d9ee7b521376de866Ian Rogers // Create the oat file from a different dex file so it looks out of date. 73840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom Copy(GetDexSrc2(), dex_location); 739dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 740eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier 741eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier // Create the odex file 742eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Copy(GetDexSrc1(), dex_location); 743be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 744be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 745dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Strip the dex file. 746dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetStrippedDexSrc1(), dex_location); 747475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes 748475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes // Verify the status. 74961b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 750dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 75161b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 75261b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 7531558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, 7541558b577907b613864e98f05862543557263e864Sebastien Hertz oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 7551558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped. 7561558b577907b613864e98f05862543557263e864Sebastien Hertz oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 7571558b577907b613864e98f05862543557263e864Sebastien Hertz 7581558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 7591558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 7601558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 7611558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 7621558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 7639d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OatFileExists()); 7649d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 7659d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 7669d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 7679d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz 7689d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz // Make the oat file up to date. 7699d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz std::string error_msg; 7709d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 7719d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 7729d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz 7739d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 7749d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 775597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped. 776597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 777597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz 778597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 779597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 780597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 781597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OdexFileNeedsRelocation()); 782597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 7831558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OatFileExists()); 784cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 785cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 786cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 7871558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 7881558b577907b613864e98f05862543557263e864Sebastien Hertz 7891558b577907b613864e98f05862543557263e864Sebastien Hertz // Verify we can load the dex files from it. 790cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 791cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz ASSERT_TRUE(oat_file.get() != nullptr); 7921558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_TRUE(oat_file->IsExecutable()); 793597c4f0aeafed2b6fa69e53ece4be4f53115d707Sebastien Hertz std::vector<std::unique_ptr<const DexFile>> dex_files; 794fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 795fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz EXPECT_EQ(1u, dex_files.size()); 796fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz} 797fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz 798fd3077e4b9ebadd281777310d26e64443858f653Sebastien Hertz// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no 7991f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang// OAT file. Expect: The status is kNoDexOptNeeded. 8001f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao YangTEST_F(OatFileAssistantTest, ResourceOnlyDex) { 8011f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar"; 8021f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 8031f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang Copy(GetStrippedDexSrc1(), dex_location); 8041f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 8051f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang // Verify the status. 806714f175bd66d03225927a84f3d5dbc923c5a3e7eSebastien Hertz OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 8071f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 8081f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 8091f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 8101f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 8111f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 8121f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 8132a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 8141f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 8151f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 8161f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 8171f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 8182a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 81962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 820dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileExists()); 821e343b76af81a005ef64f5e75a555389fd9147dabjeffhao EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 822e343b76af81a005ef64f5e75a555389fd9147dabjeffhao EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 823e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 824dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 8255ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Make the oat file up to date. This should have no effect. 8265ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao std::string error_msg; 827e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, 828dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 8295ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 8305ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 8315ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 832dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 8335ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 8345ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 8355ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 836dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 8375ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 8385ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao EXPECT_FALSE(oat_file_assistant.OatFileExists()); 83981d425b0b232962441616f8b14f73620bffef5e5Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 840dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 84100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 84200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 84381d425b0b232962441616f8b14f73620bffef5e5Ian Rogers 844dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file, no ODEX file and an OAT file that needs 84500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers// relocation. 846ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes// Expect: The status is kSelfPatchOatNeeded. 847752a0e606afdc7aa4825ebbe62b187b8abba14ccMathieu ChartierTEST_F(OatFileAssistantTest, SelfRelocation) { 848858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier std::string dex_location = GetScratchDir() + "/SelfRelocation.jar"; 849858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier std::string oat_location = GetOdexDir() + "/SelfRelocation.oat"; 850dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 851858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier // Create the dex and odex files 852858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier Copy(GetDexSrc1(), dex_location); 8539cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao GenerateOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed); 854dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 8559cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao OatFileAssistant oat_file_assistant(dex_location.c_str(), 8569cec247849c248f6c45a14eae5414b69eb8fc67dJeff Hao oat_location.c_str(), kRuntimeISA, false, true); 8578c1b5f71a8005743756206120624121d7678381fIan Rogers 8588c1b5f71a8005743756206120624121d7678381fIan Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 8598c1b5f71a8005743756206120624121d7678381fIan Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly)); 860858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, 8618c1b5f71a8005743756206120624121d7678381fIan Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 8628c1b5f71a8005743756206120624121d7678381fIan Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 8638c1b5f71a8005743756206120624121d7678381fIan Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 864858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier 8653b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 8663b4c18933c24b8a33f38573c2ebcdb9aa16efeb5Hiroshi Yamauchi EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 867dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 868dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 869dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 870dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileExists()); 87113735955f39b3b304c37d2b2840663c131262c18Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileNeedsRelocation()); 872dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 8732cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 8742cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 8752cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 8762cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Make the oat file up to date. 8772cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::string error_msg; 8782cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 879dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 880dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 881dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 882dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 883dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 884dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 885dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 886dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 887dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileNeedsRelocation()); 888dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 889dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileExists()); 890dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 891dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileNeedsRelocation()); 892dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsUpToDate()); 893dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 894dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 895dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 896cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier ASSERT_TRUE(oat_file.get() != nullptr); 897cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier EXPECT_TRUE(oat_file->IsExecutable()); 898dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::vector<std::unique_ptr<const DexFile>> dex_files; 899dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 900cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier EXPECT_EQ(1u, dex_files.size()); 901cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier} 902dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 903dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file, no ODEX file and an OAT file that needs 904dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// relocation but doesn't have patch info. 905dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kDex2OatNeeded, because we can't run patchoat. 906dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, NoSelfRelocation) { 90714cc9be4adc652071979395d337d1380763844faMathieu Chartier std::string dex_location = GetScratchDir() + "/NoSelfRelocation.jar"; 908dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string oat_location = GetOdexDir() + "/NoSelfRelocation.oat"; 909dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 910dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Create the dex and odex files 911dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 912dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers GenerateNoPatchOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed); 913dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 914dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), 915dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_location.c_str(), kRuntimeISA, false, true); 916dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 917dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 918dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 919dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 920dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Make the oat file up to date. 9215d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes std::string error_msg; 922648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 923648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 924648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 925648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 926648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 927648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 928648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ASSERT_TRUE(oat_file.get() != nullptr); 929648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison EXPECT_TRUE(oat_file->IsExecutable()); 930648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison std::vector<std::unique_ptr<const DexFile>> dex_files; 931648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 932648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison EXPECT_EQ(1u, dex_files.size()); 933648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison} 934648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison 935648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and 9368ce6b9040747054b444a7fa706503cd257801936Dave Allison// OAT files both have patch delta of 0. 9378ce6b9040747054b444a7fa706503cd257801936Dave Allison// Expect: It shouldn't crash, and status is kPatchOatNeeded. 9388ce6b9040747054b444a7fa706503cd257801936Dave AllisonTEST_F(OatFileAssistantTest, OdexOatOverlap) { 9398ce6b9040747054b444a7fa706503cd257801936Dave Allison std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar"; 9402cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex"; 9412cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat"; 9422cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi 9432cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Create the dex and odex files 944d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartier Copy(GetDexSrc1(), dex_location); 945d0ad2eea51850ed5972c23d03380b2305cdf7cb7Mathieu Chartier GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 94612d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier 947848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Create the oat file by copying the odex so they are located in the same 948848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // place in memory. 949dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(odex_location, oat_location); 95052673ffae0025d86f4023735581f19ebcc477487Ian Rogers 951b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers // Verify things don't go bad. 952b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), 953c0f0933249cf516b37717faa766e1e9808f7c1f8Elliott Hughes oat_location.c_str(), kRuntimeISA, false, true); 9540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 955365c10235438607541fa2259a5fec48061b90bd8Ian Rogers EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, 9565fe594f576225dd7d333835e39c448a71ea9b433Elliott Hughes oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 957d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz 958d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 959d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 960d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 961d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 96262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileExists()); 96362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsOutOfDate()); 964474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 965474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 966dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 967c747cffa950b8398cb8844d47e2253214c855750Ian Rogers // Things aren't relocated, so it should fall back to interpreted. 968c747cffa950b8398cb8844d47e2253214c855750Ian Rogers std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 969c747cffa950b8398cb8844d47e2253214c855750Ian Rogers ASSERT_TRUE(oat_file.get() != nullptr); 97004d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers 97104d7aa92bc5548bc4d272b9480614f06248194ccIan Rogers EXPECT_FALSE(oat_file->IsExecutable()); 972cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers std::vector<std::unique_ptr<const DexFile>> dex_files; 97300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 974b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers EXPECT_EQ(1u, dex_files.size()); 975b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers} 976d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 977accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes// Case: We have a DEX file and a PIC ODEX file, but no OAT file. 9787934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation. 97900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan RogersTEST_F(OatFileAssistantTest, DexPicOdexNoOat) { 980b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar"; 981accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex"; 98293e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 98393e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes // Create the dex and odex files 984cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers Copy(GetDexSrc1(), dex_location); 985cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 986cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers 987accd83d1523545ac69bafd38e72a7d5cff8e2facElliott Hughes // Verify the status. 988449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 989449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe 990449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 991449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 992449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 993449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything)); 994449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe 995449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 996449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 9975d76c435082332ef79a22962386fa92a0870e378Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 998b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate()); 9991efa0a9d6cd5f5b40b8a21d39f1103a3610250eeAlexei Zavjalov EXPECT_FALSE(oat_file_assistant.OatFileExists()); 1000848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 1001caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 1002caabb1b77b4a55eb1bb45ebcd3071c9ea01dd3cfBrian Carlstrom EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 1003f4d4da18aa1914d10264082bd0433f59bff45453Ian Rogers} 1004be759c63c6bb58b76ac71cad2c5a736bd31f374dElliott Hughes 1005d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file. 1006d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code. 1007d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott HughesTEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) { 1008474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar"; 1009474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex"; 101059cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman 101159cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman // Create the dex and odex files 1012df1ce91ba97bc79a0637e5504b39318fb1c9f577Ian Rogers Copy(GetDexSrc1(), dex_location); 101330e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime); 101430e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers 101530e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers // Verify the status. 101630e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 101730e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers 101830e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 101930e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime)); 102001ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 102130e173f6da202e4caa37ceb477e2fbbe09cec990Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 1022b8e087e0dfd619df90cbb56534478a60bc859ebfIan Rogers 102301ae5808367e641a983e3f8bb82b3e0d364cd03eIan Rogers EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 102459cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman EXPECT_TRUE(oat_file_assistant.OdexFileExists()); 102559cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman EXPECT_FALSE(oat_file_assistant.OdexFileIsOutOfDate()); 102659cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman EXPECT_TRUE(oat_file_assistant.OdexFileIsUpToDate()); 102759cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman EXPECT_FALSE(oat_file_assistant.OatFileExists()); 102859cde534aa295bad7de29472b3cce9576d7996a8Chris Dearman EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 1029474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 1030575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles()); 1031474b6da273c7ce6df50a4e51eb9929a77e1611c3Ian Rogers} 1032dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 10330399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers// Case: We have a DEX file and up-to-date OAT file for it. 1034dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: We should load an executable dex file. 1035dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, LoadOatUpToDate) { 10360399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar"; 1037dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1038dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 10390399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 1040dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1041dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Load the oat using an oat file assistant. 10420399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 1043dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1044dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 1045dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ASSERT_TRUE(oat_file.get() != nullptr); 10460399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers EXPECT_TRUE(oat_file->IsExecutable()); 1047dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::vector<std::unique_ptr<const DexFile>> dex_files; 1048dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 1049dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(1u, dex_files.size()); 1050dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 1051dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1052dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file and up-to-date interpret-only OAT file for it. 1053f37a88b8e6db6c587fa449a12e40cb46be1689fcZuo Wang// Expect: We should still load the oat file as executable. 1054dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) { 1055dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar"; 1056dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1057dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 1058dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly); 1059dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1060dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Load the oat using an oat file assistant. 10611f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 10621f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 10639d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 1064dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ASSERT_TRUE(oat_file.get() != nullptr); 10650399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers EXPECT_TRUE(oat_file->IsExecutable()); 1066dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::vector<std::unique_ptr<const DexFile>> dex_files; 1067575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 1068575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe EXPECT_EQ(1u, dex_files.size()); 10690399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers} 1070dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1071dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: We have a DEX file and up-to-date OAT file for it. 1072dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: Loading non-executable should load the oat non-executable. 10730399dde18753aa9bd2bd0d7cf60beef154d164a4Ian RogersTEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) { 1074dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar"; 1075dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1076dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 10770399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed); 1078dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1079dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Load the oat using an oat file assistant. 1080dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 1081dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1082dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 1083dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ASSERT_TRUE(oat_file.get() != nullptr); 10840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers EXPECT_FALSE(oat_file->IsExecutable()); 1085dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::vector<std::unique_ptr<const DexFile>> dex_files; 1086dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 1087d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers EXPECT_EQ(1u, dex_files.size()); 1088dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 1089dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1090d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers// Case: We have a DEX file. 1091dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: We should load an executable dex file from an alternative oat 1092dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// location. 1093b033c75ebda80ac75f936366fe78d1edf5cec937Ian RogersTEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) { 1094dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar"; 1095dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat"; 1096d92bec457dc6c506c80e9da6b8e0c958266b5cdcElliott Hughes 1097dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 1098dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 10999f1020305292a21fd14a402b189c765a125226abSebastien Hertz OatFileAssistant oat_file_assistant( 1100648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true); 1101648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison std::string error_msg; 1102648d7112609dd19c38131b3e71c37bcbbd19d11eDave Allison ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, 11031f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)) << error_msg; 11041f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 11051f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 11061f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang ASSERT_TRUE(oat_file.get() != nullptr); 11072cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXPECT_TRUE(oat_file->IsExecutable()); 11082cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::vector<std::unique_ptr<const DexFile>> dex_files; 11092cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 11102cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi EXPECT_EQ(1u, dex_files.size()); 11111558b577907b613864e98f05862543557263e864Sebastien Hertz 11121558b577907b613864e98f05862543557263e864Sebastien Hertz EXPECT_TRUE(OS::FileExists(oat_location.c_str())); 11131558b577907b613864e98f05862543557263e864Sebastien Hertz 11141558b577907b613864e98f05862543557263e864Sebastien Hertz // Verify it didn't create an oat in the default location. 11151558b577907b613864e98f05862543557263e864Sebastien Hertz OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false, false); 11169d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz EXPECT_FALSE(ofm.OatFileExists()); 11179d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz} 11189d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz 11199d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz// Case: We have a DEX file but can't write the oat file. 1120dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: We should fail to make the oat file up to date. 112162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian RogersTEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) { 1122dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar"; 1123dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1124dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Make the oat location unwritable by inserting some non-existent 1125d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers // intermediate directories. 1126dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat"; 1127dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1128dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 1129dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1130dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OatFileAssistant oat_file_assistant( 1131dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true); 1132dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string error_msg; 1133dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers ASSERT_EQ(OatFileAssistant::kUpdateNotAttempted, 1134dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)); 1135dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1136dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 1137449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe ASSERT_TRUE(oat_file.get() == nullptr); 1138449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe} 1139dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1140eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Case: We don't have a DEX file and can't write the oat file. 1141dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: We should fail to generate the oat file without crashing. 11421f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao YangTEST_F(OatFileAssistantTest, GenNoDex) { 11431f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang std::string dex_location = GetScratchDir() + "/GenNoDex.jar"; 11441f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang std::string oat_location = GetScratchDir() + "/GenNoDex.oat"; 1145dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 11467b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers OatFileAssistant oat_file_assistant( 114712d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier dex_location.c_str(), oat_location.c_str(), kRuntimeISA, false, true); 114812d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier std::string error_msg; 1149dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted, 1150d9c4fc94fa618617f94e1de9af5f034549100753Ian Rogers oat_file_assistant.GenerateOatFile(CompilerFilter::kSpeed, &error_msg)); 1151dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 115213735955f39b3b304c37d2b2840663c131262c18Ian Rogers 11535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes// Turn an absolute path into a path relative to the current working 11542cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier// directory. 1155dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersstatic std::string MakePathRelative(std::string target) { 1156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers char buf[MAXPATHLEN]; 1157dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string cwd = getcwd(buf, MAXPATHLEN); 1158dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 115913735955f39b3b304c37d2b2840663c131262c18Ian Rogers // Split the target and cwd paths into components. 116069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro std::vector<std::string> target_path; 1161dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::vector<std::string> cwd_path; 1162dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Split(target, '/', &target_path); 116345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers Split(cwd, '/', &cwd_path); 1164dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1165dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Reverse the path components, so we can use pop_back(). 1166dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::reverse(target_path.begin(), target_path.end()); 1167c143c55718342519db5398e41dda31422cf16c79buzbee std::reverse(cwd_path.begin(), cwd_path.end()); 1168dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1169dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // Drop the common prefix of the paths. Because we reversed the path 1170bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // components, this becomes the common suffix of target_path and cwd_path. 1171449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe while (!target_path.empty() && !cwd_path.empty() 1172449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe && target_path.back() == cwd_path.back()) { 1173449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe target_path.pop_back(); 1174449357d3f61bdd134967ecdacc3516e1707cf882Andreas Gampe cwd_path.pop_back(); 1175dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers } 1176dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1177dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // For each element of the remaining cwd_path, add '..' to the beginning 1178dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers // of the target path. Because we reversed the path components, we add to 1179726079d3e2e50854cd6ca4c393f4529a796dba58Elliott Hughes // the end of target_path. 1180dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers for (unsigned int i = 0; i < cwd_path.size(); i++) { 1181dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers target_path.push_back(".."); 1182dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers } 1183dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 11840399dde18753aa9bd2bd0d7cf60beef154d164a4Ian Rogers // Reverse again to get the right path order, and join to get the result. 1185dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::reverse(target_path.begin(), target_path.end()); 118613735955f39b3b304c37d2b2840663c131262c18Ian Rogers return Join(target_path, '/'); 1187475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes} 1188dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1189dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: Non-absolute path to Dex location. 119061b7f1b05d1fe12d4009316263bf990903e4edffSebastien Hertz// Expect: Not sure, but it shouldn't crash. 1191dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) { 1192e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar"; 1193e343b76af81a005ef64f5e75a555389fd9147dabjeffhao Copy(GetDexSrc1(), abs_dex_location); 11942cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier 1195dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = MakePathRelative(abs_dex_location); 1196899e789bd4741c0172268f7838ce8ab220a5f916Elliott Hughes OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 1197dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1198dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 119952673ffae0025d86f4023735581f19ebcc477487Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 12002cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 1201eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 12020d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes EXPECT_FALSE(oat_file_assistant.OatFileExists()); 1203dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 1204dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 120568d8b42ddec39ec0174162d90d4abaa004d1983eIan Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 1206ffb465f23d9549dd591e6aa62e9250523cb00233Elliott Hughes EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 1207dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 1208dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 120952673ffae0025d86f4023735581f19ebcc477487Ian Rogers// Case: Very short, non-existent Dex location. 1210dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: kNoDexOptNeeded. 1211dd7624d2b9e599d57762d12031b10b89defc9807Ian RogersTEST_F(OatFileAssistantTest, ShortDexLocation) { 1212dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string dex_location = "/xx"; 12135d96a7168dd3e2a4acf1a947ef12efa8f82b95c0Elliott Hughes 1214dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 1215dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 12160aded089f565008ba5908e395e5914ca4f91f2deDave Allison EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 1217dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, 1218dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 1219858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 12201f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_FALSE(oat_file_assistant.OatFileExists()); 12211f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 12221f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 12231f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 122422f454c7d349c439c774c5d79b32514b190fd531Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 12251f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); 12261f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 12272a0d4ec9532a89abe722e5babdfbb846ffaad721Andreas Gampe // Trying to make it up to date should have no effect. 1228dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers std::string error_msg; 1229dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, 1230b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison oat_file_assistant.MakeUpToDate(CompilerFilter::kSpeed, &error_msg)); 1231dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(error_msg.empty()); 1232dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 1233b373e091eac39b1a79c11f2dcbd610af01e9e8a9Dave Allison 1234dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Case: Non-standard extension for dex file. 1235dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers// Expect: The status is kDex2OatNeeded. 1236f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi YamauchiTEST_F(OatFileAssistantTest, LongDexExtension) { 12372cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx"; 1238dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers Copy(GetDexSrc1(), dex_location); 1239dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1240f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, false); 1241dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1242dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, 1243dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); 1244dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1245dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.IsInBootClassPath()); 1246f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi EXPECT_FALSE(oat_file_assistant.OdexFileExists()); 1247dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_TRUE(oat_file_assistant.OdexFileIsOutOfDate()); 124813735955f39b3b304c37d2b2840663c131262c18Ian Rogers EXPECT_FALSE(oat_file_assistant.OdexFileIsUpToDate()); 124913735955f39b3b304c37d2b2840663c131262c18Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileExists()); 125013735955f39b3b304c37d2b2840663c131262c18Ian Rogers EXPECT_TRUE(oat_file_assistant.OatFileIsOutOfDate()); 1251dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers EXPECT_FALSE(oat_file_assistant.OatFileIsUpToDate()); 1252dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers} 12530651d41e41341fb2e9ef3ee41dc1f1bfc832dbbbMathieu Chartier 1254e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers// A task to generate a dex location. Used by the RaceToGenerate test. 1255dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogersclass RaceGenerateTask : public Task { 1256dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers public: 1257cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location) 1258cb535da36915f9d10bec3880b46f1de1f7a69f22Mathieu Chartier : dex_location_(dex_location), oat_location_(oat_location), 12599e36931cc79ca665908db9575126881d1cfdea5aChao-ying Fu loaded_oat_file_(nullptr) 12609e36931cc79ca665908db9575126881d1cfdea5aChao-ying Fu {} 12619e36931cc79ca665908db9575126881d1cfdea5aChao-ying Fu 12628ce6b9040747054b444a7fa706503cd257801936Dave Allison void Run(Thread* self ATTRIBUTE_UNUSED) { 12638ce6b9040747054b444a7fa706503cd257801936Dave Allison // Load the dex files, and save a pointer to the loaded oat file, so that 12648ce6b9040747054b444a7fa706503cd257801936Dave Allison // we can verify only one oat file was loaded for the dex location. 12652cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::vector<std::unique_ptr<const DexFile>> dex_files; 12662cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi std::vector<std::string> error_msgs; 12672cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi const OatFile* oat_file = nullptr; 126812d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat( 126912d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier dex_location_.c_str(), 127012d625f87bcd6c4059a205bb39007a255f57f382Mathieu Chartier oat_location_.c_str(), 1271dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers /*class_loader*/nullptr, 1272dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers /*dex_elements*/nullptr, 1273dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers &oat_file, 1274dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers &error_msgs); 1275dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK(!dex_files.empty()) << Join(error_msgs, '\n'); 1276dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation(); 1277dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile(); 12782cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK_EQ(loaded_oat_file_, oat_file); 1279dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers } 1280dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers 1281dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers const OatFile* GetLoadedOatFile() const { 1282dd7624d2b9e599d57762d12031b10b89defc9807Ian Rogers return loaded_oat_file_; 1283f5b0e20b5b31f5f5465784adcf2a204dcd69c7fdHiroshi Yamauchi } 1284e6da9af8dfe0a3e3fbc2be700554f6478380e7b9Mathieu Chartier 128515d3402bbf8265eb1165694da2e4117eb128f3bcMathieu Chartier private: 1286692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier std::string dex_location_; 12875cf98196d488437acd1e989c08a554ef697fded1Ian Rogers std::string oat_location_; 1288692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier const OatFile* loaded_oat_file_; 1289119c6bd97f7ac24b64eaf4e9333abb44acbf780fMathieu Chartier}; 1290692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier 1291692fafd9778141fa6ef0048c9569abd7ee0253bfMathieu Chartier// Test the case where multiple processes race to generate an oat file. 12924352b4556c138eb9f583367d678531930b5b8fb0Andreas Gampe// This simulates multiple processes using multiple threads. 12934352b4556c138eb9f583367d678531930b5b8fb0Andreas Gampe// 12940e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// We want unique Oat files to be loaded even when there is a race to load. 12950e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// TODO: The test case no longer tests locking the way it was intended since we now get multiple 1296bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers// copies of the same Oat files mapped at different locations. 12972d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu ChartierTEST_F(OatFileAssistantTest, RaceToGenerate) { 12982d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar"; 12992d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat"; 13002d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier 13012d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier // We use the lib core dex file, because it's large, and hopefully should 13022d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier // take a while to generate. 13032d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier Copy(GetLibCoreDexFileNames()[0], dex_location); 13042d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier 13052d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier const int kNumThreads = 32; 13062d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier Thread* self = Thread::Current(); 13072d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads); 13082d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier std::vector<std::unique_ptr<RaceGenerateTask>> tasks; 13092d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier for (int i = 0; i < kNumThreads; i++) { 13102d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location)); 1311f2247513a54300cfa6a2f23fdbbafead115c99b2Ian Rogers thread_pool.AddTask(self, task.get()); 13122d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier tasks.push_back(std::move(task)); 13132d5f39ed5aeaeb7ca22b07b4c6e8c56348ef8893Mathieu Chartier } 13141f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang thread_pool.StartWorkers(self); 13151f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang thread_pool.Wait(self, true, false); 13161f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 13171f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang // Verify every task got a unique oat file. 13181f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang std::set<const OatFile*> oat_files; 13191f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang for (auto& task : tasks) { 13201f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang const OatFile* oat_file = task->GetLoadedOatFile(); 13211f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end()); 13221f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang oat_files.insert(oat_file); 13231f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang } 13241f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang} 13251f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang 13261f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is 13271f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang// disabled. 13281f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang// Expect: We should load the odex file non-executable. 13291f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao YangTEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) { 13301f2d3ba6af52cf6f566deb38b7e07735c9a08fb6Mingyao Yang std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar"; 1331330304de14dc7118b45b8e7b5bd11a172fa61701Elliott Hughes std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex"; 1332f795869da0a1fa006fdcdacd8afb6149a63fc1a7Sebastien Hertz 13330e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // Create the dex and odex files 13340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Copy(GetDexSrc1(), dex_location); 13350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 1336fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom 1337 // Load the oat using an executable oat file assistant. 1338 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 1339 1340 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 1341 ASSERT_TRUE(oat_file.get() != nullptr); 1342 EXPECT_FALSE(oat_file->IsExecutable()); 1343 std::vector<std::unique_ptr<const DexFile>> dex_files; 1344 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 1345 EXPECT_EQ(1u, dex_files.size()); 1346} 1347 1348// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is 1349// disabled. 1350// Expect: We should load the odex file non-executable. 1351TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) { 1352 std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar"; 1353 std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex"; 1354 1355 // Create the dex and odex files 1356 Copy(GetMultiDexSrc1(), dex_location); 1357 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed); 1358 1359 // Load the oat using an executable oat file assistant. 1360 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false, true); 1361 1362 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); 1363 ASSERT_TRUE(oat_file.get() != nullptr); 1364 EXPECT_FALSE(oat_file->IsExecutable()); 1365 std::vector<std::unique_ptr<const DexFile>> dex_files; 1366 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); 1367 EXPECT_EQ(2u, dex_files.size()); 1368} 1369 1370TEST(OatFileAssistantUtilsTest, DexFilenameToOdexFilename) { 1371 std::string error_msg; 1372 std::string odex_file; 1373 1374 EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename( 1375 "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg; 1376 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file); 1377 1378 EXPECT_TRUE(OatFileAssistant::DexFilenameToOdexFilename( 1379 "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg; 1380 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file); 1381 1382 EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename( 1383 "nopath.jar", kArm, &odex_file, &error_msg)); 1384 EXPECT_FALSE(OatFileAssistant::DexFilenameToOdexFilename( 1385 "/foo/bar/baz_noext", kArm, &odex_file, &error_msg)); 1386} 1387 1388// Verify the dexopt status values from dalvik.system.DexFile 1389// match the OatFileAssistant::DexOptStatus values. 1390TEST_F(OatFileAssistantTest, DexOptStatusValues) { 1391 ScopedObjectAccess soa(Thread::Current()); 1392 StackHandleScope<1> hs(soa.Self()); 1393 ClassLinker* linker = Runtime::Current()->GetClassLinker(); 1394 Handle<mirror::Class> dexfile( 1395 hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;"))); 1396 ASSERT_FALSE(dexfile.Get() == nullptr); 1397 linker->EnsureInitialized(soa.Self(), dexfile, true, true); 1398 1399 ArtField* no_dexopt_needed = mirror::Class::FindStaticField( 1400 soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I"); 1401 ASSERT_FALSE(no_dexopt_needed == nullptr); 1402 EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 1403 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get())); 1404 1405 ArtField* dex2oat_needed = mirror::Class::FindStaticField( 1406 soa.Self(), dexfile, "DEX2OAT_NEEDED", "I"); 1407 ASSERT_FALSE(dex2oat_needed == nullptr); 1408 EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 1409 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get())); 1410 1411 ArtField* patchoat_needed = mirror::Class::FindStaticField( 1412 soa.Self(), dexfile, "PATCHOAT_NEEDED", "I"); 1413 ASSERT_FALSE(patchoat_needed == nullptr); 1414 EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 1415 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get())); 1416 1417 ArtField* self_patchoat_needed = mirror::Class::FindStaticField( 1418 soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I"); 1419 ASSERT_FALSE(self_patchoat_needed == nullptr); 1420 EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt); 1421 EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get())); 1422} 1423 1424// TODO: More Tests: 1425// * Image checksum change is out of date for kIntepretOnly, but not 1426// kVerifyAtRuntime. But target of kVerifyAtRuntime still says current 1427// kInterpretOnly is out of date. 1428// * Test class linker falls back to unquickened dex for DexNoOat 1429// * Test class linker falls back to unquickened dex for MultiDexNoOat 1430// * Test using secondary isa 1431// * Test for status of oat while oat is being generated (how?) 1432// * Test case where 32 and 64 bit boot class paths differ, 1433// and we ask IsInBootClassPath for a class in exactly one of the 32 or 1434// 64 bit boot class paths. 1435// * Test unexpected scenarios (?): 1436// - Dex is stripped, don't have odex. 1437// - Oat file corrupted after status check, before reload unexecutable 1438// because it's unrelocated and no dex2oat 1439// * Test unrelocated specific target compilation type can be relocated to 1440// make it up to date. 1441 1442} // namespace art 1443