blob: abd3b963c5283b2911bbfe16b44a68964c89ce59 [file] [log] [blame]
Richard Uhler66d874d2015-01-15 09:37:19 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Richard Uhler66d874d2015-01-15 09:37:19 -080017#include <algorithm>
18#include <fstream>
19#include <string>
20#include <vector>
21#include <sys/param.h>
22
23#include <backtrace/BacktraceMap.h>
24#include <gtest/gtest.h>
25
Mathieu Chartierc7853442015-03-27 14:35:38 -070026#include "art_field-inl.h"
Vladimir Marko3481ba22015-04-13 12:22:36 +010027#include "class_linker-inl.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080028#include "common_runtime_test.h"
Andreas Gampebb9c6b12015-03-29 13:56:36 -070029#include "compiler_callbacks.h"
Andreas Gampee1459ae2016-06-29 09:36:30 -070030#include "dex2oat_environment_test.h"
Richard Uhlerf16d5722015-05-11 09:32:47 -070031#include "gc/space/image_space.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080032#include "mem_map.h"
Andreas Gampee1459ae2016-06-29 09:36:30 -070033#include "oat_file_assistant.h"
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -070034#include "oat_file_manager.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080035#include "os.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070036#include "scoped_thread_state_change-inl.h"
Richard Uhler66d874d2015-01-15 09:37:19 -080037#include "thread-inl.h"
38#include "utils.h"
39
40namespace art {
41
Andreas Gampee1459ae2016-06-29 09:36:30 -070042class OatFileAssistantTest : public Dex2oatEnvironmentTest {
Richard Uhler66d874d2015-01-15 09:37:19 -080043 public:
Andreas Gampee1459ae2016-06-29 09:36:30 -070044 virtual void SetUp() OVERRIDE {
Richard Uhler66d874d2015-01-15 09:37:19 -080045 ReserveImageSpace();
Andreas Gampee1459ae2016-06-29 09:36:30 -070046 Dex2oatEnvironmentTest::SetUp();
Richard Uhler66d874d2015-01-15 09:37:19 -080047 }
48
Richard Uhlera48403e2016-04-26 10:24:38 -070049 // Pre-Relocate the image to a known non-zero offset so we don't have to
50 // deal with the runtime randomly relocating the image by 0 and messing up
51 // the expected results of the tests.
52 bool PreRelocateImage(std::string* error_msg) {
53 std::string image;
54 if (!GetCachedImageFile(&image, error_msg)) {
55 return false;
56 }
57
58 std::string patchoat = GetAndroidRoot();
59 patchoat += kIsDebugBuild ? "/bin/patchoatd" : "/bin/patchoat";
60
61 std::vector<std::string> argv;
62 argv.push_back(patchoat);
63 argv.push_back("--input-image-location=" + GetImageLocation());
64 argv.push_back("--output-image-file=" + image);
65 argv.push_back("--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)));
66 argv.push_back("--base-offset-delta=0x00008000");
67 return Exec(argv, error_msg);
68 }
69
Richard Uhler66d874d2015-01-15 09:37:19 -080070 virtual void PreRuntimeCreate() {
Richard Uhlera48403e2016-04-26 10:24:38 -070071 std::string error_msg;
72 ASSERT_TRUE(PreRelocateImage(&error_msg)) << error_msg;
73
Richard Uhler66d874d2015-01-15 09:37:19 -080074 UnreserveImageSpace();
75 }
76
Andreas Gampee1459ae2016-06-29 09:36:30 -070077 virtual void PostRuntimeCreate() OVERRIDE {
Richard Uhler66d874d2015-01-15 09:37:19 -080078 ReserveImageSpace();
79 }
80
Richard Uhler93aa2102015-08-10 14:47:41 -070081 // Generate a non-PIC odex file for the purposes of test.
Richard Uhler94f5bda2015-07-22 08:25:11 -070082 // The generated odex file will be un-relocated.
Richard Uhler66d874d2015-01-15 09:37:19 -080083 void GenerateOdexForTest(const std::string& dex_location,
Andreas Gampe29d38e72016-03-23 15:31:51 +000084 const std::string& odex_location,
Richard Uhlera48403e2016-04-26 10:24:38 -070085 CompilerFilter::Filter filter,
86 bool pic = false,
87 bool with_patch_info = true) {
88 // Temporarily redirect the dalvik cache so dex2oat doesn't find the
89 // relocated image file.
David Sehrd106d9f2016-08-16 19:22:57 -070090 std::string dalvik_cache = GetDalvikCache(GetInstructionSetString(kRuntimeISA));
91 std::string dalvik_cache_tmp = dalvik_cache + ".redirected";
92 ASSERT_EQ(0, rename(dalvik_cache.c_str(), dalvik_cache_tmp.c_str())) << strerror(errno);
93
Richard Uhler93aa2102015-08-10 14:47:41 -070094 std::vector<std::string> args;
95 args.push_back("--dex-file=" + dex_location);
Richard Uhlera48403e2016-04-26 10:24:38 -070096 args.push_back("--oat-file=" + odex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +000097 args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
Richard Uhlera48403e2016-04-26 10:24:38 -070098 args.push_back("--runtime-arg");
99 args.push_back("-Xnorelocate");
Richard Uhler93aa2102015-08-10 14:47:41 -0700100
Richard Uhlera48403e2016-04-26 10:24:38 -0700101 if (pic) {
102 args.push_back("--compile-pic");
103 }
104
105 if (with_patch_info) {
106 args.push_back("--include-patch-information");
107 }
Richard Uhler93aa2102015-08-10 14:47:41 -0700108
109 std::string error_msg;
110 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
David Sehrd106d9f2016-08-16 19:22:57 -0700111 ASSERT_EQ(0, rename(dalvik_cache_tmp.c_str(), dalvik_cache.c_str())) << strerror(errno);
Richard Uhler93aa2102015-08-10 14:47:41 -0700112
113 // Verify the odex file was generated as expected and really is
114 // unrelocated.
Mathieu Chartier0b4cbd02016-03-08 16:49:58 -0800115 std::unique_ptr<OatFile> odex_file(OatFile::Open(odex_location.c_str(),
116 odex_location.c_str(),
117 nullptr,
118 nullptr,
119 false,
120 /*low_4gb*/false,
121 dex_location.c_str(),
122 &error_msg));
Richard Uhler93aa2102015-08-10 14:47:41 -0700123 ASSERT_TRUE(odex_file.get() != nullptr) << error_msg;
Richard Uhlera48403e2016-04-26 10:24:38 -0700124 EXPECT_EQ(pic, odex_file->IsPic());
125 EXPECT_EQ(with_patch_info, odex_file->HasPatchInfo());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000126 EXPECT_EQ(filter, odex_file->GetCompilerFilter());
127
Vladimir Markof6d1e0f2016-05-23 15:32:42 +0100128 if (CompilerFilter::IsBytecodeCompilationEnabled(filter)) {
Andreas Gampe29d38e72016-03-23 15:31:51 +0000129 const std::vector<gc::space::ImageSpace*> image_spaces =
Richard Uhlera48403e2016-04-26 10:24:38 -0700130 Runtime::Current()->GetHeap()->GetBootImageSpaces();
Andreas Gampe29d38e72016-03-23 15:31:51 +0000131 ASSERT_TRUE(!image_spaces.empty() && image_spaces[0] != nullptr);
132 const ImageHeader& image_header = image_spaces[0]->GetImageHeader();
133 const OatHeader& oat_header = odex_file->GetOatHeader();
Jeff Haob11ffb72016-04-07 15:40:54 -0700134 uint32_t combined_checksum = OatFileAssistant::CalculateCombinedImageChecksum();
135 EXPECT_EQ(combined_checksum, oat_header.GetImageFileLocationOatChecksum());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000136 EXPECT_NE(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
137 oat_header.GetImageFileLocationOatDataBegin());
138 EXPECT_NE(image_header.GetPatchDelta(), oat_header.GetImagePatchDelta());
139 }
Richard Uhler93aa2102015-08-10 14:47:41 -0700140 }
141
142 void GeneratePicOdexForTest(const std::string& dex_location,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000143 const std::string& odex_location,
144 CompilerFilter::Filter filter) {
Richard Uhlera48403e2016-04-26 10:24:38 -0700145 GenerateOdexForTest(dex_location, odex_location, filter, true, false);
Calin Juravleb077e152016-02-18 18:47:37 +0000146 }
David Brazdilce4b0ba2016-01-28 15:05:49 +0000147
Richard Uhlerd1537b52016-03-29 13:27:41 -0700148 // Generate a non-PIC odex file without patch information for the purposes
149 // of test. The generated odex file will be un-relocated.
Richard Uhlerd1537b52016-03-29 13:27:41 -0700150 void GenerateNoPatchOdexForTest(const std::string& dex_location,
151 const std::string& odex_location,
152 CompilerFilter::Filter filter) {
Richard Uhlera48403e2016-04-26 10:24:38 -0700153 GenerateOdexForTest(dex_location, odex_location, filter, false, false);
Richard Uhlerd1537b52016-03-29 13:27:41 -0700154 }
155
Richard Uhler66d874d2015-01-15 09:37:19 -0800156 private:
157 // Reserve memory around where the image will be loaded so other memory
158 // won't conflict when it comes time to load the image.
159 // This can be called with an already loaded image to reserve the space
160 // around it.
161 void ReserveImageSpace() {
162 MemMap::Init();
163
164 // Ensure a chunk of memory is reserved for the image space.
Richard Uhlera48403e2016-04-26 10:24:38 -0700165 // The reservation_end includes room for the main space that has to come
166 // right after the image in case of the GSS collector.
167 uintptr_t reservation_start = ART_BASE_ADDRESS;
168 uintptr_t reservation_end = ART_BASE_ADDRESS + 384 * MB;
Richard Uhler66d874d2015-01-15 09:37:19 -0800169
Richard Uhler66d874d2015-01-15 09:37:19 -0800170 std::unique_ptr<BacktraceMap> map(BacktraceMap::Create(getpid(), true));
171 ASSERT_TRUE(map.get() != nullptr) << "Failed to build process map";
172 for (BacktraceMap::const_iterator it = map->begin();
173 reservation_start < reservation_end && it != map->end(); ++it) {
Richard Uhler3efe9792015-03-30 16:18:03 -0700174 ReserveImageSpaceChunk(reservation_start, std::min(it->start, reservation_end));
175 reservation_start = std::max(reservation_start, it->end);
176 }
177 ReserveImageSpaceChunk(reservation_start, reservation_end);
178 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800179
Richard Uhler3efe9792015-03-30 16:18:03 -0700180 // Reserve a chunk of memory for the image space in the given range.
181 // Only has effect for chunks with a positive number of bytes.
182 void ReserveImageSpaceChunk(uintptr_t start, uintptr_t end) {
183 if (start < end) {
184 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800185 image_reservation_.push_back(std::unique_ptr<MemMap>(
186 MemMap::MapAnonymous("image reservation",
Richard Uhler3efe9792015-03-30 16:18:03 -0700187 reinterpret_cast<uint8_t*>(start), end - start,
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700188 PROT_NONE, false, false, &error_msg)));
Richard Uhler66d874d2015-01-15 09:37:19 -0800189 ASSERT_TRUE(image_reservation_.back().get() != nullptr) << error_msg;
190 LOG(INFO) << "Reserved space for image " <<
191 reinterpret_cast<void*>(image_reservation_.back()->Begin()) << "-" <<
192 reinterpret_cast<void*>(image_reservation_.back()->End());
Richard Uhler66d874d2015-01-15 09:37:19 -0800193 }
194 }
195
196
197 // Unreserve any memory reserved by ReserveImageSpace. This should be called
198 // before the image is loaded.
199 void UnreserveImageSpace() {
200 image_reservation_.clear();
201 }
202
Richard Uhler66d874d2015-01-15 09:37:19 -0800203 std::vector<std::unique_ptr<MemMap>> image_reservation_;
204};
205
206class OatFileAssistantNoDex2OatTest : public OatFileAssistantTest {
207 public:
208 virtual void SetUpRuntimeOptions(RuntimeOptions* options) {
209 OatFileAssistantTest::SetUpRuntimeOptions(options);
210 options->push_back(std::make_pair("-Xnodex2oat", nullptr));
211 }
212};
213
214// Generate an oat file for the purposes of test, as opposed to testing
215// generation of oat files.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000216static void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) {
217 // Use an oat file assistant to find the proper oat location.
Richard Uhlerb81881d2016-04-19 13:08:04 -0700218 std::string oat_location;
219 std::string error_msg;
220 ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename(
221 dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800222
Andreas Gampe29d38e72016-03-23 15:31:51 +0000223 std::vector<std::string> args;
224 args.push_back("--dex-file=" + std::string(dex_location));
Richard Uhlerb81881d2016-04-19 13:08:04 -0700225 args.push_back("--oat-file=" + oat_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000226 args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter));
227 args.push_back("--runtime-arg");
228 args.push_back("-Xnorelocate");
Andreas Gampe29d38e72016-03-23 15:31:51 +0000229 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
230
231 // Verify the oat file was generated as expected.
Richard Uhlerb81881d2016-04-19 13:08:04 -0700232 std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_location.c_str(),
233 oat_location.c_str(),
Andreas Gampe29d38e72016-03-23 15:31:51 +0000234 nullptr,
235 nullptr,
236 false,
237 /*low_4gb*/false,
238 dex_location,
239 &error_msg));
240 ASSERT_TRUE(oat_file.get() != nullptr) << error_msg;
241 EXPECT_EQ(filter, oat_file->GetCompilerFilter());
Richard Uhler66d874d2015-01-15 09:37:19 -0800242}
243
244// Case: We have a DEX file, but no OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700245// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800246TEST_F(OatFileAssistantTest, DexNoOat) {
247 std::string dex_location = GetScratchDir() + "/DexNoOat.jar";
248 Copy(GetDexSrc1(), dex_location);
249
Richard Uhlerd1472a22016-04-15 15:18:56 -0700250 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800251
Andreas Gampe29d38e72016-03-23 15:31:51 +0000252 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
253 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
254 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
255 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
256 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
257 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile));
258 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
259 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800260
261 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
262 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler95abd042015-03-24 09:51:28 -0700263 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800264 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler95abd042015-03-24 09:51:28 -0700265 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700266 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800267}
268
269// Case: We have no DEX file and no OAT file.
Richard Uhler9b994ea2015-06-24 08:44:19 -0700270// Expect: Status is kNoDexOptNeeded. Loading should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800271TEST_F(OatFileAssistantTest, NoDexNoOat) {
272 std::string dex_location = GetScratchDir() + "/NoDexNoOat.jar";
273
Richard Uhlerd1472a22016-04-15 15:18:56 -0700274 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800275
Andreas Gampe29d38e72016-03-23 15:31:51 +0000276 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
277 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700278 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
279
280 // Trying to make the oat file up to date should not fail or crash.
281 std::string error_msg;
Richard Uhlerd1472a22016-04-15 15:18:56 -0700282 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700283
284 // Trying to get the best oat file should fail, but not crash.
Richard Uhler66d874d2015-01-15 09:37:19 -0800285 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
286 EXPECT_EQ(nullptr, oat_file.get());
287}
288
289// Case: We have a DEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700290// Expect: The status is kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800291TEST_F(OatFileAssistantTest, OatUpToDate) {
292 std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
293 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000294 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800295
Richard Uhlerd1472a22016-04-15 15:18:56 -0700296 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800297
Andreas Gampe29d38e72016-03-23 15:31:51 +0000298 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
299 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
300 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
301 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
302 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
303 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
304 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
305 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
306
Richard Uhler66d874d2015-01-15 09:37:19 -0800307 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
308 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000309 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800310 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Richard Uhler95abd042015-03-24 09:51:28 -0700311 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700312 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800313}
314
Richard Uhler9a37efc2016-08-05 16:32:55 -0700315// Case: We have a DEX file and ODEX file for a different dex location.
316// Expect: The status is kDex2OatNeeded.
317TEST_F(OatFileAssistantTest, OatForDifferentDex) {
318 // Generate an odex file for OatForDifferentDex_A.jar
319 std::string dex_location_a = GetScratchDir() + "/OatForDifferentDex_A.jar";
320 std::string odex_location = GetOdexDir() + "/OatForDifferentDex.odex";
321 Copy(GetDexSrc1(), dex_location_a);
322 GenerateOdexForTest(dex_location_a, odex_location, CompilerFilter::kSpeed);
323
324 // Try to use that odex file for OatForDifferentDex.jar
325 std::string dex_location = GetScratchDir() + "/OatForDifferentDex.jar";
326 Copy(GetDexSrc1(), dex_location);
327
328 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
329
330 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
331 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
332
333 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
334 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000335 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler9a37efc2016-08-05 16:32:55 -0700336 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000337 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9a37efc2016-08-05 16:32:55 -0700338}
339
Andreas Gampe29d38e72016-03-23 15:31:51 +0000340// Case: We have a DEX file and speed-profile OAT file for it.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700341// Expect: The status is kNoDexOptNeeded if the profile hasn't changed, but
342// kDex2Oat if the profile has changed.
Andreas Gampe29d38e72016-03-23 15:31:51 +0000343TEST_F(OatFileAssistantTest, ProfileOatUpToDate) {
344 std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
345 Copy(GetDexSrc1(), dex_location);
346 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeedProfile);
347
Richard Uhlerd1472a22016-04-15 15:18:56 -0700348 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000349
350 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700351 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, false));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000352 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700353 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly, false));
354 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
355 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeedProfile, true));
356 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
357 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly, true));
Andreas Gampe29d38e72016-03-23 15:31:51 +0000358
359 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
360 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000361 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000362 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000363 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
364 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
365}
366
Richard Uhler66d874d2015-01-15 09:37:19 -0800367// Case: We have a MultiDEX file and up-to-date OAT file for it.
Richard Uhler95abd042015-03-24 09:51:28 -0700368// Expect: The status is kNoDexOptNeeded and we load all dex files.
Richard Uhler66d874d2015-01-15 09:37:19 -0800369TEST_F(OatFileAssistantTest, MultiDexOatUpToDate) {
370 std::string dex_location = GetScratchDir() + "/MultiDexOatUpToDate.jar";
371 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000372 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800373
Richard Uhlerd1472a22016-04-15 15:18:56 -0700374 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000375 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700376 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700377 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700378
379 // Verify we can load both dex files.
Richard Uhlere5fed032015-03-18 08:21:11 -0700380 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
Richard Uhler66d874d2015-01-15 09:37:19 -0800381 ASSERT_TRUE(oat_file.get() != nullptr);
382 EXPECT_TRUE(oat_file->IsExecutable());
383 std::vector<std::unique_ptr<const DexFile>> dex_files;
Richard Uhlere5fed032015-03-18 08:21:11 -0700384 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
385 EXPECT_EQ(2u, dex_files.size());
386}
387
Richard Uhler67ff7d12015-05-14 13:21:13 -0700388// Case: We have a MultiDEX file where the secondary dex file is out of date.
389// Expect: The status is kDex2OatNeeded.
390TEST_F(OatFileAssistantTest, MultiDexSecondaryOutOfDate) {
391 std::string dex_location = GetScratchDir() + "/MultiDexSecondaryOutOfDate.jar";
392
393 // Compile code for GetMultiDexSrc1.
394 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000395 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler67ff7d12015-05-14 13:21:13 -0700396
397 // Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
398 // is out of date.
399 Copy(GetMultiDexSrc2(), dex_location);
400
Richard Uhlerd1472a22016-04-15 15:18:56 -0700401 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000402 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700403 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed, false));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700404 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler67ff7d12015-05-14 13:21:13 -0700405}
406
Richard Uhlere5fed032015-03-18 08:21:11 -0700407// Case: We have a MultiDEX file and up-to-date OAT file for it with relative
408// encoded dex locations.
Richard Uhler95abd042015-03-24 09:51:28 -0700409// Expect: The oat file status is kNoDexOptNeeded.
Richard Uhlere5fed032015-03-18 08:21:11 -0700410TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) {
411 std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700412 std::string oat_location = GetOdexDir() + "/RelativeEncodedDexLocation.oat";
Richard Uhlere5fed032015-03-18 08:21:11 -0700413
414 // Create the dex file
415 Copy(GetMultiDexSrc1(), dex_location);
416
417 // Create the oat file with relative encoded dex location.
418 std::vector<std::string> args;
419 args.push_back("--dex-file=" + dex_location);
420 args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar"));
421 args.push_back("--oat-file=" + oat_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000422 args.push_back("--compiler-filter=speed");
Richard Uhlere5fed032015-03-18 08:21:11 -0700423
424 std::string error_msg;
Igor Murashkinb1d8c312015-08-04 11:18:43 -0700425 ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
Richard Uhlere5fed032015-03-18 08:21:11 -0700426
427 // Verify we can load both dex files.
428 OatFileAssistant oat_file_assistant(dex_location.c_str(),
429 oat_location.c_str(),
Richard Uhlerd1472a22016-04-15 15:18:56 -0700430 kRuntimeISA, true);
Richard Uhlere5fed032015-03-18 08:21:11 -0700431 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
432 ASSERT_TRUE(oat_file.get() != nullptr);
433 EXPECT_TRUE(oat_file->IsExecutable());
434 std::vector<std::unique_ptr<const DexFile>> dex_files;
435 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
Richard Uhler66d874d2015-01-15 09:37:19 -0800436 EXPECT_EQ(2u, dex_files.size());
437}
438
Richard Uhler95abd042015-03-24 09:51:28 -0700439// Case: We have a DEX file and out-of-date OAT file.
440// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800441TEST_F(OatFileAssistantTest, OatOutOfDate) {
442 std::string dex_location = GetScratchDir() + "/OatOutOfDate.jar";
443
444 // We create a dex, generate an oat for it, then overwrite the dex with a
445 // different dex to make the oat out of date.
446 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000447 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800448 Copy(GetDexSrc2(), dex_location);
449
Richard Uhlerd1472a22016-04-15 15:18:56 -0700450 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000451 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
452 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
453 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
454 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800455
456 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
457 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000458 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800459 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000460 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700461 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800462}
463
464// Case: We have a DEX file and an ODEX file, but no OAT file.
Richard Uhler95abd042015-03-24 09:51:28 -0700465// Expect: The status is kPatchOatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800466TEST_F(OatFileAssistantTest, DexOdexNoOat) {
467 std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700468 std::string odex_location = GetOdexDir() + "/DexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800469
470 // Create the dex and odex files
471 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000472 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800473
474 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700475 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800476
Andreas Gampe29d38e72016-03-23 15:31:51 +0000477 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
478 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
479 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
480 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800481
482 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
483 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000484 EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800485 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000486 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700487 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler5f946da2015-07-17 12:28:32 -0700488
489 // We should still be able to get the non-executable odex file to run from.
490 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
491 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhler66d874d2015-01-15 09:37:19 -0800492}
493
494// Case: We have a stripped DEX file and an ODEX file, but no OAT file.
Richard Uhler95abd042015-03-24 09:51:28 -0700495// Expect: The status is kPatchOatNeeded
Richard Uhler66d874d2015-01-15 09:37:19 -0800496TEST_F(OatFileAssistantTest, StrippedDexOdexNoOat) {
497 std::string dex_location = GetScratchDir() + "/StrippedDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700498 std::string odex_location = GetOdexDir() + "/StrippedDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800499
500 // Create the dex and odex files
501 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000502 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800503
504 // Strip the dex file
505 Copy(GetStrippedDexSrc1(), dex_location);
506
507 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700508 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800509
Andreas Gampe29d38e72016-03-23 15:31:51 +0000510 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
511 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800512
513 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
514 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000515 EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800516 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000517 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700518 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800519
520 // Make the oat file up to date.
521 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700522 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700523 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700524 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800525
Andreas Gampe29d38e72016-03-23 15:31:51 +0000526 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
527 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800528
529 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
530 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000531 EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800532 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000533 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700534 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800535
536 // Verify we can load the dex files from it.
537 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
538 ASSERT_TRUE(oat_file.get() != nullptr);
539 EXPECT_TRUE(oat_file->IsExecutable());
540 std::vector<std::unique_ptr<const DexFile>> dex_files;
541 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
542 EXPECT_EQ(1u, dex_files.size());
543}
544
Richard Uhler95abd042015-03-24 09:51:28 -0700545// Case: We have a stripped DEX file, an ODEX file, and an out-of-date OAT file.
546// Expect: The status is kPatchOatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800547TEST_F(OatFileAssistantTest, StrippedDexOdexOat) {
548 std::string dex_location = GetScratchDir() + "/StrippedDexOdexOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700549 std::string odex_location = GetOdexDir() + "/StrippedDexOdexOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800550
551 // Create the oat file from a different dex file so it looks out of date.
552 Copy(GetDexSrc2(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000553 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800554
555 // Create the odex file
556 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000557 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800558
559 // Strip the dex file.
560 Copy(GetStrippedDexSrc1(), dex_location);
561
562 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700563 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800564
Andreas Gampe29d38e72016-03-23 15:31:51 +0000565 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
566 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
567 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded,
568 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
569 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped.
570 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800571
572 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
573 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000574 EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800575 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000576 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700577 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800578
579 // Make the oat file up to date.
580 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700581 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700582 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700583 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800584
Andreas Gampe29d38e72016-03-23 15:31:51 +0000585 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
586 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
587 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, // Can't run dex2oat because dex file is stripped.
588 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800589
590 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
591 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000592 EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus());
593
Richard Uhler66d874d2015-01-15 09:37:19 -0800594 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000595 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700596 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800597
598 // Verify we can load the dex files from it.
599 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
600 ASSERT_TRUE(oat_file.get() != nullptr);
601 EXPECT_TRUE(oat_file->IsExecutable());
602 std::vector<std::unique_ptr<const DexFile>> dex_files;
603 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
604 EXPECT_EQ(1u, dex_files.size());
605}
606
Richard Uhler9b994ea2015-06-24 08:44:19 -0700607// Case: We have a stripped (or resource-only) DEX file, no ODEX file and no
608// OAT file. Expect: The status is kNoDexOptNeeded.
609TEST_F(OatFileAssistantTest, ResourceOnlyDex) {
610 std::string dex_location = GetScratchDir() + "/ResourceOnlyDex.jar";
611
612 Copy(GetStrippedDexSrc1(), dex_location);
613
614 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700615 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler9b994ea2015-06-24 08:44:19 -0700616
Andreas Gampe29d38e72016-03-23 15:31:51 +0000617 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
618 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
619 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
620 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
621 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
622 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700623
624 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
625 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000626 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700627 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000628 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700629 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
630
631 // Make the oat file up to date. This should have no effect.
632 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700633 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700634 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700635 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhler9b994ea2015-06-24 08:44:19 -0700636
Andreas Gampe29d38e72016-03-23 15:31:51 +0000637 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
638 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler9b994ea2015-06-24 08:44:19 -0700639
640 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
641 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000642 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700643 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000644 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700645 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
646}
647
Richard Uhler95abd042015-03-24 09:51:28 -0700648// Case: We have a DEX file, no ODEX file and an OAT file that needs
649// relocation.
650// Expect: The status is kSelfPatchOatNeeded.
651TEST_F(OatFileAssistantTest, SelfRelocation) {
652 std::string dex_location = GetScratchDir() + "/SelfRelocation.jar";
653 std::string oat_location = GetOdexDir() + "/SelfRelocation.oat";
654
655 // Create the dex and odex files
656 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000657 GenerateOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
Richard Uhler95abd042015-03-24 09:51:28 -0700658
659 OatFileAssistant oat_file_assistant(dex_location.c_str(),
Richard Uhlerd1472a22016-04-15 15:18:56 -0700660 oat_location.c_str(), kRuntimeISA, true);
Richard Uhler95abd042015-03-24 09:51:28 -0700661
Andreas Gampe29d38e72016-03-23 15:31:51 +0000662 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
663 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
664 EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded,
665 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
666 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
667 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler95abd042015-03-24 09:51:28 -0700668
669 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
670 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000671 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler95abd042015-03-24 09:51:28 -0700672 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000673 EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700674 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700675
676 // Make the oat file up to date.
677 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700678 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700679 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700680 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhler95abd042015-03-24 09:51:28 -0700681
Andreas Gampe29d38e72016-03-23 15:31:51 +0000682 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
683 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler95abd042015-03-24 09:51:28 -0700684
685 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
686 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000687 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler95abd042015-03-24 09:51:28 -0700688 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000689 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700690 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler95abd042015-03-24 09:51:28 -0700691
692 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
693 ASSERT_TRUE(oat_file.get() != nullptr);
694 EXPECT_TRUE(oat_file->IsExecutable());
695 std::vector<std::unique_ptr<const DexFile>> dex_files;
696 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
697 EXPECT_EQ(1u, dex_files.size());
698}
699
Richard Uhlerd1537b52016-03-29 13:27:41 -0700700// Case: We have a DEX file, no ODEX file and an OAT file that needs
701// relocation but doesn't have patch info.
702// Expect: The status is kDex2OatNeeded, because we can't run patchoat.
703TEST_F(OatFileAssistantTest, NoSelfRelocation) {
704 std::string dex_location = GetScratchDir() + "/NoSelfRelocation.jar";
705 std::string oat_location = GetOdexDir() + "/NoSelfRelocation.oat";
706
707 // Create the dex and odex files
708 Copy(GetDexSrc1(), dex_location);
709 GenerateNoPatchOdexForTest(dex_location, oat_location, CompilerFilter::kSpeed);
710
711 OatFileAssistant oat_file_assistant(dex_location.c_str(),
Richard Uhlerd1472a22016-04-15 15:18:56 -0700712 oat_location.c_str(), kRuntimeISA, true);
Richard Uhlerd1537b52016-03-29 13:27:41 -0700713
714 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
715 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
716
717 // Make the oat file up to date.
718 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700719 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700720 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700721 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhlerd1537b52016-03-29 13:27:41 -0700722 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
723 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
724
725 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
726 ASSERT_TRUE(oat_file.get() != nullptr);
727 EXPECT_TRUE(oat_file->IsExecutable());
728 std::vector<std::unique_ptr<const DexFile>> dex_files;
729 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
730 EXPECT_EQ(1u, dex_files.size());
731}
732
Richard Uhler66d874d2015-01-15 09:37:19 -0800733// Case: We have a DEX file, an ODEX file and an OAT file, where the ODEX and
734// OAT files both have patch delta of 0.
Richard Uhler70a84262016-11-08 16:51:51 +0000735// Expect: It shouldn't crash, and status is kSelfPatchOatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -0800736TEST_F(OatFileAssistantTest, OdexOatOverlap) {
737 std::string dex_location = GetScratchDir() + "/OdexOatOverlap.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700738 std::string odex_location = GetOdexDir() + "/OdexOatOverlap.odex";
739 std::string oat_location = GetOdexDir() + "/OdexOatOverlap.oat";
Richard Uhler66d874d2015-01-15 09:37:19 -0800740
741 // Create the dex and odex files
742 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000743 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800744
745 // Create the oat file by copying the odex so they are located in the same
746 // place in memory.
747 Copy(odex_location, oat_location);
748
749 // Verify things don't go bad.
750 OatFileAssistant oat_file_assistant(dex_location.c_str(),
Richard Uhlerd1472a22016-04-15 15:18:56 -0700751 oat_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800752
Richard Uhler70a84262016-11-08 16:51:51 +0000753 // kSelfPatchOatNeeded is expected rather than kPatchOatNeeded based on the
754 // assumption that the oat location is more up-to-date than the odex
755 // location, even if they both need relocation.
756 EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded,
Andreas Gampe29d38e72016-03-23 15:31:51 +0000757 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800758
759 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
760 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000761 EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800762 EXPECT_TRUE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000763 EXPECT_EQ(OatFileAssistant::kOatNeedsRelocation, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700764 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800765
766 // Things aren't relocated, so it should fall back to interpreted.
767 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
768 ASSERT_TRUE(oat_file.get() != nullptr);
Richard Uhlerf16d5722015-05-11 09:32:47 -0700769
Richard Uhler66d874d2015-01-15 09:37:19 -0800770 EXPECT_FALSE(oat_file->IsExecutable());
771 std::vector<std::unique_ptr<const DexFile>> dex_files;
772 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
773 EXPECT_EQ(1u, dex_files.size());
774}
775
776// Case: We have a DEX file and a PIC ODEX file, but no OAT file.
Richard Uhler95abd042015-03-24 09:51:28 -0700777// Expect: The status is kNoDexOptNeeded, because PIC needs no relocation.
Richard Uhler66d874d2015-01-15 09:37:19 -0800778TEST_F(OatFileAssistantTest, DexPicOdexNoOat) {
779 std::string dex_location = GetScratchDir() + "/DexPicOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -0700780 std::string odex_location = GetOdexDir() + "/DexPicOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -0800781
782 // Create the dex and odex files
783 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000784 GeneratePicOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800785
786 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700787 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800788
Andreas Gampe29d38e72016-03-23 15:31:51 +0000789 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
790 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
791 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
792 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kEverything));
Richard Uhler66d874d2015-01-15 09:37:19 -0800793
794 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
795 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000796 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -0800797 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000798 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -0700799 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -0800800}
801
Andreas Gampe29d38e72016-03-23 15:31:51 +0000802// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file.
803// Expect: The status is kNoDexOptNeeded, because VerifyAtRuntime contains no code.
804TEST_F(OatFileAssistantTest, DexVerifyAtRuntimeOdexNoOat) {
805 std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
806 std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
David Brazdilce4b0ba2016-01-28 15:05:49 +0000807
808 // Create the dex and odex files
809 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000810 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerifyAtRuntime);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000811
812 // Verify the status.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700813 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
David Brazdilce4b0ba2016-01-28 15:05:49 +0000814
Andreas Gampe29d38e72016-03-23 15:31:51 +0000815 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
816 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kVerifyAtRuntime));
817 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
818 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
David Brazdilce4b0ba2016-01-28 15:05:49 +0000819
820 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
821 EXPECT_TRUE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000822 EXPECT_EQ(OatFileAssistant::kOatUpToDate, oat_file_assistant.OdexFileStatus());
David Brazdilce4b0ba2016-01-28 15:05:49 +0000823 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +0000824 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
David Brazdilce4b0ba2016-01-28 15:05:49 +0000825 EXPECT_TRUE(oat_file_assistant.HasOriginalDexFiles());
826}
827
Richard Uhler66d874d2015-01-15 09:37:19 -0800828// Case: We have a DEX file and up-to-date OAT file for it.
829// Expect: We should load an executable dex file.
830TEST_F(OatFileAssistantTest, LoadOatUpToDate) {
831 std::string dex_location = GetScratchDir() + "/LoadOatUpToDate.jar";
832
833 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000834 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800835
836 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700837 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000838
839 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
840 ASSERT_TRUE(oat_file.get() != nullptr);
841 EXPECT_TRUE(oat_file->IsExecutable());
842 std::vector<std::unique_ptr<const DexFile>> dex_files;
843 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
844 EXPECT_EQ(1u, dex_files.size());
845}
846
847// Case: We have a DEX file and up-to-date interpret-only OAT file for it.
848// Expect: We should still load the oat file as executable.
849TEST_F(OatFileAssistantTest, LoadExecInterpretOnlyOatUpToDate) {
850 std::string dex_location = GetScratchDir() + "/LoadExecInterpretOnlyOatUpToDate.jar";
851
852 Copy(GetDexSrc1(), dex_location);
853 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kInterpretOnly);
854
855 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700856 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800857
858 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
859 ASSERT_TRUE(oat_file.get() != nullptr);
860 EXPECT_TRUE(oat_file->IsExecutable());
861 std::vector<std::unique_ptr<const DexFile>> dex_files;
862 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
863 EXPECT_EQ(1u, dex_files.size());
864}
865
866// Case: We have a DEX file and up-to-date OAT file for it.
867// Expect: Loading non-executable should load the oat non-executable.
868TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) {
869 std::string dex_location = GetScratchDir() + "/LoadNoExecOatUpToDate.jar";
870
871 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000872 GenerateOatForTest(dex_location.c_str(), CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -0800873
874 // Load the oat using an oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700875 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800876
877 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
878 ASSERT_TRUE(oat_file.get() != nullptr);
879 EXPECT_FALSE(oat_file->IsExecutable());
880 std::vector<std::unique_ptr<const DexFile>> dex_files;
881 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
882 EXPECT_EQ(1u, dex_files.size());
883}
884
885// Case: We have a DEX file.
886// Expect: We should load an executable dex file from an alternative oat
887// location.
888TEST_F(OatFileAssistantTest, LoadDexNoAlternateOat) {
889 std::string dex_location = GetScratchDir() + "/LoadDexNoAlternateOat.jar";
890 std::string oat_location = GetScratchDir() + "/LoadDexNoAlternateOat.oat";
891
892 Copy(GetDexSrc1(), dex_location);
893
894 OatFileAssistant oat_file_assistant(
Richard Uhlerd1472a22016-04-15 15:18:56 -0700895 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800896 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700897 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700898 ASSERT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700899 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800900
901 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
902 ASSERT_TRUE(oat_file.get() != nullptr);
903 EXPECT_TRUE(oat_file->IsExecutable());
904 std::vector<std::unique_ptr<const DexFile>> dex_files;
905 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
906 EXPECT_EQ(1u, dex_files.size());
907
908 EXPECT_TRUE(OS::FileExists(oat_location.c_str()));
909
910 // Verify it didn't create an oat in the default location.
Richard Uhlerd1472a22016-04-15 15:18:56 -0700911 OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -0800912 EXPECT_FALSE(ofm.OatFileExists());
913}
914
Richard Uhler8327cf72015-10-13 16:34:59 -0700915// Case: We have a DEX file but can't write the oat file.
916// Expect: We should fail to make the oat file up to date.
917TEST_F(OatFileAssistantTest, LoadDexUnwriteableAlternateOat) {
918 std::string dex_location = GetScratchDir() + "/LoadDexUnwriteableAlternateOat.jar";
919
920 // Make the oat location unwritable by inserting some non-existent
921 // intermediate directories.
922 std::string oat_location = GetScratchDir() + "/foo/bar/LoadDexUnwriteableAlternateOat.oat";
923
924 Copy(GetDexSrc1(), dex_location);
925
926 OatFileAssistant oat_file_assistant(
Richard Uhlerd1472a22016-04-15 15:18:56 -0700927 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
Richard Uhler8327cf72015-10-13 16:34:59 -0700928 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700929 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700930 ASSERT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerd1472a22016-04-15 15:18:56 -0700931 oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhler8327cf72015-10-13 16:34:59 -0700932
933 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
934 ASSERT_TRUE(oat_file.get() == nullptr);
935}
936
937// Case: We don't have a DEX file and can't write the oat file.
938// Expect: We should fail to generate the oat file without crashing.
939TEST_F(OatFileAssistantTest, GenNoDex) {
940 std::string dex_location = GetScratchDir() + "/GenNoDex.jar";
941 std::string oat_location = GetScratchDir() + "/GenNoDex.oat";
942
943 OatFileAssistant oat_file_assistant(
Richard Uhlerd1472a22016-04-15 15:18:56 -0700944 dex_location.c_str(), oat_location.c_str(), kRuntimeISA, true);
Richard Uhler8327cf72015-10-13 16:34:59 -0700945 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -0700946 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -0700947 EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerf4b34872016-04-13 11:03:46 -0700948 oat_file_assistant.GenerateOatFile(&error_msg));
Richard Uhler8327cf72015-10-13 16:34:59 -0700949}
950
Richard Uhler66d874d2015-01-15 09:37:19 -0800951// Turn an absolute path into a path relative to the current working
952// directory.
Andreas Gampeca620d72016-11-08 08:09:33 -0800953static std::string MakePathRelative(const std::string& target) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800954 char buf[MAXPATHLEN];
955 std::string cwd = getcwd(buf, MAXPATHLEN);
956
957 // Split the target and cwd paths into components.
958 std::vector<std::string> target_path;
959 std::vector<std::string> cwd_path;
960 Split(target, '/', &target_path);
961 Split(cwd, '/', &cwd_path);
962
963 // Reverse the path components, so we can use pop_back().
964 std::reverse(target_path.begin(), target_path.end());
965 std::reverse(cwd_path.begin(), cwd_path.end());
966
967 // Drop the common prefix of the paths. Because we reversed the path
968 // components, this becomes the common suffix of target_path and cwd_path.
969 while (!target_path.empty() && !cwd_path.empty()
970 && target_path.back() == cwd_path.back()) {
971 target_path.pop_back();
972 cwd_path.pop_back();
973 }
974
975 // For each element of the remaining cwd_path, add '..' to the beginning
976 // of the target path. Because we reversed the path components, we add to
977 // the end of target_path.
978 for (unsigned int i = 0; i < cwd_path.size(); i++) {
979 target_path.push_back("..");
980 }
981
982 // Reverse again to get the right path order, and join to get the result.
983 std::reverse(target_path.begin(), target_path.end());
984 return Join(target_path, '/');
985}
986
987// Case: Non-absolute path to Dex location.
988// Expect: Not sure, but it shouldn't crash.
989TEST_F(OatFileAssistantTest, NonAbsoluteDexLocation) {
990 std::string abs_dex_location = GetScratchDir() + "/NonAbsoluteDexLocation.jar";
991 Copy(GetDexSrc1(), abs_dex_location);
992
993 std::string dex_location = MakePathRelative(abs_dex_location);
Richard Uhlerd1472a22016-04-15 15:18:56 -0700994 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -0800995
996 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Andreas Gampe29d38e72016-03-23 15:31:51 +0000997 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
998 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -0800999 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +00001000 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001001 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +00001002 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001003}
1004
1005// Case: Very short, non-existent Dex location.
Richard Uhler9b994ea2015-06-24 08:44:19 -07001006// Expect: kNoDexOptNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -08001007TEST_F(OatFileAssistantTest, ShortDexLocation) {
1008 std::string dex_location = "/xx";
1009
Richard Uhlerd1472a22016-04-15 15:18:56 -07001010 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001011
1012 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
Andreas Gampe29d38e72016-03-23 15:31:51 +00001013 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1014 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -08001015 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +00001016 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001017 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +00001018 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler9b994ea2015-06-24 08:44:19 -07001019 EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles());
Richard Uhler66d874d2015-01-15 09:37:19 -08001020
Richard Uhler9b994ea2015-06-24 08:44:19 -07001021 // Trying to make it up to date should have no effect.
Richard Uhler66d874d2015-01-15 09:37:19 -08001022 std::string error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001023 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
Richard Uhler1e860612016-03-30 12:17:55 -07001024 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -07001025 oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhler9b994ea2015-06-24 08:44:19 -07001026 EXPECT_TRUE(error_msg.empty());
Richard Uhler66d874d2015-01-15 09:37:19 -08001027}
1028
1029// Case: Non-standard extension for dex file.
Richard Uhler95abd042015-03-24 09:51:28 -07001030// Expect: The status is kDex2OatNeeded.
Richard Uhler66d874d2015-01-15 09:37:19 -08001031TEST_F(OatFileAssistantTest, LongDexExtension) {
1032 std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";
1033 Copy(GetDexSrc1(), dex_location);
1034
Richard Uhlerd1472a22016-04-15 15:18:56 -07001035 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhler66d874d2015-01-15 09:37:19 -08001036
Andreas Gampe29d38e72016-03-23 15:31:51 +00001037 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
1038 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
Richard Uhler66d874d2015-01-15 09:37:19 -08001039
1040 EXPECT_FALSE(oat_file_assistant.IsInBootClassPath());
1041 EXPECT_FALSE(oat_file_assistant.OdexFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +00001042 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OdexFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001043 EXPECT_FALSE(oat_file_assistant.OatFileExists());
Richard Uhler3e580bc2016-11-08 16:23:07 +00001044 EXPECT_EQ(OatFileAssistant::kOatOutOfDate, oat_file_assistant.OatFileStatus());
Richard Uhler66d874d2015-01-15 09:37:19 -08001045}
1046
1047// A task to generate a dex location. Used by the RaceToGenerate test.
1048class RaceGenerateTask : public Task {
1049 public:
1050 explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location)
Jeff Haof0192c82016-03-28 20:39:50 -07001051 : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr)
Richard Uhler66d874d2015-01-15 09:37:19 -08001052 {}
1053
Roland Levillain4b8f1ec2015-08-26 18:34:03 +01001054 void Run(Thread* self ATTRIBUTE_UNUSED) {
Richard Uhler66d874d2015-01-15 09:37:19 -08001055 // Load the dex files, and save a pointer to the loaded oat file, so that
1056 // we can verify only one oat file was loaded for the dex location.
Richard Uhler66d874d2015-01-15 09:37:19 -08001057 std::vector<std::unique_ptr<const DexFile>> dex_files;
1058 std::vector<std::string> error_msgs;
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001059 const OatFile* oat_file = nullptr;
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001060 dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat(
1061 dex_location_.c_str(),
1062 oat_location_.c_str(),
Mathieu Chartierfbc31082016-01-24 11:59:56 -08001063 /*class_loader*/nullptr,
1064 /*dex_elements*/nullptr,
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001065 &oat_file,
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001066 &error_msgs);
Richard Uhler66d874d2015-01-15 09:37:19 -08001067 CHECK(!dex_files.empty()) << Join(error_msgs, '\n');
Richard Uhler07b3c232015-03-31 15:57:54 -07001068 CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation();
1069 loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile();
Mathieu Chartiere58991b2015-10-13 07:59:34 -07001070 CHECK_EQ(loaded_oat_file_, oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001071 }
1072
1073 const OatFile* GetLoadedOatFile() const {
1074 return loaded_oat_file_;
1075 }
1076
1077 private:
1078 std::string dex_location_;
1079 std::string oat_location_;
1080 const OatFile* loaded_oat_file_;
1081};
1082
1083// Test the case where multiple processes race to generate an oat file.
1084// This simulates multiple processes using multiple threads.
1085//
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001086// We want unique Oat files to be loaded even when there is a race to load.
1087// TODO: The test case no longer tests locking the way it was intended since we now get multiple
1088// copies of the same Oat files mapped at different locations.
Richard Uhler66d874d2015-01-15 09:37:19 -08001089TEST_F(OatFileAssistantTest, RaceToGenerate) {
1090 std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001091 std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat";
Richard Uhler66d874d2015-01-15 09:37:19 -08001092
1093 // We use the lib core dex file, because it's large, and hopefully should
1094 // take a while to generate.
Narayan Kamathd1ef4362015-11-12 11:49:06 +00001095 Copy(GetLibCoreDexFileNames()[0], dex_location);
Richard Uhler66d874d2015-01-15 09:37:19 -08001096
1097 const int kNumThreads = 32;
1098 Thread* self = Thread::Current();
1099 ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads);
1100 std::vector<std::unique_ptr<RaceGenerateTask>> tasks;
1101 for (int i = 0; i < kNumThreads; i++) {
1102 std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location));
1103 thread_pool.AddTask(self, task.get());
1104 tasks.push_back(std::move(task));
1105 }
1106 thread_pool.StartWorkers(self);
1107 thread_pool.Wait(self, true, false);
1108
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001109 // Verify every task got a unique oat file.
1110 std::set<const OatFile*> oat_files;
Richard Uhler66d874d2015-01-15 09:37:19 -08001111 for (auto& task : tasks) {
Mathieu Chartierf9c6fc62015-10-07 11:44:05 -07001112 const OatFile* oat_file = task->GetLoadedOatFile();
1113 EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end());
1114 oat_files.insert(oat_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001115 }
1116}
1117
1118// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is
1119// disabled.
1120// Expect: We should load the odex file non-executable.
1121TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) {
1122 std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001123 std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -08001124
1125 // Create the dex and odex files
1126 Copy(GetDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001127 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001128
1129 // Load the oat using an executable oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -07001130 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001131
1132 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1133 ASSERT_TRUE(oat_file.get() != nullptr);
1134 EXPECT_FALSE(oat_file->IsExecutable());
1135 std::vector<std::unique_ptr<const DexFile>> dex_files;
1136 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1137 EXPECT_EQ(1u, dex_files.size());
1138}
1139
1140// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is
1141// disabled.
1142// Expect: We should load the odex file non-executable.
1143TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) {
1144 std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar";
Richard Uhler63434112015-03-16 14:32:16 -07001145 std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex";
Richard Uhler66d874d2015-01-15 09:37:19 -08001146
1147 // Create the dex and odex files
1148 Copy(GetMultiDexSrc1(), dex_location);
Andreas Gampe29d38e72016-03-23 15:31:51 +00001149 GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Richard Uhler66d874d2015-01-15 09:37:19 -08001150
1151 // Load the oat using an executable oat file assistant.
Richard Uhlerd1472a22016-04-15 15:18:56 -07001152 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true);
Richard Uhler66d874d2015-01-15 09:37:19 -08001153
1154 std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile();
1155 ASSERT_TRUE(oat_file.get() != nullptr);
1156 EXPECT_FALSE(oat_file->IsExecutable());
1157 std::vector<std::unique_ptr<const DexFile>> dex_files;
1158 dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str());
1159 EXPECT_EQ(2u, dex_files.size());
1160}
1161
Richard Uhlerf4b34872016-04-13 11:03:46 -07001162TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) {
1163 std::string dex_location = GetScratchDir() + "/RuntimeCompilerFilterOptionUsed.jar";
1164 Copy(GetDexSrc1(), dex_location);
1165
Richard Uhlerd1472a22016-04-15 15:18:56 -07001166 OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false);
Richard Uhlerf4b34872016-04-13 11:03:46 -07001167
1168 std::string error_msg;
1169 Runtime::Current()->AddCompilerOption("--compiler-filter=interpret-only");
1170 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -07001171 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001172 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1173 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
1174 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded,
1175 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1176
1177 Runtime::Current()->AddCompilerOption("--compiler-filter=speed");
1178 EXPECT_EQ(OatFileAssistant::kUpdateSucceeded,
Richard Uhlerd1472a22016-04-15 15:18:56 -07001179 oat_file_assistant.MakeUpToDate(false, &error_msg)) << error_msg;
Richard Uhlerf4b34872016-04-13 11:03:46 -07001180 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1181 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kInterpretOnly));
1182 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded,
1183 oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed));
1184
1185 Runtime::Current()->AddCompilerOption("--compiler-filter=bogus");
1186 EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted,
Richard Uhlerd1472a22016-04-15 15:18:56 -07001187 oat_file_assistant.MakeUpToDate(false, &error_msg));
Richard Uhlerf4b34872016-04-13 11:03:46 -07001188}
1189
Richard Uhlerb81881d2016-04-19 13:08:04 -07001190TEST(OatFileAssistantUtilsTest, DexLocationToOdexFilename) {
Richard Uhler66d874d2015-01-15 09:37:19 -08001191 std::string error_msg;
1192 std::string odex_file;
1193
Richard Uhlerb81881d2016-04-19 13:08:04 -07001194 EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001195 "/foo/bar/baz.jar", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -07001196 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001197
Richard Uhlerb81881d2016-04-19 13:08:04 -07001198 EXPECT_TRUE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001199 "/foo/bar/baz.funnyext", kArm, &odex_file, &error_msg)) << error_msg;
Richard Uhler63434112015-03-16 14:32:16 -07001200 EXPECT_EQ("/foo/bar/oat/arm/baz.odex", odex_file);
Richard Uhler66d874d2015-01-15 09:37:19 -08001201
Richard Uhlerb81881d2016-04-19 13:08:04 -07001202 EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001203 "nopath.jar", kArm, &odex_file, &error_msg));
Richard Uhlerb81881d2016-04-19 13:08:04 -07001204 EXPECT_FALSE(OatFileAssistant::DexLocationToOdexFilename(
Igor Murashkinb1d8c312015-08-04 11:18:43 -07001205 "/foo/bar/baz_noext", kArm, &odex_file, &error_msg));
Richard Uhler66d874d2015-01-15 09:37:19 -08001206}
1207
Richard Uhler23cedd22015-04-08 13:17:29 -07001208// Verify the dexopt status values from dalvik.system.DexFile
1209// match the OatFileAssistant::DexOptStatus values.
1210TEST_F(OatFileAssistantTest, DexOptStatusValues) {
1211 ScopedObjectAccess soa(Thread::Current());
1212 StackHandleScope<1> hs(soa.Self());
1213 ClassLinker* linker = Runtime::Current()->GetClassLinker();
1214 Handle<mirror::Class> dexfile(
1215 hs.NewHandle(linker->FindSystemClass(soa.Self(), "Ldalvik/system/DexFile;")));
1216 ASSERT_FALSE(dexfile.Get() == nullptr);
1217 linker->EnsureInitialized(soa.Self(), dexfile, true, true);
1218
Mathieu Chartierc7853442015-03-27 14:35:38 -07001219 ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
Richard Uhler23cedd22015-04-08 13:17:29 -07001220 soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
1221 ASSERT_FALSE(no_dexopt_needed == nullptr);
1222 EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1223 EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
1224
Mathieu Chartierc7853442015-03-27 14:35:38 -07001225 ArtField* dex2oat_needed = mirror::Class::FindStaticField(
Richard Uhler23cedd22015-04-08 13:17:29 -07001226 soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
1227 ASSERT_FALSE(dex2oat_needed == nullptr);
1228 EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1229 EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
1230
Mathieu Chartierc7853442015-03-27 14:35:38 -07001231 ArtField* patchoat_needed = mirror::Class::FindStaticField(
Richard Uhler23cedd22015-04-08 13:17:29 -07001232 soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
1233 ASSERT_FALSE(patchoat_needed == nullptr);
1234 EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1235 EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
1236
Mathieu Chartierc7853442015-03-27 14:35:38 -07001237 ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
Richard Uhler23cedd22015-04-08 13:17:29 -07001238 soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
1239 ASSERT_FALSE(self_patchoat_needed == nullptr);
1240 EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
1241 EXPECT_EQ(OatFileAssistant::kSelfPatchOatNeeded, self_patchoat_needed->GetInt(dexfile.Get()));
1242}
Richard Uhler66d874d2015-01-15 09:37:19 -08001243
1244// TODO: More Tests:
Andreas Gampe29d38e72016-03-23 15:31:51 +00001245// * Image checksum change is out of date for kIntepretOnly, but not
1246// kVerifyAtRuntime. But target of kVerifyAtRuntime still says current
1247// kInterpretOnly is out of date.
Richard Uhler66d874d2015-01-15 09:37:19 -08001248// * Test class linker falls back to unquickened dex for DexNoOat
1249// * Test class linker falls back to unquickened dex for MultiDexNoOat
Richard Uhler66d874d2015-01-15 09:37:19 -08001250// * Test using secondary isa
Richard Uhler66d874d2015-01-15 09:37:19 -08001251// * Test for status of oat while oat is being generated (how?)
1252// * Test case where 32 and 64 bit boot class paths differ,
1253// and we ask IsInBootClassPath for a class in exactly one of the 32 or
1254// 64 bit boot class paths.
1255// * Test unexpected scenarios (?):
1256// - Dex is stripped, don't have odex.
1257// - Oat file corrupted after status check, before reload unexecutable
1258// because it's unrelocated and no dex2oat
Calin Juravleb077e152016-02-18 18:47:37 +00001259// * Test unrelocated specific target compilation type can be relocated to
1260// make it up to date.
Richard Uhler66d874d2015-01-15 09:37:19 -08001261
1262} // namespace art