blob: f7859ea0bcdf68e2116cb6a81a758d619b096559 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Brian Carlstrom934486c2011-07-12 23:42:50 -070016
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_COMMON_TEST_H_
18#define ART_RUNTIME_COMMON_TEST_H_
19
Brian Carlstromb0460ea2011-07-29 10:08:05 -070020#include <dirent.h>
Elliott Hughes0af55432011-08-17 18:37:28 -070021#include <dlfcn.h>
Brian Carlstrom27ec9612011-09-19 20:20:38 -070022#include <sys/mman.h>
Brian Carlstromb0460ea2011-07-29 10:08:05 -070023#include <sys/stat.h>
24#include <sys/types.h>
Dave Allison70202782013-10-22 17:52:19 -070025#include <fstream>
Brian Carlstromb0460ea2011-07-29 10:08:05 -070026
Elliott Hughesf66330a2012-12-12 17:27:00 -080027#include "../../external/icu4c/common/unicode/uvernum.h"
Sebastien Hertz102a8f22013-12-18 11:41:30 +010028#include "../compiler/dex/quick/dex_file_to_method_inliner_map.h"
Vladimir Markoc7f83202014-01-24 17:55:18 +000029#include "../compiler/dex/verification_results.h"
Sebastien Hertz102a8f22013-12-18 11:41:30 +010030#include "../compiler/driver/compiler_driver.h"
Elliott Hughes76160052012-12-12 16:31:20 -080031#include "base/macros.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080032#include "base/stl_util.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080033#include "base/stringprintf.h"
Elliott Hughes76160052012-12-12 16:31:20 -080034#include "base/unix_file/fd_file.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070035#include "class_linker.h"
Vladimir Marko95a4de72013-12-18 10:29:11 +000036#include "compiler_callbacks.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070037#include "dex_file-inl.h"
Ian Rogers7655f292013-07-29 11:07:13 -070038#include "entrypoints/entrypoint_utils.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070039#include "gc/heap.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070040#include "gtest/gtest.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070041#include "instruction_set.h"
Ian Rogers0f40ac32013-08-13 22:10:30 -070042#include "interpreter/interpreter.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080043#include "mirror/class_loader.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070044#include "oat_file.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080045#include "object_utils.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070046#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070047#include "runtime.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070048#include "scoped_thread_state_change.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080049#include "ScopedLocalRef.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070050#include "thread.h"
Ian Rogersef7d42f2014-01-06 12:55:46 -080051#include "utils.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070052#include "UniquePtr.h"
Vladimir Marko95a4de72013-12-18 10:29:11 +000053#include "verifier/method_verifier.h"
54#include "verifier/method_verifier-inl.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070055#include "well_known_classes.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070056
Brian Carlstrom934486c2011-07-12 23:42:50 -070057namespace art {
58
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080059static const byte kBase64Map[256] = {
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
64 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
65 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Brian Carlstrom7934ac22013-07-26 10:54:15 -070066 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
67 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080068 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Brian Carlstrom7934ac22013-07-26 10:54:15 -070069 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
70 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080071 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
72 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
73 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
74 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
76 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
77 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
78 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
79 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
80 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
81 255, 255, 255, 255
82};
83
84byte* DecodeBase64(const char* src, size_t* dst_size) {
85 std::vector<byte> tmp;
Elliott Hughesa21039c2012-06-21 12:09:25 -070086 uint32_t t = 0, y = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080087 int g = 3;
88 for (size_t i = 0; src[i] != '\0'; ++i) {
89 byte c = kBase64Map[src[i] & 0xFF];
90 if (c == 255) continue;
91 // the final = symbols are read and used to trim the remaining bytes
92 if (c == 254) {
93 c = 0;
94 // prevent g < 0 which would potentially allow an overflow later
95 if (--g < 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -070096 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080097 return NULL;
98 }
99 } else if (g != 3) {
100 // we only allow = to be at the end
Brian Carlstrom51477332012-03-25 20:20:26 -0700101 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800102 return NULL;
103 }
104 t = (t << 6) | c;
105 if (++y == 4) {
106 tmp.push_back((t >> 16) & 255);
107 if (g > 1) {
108 tmp.push_back((t >> 8) & 255);
109 }
110 if (g > 2) {
111 tmp.push_back(t & 255);
112 }
113 y = t = 0;
114 }
115 }
116 if (y != 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -0700117 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800118 return NULL;
119 }
120 UniquePtr<byte[]> dst(new byte[tmp.size()]);
121 if (dst_size != NULL) {
122 *dst_size = tmp.size();
Brian Carlstrom51477332012-03-25 20:20:26 -0700123 } else {
124 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800125 }
126 std::copy(tmp.begin(), tmp.end(), dst.get());
127 return dst.release();
128}
129
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700130class ScratchFile {
131 public:
132 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700133 filename_ = getenv("ANDROID_DATA");
134 filename_ += "/TmpFile-XXXXXX";
Elliott Hughes76160052012-12-12 16:31:20 -0800135 int fd = mkstemp(&filename_[0]);
136 CHECK_NE(-1, fd);
137 file_.reset(new File(fd, GetFilename()));
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700138 }
139
140 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700141 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700142 CHECK_EQ(0, unlink_result);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700143 }
144
Brian Carlstroma004aa92012-02-08 18:05:09 -0800145 const std::string& GetFilename() const {
146 return filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700147 }
148
Elliott Hughes234da572011-11-03 22:13:06 -0700149 File* GetFile() const {
150 return file_.get();
151 }
152
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700153 int GetFd() const {
Elliott Hughes76160052012-12-12 16:31:20 -0800154 return file_->Fd();
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700155 }
156
157 private:
Elliott Hughes34023802011-08-30 12:06:17 -0700158 std::string filename_;
Elliott Hughes234da572011-11-03 22:13:06 -0700159 UniquePtr<File> file_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700160};
161
Dave Allison70202782013-10-22 17:52:19 -0700162#if defined(__arm__)
163
Elliott Hughesee287732014-01-30 12:09:13 -0800164#include <sys/ucontext.h>
Dave Allison70202782013-10-22 17:52:19 -0700165
166// A signal handler called when have an illegal instruction. We record the fact in
167// a global boolean and then increment the PC in the signal context to return to
168// the next instruction. We know the instruction is an sdiv (4 bytes long).
169static void baddivideinst(int signo, siginfo *si, void *data) {
170 (void)signo;
171 (void)si;
172 struct ucontext *uc = (struct ucontext *)data;
173 struct sigcontext *sc = &uc->uc_mcontext;
174 sc->arm_r0 = 0; // set R0 to #0 to signal error
175 sc->arm_pc += 4; // skip offending instruction
176}
177
178// This is in arch/arm/arm_sdiv.S. It does the following:
179// mov r1,#1
180// sdiv r0,r1,r1
181// bx lr
182//
183// the result will be the value 1 if sdiv is supported. If it is not supported
184// a SIGILL signal will be raised and the signal handler (baddivideinst) called.
185// The signal handler sets r0 to #0 and then increments pc beyond the failed instruction.
186// Thus if the instruction is not supported, the result of this function will be #0
187
188extern "C" bool CheckForARMSDIVInstruction();
189
190static InstructionSetFeatures GuessInstructionFeatures() {
191 InstructionSetFeatures f;
192
193 // Uncomment this for processing of /proc/cpuinfo.
194 if (false) {
195 // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
196 // the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
197 std::ifstream in("/proc/cpuinfo");
198 if (in) {
199 while (!in.eof()) {
200 std::string line;
201 std::getline(in, line);
202 if (!in.eof()) {
203 if (line.find("Features") != std::string::npos) {
204 if (line.find("idivt") != std::string::npos) {
205 f.SetHasDivideInstruction(true);
206 }
207 }
208 }
209 in.close();
210 }
211 } else {
212 LOG(INFO) << "Failed to open /proc/cpuinfo";
213 }
214 }
215
216 // See if have a sdiv instruction. Register a signal handler and try to execute
217 // an sdiv instruction. If we get a SIGILL then it's not supported. We can't use
218 // the /proc/cpuinfo method for this because Krait devices don't always put the idivt
219 // feature in the list.
220 struct sigaction sa, osa;
221 sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
222 sa.sa_sigaction = baddivideinst;
223 sigaction(SIGILL, &sa, &osa);
224
225 if (CheckForARMSDIVInstruction()) {
226 f.SetHasDivideInstruction(true);
227 }
228
229 // Restore the signal handler.
230 sigaction(SIGILL, &osa, NULL);
231
232 // Other feature guesses in here.
233 return f;
234}
235
236#endif
237
238// Given a set of instruction features from the build, parse it. The
239// input 'str' is a comma separated list of feature names. Parse it and
240// return the InstructionSetFeatures object.
241static InstructionSetFeatures ParseFeatureList(std::string str) {
Dave Allison70202782013-10-22 17:52:19 -0700242 InstructionSetFeatures result;
243 typedef std::vector<std::string> FeatureList;
244 FeatureList features;
245 Split(str, ',', features);
246 for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
247 std::string feature = Trim(*i);
248 if (feature == "default") {
249 // Nothing to do.
250 } else if (feature == "div") {
251 // Supports divide instruction.
252 result.SetHasDivideInstruction(true);
253 } else if (feature == "nodiv") {
254 // Turn off support for divide instruction.
255 result.SetHasDivideInstruction(false);
256 } else {
257 LOG(FATAL) << "Unknown instruction set feature: '" << feature << "'";
258 }
259 }
260 // Others...
261 return result;
262}
263
Brian Carlstromf734cf52011-08-17 16:28:14 -0700264class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700265 public:
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700266 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700267 CHECK_NE(code.size(), 0U);
268 MakeExecutable(&code[0], code.size());
269 }
270
Ian Rogers0177e532014-02-11 16:30:46 -0800271 // Create an OatMethod based on pointers (for unit tests).
Brian Carlstromae826982011-11-09 01:33:42 -0800272 OatFile::OatMethod CreateOatMethod(const void* code,
273 const size_t frame_size_in_bytes,
274 const uint32_t core_spill_mask,
275 const uint32_t fp_spill_mask,
Ian Rogers1809a722013-08-09 22:05:32 -0700276 const uint8_t* mapping_table,
277 const uint8_t* vmap_table,
Jeff Hao74180ca2013-03-27 15:29:11 -0700278 const uint8_t* gc_map) {
Ian Rogers0177e532014-02-11 16:30:46 -0800279 const byte* base;
280 uint32_t code_offset, mapping_table_offset, vmap_table_offset, gc_map_offset;
281 if (mapping_table == nullptr && vmap_table == nullptr && gc_map == nullptr) {
282 base = reinterpret_cast<const byte*>(code); // Base of data points at code.
283 base -= kPointerSize; // Move backward so that code_offset != 0.
284 code_offset = kPointerSize;
285 mapping_table_offset = 0;
286 vmap_table_offset = 0;
287 gc_map_offset = 0;
288 } else {
289 // TODO: 64bit support.
290 base = nullptr; // Base of data in oat file, ie 0.
291 code_offset = PointerToLowMemUInt32(code);
292 mapping_table_offset = PointerToLowMemUInt32(mapping_table);
293 vmap_table_offset = PointerToLowMemUInt32(vmap_table);
294 gc_map_offset = PointerToLowMemUInt32(gc_map);
295 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800296 return OatFile::OatMethod(base,
297 code_offset,
298 frame_size_in_bytes,
299 core_spill_mask,
300 fp_spill_mask,
301 mapping_table_offset,
302 vmap_table_offset,
303 gc_map_offset);
Brian Carlstromae826982011-11-09 01:33:42 -0800304 }
305
Brian Carlstromea46f952013-07-30 01:26:50 -0700306 void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800307 CHECK(method != nullptr);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700308
Ian Rogersef7d42f2014-01-06 12:55:46 -0800309 const CompiledMethod* compiled_method = nullptr;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700310 if (!method->IsAbstract()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800311 mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700312 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogersf3e98552013-03-20 15:49:49 -0700313 compiled_method =
Brian Carlstrom51c24672013-07-11 16:00:56 -0700314 compiler_driver_->GetCompiledMethod(MethodReference(&dex_file,
315 method->GetDexMethodIndex()));
Ian Rogersf3e98552013-03-20 15:49:49 -0700316 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800317 if (compiled_method != nullptr) {
318 const std::vector<uint8_t>* code = compiled_method->GetQuickCode();
319 if (code == nullptr) {
320 code = compiled_method->GetPortableCode();
321 }
322 MakeExecutable(*code);
323 const void* method_code = CompiledMethod::CodePointer(&(*code)[0],
Logan Chien971bf3f2012-05-01 15:47:55 +0800324 compiled_method->GetInstructionSet());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700325 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800326 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
327 compiled_method->GetFrameSizeInBytes(),
328 compiled_method->GetCoreSpillMask(),
329 compiled_method->GetFpSpillMask(),
330 &compiled_method->GetMappingTable()[0],
331 &compiled_method->GetVmapTable()[0],
Jeff Hao74180ca2013-03-27 15:29:11 -0700332 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800333 oat_method.LinkMethod(method);
Ian Rogers0f40ac32013-08-13 22:10:30 -0700334 method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700335 } else {
Ian Rogers848871b2013-08-05 10:56:33 -0700336 // No code? You must mean to go into the interpreter.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800337 const void* method_code = kUsePortableCompiler ? GetPortableToInterpreterBridge()
338 : GetQuickToInterpreterBridge();
Brian Carlstromae826982011-11-09 01:33:42 -0800339 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
340 kStackAlignment,
341 0,
342 0,
343 NULL,
344 NULL,
Jeff Hao74180ca2013-03-27 15:29:11 -0700345 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800346 oat_method.LinkMethod(method);
Ian Rogers0f40ac32013-08-13 22:10:30 -0700347 method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700348 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800349 // Create bridges to transition between different kinds of compiled bridge.
350 if (method->GetEntryPointFromPortableCompiledCode() == nullptr) {
351 method->SetEntryPointFromPortableCompiledCode(GetPortableToQuickBridge());
352 } else {
353 CHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
354 method->SetEntryPointFromQuickCompiledCode(GetQuickToPortableBridge());
355 method->SetIsPortableCompiled();
356 }
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700357 }
358
359 static void MakeExecutable(const void* code_start, size_t code_length) {
360 CHECK(code_start != NULL);
361 CHECK_NE(code_length, 0U);
362 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700363 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700364 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700365 uintptr_t len = limit - base;
366 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800367 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800368
Ian Rogers16341552011-10-10 11:33:06 -0700369 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800370 // Only uses __builtin___clear_cache if GCC >= 4.3.3
371#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700372 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800373#else
Brian Carlstrom6f485c62013-07-18 15:35:35 -0700374 LOG(FATAL) << "UNIMPLEMENTED: cache flush";
Shih-wei Liao24782c62012-01-08 12:46:11 -0800375#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700376 }
377
Elliott Hughes76160052012-12-12 16:31:20 -0800378 static void SetEnvironmentVariables(std::string& android_data) {
379 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700380 // $ANDROID_ROOT is set on the device, but not on the host.
381 // We need to set this so that icu4c can find its locale data.
382 std::string root;
383 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800384#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700385 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800386#elif defined(__APPLE__)
387 root += "/out/host/darwin-x86";
388#else
389#error unsupported OS
390#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700391 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700392 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700393 }
394
Brian Carlstrom7675e162013-06-10 16:18:04 -0700395 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
396 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/dalvik-cache/art-data-XXXXXX");
Elliott Hughes76160052012-12-12 16:31:20 -0800397 if (mkdtemp(&android_data[0]) == NULL) {
398 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700399 }
Elliott Hughes76160052012-12-12 16:31:20 -0800400 setenv("ANDROID_DATA", android_data.c_str(), 1);
401 }
402
Ian Rogers1d99e452014-01-02 17:36:41 -0800403 void MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name)
404 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
405 std::string class_descriptor(DotToDescriptor(class_name));
406 SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
407 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
408 CHECK(klass != NULL) << "Class not found " << class_name;
409 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
410 MakeExecutable(klass->GetDirectMethod(i));
411 }
412 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
413 MakeExecutable(klass->GetVirtualMethod(i));
414 }
415 }
416
Elliott Hughes76160052012-12-12 16:31:20 -0800417 protected:
418 static bool IsHost() {
419 return (getenv("ANDROID_BUILD_TOP") != NULL);
420 }
421
422 virtual void SetUp() {
423 SetEnvironmentVariables(android_data_);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700424 dalvik_cache_.append(android_data_.c_str());
425 dalvik_cache_.append("/dalvik-cache");
426 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700427 ASSERT_EQ(mkdir_result, 0);
428
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700429 std::string error_msg;
430 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName().c_str(),
431 GetLibCoreDexFileName().c_str(), &error_msg);
Ian Rogers33e95662013-05-20 20:29:14 -0700432 if (java_lang_dex_file_ == NULL) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700433 LOG(FATAL) << "Could not open .dex file '" << GetLibCoreDexFileName() << "': "
434 << error_msg << "\n";
Ian Rogers33e95662013-05-20 20:29:14 -0700435 }
Brian Carlstroma004aa92012-02-08 18:05:09 -0800436 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700437
Ian Rogers1d54e732013-05-02 21:10:01 -0700438 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
439 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800440
Vladimir Marko95a4de72013-12-18 10:29:11 +0000441 // TODO: make selectable
Ian Rogersef7d42f2014-01-06 12:55:46 -0800442 CompilerBackend compiler_backend = kUsePortableCompiler ? kPortable : kQuick;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000443
Vladimir Markoc7f83202014-01-24 17:55:18 +0000444 verification_results_.reset(new VerificationResults);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000445 method_inliner_map_.reset(compiler_backend == kQuick ? new DexFileToMethodInlinerMap : nullptr);
Vladimir Markoc7f83202014-01-24 17:55:18 +0000446 callbacks_.Reset(verification_results_.get(), method_inliner_map_.get());
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700447 Runtime::Options options;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000448 options.push_back(std::make_pair("compilercallbacks", static_cast<CompilerCallbacks*>(&callbacks_)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800449 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700450 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800451 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
452 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstromdf629502013-07-17 22:39:56 -0700453 if (!Runtime::Create(options, false)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700454 LOG(FATAL) << "Failed to create runtime";
455 return;
456 }
457 runtime_.reset(Runtime::Current());
458 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
459 // give it away now and then switch to a more managable ScopedObjectAccess.
460 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
Ian Rogers1d54e732013-05-02 21:10:01 -0700461 {
462 ScopedObjectAccess soa(Thread::Current());
463 ASSERT_TRUE(runtime_.get() != NULL);
464 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700465
Ian Rogers1d54e732013-05-02 21:10:01 -0700466 InstructionSet instruction_set = kNone;
Dave Allison70202782013-10-22 17:52:19 -0700467
Brian Carlstrom1bd2ceb2013-11-06 00:29:48 -0800468 // Take the default set of instruction features from the build.
Dave Allison70202782013-10-22 17:52:19 -0700469 InstructionSetFeatures instruction_set_features =
Brian Carlstrom1bd2ceb2013-11-06 00:29:48 -0800470 ParseFeatureList(STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES));
Dave Allison70202782013-10-22 17:52:19 -0700471
jeffhaoc0228b82012-08-29 18:15:05 -0700472#if defined(__arm__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700473 instruction_set = kThumb2;
Dave Allison70202782013-10-22 17:52:19 -0700474 InstructionSetFeatures runtime_features = GuessInstructionFeatures();
475
476 // for ARM, do a runtime check to make sure that the features we are passed from
477 // the build match the features we actually determine at runtime.
478 ASSERT_EQ(instruction_set_features, runtime_features);
jeffhaoc0228b82012-08-29 18:15:05 -0700479#elif defined(__mips__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700480 instruction_set = kMips;
jeffhaoc0228b82012-08-29 18:15:05 -0700481#elif defined(__i386__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700482 instruction_set = kX86;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800483#elif defined(__x86_64__)
484 instruction_set = kX86_64;
Ian Rogers0177e532014-02-11 16:30:46 -0800485 // TODO: x86_64 compilation support.
486 runtime_->SetCompilerFilter(Runtime::kInterpretOnly);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700487#endif
buzbeec531cef2012-10-18 07:09:20 -0700488
Ian Rogers1d54e732013-05-02 21:10:01 -0700489 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
490 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
491 if (!runtime_->HasCalleeSaveMethod(type)) {
492 runtime_->SetCalleeSaveMethod(
493 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
494 }
495 }
496 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000497 timer_.reset(new CumulativeLogger("Compilation times"));
Vladimir Markoc7f83202014-01-24 17:55:18 +0000498 compiler_driver_.reset(new CompilerDriver(verification_results_.get(),
Sebastien Hertz102a8f22013-12-18 11:41:30 +0100499 method_inliner_map_.get(),
500 compiler_backend, instruction_set,
Dave Allison70202782013-10-22 17:52:19 -0700501 instruction_set_features,
Ian Rogers1d54e732013-05-02 21:10:01 -0700502 true, new CompilerDriver::DescriptorSet,
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000503 2, true, true, timer_.get()));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700504 }
Brian Carlstrom96391602013-06-13 19:49:50 -0700505 // We typically don't generate an image in unit tests, disable this optimization by default.
506 compiler_driver_->SetSupportBootImageFixup(false);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700507
Ian Rogers1d54e732013-05-02 21:10:01 -0700508 // We're back in native, take the opportunity to initialize well known classes.
Brian Carlstromea46f952013-07-30 01:26:50 -0700509 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700510 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
511 // pool is created by the runtime.
512 runtime_->GetHeap()->CreateThreadPool();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700513 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700514 }
515
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700516 virtual void TearDown() {
517 const char* android_data = getenv("ANDROID_DATA");
518 ASSERT_TRUE(android_data != NULL);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700519 DIR* dir = opendir(dalvik_cache_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700520 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700521 dirent* e;
522 while ((e = readdir(dir)) != NULL) {
523 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700524 continue;
525 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700526 std::string filename(dalvik_cache_);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700527 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700528 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700529 int unlink_result = unlink(filename.c_str());
530 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400531 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700532 closedir(dir);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700533 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700534 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700535 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700536 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700537
538 // icu4c has a fixed 10-element array "gCommonICUDataArray".
539 // If we run > 10 tests, we fill that array and u_setCommonData fails.
540 // There's a function to clear the array, but it's not public...
541 typedef void (*IcuCleanupFn)();
542 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
543 CHECK(sym != NULL);
544 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
545 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700546
Ian Rogers1212a022013-03-04 10:48:41 -0800547 compiler_driver_.reset();
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000548 timer_.reset();
Vladimir Marko95a4de72013-12-18 10:29:11 +0000549 callbacks_.Reset(nullptr, nullptr);
550 method_inliner_map_.reset();
Vladimir Markoc7f83202014-01-24 17:55:18 +0000551 verification_results_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800552 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700553
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800554 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700555 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400556
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700557 std::string GetLibCoreDexFileName() {
Brian Carlstrom3b010aa2013-06-25 23:06:36 -0700558 return GetDexFileName("core-libart");
Brian Carlstrom265091e2013-01-30 14:08:26 -0800559 }
560
561 std::string GetDexFileName(const std::string& jar_prefix) {
Elliott Hughes76160052012-12-12 16:31:20 -0800562 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700563 const char* host_dir = getenv("ANDROID_HOST_OUT");
564 CHECK(host_dir != NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800565 return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700566 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800567 return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700568 }
569
Brian Carlstrom3f47c122013-03-07 00:02:40 -0800570 std::string GetTestAndroidRoot() {
571 if (IsHost()) {
572 const char* host_dir = getenv("ANDROID_HOST_OUT");
573 CHECK(host_dir != NULL);
574 return host_dir;
575 }
576 return GetAndroidRoot();
577 }
578
Ian Rogers33e95662013-05-20 20:29:14 -0700579 const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700580 CHECK(name != NULL);
581 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800582 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700583 filename += getenv("ANDROID_HOST_OUT");
584 filename += "/framework/";
585 } else {
586 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700587 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700588 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700589 filename += name;
590 filename += ".jar";
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700591 std::string error_msg;
592 const DexFile* dex_file = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg);
593 CHECK(dex_file != NULL) << "Failed to open '" << filename << "': " << error_msg;
Brian Carlstrome0948e12013-08-29 09:36:15 -0700594 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
595 CHECK(dex_file->IsReadOnly());
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800596 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700597 return dex_file;
598 }
599
Ian Rogers33e95662013-05-20 20:29:14 -0700600 jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700601 const DexFile* dex_file = OpenTestDexFile(dex_name);
602 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700603 class_linker_->RegisterDexFile(*dex_file);
604 std::vector<const DexFile*> class_path;
605 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700606 ScopedObjectAccessUnchecked soa(Thread::Current());
607 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
608 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
609 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800610 soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700611 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
612 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700613 }
614
Ian Rogers33e95662013-05-20 20:29:14 -0700615 void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
616 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800617 std::string class_descriptor(DotToDescriptor(class_name));
Mathieu Chartier590fee92013-09-13 13:46:47 -0700618 SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
619 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700620 CHECK(klass != NULL) << "Class not found " << class_name;
621 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
622 CompileMethod(klass->GetDirectMethod(i));
623 }
624 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
625 CompileMethod(klass->GetVirtualMethod(i));
626 }
627 }
628
Brian Carlstromea46f952013-07-30 01:26:50 -0700629 void CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700630 CHECK(method != NULL);
Ian Rogers5fe9af72013-11-14 00:17:20 -0800631 TimingLogger timings("CommonTest::CompileMethod", false, false);
Anwar Ghuloumbe576f42013-07-25 17:32:40 -0700632 timings.StartSplit("CompileOne");
Brian Carlstrom45602482013-07-21 22:07:55 -0700633 compiler_driver_->CompileOne(method, timings);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700634 MakeExecutable(method);
Ian Rogers5fe9af72013-11-14 00:17:20 -0800635 timings.EndSplit();
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700636 }
637
Mathieu Chartier590fee92013-09-13 13:46:47 -0700638 void CompileDirectMethod(SirtRef<mirror::ClassLoader>& class_loader, const char* class_name,
639 const char* method_name, const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700640 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800641 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800642 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700643 CHECK(klass != NULL) << "Class not found " << class_name;
Brian Carlstromea46f952013-07-30 01:26:50 -0700644 mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700645 CHECK(method != NULL) << "Direct method not found: "
646 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700647 CompileMethod(method);
648 }
649
Mathieu Chartier590fee92013-09-13 13:46:47 -0700650 void CompileVirtualMethod(SirtRef<mirror::ClassLoader>& class_loader, const char* class_name,
651 const char* method_name, const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700652 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800653 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800654 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700655 CHECK(klass != NULL) << "Class not found " << class_name;
Brian Carlstromea46f952013-07-30 01:26:50 -0700656 mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700657 CHECK(method != NULL) << "Virtual method not found: "
658 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700659 CompileMethod(method);
660 }
661
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800662 void ReserveImageSpace() {
663 // Reserve where the image will be loaded up front so that other parts of test set up don't
664 // accidentally end up colliding with the fixed memory address when we need to load the image.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700665 std::string error_msg;
Brian Carlstrom2d888622013-07-18 17:02:00 -0700666 image_reservation_.reset(MemMap::MapAnonymous("image reservation",
667 reinterpret_cast<byte*>(ART_BASE_ADDRESS),
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800668 (size_t)100 * 1024 * 1024, // 100MB
Ian Rogersef7d42f2014-01-06 12:55:46 -0800669 PROT_NONE,
670 false /* no need for 4gb flag with fixed mmap*/,
671 &error_msg));
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700672 CHECK(image_reservation_.get() != nullptr) << error_msg;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800673 }
674
675 void UnreserveImageSpace() {
676 image_reservation_.reset();
677 }
678
Vladimir Marko95a4de72013-12-18 10:29:11 +0000679 class TestCompilerCallbacks : public CompilerCallbacks {
680 public:
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000681 TestCompilerCallbacks() : verification_results_(nullptr), method_inliner_map_(nullptr) {}
Vladimir Marko95a4de72013-12-18 10:29:11 +0000682
Vladimir Markoc7f83202014-01-24 17:55:18 +0000683 void Reset(VerificationResults* verification_results,
Vladimir Marko95a4de72013-12-18 10:29:11 +0000684 DexFileToMethodInlinerMap* method_inliner_map) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000685 verification_results_ = verification_results;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000686 method_inliner_map_ = method_inliner_map;
687 }
688
689 virtual bool MethodVerified(verifier::MethodVerifier* verifier)
690 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000691 CHECK(verification_results_);
692 bool result = verification_results_->ProcessVerifiedMethod(verifier);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000693 if (result && method_inliner_map_ != nullptr) {
694 MethodReference ref = verifier->GetMethodReference();
695 method_inliner_map_->GetMethodInliner(ref.dex_file)
Vladimir Marko2bc47802014-02-10 09:43:07 +0000696 ->AnalyseMethodCode(verifier);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000697 }
698 return result;
699 }
700 virtual void ClassRejected(ClassReference ref) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000701 verification_results_->AddRejectedClass(ref);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000702 }
703
704 private:
Vladimir Markoc7f83202014-01-24 17:55:18 +0000705 VerificationResults* verification_results_;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000706 DexFileToMethodInlinerMap* method_inliner_map_;
707 };
708
Elliott Hughes34023802011-08-30 12:06:17 -0700709 std::string android_data_;
Brian Carlstrom7675e162013-06-10 16:18:04 -0700710 std::string dalvik_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800711 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700712 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700713 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700714 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700715 ClassLinker* class_linker_;
Vladimir Markoc7f83202014-01-24 17:55:18 +0000716 UniquePtr<VerificationResults> verification_results_;
Sebastien Hertz102a8f22013-12-18 11:41:30 +0100717 UniquePtr<DexFileToMethodInlinerMap> method_inliner_map_;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000718 TestCompilerCallbacks callbacks_;
Ian Rogers1212a022013-03-04 10:48:41 -0800719 UniquePtr<CompilerDriver> compiler_driver_;
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000720 UniquePtr<CumulativeLogger> timer_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700721
722 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800723 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800724 UniquePtr<MemMap> image_reservation_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700725};
726
Elliott Hughesb264f082012-04-06 17:10:10 -0700727// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
728// rather than aborting, so be careful!
729class CheckJniAbortCatcher {
730 public:
731 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
732 vm_->check_jni_abort_hook = Hook;
733 vm_->check_jni_abort_hook_data = &actual_;
734 }
735
736 ~CheckJniAbortCatcher() {
737 vm_->check_jni_abort_hook = NULL;
738 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700739 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700740 }
741
742 void Check(const char* expected_text) {
743 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
744 << "Expected to find: " << expected_text << "\n"
745 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700746 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700747 }
748
749 private:
750 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700751 // We use += because when we're hooking the aborts like this, multiple problems can be found.
752 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700753 }
754
755 JavaVMExt* vm_;
756 std::string actual_;
757
758 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
759};
760
Brian Carlstrom265091e2013-01-30 14:08:26 -0800761// TODO: These tests were disabled for portable when we went to having
762// MCLinker link LLVM ELF output because we no longer just have code
763// blobs in memory. We'll need to dlopen to load and relocate
764// temporary output to resurrect these tests.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800765#define TEST_DISABLED_FOR_PORTABLE() \
766 if (kUsePortableCompiler) { \
767 printf("WARNING: TEST DISABLED FOR PORTABLE\n"); \
768 return; \
769 }
770
Brian Carlstrom934486c2011-07-12 23:42:50 -0700771} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700772
773namespace std {
774
775// TODO: isn't gtest supposed to be able to print STL types for itself?
776template <typename T>
777std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700778 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700779 return os;
780}
781
782} // namespace std
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700783
784#endif // ART_RUNTIME_COMMON_TEST_H_