blob: 5e6354e02635df36ad9320f4b162f77cd87831f7 [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"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070051#include "UniquePtr.h"
Vladimir Marko95a4de72013-12-18 10:29:11 +000052#include "verifier/method_verifier.h"
53#include "verifier/method_verifier-inl.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070054#include "well_known_classes.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070055
Brian Carlstrom934486c2011-07-12 23:42:50 -070056namespace art {
57
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080058static const byte kBase64Map[256] = {
59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
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, 62, 255, 255, 255, 63,
63 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
64 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Brian Carlstrom7934ac22013-07-26 10:54:15 -070065 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
66 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080067 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Brian Carlstrom7934ac22013-07-26 10:54:15 -070068 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
69 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080070 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
71 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
81};
82
83byte* DecodeBase64(const char* src, size_t* dst_size) {
84 std::vector<byte> tmp;
Elliott Hughesa21039c2012-06-21 12:09:25 -070085 uint32_t t = 0, y = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080086 int g = 3;
87 for (size_t i = 0; src[i] != '\0'; ++i) {
88 byte c = kBase64Map[src[i] & 0xFF];
89 if (c == 255) continue;
90 // the final = symbols are read and used to trim the remaining bytes
91 if (c == 254) {
92 c = 0;
93 // prevent g < 0 which would potentially allow an overflow later
94 if (--g < 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -070095 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080096 return NULL;
97 }
98 } else if (g != 3) {
99 // we only allow = to be at the end
Brian Carlstrom51477332012-03-25 20:20:26 -0700100 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800101 return NULL;
102 }
103 t = (t << 6) | c;
104 if (++y == 4) {
105 tmp.push_back((t >> 16) & 255);
106 if (g > 1) {
107 tmp.push_back((t >> 8) & 255);
108 }
109 if (g > 2) {
110 tmp.push_back(t & 255);
111 }
112 y = t = 0;
113 }
114 }
115 if (y != 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -0700116 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800117 return NULL;
118 }
119 UniquePtr<byte[]> dst(new byte[tmp.size()]);
120 if (dst_size != NULL) {
121 *dst_size = tmp.size();
Brian Carlstrom51477332012-03-25 20:20:26 -0700122 } else {
123 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800124 }
125 std::copy(tmp.begin(), tmp.end(), dst.get());
126 return dst.release();
127}
128
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700129class ScratchFile {
130 public:
131 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700132 filename_ = getenv("ANDROID_DATA");
133 filename_ += "/TmpFile-XXXXXX";
Elliott Hughes76160052012-12-12 16:31:20 -0800134 int fd = mkstemp(&filename_[0]);
135 CHECK_NE(-1, fd);
136 file_.reset(new File(fd, GetFilename()));
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700137 }
138
139 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700140 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700141 CHECK_EQ(0, unlink_result);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700142 }
143
Brian Carlstroma004aa92012-02-08 18:05:09 -0800144 const std::string& GetFilename() const {
145 return filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700146 }
147
Elliott Hughes234da572011-11-03 22:13:06 -0700148 File* GetFile() const {
149 return file_.get();
150 }
151
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700152 int GetFd() const {
Elliott Hughes76160052012-12-12 16:31:20 -0800153 return file_->Fd();
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700154 }
155
156 private:
Elliott Hughes34023802011-08-30 12:06:17 -0700157 std::string filename_;
Elliott Hughes234da572011-11-03 22:13:06 -0700158 UniquePtr<File> file_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700159};
160
Dave Allison70202782013-10-22 17:52:19 -0700161#if defined(__arm__)
162
163
164#include <signal.h>
165#include <asm/sigcontext.h>
Christopher Ferrisf0d5f552013-12-16 15:05:39 -0800166#include <asm-generic/ucontext.h>
Dave Allison70202782013-10-22 17:52:19 -0700167
168
169// A signal handler called when have an illegal instruction. We record the fact in
170// a global boolean and then increment the PC in the signal context to return to
171// the next instruction. We know the instruction is an sdiv (4 bytes long).
172static void baddivideinst(int signo, siginfo *si, void *data) {
173 (void)signo;
174 (void)si;
175 struct ucontext *uc = (struct ucontext *)data;
176 struct sigcontext *sc = &uc->uc_mcontext;
177 sc->arm_r0 = 0; // set R0 to #0 to signal error
178 sc->arm_pc += 4; // skip offending instruction
179}
180
181// This is in arch/arm/arm_sdiv.S. It does the following:
182// mov r1,#1
183// sdiv r0,r1,r1
184// bx lr
185//
186// the result will be the value 1 if sdiv is supported. If it is not supported
187// a SIGILL signal will be raised and the signal handler (baddivideinst) called.
188// The signal handler sets r0 to #0 and then increments pc beyond the failed instruction.
189// Thus if the instruction is not supported, the result of this function will be #0
190
191extern "C" bool CheckForARMSDIVInstruction();
192
193static InstructionSetFeatures GuessInstructionFeatures() {
194 InstructionSetFeatures f;
195
196 // Uncomment this for processing of /proc/cpuinfo.
197 if (false) {
198 // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
199 // the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
200 std::ifstream in("/proc/cpuinfo");
201 if (in) {
202 while (!in.eof()) {
203 std::string line;
204 std::getline(in, line);
205 if (!in.eof()) {
206 if (line.find("Features") != std::string::npos) {
207 if (line.find("idivt") != std::string::npos) {
208 f.SetHasDivideInstruction(true);
209 }
210 }
211 }
212 in.close();
213 }
214 } else {
215 LOG(INFO) << "Failed to open /proc/cpuinfo";
216 }
217 }
218
219 // See if have a sdiv instruction. Register a signal handler and try to execute
220 // an sdiv instruction. If we get a SIGILL then it's not supported. We can't use
221 // the /proc/cpuinfo method for this because Krait devices don't always put the idivt
222 // feature in the list.
223 struct sigaction sa, osa;
224 sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
225 sa.sa_sigaction = baddivideinst;
226 sigaction(SIGILL, &sa, &osa);
227
228 if (CheckForARMSDIVInstruction()) {
229 f.SetHasDivideInstruction(true);
230 }
231
232 // Restore the signal handler.
233 sigaction(SIGILL, &osa, NULL);
234
235 // Other feature guesses in here.
236 return f;
237}
238
239#endif
240
241// Given a set of instruction features from the build, parse it. The
242// input 'str' is a comma separated list of feature names. Parse it and
243// return the InstructionSetFeatures object.
244static InstructionSetFeatures ParseFeatureList(std::string str) {
Dave Allison70202782013-10-22 17:52:19 -0700245 InstructionSetFeatures result;
246 typedef std::vector<std::string> FeatureList;
247 FeatureList features;
248 Split(str, ',', features);
249 for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
250 std::string feature = Trim(*i);
251 if (feature == "default") {
252 // Nothing to do.
253 } else if (feature == "div") {
254 // Supports divide instruction.
255 result.SetHasDivideInstruction(true);
256 } else if (feature == "nodiv") {
257 // Turn off support for divide instruction.
258 result.SetHasDivideInstruction(false);
259 } else {
260 LOG(FATAL) << "Unknown instruction set feature: '" << feature << "'";
261 }
262 }
263 // Others...
264 return result;
265}
266
Brian Carlstromf734cf52011-08-17 16:28:14 -0700267class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700268 public:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800269 static void MakeExecutable(const mirror::ByteArray* code_array) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700270 CHECK(code_array != NULL);
271 MakeExecutable(code_array->GetData(), code_array->GetLength());
272 }
273
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700274 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700275 CHECK_NE(code.size(), 0U);
276 MakeExecutable(&code[0], code.size());
277 }
278
Brian Carlstromae826982011-11-09 01:33:42 -0800279 // Create an OatMethod based on pointers (for unit tests)
280 OatFile::OatMethod CreateOatMethod(const void* code,
281 const size_t frame_size_in_bytes,
282 const uint32_t core_spill_mask,
283 const uint32_t fp_spill_mask,
Ian Rogers1809a722013-08-09 22:05:32 -0700284 const uint8_t* mapping_table,
285 const uint8_t* vmap_table,
Jeff Hao74180ca2013-03-27 15:29:11 -0700286 const uint8_t* gc_map) {
Brian Carlstromae826982011-11-09 01:33:42 -0800287 return OatFile::OatMethod(NULL,
288 reinterpret_cast<uint32_t>(code),
289 frame_size_in_bytes,
290 core_spill_mask,
291 fp_spill_mask,
292 reinterpret_cast<uint32_t>(mapping_table),
293 reinterpret_cast<uint32_t>(vmap_table),
Brian Carlstromdf629502013-07-17 22:39:56 -0700294 reinterpret_cast<uint32_t>(gc_map));
Brian Carlstromae826982011-11-09 01:33:42 -0800295 }
296
Brian Carlstromea46f952013-07-30 01:26:50 -0700297 void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700298 CHECK(method != NULL);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700299
Ian Rogersf3e98552013-03-20 15:49:49 -0700300 const CompiledMethod* compiled_method = NULL;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700301 if (!method->IsAbstract()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800302 const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700303 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogersf3e98552013-03-20 15:49:49 -0700304 compiled_method =
Brian Carlstrom51c24672013-07-11 16:00:56 -0700305 compiler_driver_->GetCompiledMethod(MethodReference(&dex_file,
306 method->GetDexMethodIndex()));
Ian Rogersf3e98552013-03-20 15:49:49 -0700307 }
308 if (compiled_method != NULL) {
Logan Chien971bf3f2012-05-01 15:47:55 +0800309 const std::vector<uint8_t>& code = compiled_method->GetCode();
310 MakeExecutable(code);
311 const void* method_code = CompiledMethod::CodePointer(&code[0],
312 compiled_method->GetInstructionSet());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700313 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800314 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
315 compiled_method->GetFrameSizeInBytes(),
316 compiled_method->GetCoreSpillMask(),
317 compiled_method->GetFpSpillMask(),
318 &compiled_method->GetMappingTable()[0],
319 &compiled_method->GetVmapTable()[0],
Jeff Hao74180ca2013-03-27 15:29:11 -0700320 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800321 oat_method.LinkMethod(method);
Ian Rogers0f40ac32013-08-13 22:10:30 -0700322 method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700323 } else {
Ian Rogersf3e98552013-03-20 15:49:49 -0700324 const void* method_code;
Ian Rogers848871b2013-08-05 10:56:33 -0700325 // No code? You must mean to go into the interpreter.
326 method_code = GetCompiledCodeToInterpreterBridge();
Brian Carlstromae826982011-11-09 01:33:42 -0800327 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
328 kStackAlignment,
329 0,
330 0,
331 NULL,
332 NULL,
Jeff Hao74180ca2013-03-27 15:29:11 -0700333 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800334 oat_method.LinkMethod(method);
Ian Rogers0f40ac32013-08-13 22:10:30 -0700335 method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700336 }
337 }
338
339 static void MakeExecutable(const void* code_start, size_t code_length) {
340 CHECK(code_start != NULL);
341 CHECK_NE(code_length, 0U);
342 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700343 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700344 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700345 uintptr_t len = limit - base;
346 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800347 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800348
Ian Rogers16341552011-10-10 11:33:06 -0700349 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800350 // Only uses __builtin___clear_cache if GCC >= 4.3.3
351#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700352 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800353#else
Brian Carlstrom6f485c62013-07-18 15:35:35 -0700354 LOG(FATAL) << "UNIMPLEMENTED: cache flush";
Shih-wei Liao24782c62012-01-08 12:46:11 -0800355#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700356 }
357
Elliott Hughes76160052012-12-12 16:31:20 -0800358 static void SetEnvironmentVariables(std::string& android_data) {
359 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700360 // $ANDROID_ROOT is set on the device, but not on the host.
361 // We need to set this so that icu4c can find its locale data.
362 std::string root;
363 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800364#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700365 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800366#elif defined(__APPLE__)
367 root += "/out/host/darwin-x86";
368#else
369#error unsupported OS
370#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700371 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700372 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700373 }
374
Brian Carlstrom7675e162013-06-10 16:18:04 -0700375 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
376 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/dalvik-cache/art-data-XXXXXX");
Elliott Hughes76160052012-12-12 16:31:20 -0800377 if (mkdtemp(&android_data[0]) == NULL) {
378 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700379 }
Elliott Hughes76160052012-12-12 16:31:20 -0800380 setenv("ANDROID_DATA", android_data.c_str(), 1);
381 }
382
Ian Rogers1d99e452014-01-02 17:36:41 -0800383 void MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name)
384 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
385 std::string class_descriptor(DotToDescriptor(class_name));
386 SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
387 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
388 CHECK(klass != NULL) << "Class not found " << class_name;
389 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
390 MakeExecutable(klass->GetDirectMethod(i));
391 }
392 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
393 MakeExecutable(klass->GetVirtualMethod(i));
394 }
395 }
396
Elliott Hughes76160052012-12-12 16:31:20 -0800397 protected:
398 static bool IsHost() {
399 return (getenv("ANDROID_BUILD_TOP") != NULL);
400 }
401
402 virtual void SetUp() {
403 SetEnvironmentVariables(android_data_);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700404 dalvik_cache_.append(android_data_.c_str());
405 dalvik_cache_.append("/dalvik-cache");
406 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700407 ASSERT_EQ(mkdir_result, 0);
408
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700409 std::string error_msg;
410 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName().c_str(),
411 GetLibCoreDexFileName().c_str(), &error_msg);
Ian Rogers33e95662013-05-20 20:29:14 -0700412 if (java_lang_dex_file_ == NULL) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700413 LOG(FATAL) << "Could not open .dex file '" << GetLibCoreDexFileName() << "': "
414 << error_msg << "\n";
Ian Rogers33e95662013-05-20 20:29:14 -0700415 }
Brian Carlstroma004aa92012-02-08 18:05:09 -0800416 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700417
Ian Rogers1d54e732013-05-02 21:10:01 -0700418 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
419 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800420
Vladimir Marko95a4de72013-12-18 10:29:11 +0000421 // TODO: make selectable
422#if defined(ART_USE_PORTABLE_COMPILER)
423 CompilerBackend compiler_backend = kPortable;
424#else
425 CompilerBackend compiler_backend = kQuick;
426#endif
427
Vladimir Markoc7f83202014-01-24 17:55:18 +0000428 verification_results_.reset(new VerificationResults);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000429 method_inliner_map_.reset(compiler_backend == kQuick ? new DexFileToMethodInlinerMap : nullptr);
Vladimir Markoc7f83202014-01-24 17:55:18 +0000430 callbacks_.Reset(verification_results_.get(), method_inliner_map_.get());
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700431 Runtime::Options options;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000432 options.push_back(std::make_pair("compilercallbacks", static_cast<CompilerCallbacks*>(&callbacks_)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800433 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700434 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800435 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
436 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstromdf629502013-07-17 22:39:56 -0700437 if (!Runtime::Create(options, false)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700438 LOG(FATAL) << "Failed to create runtime";
439 return;
440 }
441 runtime_.reset(Runtime::Current());
442 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
443 // give it away now and then switch to a more managable ScopedObjectAccess.
444 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
Ian Rogers1d54e732013-05-02 21:10:01 -0700445 {
446 ScopedObjectAccess soa(Thread::Current());
447 ASSERT_TRUE(runtime_.get() != NULL);
448 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700449
Ian Rogers1d54e732013-05-02 21:10:01 -0700450 InstructionSet instruction_set = kNone;
Dave Allison70202782013-10-22 17:52:19 -0700451
Brian Carlstrom1bd2ceb2013-11-06 00:29:48 -0800452 // Take the default set of instruction features from the build.
Dave Allison70202782013-10-22 17:52:19 -0700453 InstructionSetFeatures instruction_set_features =
Brian Carlstrom1bd2ceb2013-11-06 00:29:48 -0800454 ParseFeatureList(STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES));
Dave Allison70202782013-10-22 17:52:19 -0700455
jeffhaoc0228b82012-08-29 18:15:05 -0700456#if defined(__arm__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700457 instruction_set = kThumb2;
Dave Allison70202782013-10-22 17:52:19 -0700458 InstructionSetFeatures runtime_features = GuessInstructionFeatures();
459
460 // for ARM, do a runtime check to make sure that the features we are passed from
461 // the build match the features we actually determine at runtime.
462 ASSERT_EQ(instruction_set_features, runtime_features);
jeffhaoc0228b82012-08-29 18:15:05 -0700463#elif defined(__mips__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700464 instruction_set = kMips;
jeffhaoc0228b82012-08-29 18:15:05 -0700465#elif defined(__i386__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700466 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700467#endif
buzbeec531cef2012-10-18 07:09:20 -0700468
Ian Rogers1d54e732013-05-02 21:10:01 -0700469 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
470 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
471 if (!runtime_->HasCalleeSaveMethod(type)) {
472 runtime_->SetCalleeSaveMethod(
473 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
474 }
475 }
476 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Vladimir Markoc7f83202014-01-24 17:55:18 +0000477 compiler_driver_.reset(new CompilerDriver(verification_results_.get(),
Sebastien Hertz102a8f22013-12-18 11:41:30 +0100478 method_inliner_map_.get(),
479 compiler_backend, instruction_set,
Dave Allison70202782013-10-22 17:52:19 -0700480 instruction_set_features,
Ian Rogers1d54e732013-05-02 21:10:01 -0700481 true, new CompilerDriver::DescriptorSet,
Brian Carlstrom650be762014-01-20 10:55:16 -0800482 2, true));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700483 }
Brian Carlstrom96391602013-06-13 19:49:50 -0700484 // We typically don't generate an image in unit tests, disable this optimization by default.
485 compiler_driver_->SetSupportBootImageFixup(false);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700486
Ian Rogers1d54e732013-05-02 21:10:01 -0700487 // We're back in native, take the opportunity to initialize well known classes.
Brian Carlstromea46f952013-07-30 01:26:50 -0700488 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700489 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
490 // pool is created by the runtime.
491 runtime_->GetHeap()->CreateThreadPool();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700492 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700493 }
494
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700495 virtual void TearDown() {
496 const char* android_data = getenv("ANDROID_DATA");
497 ASSERT_TRUE(android_data != NULL);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700498 DIR* dir = opendir(dalvik_cache_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700499 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700500 dirent* e;
501 while ((e = readdir(dir)) != NULL) {
502 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700503 continue;
504 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700505 std::string filename(dalvik_cache_);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700506 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700507 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700508 int unlink_result = unlink(filename.c_str());
509 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400510 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700511 closedir(dir);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700512 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700513 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700514 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700515 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700516
517 // icu4c has a fixed 10-element array "gCommonICUDataArray".
518 // If we run > 10 tests, we fill that array and u_setCommonData fails.
519 // There's a function to clear the array, but it's not public...
520 typedef void (*IcuCleanupFn)();
521 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
522 CHECK(sym != NULL);
523 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
524 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700525
Ian Rogers1212a022013-03-04 10:48:41 -0800526 compiler_driver_.reset();
Vladimir Marko95a4de72013-12-18 10:29:11 +0000527 callbacks_.Reset(nullptr, nullptr);
528 method_inliner_map_.reset();
Vladimir Markoc7f83202014-01-24 17:55:18 +0000529 verification_results_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800530 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700531
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800532 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700533 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400534
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700535 std::string GetLibCoreDexFileName() {
Brian Carlstrom3b010aa2013-06-25 23:06:36 -0700536 return GetDexFileName("core-libart");
Brian Carlstrom265091e2013-01-30 14:08:26 -0800537 }
538
539 std::string GetDexFileName(const std::string& jar_prefix) {
Elliott Hughes76160052012-12-12 16:31:20 -0800540 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700541 const char* host_dir = getenv("ANDROID_HOST_OUT");
542 CHECK(host_dir != NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800543 return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700544 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800545 return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700546 }
547
Brian Carlstrom3f47c122013-03-07 00:02:40 -0800548 std::string GetTestAndroidRoot() {
549 if (IsHost()) {
550 const char* host_dir = getenv("ANDROID_HOST_OUT");
551 CHECK(host_dir != NULL);
552 return host_dir;
553 }
554 return GetAndroidRoot();
555 }
556
Ian Rogers33e95662013-05-20 20:29:14 -0700557 const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700558 CHECK(name != NULL);
559 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800560 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700561 filename += getenv("ANDROID_HOST_OUT");
562 filename += "/framework/";
563 } else {
564 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700565 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700566 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700567 filename += name;
568 filename += ".jar";
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700569 std::string error_msg;
570 const DexFile* dex_file = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg);
571 CHECK(dex_file != NULL) << "Failed to open '" << filename << "': " << error_msg;
Brian Carlstrome0948e12013-08-29 09:36:15 -0700572 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
573 CHECK(dex_file->IsReadOnly());
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800574 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700575 return dex_file;
576 }
577
Ian Rogers33e95662013-05-20 20:29:14 -0700578 jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700579 const DexFile* dex_file = OpenTestDexFile(dex_name);
580 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700581 class_linker_->RegisterDexFile(*dex_file);
582 std::vector<const DexFile*> class_path;
583 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700584 ScopedObjectAccessUnchecked soa(Thread::Current());
585 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
586 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
587 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800588 soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700589 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
590 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700591 }
592
Ian Rogers33e95662013-05-20 20:29:14 -0700593 void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
594 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800595 std::string class_descriptor(DotToDescriptor(class_name));
Mathieu Chartier590fee92013-09-13 13:46:47 -0700596 SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
597 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700598 CHECK(klass != NULL) << "Class not found " << class_name;
599 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
600 CompileMethod(klass->GetDirectMethod(i));
601 }
602 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
603 CompileMethod(klass->GetVirtualMethod(i));
604 }
605 }
606
Brian Carlstromea46f952013-07-30 01:26:50 -0700607 void CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700608 CHECK(method != NULL);
Ian Rogers5fe9af72013-11-14 00:17:20 -0800609 TimingLogger timings("CommonTest::CompileMethod", false, false);
Anwar Ghuloumbe576f42013-07-25 17:32:40 -0700610 timings.StartSplit("CompileOne");
Brian Carlstrom45602482013-07-21 22:07:55 -0700611 compiler_driver_->CompileOne(method, timings);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700612 MakeExecutable(method);
Ian Rogers5fe9af72013-11-14 00:17:20 -0800613 timings.EndSplit();
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700614 }
615
Mathieu Chartier590fee92013-09-13 13:46:47 -0700616 void CompileDirectMethod(SirtRef<mirror::ClassLoader>& class_loader, const char* class_name,
617 const char* method_name, const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700618 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800619 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800620 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700621 CHECK(klass != NULL) << "Class not found " << class_name;
Brian Carlstromea46f952013-07-30 01:26:50 -0700622 mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700623 CHECK(method != NULL) << "Direct method not found: "
624 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700625 CompileMethod(method);
626 }
627
Mathieu Chartier590fee92013-09-13 13:46:47 -0700628 void CompileVirtualMethod(SirtRef<mirror::ClassLoader>& class_loader, const char* class_name,
629 const char* method_name, const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700630 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800631 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800632 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700633 CHECK(klass != NULL) << "Class not found " << class_name;
Brian Carlstromea46f952013-07-30 01:26:50 -0700634 mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700635 CHECK(method != NULL) << "Virtual method not found: "
636 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700637 CompileMethod(method);
638 }
639
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800640 void ReserveImageSpace() {
641 // Reserve where the image will be loaded up front so that other parts of test set up don't
642 // accidentally end up colliding with the fixed memory address when we need to load the image.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700643 std::string error_msg;
Brian Carlstrom2d888622013-07-18 17:02:00 -0700644 image_reservation_.reset(MemMap::MapAnonymous("image reservation",
645 reinterpret_cast<byte*>(ART_BASE_ADDRESS),
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800646 (size_t)100 * 1024 * 1024, // 100MB
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700647 PROT_NONE, &error_msg));
648 CHECK(image_reservation_.get() != nullptr) << error_msg;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800649 }
650
651 void UnreserveImageSpace() {
652 image_reservation_.reset();
653 }
654
Vladimir Marko95a4de72013-12-18 10:29:11 +0000655 class TestCompilerCallbacks : public CompilerCallbacks {
656 public:
Vladimir Markoc7f83202014-01-24 17:55:18 +0000657 TestCompilerCallbacks() : verification_results_(nullptr), method_inliner_map_(nullptr) { }
Vladimir Marko95a4de72013-12-18 10:29:11 +0000658
Vladimir Markoc7f83202014-01-24 17:55:18 +0000659 void Reset(VerificationResults* verification_results,
Vladimir Marko95a4de72013-12-18 10:29:11 +0000660 DexFileToMethodInlinerMap* method_inliner_map) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000661 verification_results_ = verification_results;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000662 method_inliner_map_ = method_inliner_map;
663 }
664
665 virtual bool MethodVerified(verifier::MethodVerifier* verifier)
666 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000667 CHECK(verification_results_);
668 bool result = verification_results_->ProcessVerifiedMethod(verifier);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000669 if (result && method_inliner_map_ != nullptr) {
670 MethodReference ref = verifier->GetMethodReference();
671 method_inliner_map_->GetMethodInliner(ref.dex_file)
672 ->AnalyseMethodCode(ref.dex_method_index, verifier->CodeItem());
673 }
674 return result;
675 }
676 virtual void ClassRejected(ClassReference ref) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000677 verification_results_->AddRejectedClass(ref);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000678 }
679
680 private:
Vladimir Markoc7f83202014-01-24 17:55:18 +0000681 VerificationResults* verification_results_;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000682 DexFileToMethodInlinerMap* method_inliner_map_;
683 };
684
Elliott Hughes34023802011-08-30 12:06:17 -0700685 std::string android_data_;
Brian Carlstrom7675e162013-06-10 16:18:04 -0700686 std::string dalvik_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800687 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700688 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700689 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700690 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700691 ClassLinker* class_linker_;
Vladimir Markoc7f83202014-01-24 17:55:18 +0000692 UniquePtr<VerificationResults> verification_results_;
Sebastien Hertz102a8f22013-12-18 11:41:30 +0100693 UniquePtr<DexFileToMethodInlinerMap> method_inliner_map_;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000694 TestCompilerCallbacks callbacks_;
Ian Rogers1212a022013-03-04 10:48:41 -0800695 UniquePtr<CompilerDriver> compiler_driver_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700696
697 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800698 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800699 UniquePtr<MemMap> image_reservation_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700700};
701
Elliott Hughesb264f082012-04-06 17:10:10 -0700702// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
703// rather than aborting, so be careful!
704class CheckJniAbortCatcher {
705 public:
706 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
707 vm_->check_jni_abort_hook = Hook;
708 vm_->check_jni_abort_hook_data = &actual_;
709 }
710
711 ~CheckJniAbortCatcher() {
712 vm_->check_jni_abort_hook = NULL;
713 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700714 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700715 }
716
717 void Check(const char* expected_text) {
718 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
719 << "Expected to find: " << expected_text << "\n"
720 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700721 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700722 }
723
724 private:
725 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700726 // We use += because when we're hooking the aborts like this, multiple problems can be found.
727 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700728 }
729
730 JavaVMExt* vm_;
731 std::string actual_;
732
733 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
734};
735
Brian Carlstrom265091e2013-01-30 14:08:26 -0800736// TODO: These tests were disabled for portable when we went to having
737// MCLinker link LLVM ELF output because we no longer just have code
738// blobs in memory. We'll need to dlopen to load and relocate
739// temporary output to resurrect these tests.
740#if defined(ART_USE_PORTABLE_COMPILER)
741#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
742#else
743#define TEST_DISABLED_FOR_PORTABLE()
744#endif
Brian Carlstrom934486c2011-07-12 23:42:50 -0700745} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700746
747namespace std {
748
749// TODO: isn't gtest supposed to be able to print STL types for itself?
750template <typename T>
751std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700752 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700753 return os;
754}
755
756} // namespace std
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700757
758#endif // ART_RUNTIME_COMMON_TEST_H_