blob: fce3f3f7c2b762039b0a49b1f250105b29cef222 [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
Elliott Hughesee287732014-01-30 12:09:13 -0800163#include <sys/ucontext.h>
Dave Allison70202782013-10-22 17:52:19 -0700164
165// A signal handler called when have an illegal instruction. We record the fact in
166// a global boolean and then increment the PC in the signal context to return to
167// the next instruction. We know the instruction is an sdiv (4 bytes long).
168static void baddivideinst(int signo, siginfo *si, void *data) {
169 (void)signo;
170 (void)si;
171 struct ucontext *uc = (struct ucontext *)data;
172 struct sigcontext *sc = &uc->uc_mcontext;
173 sc->arm_r0 = 0; // set R0 to #0 to signal error
174 sc->arm_pc += 4; // skip offending instruction
175}
176
177// This is in arch/arm/arm_sdiv.S. It does the following:
178// mov r1,#1
179// sdiv r0,r1,r1
180// bx lr
181//
182// the result will be the value 1 if sdiv is supported. If it is not supported
183// a SIGILL signal will be raised and the signal handler (baddivideinst) called.
184// The signal handler sets r0 to #0 and then increments pc beyond the failed instruction.
185// Thus if the instruction is not supported, the result of this function will be #0
186
187extern "C" bool CheckForARMSDIVInstruction();
188
189static InstructionSetFeatures GuessInstructionFeatures() {
190 InstructionSetFeatures f;
191
192 // Uncomment this for processing of /proc/cpuinfo.
193 if (false) {
194 // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
195 // the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
196 std::ifstream in("/proc/cpuinfo");
197 if (in) {
198 while (!in.eof()) {
199 std::string line;
200 std::getline(in, line);
201 if (!in.eof()) {
202 if (line.find("Features") != std::string::npos) {
203 if (line.find("idivt") != std::string::npos) {
204 f.SetHasDivideInstruction(true);
205 }
206 }
207 }
208 in.close();
209 }
210 } else {
211 LOG(INFO) << "Failed to open /proc/cpuinfo";
212 }
213 }
214
215 // See if have a sdiv instruction. Register a signal handler and try to execute
216 // an sdiv instruction. If we get a SIGILL then it's not supported. We can't use
217 // the /proc/cpuinfo method for this because Krait devices don't always put the idivt
218 // feature in the list.
219 struct sigaction sa, osa;
220 sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
221 sa.sa_sigaction = baddivideinst;
222 sigaction(SIGILL, &sa, &osa);
223
224 if (CheckForARMSDIVInstruction()) {
225 f.SetHasDivideInstruction(true);
226 }
227
228 // Restore the signal handler.
229 sigaction(SIGILL, &osa, NULL);
230
231 // Other feature guesses in here.
232 return f;
233}
234
235#endif
236
237// Given a set of instruction features from the build, parse it. The
238// input 'str' is a comma separated list of feature names. Parse it and
239// return the InstructionSetFeatures object.
240static InstructionSetFeatures ParseFeatureList(std::string str) {
Dave Allison70202782013-10-22 17:52:19 -0700241 InstructionSetFeatures result;
242 typedef std::vector<std::string> FeatureList;
243 FeatureList features;
244 Split(str, ',', features);
245 for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
246 std::string feature = Trim(*i);
247 if (feature == "default") {
248 // Nothing to do.
249 } else if (feature == "div") {
250 // Supports divide instruction.
251 result.SetHasDivideInstruction(true);
252 } else if (feature == "nodiv") {
253 // Turn off support for divide instruction.
254 result.SetHasDivideInstruction(false);
255 } else {
256 LOG(FATAL) << "Unknown instruction set feature: '" << feature << "'";
257 }
258 }
259 // Others...
260 return result;
261}
262
Brian Carlstromf734cf52011-08-17 16:28:14 -0700263class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700264 public:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800265 static void MakeExecutable(const mirror::ByteArray* code_array) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700266 CHECK(code_array != NULL);
267 MakeExecutable(code_array->GetData(), code_array->GetLength());
268 }
269
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700270 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700271 CHECK_NE(code.size(), 0U);
272 MakeExecutable(&code[0], code.size());
273 }
274
Brian Carlstromae826982011-11-09 01:33:42 -0800275 // Create an OatMethod based on pointers (for unit tests)
276 OatFile::OatMethod CreateOatMethod(const void* code,
277 const size_t frame_size_in_bytes,
278 const uint32_t core_spill_mask,
279 const uint32_t fp_spill_mask,
Ian Rogers1809a722013-08-09 22:05:32 -0700280 const uint8_t* mapping_table,
281 const uint8_t* vmap_table,
Jeff Hao74180ca2013-03-27 15:29:11 -0700282 const uint8_t* gc_map) {
Brian Carlstromae826982011-11-09 01:33:42 -0800283 return OatFile::OatMethod(NULL,
284 reinterpret_cast<uint32_t>(code),
285 frame_size_in_bytes,
286 core_spill_mask,
287 fp_spill_mask,
288 reinterpret_cast<uint32_t>(mapping_table),
289 reinterpret_cast<uint32_t>(vmap_table),
Brian Carlstromdf629502013-07-17 22:39:56 -0700290 reinterpret_cast<uint32_t>(gc_map));
Brian Carlstromae826982011-11-09 01:33:42 -0800291 }
292
Brian Carlstromea46f952013-07-30 01:26:50 -0700293 void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700294 CHECK(method != NULL);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700295
Ian Rogersf3e98552013-03-20 15:49:49 -0700296 const CompiledMethod* compiled_method = NULL;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700297 if (!method->IsAbstract()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800298 const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700299 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogersf3e98552013-03-20 15:49:49 -0700300 compiled_method =
Brian Carlstrom51c24672013-07-11 16:00:56 -0700301 compiler_driver_->GetCompiledMethod(MethodReference(&dex_file,
302 method->GetDexMethodIndex()));
Ian Rogersf3e98552013-03-20 15:49:49 -0700303 }
304 if (compiled_method != NULL) {
Logan Chien971bf3f2012-05-01 15:47:55 +0800305 const std::vector<uint8_t>& code = compiled_method->GetCode();
306 MakeExecutable(code);
307 const void* method_code = CompiledMethod::CodePointer(&code[0],
308 compiled_method->GetInstructionSet());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700309 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800310 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
311 compiled_method->GetFrameSizeInBytes(),
312 compiled_method->GetCoreSpillMask(),
313 compiled_method->GetFpSpillMask(),
314 &compiled_method->GetMappingTable()[0],
315 &compiled_method->GetVmapTable()[0],
Jeff Hao74180ca2013-03-27 15:29:11 -0700316 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800317 oat_method.LinkMethod(method);
Ian Rogers0f40ac32013-08-13 22:10:30 -0700318 method->SetEntryPointFromInterpreter(artInterpreterToCompiledCodeBridge);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700319 } else {
Ian Rogersf3e98552013-03-20 15:49:49 -0700320 const void* method_code;
Ian Rogers848871b2013-08-05 10:56:33 -0700321 // No code? You must mean to go into the interpreter.
322 method_code = GetCompiledCodeToInterpreterBridge();
Brian Carlstromae826982011-11-09 01:33:42 -0800323 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
324 kStackAlignment,
325 0,
326 0,
327 NULL,
328 NULL,
Jeff Hao74180ca2013-03-27 15:29:11 -0700329 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800330 oat_method.LinkMethod(method);
Ian Rogers0f40ac32013-08-13 22:10:30 -0700331 method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700332 }
333 }
334
335 static void MakeExecutable(const void* code_start, size_t code_length) {
336 CHECK(code_start != NULL);
337 CHECK_NE(code_length, 0U);
338 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700339 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700340 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700341 uintptr_t len = limit - base;
342 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800343 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800344
Ian Rogers16341552011-10-10 11:33:06 -0700345 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800346 // Only uses __builtin___clear_cache if GCC >= 4.3.3
347#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700348 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800349#else
Brian Carlstrom6f485c62013-07-18 15:35:35 -0700350 LOG(FATAL) << "UNIMPLEMENTED: cache flush";
Shih-wei Liao24782c62012-01-08 12:46:11 -0800351#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700352 }
353
Elliott Hughes76160052012-12-12 16:31:20 -0800354 static void SetEnvironmentVariables(std::string& android_data) {
355 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700356 // $ANDROID_ROOT is set on the device, but not on the host.
357 // We need to set this so that icu4c can find its locale data.
358 std::string root;
359 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800360#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700361 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800362#elif defined(__APPLE__)
363 root += "/out/host/darwin-x86";
364#else
365#error unsupported OS
366#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700367 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700368 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700369 }
370
Brian Carlstrom7675e162013-06-10 16:18:04 -0700371 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
372 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/dalvik-cache/art-data-XXXXXX");
Elliott Hughes76160052012-12-12 16:31:20 -0800373 if (mkdtemp(&android_data[0]) == NULL) {
374 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700375 }
Elliott Hughes76160052012-12-12 16:31:20 -0800376 setenv("ANDROID_DATA", android_data.c_str(), 1);
377 }
378
Ian Rogers1d99e452014-01-02 17:36:41 -0800379 void MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name)
380 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
381 std::string class_descriptor(DotToDescriptor(class_name));
382 SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
383 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
384 CHECK(klass != NULL) << "Class not found " << class_name;
385 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
386 MakeExecutable(klass->GetDirectMethod(i));
387 }
388 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
389 MakeExecutable(klass->GetVirtualMethod(i));
390 }
391 }
392
Elliott Hughes76160052012-12-12 16:31:20 -0800393 protected:
394 static bool IsHost() {
395 return (getenv("ANDROID_BUILD_TOP") != NULL);
396 }
397
398 virtual void SetUp() {
399 SetEnvironmentVariables(android_data_);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700400 dalvik_cache_.append(android_data_.c_str());
401 dalvik_cache_.append("/dalvik-cache");
402 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700403 ASSERT_EQ(mkdir_result, 0);
404
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700405 std::string error_msg;
406 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName().c_str(),
407 GetLibCoreDexFileName().c_str(), &error_msg);
Ian Rogers33e95662013-05-20 20:29:14 -0700408 if (java_lang_dex_file_ == NULL) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700409 LOG(FATAL) << "Could not open .dex file '" << GetLibCoreDexFileName() << "': "
410 << error_msg << "\n";
Ian Rogers33e95662013-05-20 20:29:14 -0700411 }
Brian Carlstroma004aa92012-02-08 18:05:09 -0800412 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700413
Ian Rogers1d54e732013-05-02 21:10:01 -0700414 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
415 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800416
Vladimir Marko95a4de72013-12-18 10:29:11 +0000417 // TODO: make selectable
418#if defined(ART_USE_PORTABLE_COMPILER)
419 CompilerBackend compiler_backend = kPortable;
420#else
421 CompilerBackend compiler_backend = kQuick;
422#endif
423
Vladimir Markoc7f83202014-01-24 17:55:18 +0000424 verification_results_.reset(new VerificationResults);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000425 method_inliner_map_.reset(compiler_backend == kQuick ? new DexFileToMethodInlinerMap : nullptr);
Vladimir Markoc7f83202014-01-24 17:55:18 +0000426 callbacks_.Reset(verification_results_.get(), method_inliner_map_.get());
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700427 Runtime::Options options;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000428 options.push_back(std::make_pair("compilercallbacks", static_cast<CompilerCallbacks*>(&callbacks_)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800429 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700430 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800431 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
432 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstromdf629502013-07-17 22:39:56 -0700433 if (!Runtime::Create(options, false)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700434 LOG(FATAL) << "Failed to create runtime";
435 return;
436 }
437 runtime_.reset(Runtime::Current());
438 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
439 // give it away now and then switch to a more managable ScopedObjectAccess.
440 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
Ian Rogers1d54e732013-05-02 21:10:01 -0700441 {
442 ScopedObjectAccess soa(Thread::Current());
443 ASSERT_TRUE(runtime_.get() != NULL);
444 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700445
Ian Rogers1d54e732013-05-02 21:10:01 -0700446 InstructionSet instruction_set = kNone;
Dave Allison70202782013-10-22 17:52:19 -0700447
Brian Carlstrom1bd2ceb2013-11-06 00:29:48 -0800448 // Take the default set of instruction features from the build.
Dave Allison70202782013-10-22 17:52:19 -0700449 InstructionSetFeatures instruction_set_features =
Brian Carlstrom1bd2ceb2013-11-06 00:29:48 -0800450 ParseFeatureList(STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES));
Dave Allison70202782013-10-22 17:52:19 -0700451
jeffhaoc0228b82012-08-29 18:15:05 -0700452#if defined(__arm__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700453 instruction_set = kThumb2;
Dave Allison70202782013-10-22 17:52:19 -0700454 InstructionSetFeatures runtime_features = GuessInstructionFeatures();
455
456 // for ARM, do a runtime check to make sure that the features we are passed from
457 // the build match the features we actually determine at runtime.
458 ASSERT_EQ(instruction_set_features, runtime_features);
jeffhaoc0228b82012-08-29 18:15:05 -0700459#elif defined(__mips__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700460 instruction_set = kMips;
jeffhaoc0228b82012-08-29 18:15:05 -0700461#elif defined(__i386__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700462 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700463#endif
buzbeec531cef2012-10-18 07:09:20 -0700464
Ian Rogers1d54e732013-05-02 21:10:01 -0700465 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
466 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
467 if (!runtime_->HasCalleeSaveMethod(type)) {
468 runtime_->SetCalleeSaveMethod(
469 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
470 }
471 }
472 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Vladimir Markoc7f83202014-01-24 17:55:18 +0000473 compiler_driver_.reset(new CompilerDriver(verification_results_.get(),
Sebastien Hertz102a8f22013-12-18 11:41:30 +0100474 method_inliner_map_.get(),
475 compiler_backend, instruction_set,
Dave Allison70202782013-10-22 17:52:19 -0700476 instruction_set_features,
Ian Rogers1d54e732013-05-02 21:10:01 -0700477 true, new CompilerDriver::DescriptorSet,
Brian Carlstrom650be762014-01-20 10:55:16 -0800478 2, true));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700479 }
Brian Carlstrom96391602013-06-13 19:49:50 -0700480 // We typically don't generate an image in unit tests, disable this optimization by default.
481 compiler_driver_->SetSupportBootImageFixup(false);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700482
Ian Rogers1d54e732013-05-02 21:10:01 -0700483 // We're back in native, take the opportunity to initialize well known classes.
Brian Carlstromea46f952013-07-30 01:26:50 -0700484 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700485 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
486 // pool is created by the runtime.
487 runtime_->GetHeap()->CreateThreadPool();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700488 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700489 }
490
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700491 virtual void TearDown() {
492 const char* android_data = getenv("ANDROID_DATA");
493 ASSERT_TRUE(android_data != NULL);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700494 DIR* dir = opendir(dalvik_cache_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700495 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700496 dirent* e;
497 while ((e = readdir(dir)) != NULL) {
498 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700499 continue;
500 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700501 std::string filename(dalvik_cache_);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700502 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700503 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700504 int unlink_result = unlink(filename.c_str());
505 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400506 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700507 closedir(dir);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700508 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700509 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700510 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700511 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700512
513 // icu4c has a fixed 10-element array "gCommonICUDataArray".
514 // If we run > 10 tests, we fill that array and u_setCommonData fails.
515 // There's a function to clear the array, but it's not public...
516 typedef void (*IcuCleanupFn)();
517 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
518 CHECK(sym != NULL);
519 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
520 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700521
Ian Rogers1212a022013-03-04 10:48:41 -0800522 compiler_driver_.reset();
Vladimir Marko95a4de72013-12-18 10:29:11 +0000523 callbacks_.Reset(nullptr, nullptr);
524 method_inliner_map_.reset();
Vladimir Markoc7f83202014-01-24 17:55:18 +0000525 verification_results_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800526 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700527
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800528 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700529 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400530
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700531 std::string GetLibCoreDexFileName() {
Brian Carlstrom3b010aa2013-06-25 23:06:36 -0700532 return GetDexFileName("core-libart");
Brian Carlstrom265091e2013-01-30 14:08:26 -0800533 }
534
535 std::string GetDexFileName(const std::string& jar_prefix) {
Elliott Hughes76160052012-12-12 16:31:20 -0800536 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700537 const char* host_dir = getenv("ANDROID_HOST_OUT");
538 CHECK(host_dir != NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800539 return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700540 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800541 return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700542 }
543
Brian Carlstrom3f47c122013-03-07 00:02:40 -0800544 std::string GetTestAndroidRoot() {
545 if (IsHost()) {
546 const char* host_dir = getenv("ANDROID_HOST_OUT");
547 CHECK(host_dir != NULL);
548 return host_dir;
549 }
550 return GetAndroidRoot();
551 }
552
Ian Rogers33e95662013-05-20 20:29:14 -0700553 const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700554 CHECK(name != NULL);
555 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800556 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700557 filename += getenv("ANDROID_HOST_OUT");
558 filename += "/framework/";
559 } else {
560 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700561 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700562 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700563 filename += name;
564 filename += ".jar";
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700565 std::string error_msg;
566 const DexFile* dex_file = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg);
567 CHECK(dex_file != NULL) << "Failed to open '" << filename << "': " << error_msg;
Brian Carlstrome0948e12013-08-29 09:36:15 -0700568 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
569 CHECK(dex_file->IsReadOnly());
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800570 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700571 return dex_file;
572 }
573
Ian Rogers33e95662013-05-20 20:29:14 -0700574 jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700575 const DexFile* dex_file = OpenTestDexFile(dex_name);
576 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700577 class_linker_->RegisterDexFile(*dex_file);
578 std::vector<const DexFile*> class_path;
579 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700580 ScopedObjectAccessUnchecked soa(Thread::Current());
581 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
582 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
583 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800584 soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700585 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
586 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700587 }
588
Ian Rogers33e95662013-05-20 20:29:14 -0700589 void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
590 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800591 std::string class_descriptor(DotToDescriptor(class_name));
Mathieu Chartier590fee92013-09-13 13:46:47 -0700592 SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
593 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700594 CHECK(klass != NULL) << "Class not found " << class_name;
595 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
596 CompileMethod(klass->GetDirectMethod(i));
597 }
598 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
599 CompileMethod(klass->GetVirtualMethod(i));
600 }
601 }
602
Brian Carlstromea46f952013-07-30 01:26:50 -0700603 void CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700604 CHECK(method != NULL);
Ian Rogers5fe9af72013-11-14 00:17:20 -0800605 TimingLogger timings("CommonTest::CompileMethod", false, false);
Anwar Ghuloumbe576f42013-07-25 17:32:40 -0700606 timings.StartSplit("CompileOne");
Brian Carlstrom45602482013-07-21 22:07:55 -0700607 compiler_driver_->CompileOne(method, timings);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700608 MakeExecutable(method);
Ian Rogers5fe9af72013-11-14 00:17:20 -0800609 timings.EndSplit();
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700610 }
611
Mathieu Chartier590fee92013-09-13 13:46:47 -0700612 void CompileDirectMethod(SirtRef<mirror::ClassLoader>& class_loader, const char* class_name,
613 const char* method_name, const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700614 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800615 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800616 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700617 CHECK(klass != NULL) << "Class not found " << class_name;
Brian Carlstromea46f952013-07-30 01:26:50 -0700618 mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700619 CHECK(method != NULL) << "Direct method not found: "
620 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700621 CompileMethod(method);
622 }
623
Mathieu Chartier590fee92013-09-13 13:46:47 -0700624 void CompileVirtualMethod(SirtRef<mirror::ClassLoader>& class_loader, const char* class_name,
625 const char* method_name, const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700626 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800627 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800628 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700629 CHECK(klass != NULL) << "Class not found " << class_name;
Brian Carlstromea46f952013-07-30 01:26:50 -0700630 mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700631 CHECK(method != NULL) << "Virtual method not found: "
632 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700633 CompileMethod(method);
634 }
635
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800636 void ReserveImageSpace() {
637 // Reserve where the image will be loaded up front so that other parts of test set up don't
638 // accidentally end up colliding with the fixed memory address when we need to load the image.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700639 std::string error_msg;
Brian Carlstrom2d888622013-07-18 17:02:00 -0700640 image_reservation_.reset(MemMap::MapAnonymous("image reservation",
641 reinterpret_cast<byte*>(ART_BASE_ADDRESS),
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800642 (size_t)100 * 1024 * 1024, // 100MB
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700643 PROT_NONE, &error_msg));
644 CHECK(image_reservation_.get() != nullptr) << error_msg;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800645 }
646
647 void UnreserveImageSpace() {
648 image_reservation_.reset();
649 }
650
Vladimir Marko95a4de72013-12-18 10:29:11 +0000651 class TestCompilerCallbacks : public CompilerCallbacks {
652 public:
Vladimir Markoc7f83202014-01-24 17:55:18 +0000653 TestCompilerCallbacks() : verification_results_(nullptr), method_inliner_map_(nullptr) { }
Vladimir Marko95a4de72013-12-18 10:29:11 +0000654
Vladimir Markoc7f83202014-01-24 17:55:18 +0000655 void Reset(VerificationResults* verification_results,
Vladimir Marko95a4de72013-12-18 10:29:11 +0000656 DexFileToMethodInlinerMap* method_inliner_map) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000657 verification_results_ = verification_results;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000658 method_inliner_map_ = method_inliner_map;
659 }
660
661 virtual bool MethodVerified(verifier::MethodVerifier* verifier)
662 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000663 CHECK(verification_results_);
664 bool result = verification_results_->ProcessVerifiedMethod(verifier);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000665 if (result && method_inliner_map_ != nullptr) {
666 MethodReference ref = verifier->GetMethodReference();
667 method_inliner_map_->GetMethodInliner(ref.dex_file)
668 ->AnalyseMethodCode(ref.dex_method_index, verifier->CodeItem());
669 }
670 return result;
671 }
672 virtual void ClassRejected(ClassReference ref) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000673 verification_results_->AddRejectedClass(ref);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000674 }
675
676 private:
Vladimir Markoc7f83202014-01-24 17:55:18 +0000677 VerificationResults* verification_results_;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000678 DexFileToMethodInlinerMap* method_inliner_map_;
679 };
680
Elliott Hughes34023802011-08-30 12:06:17 -0700681 std::string android_data_;
Brian Carlstrom7675e162013-06-10 16:18:04 -0700682 std::string dalvik_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800683 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700684 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700685 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700686 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700687 ClassLinker* class_linker_;
Vladimir Markoc7f83202014-01-24 17:55:18 +0000688 UniquePtr<VerificationResults> verification_results_;
Sebastien Hertz102a8f22013-12-18 11:41:30 +0100689 UniquePtr<DexFileToMethodInlinerMap> method_inliner_map_;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000690 TestCompilerCallbacks callbacks_;
Ian Rogers1212a022013-03-04 10:48:41 -0800691 UniquePtr<CompilerDriver> compiler_driver_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700692
693 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800694 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800695 UniquePtr<MemMap> image_reservation_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700696};
697
Elliott Hughesb264f082012-04-06 17:10:10 -0700698// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
699// rather than aborting, so be careful!
700class CheckJniAbortCatcher {
701 public:
702 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
703 vm_->check_jni_abort_hook = Hook;
704 vm_->check_jni_abort_hook_data = &actual_;
705 }
706
707 ~CheckJniAbortCatcher() {
708 vm_->check_jni_abort_hook = NULL;
709 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700710 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700711 }
712
713 void Check(const char* expected_text) {
714 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
715 << "Expected to find: " << expected_text << "\n"
716 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700717 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700718 }
719
720 private:
721 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700722 // We use += because when we're hooking the aborts like this, multiple problems can be found.
723 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700724 }
725
726 JavaVMExt* vm_;
727 std::string actual_;
728
729 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
730};
731
Brian Carlstrom265091e2013-01-30 14:08:26 -0800732// TODO: These tests were disabled for portable when we went to having
733// MCLinker link LLVM ELF output because we no longer just have code
734// blobs in memory. We'll need to dlopen to load and relocate
735// temporary output to resurrect these tests.
736#if defined(ART_USE_PORTABLE_COMPILER)
737#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
738#else
739#define TEST_DISABLED_FOR_PORTABLE()
740#endif
Brian Carlstrom934486c2011-07-12 23:42:50 -0700741} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700742
743namespace std {
744
745// TODO: isn't gtest supposed to be able to print STL types for itself?
746template <typename T>
747std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700748 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700749 return os;
750}
751
752} // namespace std
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700753
754#endif // ART_RUNTIME_COMMON_TEST_H_