blob: 7f9b6b192b704b454925891d6e156fc6a8de6923 [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"
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +000028#include "../compiler/compiler_backend.h"
Sebastien Hertz102a8f22013-12-18 11:41:30 +010029#include "../compiler/dex/quick/dex_file_to_method_inliner_map.h"
Vladimir Markoc7f83202014-01-24 17:55:18 +000030#include "../compiler/dex/verification_results.h"
Sebastien Hertz102a8f22013-12-18 11:41:30 +010031#include "../compiler/driver/compiler_driver.h"
Elliott Hughes76160052012-12-12 16:31:20 -080032#include "base/macros.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080033#include "base/stl_util.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080034#include "base/stringprintf.h"
Elliott Hughes76160052012-12-12 16:31:20 -080035#include "base/unix_file/fd_file.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070036#include "class_linker.h"
Vladimir Marko95a4de72013-12-18 10:29:11 +000037#include "compiler_callbacks.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070038#include "dex_file-inl.h"
Ian Rogers7655f292013-07-29 11:07:13 -070039#include "entrypoints/entrypoint_utils.h"
Ian Rogers1d54e732013-05-02 21:10:01 -070040#include "gc/heap.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070041#include "gtest/gtest.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070042#include "instruction_set.h"
Ian Rogers0f40ac32013-08-13 22:10:30 -070043#include "interpreter/interpreter.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080044#include "mirror/class_loader.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070045#include "oat_file.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080046#include "object_utils.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070047#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070048#include "runtime.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070049#include "scoped_thread_state_change.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080050#include "ScopedLocalRef.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070051#include "thread.h"
Ian Rogersef7d42f2014-01-06 12:55:46 -080052#include "utils.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070053#include "UniquePtr.h"
Vladimir Marko95a4de72013-12-18 10:29:11 +000054#include "verifier/method_verifier.h"
55#include "verifier/method_verifier-inl.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070056#include "well_known_classes.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070057
Brian Carlstrom934486c2011-07-12 23:42:50 -070058namespace art {
59
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080060static const byte kBase64Map[256] = {
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, 255, 255, 255, 255, 255,
64 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
65 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
66 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Brian Carlstrom7934ac22013-07-26 10:54:15 -070067 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
68 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080069 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Brian Carlstrom7934ac22013-07-26 10:54:15 -070070 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
71 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080072 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, 255, 255, 255, 255, 255, 255, 255, 255,
82 255, 255, 255, 255
83};
84
85byte* DecodeBase64(const char* src, size_t* dst_size) {
86 std::vector<byte> tmp;
Elliott Hughesa21039c2012-06-21 12:09:25 -070087 uint32_t t = 0, y = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080088 int g = 3;
89 for (size_t i = 0; src[i] != '\0'; ++i) {
90 byte c = kBase64Map[src[i] & 0xFF];
91 if (c == 255) continue;
92 // the final = symbols are read and used to trim the remaining bytes
93 if (c == 254) {
94 c = 0;
95 // prevent g < 0 which would potentially allow an overflow later
96 if (--g < 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -070097 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080098 return NULL;
99 }
100 } else if (g != 3) {
101 // we only allow = to be at the end
Brian Carlstrom51477332012-03-25 20:20:26 -0700102 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800103 return NULL;
104 }
105 t = (t << 6) | c;
106 if (++y == 4) {
107 tmp.push_back((t >> 16) & 255);
108 if (g > 1) {
109 tmp.push_back((t >> 8) & 255);
110 }
111 if (g > 2) {
112 tmp.push_back(t & 255);
113 }
114 y = t = 0;
115 }
116 }
117 if (y != 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -0700118 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800119 return NULL;
120 }
121 UniquePtr<byte[]> dst(new byte[tmp.size()]);
122 if (dst_size != NULL) {
123 *dst_size = tmp.size();
Brian Carlstrom51477332012-03-25 20:20:26 -0700124 } else {
125 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800126 }
127 std::copy(tmp.begin(), tmp.end(), dst.get());
128 return dst.release();
129}
130
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700131class ScratchFile {
132 public:
133 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700134 filename_ = getenv("ANDROID_DATA");
135 filename_ += "/TmpFile-XXXXXX";
Elliott Hughes76160052012-12-12 16:31:20 -0800136 int fd = mkstemp(&filename_[0]);
137 CHECK_NE(-1, fd);
138 file_.reset(new File(fd, GetFilename()));
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700139 }
140
141 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700142 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700143 CHECK_EQ(0, unlink_result);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700144 }
145
Brian Carlstroma004aa92012-02-08 18:05:09 -0800146 const std::string& GetFilename() const {
147 return filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700148 }
149
Elliott Hughes234da572011-11-03 22:13:06 -0700150 File* GetFile() const {
151 return file_.get();
152 }
153
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700154 int GetFd() const {
Elliott Hughes76160052012-12-12 16:31:20 -0800155 return file_->Fd();
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700156 }
157
158 private:
Elliott Hughes34023802011-08-30 12:06:17 -0700159 std::string filename_;
Elliott Hughes234da572011-11-03 22:13:06 -0700160 UniquePtr<File> file_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700161};
162
Dave Allison70202782013-10-22 17:52:19 -0700163#if defined(__arm__)
164
Elliott Hughesee287732014-01-30 12:09:13 -0800165#include <sys/ucontext.h>
Dave Allison70202782013-10-22 17:52:19 -0700166
167// A signal handler called when have an illegal instruction. We record the fact in
168// a global boolean and then increment the PC in the signal context to return to
169// the next instruction. We know the instruction is an sdiv (4 bytes long).
170static void baddivideinst(int signo, siginfo *si, void *data) {
171 (void)signo;
172 (void)si;
173 struct ucontext *uc = (struct ucontext *)data;
174 struct sigcontext *sc = &uc->uc_mcontext;
175 sc->arm_r0 = 0; // set R0 to #0 to signal error
176 sc->arm_pc += 4; // skip offending instruction
177}
178
179// This is in arch/arm/arm_sdiv.S. It does the following:
180// mov r1,#1
181// sdiv r0,r1,r1
182// bx lr
183//
184// the result will be the value 1 if sdiv is supported. If it is not supported
185// a SIGILL signal will be raised and the signal handler (baddivideinst) called.
186// The signal handler sets r0 to #0 and then increments pc beyond the failed instruction.
187// Thus if the instruction is not supported, the result of this function will be #0
188
189extern "C" bool CheckForARMSDIVInstruction();
190
191static InstructionSetFeatures GuessInstructionFeatures() {
192 InstructionSetFeatures f;
193
194 // Uncomment this for processing of /proc/cpuinfo.
195 if (false) {
196 // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
197 // the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
198 std::ifstream in("/proc/cpuinfo");
199 if (in) {
200 while (!in.eof()) {
201 std::string line;
202 std::getline(in, line);
203 if (!in.eof()) {
204 if (line.find("Features") != std::string::npos) {
205 if (line.find("idivt") != std::string::npos) {
206 f.SetHasDivideInstruction(true);
207 }
208 }
209 }
210 in.close();
211 }
212 } else {
213 LOG(INFO) << "Failed to open /proc/cpuinfo";
214 }
215 }
216
217 // See if have a sdiv instruction. Register a signal handler and try to execute
218 // an sdiv instruction. If we get a SIGILL then it's not supported. We can't use
219 // the /proc/cpuinfo method for this because Krait devices don't always put the idivt
220 // feature in the list.
221 struct sigaction sa, osa;
222 sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
223 sa.sa_sigaction = baddivideinst;
224 sigaction(SIGILL, &sa, &osa);
225
226 if (CheckForARMSDIVInstruction()) {
227 f.SetHasDivideInstruction(true);
228 }
229
230 // Restore the signal handler.
231 sigaction(SIGILL, &osa, NULL);
232
233 // Other feature guesses in here.
234 return f;
235}
236
237#endif
238
239// Given a set of instruction features from the build, parse it. The
240// input 'str' is a comma separated list of feature names. Parse it and
241// return the InstructionSetFeatures object.
242static InstructionSetFeatures ParseFeatureList(std::string str) {
Dave Allison70202782013-10-22 17:52:19 -0700243 InstructionSetFeatures result;
244 typedef std::vector<std::string> FeatureList;
245 FeatureList features;
246 Split(str, ',', features);
247 for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
248 std::string feature = Trim(*i);
249 if (feature == "default") {
250 // Nothing to do.
251 } else if (feature == "div") {
252 // Supports divide instruction.
253 result.SetHasDivideInstruction(true);
254 } else if (feature == "nodiv") {
255 // Turn off support for divide instruction.
256 result.SetHasDivideInstruction(false);
257 } else {
258 LOG(FATAL) << "Unknown instruction set feature: '" << feature << "'";
259 }
260 }
261 // Others...
262 return result;
263}
264
Brian Carlstromf734cf52011-08-17 16:28:14 -0700265class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700266 public:
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700267 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700268 CHECK_NE(code.size(), 0U);
269 MakeExecutable(&code[0], code.size());
270 }
271
Ian Rogers0177e532014-02-11 16:30:46 -0800272 // Create an OatMethod based on pointers (for unit tests).
Brian Carlstromae826982011-11-09 01:33:42 -0800273 OatFile::OatMethod CreateOatMethod(const void* code,
274 const size_t frame_size_in_bytes,
275 const uint32_t core_spill_mask,
276 const uint32_t fp_spill_mask,
Ian Rogers1809a722013-08-09 22:05:32 -0700277 const uint8_t* mapping_table,
278 const uint8_t* vmap_table,
Jeff Hao74180ca2013-03-27 15:29:11 -0700279 const uint8_t* gc_map) {
Ian Rogers0177e532014-02-11 16:30:46 -0800280 const byte* base;
281 uint32_t code_offset, mapping_table_offset, vmap_table_offset, gc_map_offset;
282 if (mapping_table == nullptr && vmap_table == nullptr && gc_map == nullptr) {
283 base = reinterpret_cast<const byte*>(code); // Base of data points at code.
284 base -= kPointerSize; // Move backward so that code_offset != 0.
285 code_offset = kPointerSize;
286 mapping_table_offset = 0;
287 vmap_table_offset = 0;
288 gc_map_offset = 0;
289 } else {
290 // TODO: 64bit support.
291 base = nullptr; // Base of data in oat file, ie 0.
292 code_offset = PointerToLowMemUInt32(code);
293 mapping_table_offset = PointerToLowMemUInt32(mapping_table);
294 vmap_table_offset = PointerToLowMemUInt32(vmap_table);
295 gc_map_offset = PointerToLowMemUInt32(gc_map);
296 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800297 return OatFile::OatMethod(base,
298 code_offset,
299 frame_size_in_bytes,
300 core_spill_mask,
301 fp_spill_mask,
302 mapping_table_offset,
303 vmap_table_offset,
304 gc_map_offset);
Brian Carlstromae826982011-11-09 01:33:42 -0800305 }
306
Brian Carlstromea46f952013-07-30 01:26:50 -0700307 void MakeExecutable(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800308 CHECK(method != nullptr);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700309
Ian Rogersef7d42f2014-01-06 12:55:46 -0800310 const CompiledMethod* compiled_method = nullptr;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700311 if (!method->IsAbstract()) {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800312 mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700313 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogersf3e98552013-03-20 15:49:49 -0700314 compiled_method =
Brian Carlstrom51c24672013-07-11 16:00:56 -0700315 compiler_driver_->GetCompiledMethod(MethodReference(&dex_file,
316 method->GetDexMethodIndex()));
Ian Rogersf3e98552013-03-20 15:49:49 -0700317 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800318 if (compiled_method != nullptr) {
319 const std::vector<uint8_t>* code = compiled_method->GetQuickCode();
320 if (code == nullptr) {
321 code = compiled_method->GetPortableCode();
322 }
323 MakeExecutable(*code);
324 const void* method_code = CompiledMethod::CodePointer(&(*code)[0],
Logan Chien971bf3f2012-05-01 15:47:55 +0800325 compiled_method->GetInstructionSet());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700326 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800327 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
328 compiled_method->GetFrameSizeInBytes(),
329 compiled_method->GetCoreSpillMask(),
330 compiled_method->GetFpSpillMask(),
331 &compiled_method->GetMappingTable()[0],
332 &compiled_method->GetVmapTable()[0],
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(artInterpreterToCompiledCodeBridge);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700336 } else {
Ian Rogers848871b2013-08-05 10:56:33 -0700337 // No code? You must mean to go into the interpreter.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800338 const void* method_code = kUsePortableCompiler ? GetPortableToInterpreterBridge()
339 : GetQuickToInterpreterBridge();
Brian Carlstromae826982011-11-09 01:33:42 -0800340 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
341 kStackAlignment,
342 0,
343 0,
344 NULL,
345 NULL,
Jeff Hao74180ca2013-03-27 15:29:11 -0700346 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800347 oat_method.LinkMethod(method);
Ian Rogers0f40ac32013-08-13 22:10:30 -0700348 method->SetEntryPointFromInterpreter(interpreter::artInterpreterToInterpreterBridge);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700349 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800350 // Create bridges to transition between different kinds of compiled bridge.
351 if (method->GetEntryPointFromPortableCompiledCode() == nullptr) {
352 method->SetEntryPointFromPortableCompiledCode(GetPortableToQuickBridge());
353 } else {
354 CHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr);
355 method->SetEntryPointFromQuickCompiledCode(GetQuickToPortableBridge());
356 method->SetIsPortableCompiled();
357 }
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700358 }
359
360 static void MakeExecutable(const void* code_start, size_t code_length) {
361 CHECK(code_start != NULL);
362 CHECK_NE(code_length, 0U);
363 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700364 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700365 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700366 uintptr_t len = limit - base;
367 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800368 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800369
Ian Rogers16341552011-10-10 11:33:06 -0700370 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800371 // Only uses __builtin___clear_cache if GCC >= 4.3.3
372#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700373 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800374#else
Brian Carlstrom6f485c62013-07-18 15:35:35 -0700375 LOG(FATAL) << "UNIMPLEMENTED: cache flush";
Shih-wei Liao24782c62012-01-08 12:46:11 -0800376#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700377 }
378
Elliott Hughes76160052012-12-12 16:31:20 -0800379 static void SetEnvironmentVariables(std::string& android_data) {
380 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700381 // $ANDROID_ROOT is set on the device, but not on the host.
382 // We need to set this so that icu4c can find its locale data.
383 std::string root;
Brian Carlstrom43534862014-02-19 01:13:52 -0800384 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
385 if (android_build_top != nullptr) {
386 root += android_build_top;
387 } else {
388 // Not set by build server, so default to current directory
389 char* cwd = getcwd(nullptr, 0);
390 setenv("ANDROID_BUILD_TOP", cwd, 1);
391 root += cwd;
392 free(cwd);
393 }
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800394#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700395 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800396#elif defined(__APPLE__)
397 root += "/out/host/darwin-x86";
398#else
399#error unsupported OS
400#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700401 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700402 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Brian Carlstrom43534862014-02-19 01:13:52 -0800403
404 // Not set by build server, so default
405 if (getenv("ANDROID_HOST_OUT") == nullptr) {
406 setenv("ANDROID_HOST_OUT", root.c_str(), 1);
407 }
Elliott Hughes0af55432011-08-17 18:37:28 -0700408 }
409
Brian Carlstrom7675e162013-06-10 16:18:04 -0700410 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
411 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/dalvik-cache/art-data-XXXXXX");
Elliott Hughes76160052012-12-12 16:31:20 -0800412 if (mkdtemp(&android_data[0]) == NULL) {
413 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700414 }
Elliott Hughes76160052012-12-12 16:31:20 -0800415 setenv("ANDROID_DATA", android_data.c_str(), 1);
416 }
417
Ian Rogers1d99e452014-01-02 17:36:41 -0800418 void MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name)
419 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
420 std::string class_descriptor(DotToDescriptor(class_name));
421 SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
422 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
423 CHECK(klass != NULL) << "Class not found " << class_name;
424 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
425 MakeExecutable(klass->GetDirectMethod(i));
426 }
427 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
428 MakeExecutable(klass->GetVirtualMethod(i));
429 }
430 }
431
Elliott Hughes76160052012-12-12 16:31:20 -0800432 protected:
433 static bool IsHost() {
Brian Carlstrom43534862014-02-19 01:13:52 -0800434 return !kIsTargetBuild;
Elliott Hughes76160052012-12-12 16:31:20 -0800435 }
436
437 virtual void SetUp() {
438 SetEnvironmentVariables(android_data_);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700439 dalvik_cache_.append(android_data_.c_str());
440 dalvik_cache_.append("/dalvik-cache");
441 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700442 ASSERT_EQ(mkdir_result, 0);
443
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700444 std::string error_msg;
445 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName().c_str(),
446 GetLibCoreDexFileName().c_str(), &error_msg);
Ian Rogers33e95662013-05-20 20:29:14 -0700447 if (java_lang_dex_file_ == NULL) {
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700448 LOG(FATAL) << "Could not open .dex file '" << GetLibCoreDexFileName() << "': "
449 << error_msg << "\n";
Ian Rogers33e95662013-05-20 20:29:14 -0700450 }
Brian Carlstroma004aa92012-02-08 18:05:09 -0800451 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700452
Ian Rogers1d54e732013-05-02 21:10:01 -0700453 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
454 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800455
Vladimir Marko95a4de72013-12-18 10:29:11 +0000456 // TODO: make selectable
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +0000457 CompilerBackend::Kind compiler_backend = kUsePortableCompiler
458 ? CompilerBackend::kPortable
459 : CompilerBackend::kQuick;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000460
Vladimir Markoc7f83202014-01-24 17:55:18 +0000461 verification_results_.reset(new VerificationResults);
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +0000462 method_inliner_map_.reset(new DexFileToMethodInlinerMap);
Vladimir Markoc7f83202014-01-24 17:55:18 +0000463 callbacks_.Reset(verification_results_.get(), method_inliner_map_.get());
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700464 Runtime::Options options;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000465 options.push_back(std::make_pair("compilercallbacks", static_cast<CompilerCallbacks*>(&callbacks_)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800466 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700467 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800468 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
469 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Brian Carlstromdf629502013-07-17 22:39:56 -0700470 if (!Runtime::Create(options, false)) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700471 LOG(FATAL) << "Failed to create runtime";
472 return;
473 }
474 runtime_.reset(Runtime::Current());
475 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
476 // give it away now and then switch to a more managable ScopedObjectAccess.
477 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
Ian Rogers1d54e732013-05-02 21:10:01 -0700478 {
479 ScopedObjectAccess soa(Thread::Current());
480 ASSERT_TRUE(runtime_.get() != NULL);
481 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700482
Ian Rogers1d54e732013-05-02 21:10:01 -0700483 InstructionSet instruction_set = kNone;
Dave Allison70202782013-10-22 17:52:19 -0700484
Brian Carlstrom1bd2ceb2013-11-06 00:29:48 -0800485 // Take the default set of instruction features from the build.
Dave Allison70202782013-10-22 17:52:19 -0700486 InstructionSetFeatures instruction_set_features =
Brian Carlstrom1bd2ceb2013-11-06 00:29:48 -0800487 ParseFeatureList(STRINGIFY(ART_DEFAULT_INSTRUCTION_SET_FEATURES));
Dave Allison70202782013-10-22 17:52:19 -0700488
jeffhaoc0228b82012-08-29 18:15:05 -0700489#if defined(__arm__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700490 instruction_set = kThumb2;
Dave Allison70202782013-10-22 17:52:19 -0700491 InstructionSetFeatures runtime_features = GuessInstructionFeatures();
492
493 // for ARM, do a runtime check to make sure that the features we are passed from
494 // the build match the features we actually determine at runtime.
495 ASSERT_EQ(instruction_set_features, runtime_features);
jeffhaoc0228b82012-08-29 18:15:05 -0700496#elif defined(__mips__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700497 instruction_set = kMips;
jeffhaoc0228b82012-08-29 18:15:05 -0700498#elif defined(__i386__)
Ian Rogers1d54e732013-05-02 21:10:01 -0700499 instruction_set = kX86;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800500#elif defined(__x86_64__)
501 instruction_set = kX86_64;
Ian Rogers0177e532014-02-11 16:30:46 -0800502 // TODO: x86_64 compilation support.
503 runtime_->SetCompilerFilter(Runtime::kInterpretOnly);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700504#endif
buzbeec531cef2012-10-18 07:09:20 -0700505
Ian Rogers1d54e732013-05-02 21:10:01 -0700506 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
507 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
508 if (!runtime_->HasCalleeSaveMethod(type)) {
509 runtime_->SetCalleeSaveMethod(
510 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
511 }
512 }
513 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000514 timer_.reset(new CumulativeLogger("Compilation times"));
Vladimir Markoc7f83202014-01-24 17:55:18 +0000515 compiler_driver_.reset(new CompilerDriver(verification_results_.get(),
Sebastien Hertz102a8f22013-12-18 11:41:30 +0100516 method_inliner_map_.get(),
517 compiler_backend, instruction_set,
Dave Allison70202782013-10-22 17:52:19 -0700518 instruction_set_features,
Ian Rogers1d54e732013-05-02 21:10:01 -0700519 true, new CompilerDriver::DescriptorSet,
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000520 2, true, true, timer_.get()));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700521 }
Brian Carlstrom96391602013-06-13 19:49:50 -0700522 // We typically don't generate an image in unit tests, disable this optimization by default.
523 compiler_driver_->SetSupportBootImageFixup(false);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700524
Ian Rogers1d54e732013-05-02 21:10:01 -0700525 // We're back in native, take the opportunity to initialize well known classes.
Brian Carlstromea46f952013-07-30 01:26:50 -0700526 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700527 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
528 // pool is created by the runtime.
529 runtime_->GetHeap()->CreateThreadPool();
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700530 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700531 }
532
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700533 virtual void TearDown() {
534 const char* android_data = getenv("ANDROID_DATA");
535 ASSERT_TRUE(android_data != NULL);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700536 DIR* dir = opendir(dalvik_cache_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700537 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700538 dirent* e;
539 while ((e = readdir(dir)) != NULL) {
540 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700541 continue;
542 }
Brian Carlstrom7675e162013-06-10 16:18:04 -0700543 std::string filename(dalvik_cache_);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700544 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700545 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700546 int unlink_result = unlink(filename.c_str());
547 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400548 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700549 closedir(dir);
Brian Carlstrom7675e162013-06-10 16:18:04 -0700550 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700551 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700552 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700553 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700554
555 // icu4c has a fixed 10-element array "gCommonICUDataArray".
556 // If we run > 10 tests, we fill that array and u_setCommonData fails.
557 // There's a function to clear the array, but it's not public...
558 typedef void (*IcuCleanupFn)();
559 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
560 CHECK(sym != NULL);
561 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
562 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700563
Ian Rogers1212a022013-03-04 10:48:41 -0800564 compiler_driver_.reset();
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000565 timer_.reset();
Vladimir Marko95a4de72013-12-18 10:29:11 +0000566 callbacks_.Reset(nullptr, nullptr);
567 method_inliner_map_.reset();
Vladimir Markoc7f83202014-01-24 17:55:18 +0000568 verification_results_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800569 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700570
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800571 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700572 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400573
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700574 std::string GetLibCoreDexFileName() {
Brian Carlstrom3b010aa2013-06-25 23:06:36 -0700575 return GetDexFileName("core-libart");
Brian Carlstrom265091e2013-01-30 14:08:26 -0800576 }
577
578 std::string GetDexFileName(const std::string& jar_prefix) {
Elliott Hughes76160052012-12-12 16:31:20 -0800579 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700580 const char* host_dir = getenv("ANDROID_HOST_OUT");
581 CHECK(host_dir != NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800582 return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700583 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800584 return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700585 }
586
Brian Carlstrom3f47c122013-03-07 00:02:40 -0800587 std::string GetTestAndroidRoot() {
588 if (IsHost()) {
589 const char* host_dir = getenv("ANDROID_HOST_OUT");
590 CHECK(host_dir != NULL);
591 return host_dir;
592 }
593 return GetAndroidRoot();
594 }
595
Ian Rogers33e95662013-05-20 20:29:14 -0700596 const DexFile* OpenTestDexFile(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700597 CHECK(name != NULL);
598 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800599 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700600 filename += getenv("ANDROID_HOST_OUT");
601 filename += "/framework/";
602 } else {
603 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700604 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700605 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700606 filename += name;
607 filename += ".jar";
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700608 std::string error_msg;
609 const DexFile* dex_file = DexFile::Open(filename.c_str(), filename.c_str(), &error_msg);
610 CHECK(dex_file != NULL) << "Failed to open '" << filename << "': " << error_msg;
Brian Carlstrome0948e12013-08-29 09:36:15 -0700611 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
612 CHECK(dex_file->IsReadOnly());
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800613 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700614 return dex_file;
615 }
616
Ian Rogers33e95662013-05-20 20:29:14 -0700617 jobject LoadDex(const char* dex_name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700618 const DexFile* dex_file = OpenTestDexFile(dex_name);
619 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700620 class_linker_->RegisterDexFile(*dex_file);
621 std::vector<const DexFile*> class_path;
622 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700623 ScopedObjectAccessUnchecked soa(Thread::Current());
624 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
625 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
626 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800627 soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700628 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
629 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700630 }
631
Ian Rogers33e95662013-05-20 20:29:14 -0700632 void CompileClass(mirror::ClassLoader* class_loader, const char* class_name)
633 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800634 std::string class_descriptor(DotToDescriptor(class_name));
Mathieu Chartier590fee92013-09-13 13:46:47 -0700635 SirtRef<mirror::ClassLoader> loader(Thread::Current(), class_loader);
636 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700637 CHECK(klass != NULL) << "Class not found " << class_name;
638 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
639 CompileMethod(klass->GetDirectMethod(i));
640 }
641 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
642 CompileMethod(klass->GetVirtualMethod(i));
643 }
644 }
645
Brian Carlstromea46f952013-07-30 01:26:50 -0700646 void CompileMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700647 CHECK(method != NULL);
Ian Rogers5fe9af72013-11-14 00:17:20 -0800648 TimingLogger timings("CommonTest::CompileMethod", false, false);
Anwar Ghuloumbe576f42013-07-25 17:32:40 -0700649 timings.StartSplit("CompileOne");
Brian Carlstrom45602482013-07-21 22:07:55 -0700650 compiler_driver_->CompileOne(method, timings);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700651 MakeExecutable(method);
Ian Rogers5fe9af72013-11-14 00:17:20 -0800652 timings.EndSplit();
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700653 }
654
Mathieu Chartier590fee92013-09-13 13:46:47 -0700655 void CompileDirectMethod(SirtRef<mirror::ClassLoader>& class_loader, const char* class_name,
656 const char* method_name, const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700657 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800658 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800659 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700660 CHECK(klass != NULL) << "Class not found " << class_name;
Brian Carlstromea46f952013-07-30 01:26:50 -0700661 mirror::ArtMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700662 CHECK(method != NULL) << "Direct method not found: "
663 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700664 CompileMethod(method);
665 }
666
Mathieu Chartier590fee92013-09-13 13:46:47 -0700667 void CompileVirtualMethod(SirtRef<mirror::ClassLoader>& class_loader, const char* class_name,
668 const char* method_name, const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700669 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800670 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800671 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700672 CHECK(klass != NULL) << "Class not found " << class_name;
Brian Carlstromea46f952013-07-30 01:26:50 -0700673 mirror::ArtMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700674 CHECK(method != NULL) << "Virtual method not found: "
675 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700676 CompileMethod(method);
677 }
678
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800679 void ReserveImageSpace() {
680 // Reserve where the image will be loaded up front so that other parts of test set up don't
681 // accidentally end up colliding with the fixed memory address when we need to load the image.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700682 std::string error_msg;
Brian Carlstrom2d888622013-07-18 17:02:00 -0700683 image_reservation_.reset(MemMap::MapAnonymous("image reservation",
684 reinterpret_cast<byte*>(ART_BASE_ADDRESS),
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800685 (size_t)100 * 1024 * 1024, // 100MB
Ian Rogersef7d42f2014-01-06 12:55:46 -0800686 PROT_NONE,
687 false /* no need for 4gb flag with fixed mmap*/,
688 &error_msg));
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700689 CHECK(image_reservation_.get() != nullptr) << error_msg;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800690 }
691
692 void UnreserveImageSpace() {
693 image_reservation_.reset();
694 }
695
Vladimir Marko95a4de72013-12-18 10:29:11 +0000696 class TestCompilerCallbacks : public CompilerCallbacks {
697 public:
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000698 TestCompilerCallbacks() : verification_results_(nullptr), method_inliner_map_(nullptr) {}
Vladimir Marko95a4de72013-12-18 10:29:11 +0000699
Vladimir Markoc7f83202014-01-24 17:55:18 +0000700 void Reset(VerificationResults* verification_results,
Vladimir Marko95a4de72013-12-18 10:29:11 +0000701 DexFileToMethodInlinerMap* method_inliner_map) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000702 verification_results_ = verification_results;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000703 method_inliner_map_ = method_inliner_map;
704 }
705
706 virtual bool MethodVerified(verifier::MethodVerifier* verifier)
707 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000708 CHECK(verification_results_);
709 bool result = verification_results_->ProcessVerifiedMethod(verifier);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000710 if (result && method_inliner_map_ != nullptr) {
711 MethodReference ref = verifier->GetMethodReference();
712 method_inliner_map_->GetMethodInliner(ref.dex_file)
Vladimir Marko2bc47802014-02-10 09:43:07 +0000713 ->AnalyseMethodCode(verifier);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000714 }
715 return result;
716 }
717 virtual void ClassRejected(ClassReference ref) {
Vladimir Markoc7f83202014-01-24 17:55:18 +0000718 verification_results_->AddRejectedClass(ref);
Vladimir Marko95a4de72013-12-18 10:29:11 +0000719 }
720
721 private:
Vladimir Markoc7f83202014-01-24 17:55:18 +0000722 VerificationResults* verification_results_;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000723 DexFileToMethodInlinerMap* method_inliner_map_;
724 };
725
Elliott Hughes34023802011-08-30 12:06:17 -0700726 std::string android_data_;
Brian Carlstrom7675e162013-06-10 16:18:04 -0700727 std::string dalvik_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800728 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700729 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700730 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700731 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700732 ClassLinker* class_linker_;
Vladimir Markoc7f83202014-01-24 17:55:18 +0000733 UniquePtr<VerificationResults> verification_results_;
Sebastien Hertz102a8f22013-12-18 11:41:30 +0100734 UniquePtr<DexFileToMethodInlinerMap> method_inliner_map_;
Vladimir Marko95a4de72013-12-18 10:29:11 +0000735 TestCompilerCallbacks callbacks_;
Ian Rogers1212a022013-03-04 10:48:41 -0800736 UniquePtr<CompilerDriver> compiler_driver_;
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000737 UniquePtr<CumulativeLogger> timer_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700738
739 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800740 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800741 UniquePtr<MemMap> image_reservation_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700742};
743
Elliott Hughesb264f082012-04-06 17:10:10 -0700744// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
745// rather than aborting, so be careful!
746class CheckJniAbortCatcher {
747 public:
748 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
749 vm_->check_jni_abort_hook = Hook;
750 vm_->check_jni_abort_hook_data = &actual_;
751 }
752
753 ~CheckJniAbortCatcher() {
754 vm_->check_jni_abort_hook = NULL;
755 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700756 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700757 }
758
759 void Check(const char* expected_text) {
760 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
761 << "Expected to find: " << expected_text << "\n"
762 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700763 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700764 }
765
766 private:
767 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700768 // We use += because when we're hooking the aborts like this, multiple problems can be found.
769 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700770 }
771
772 JavaVMExt* vm_;
773 std::string actual_;
774
775 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
776};
777
Brian Carlstrom265091e2013-01-30 14:08:26 -0800778// TODO: These tests were disabled for portable when we went to having
779// MCLinker link LLVM ELF output because we no longer just have code
780// blobs in memory. We'll need to dlopen to load and relocate
781// temporary output to resurrect these tests.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800782#define TEST_DISABLED_FOR_PORTABLE() \
783 if (kUsePortableCompiler) { \
784 printf("WARNING: TEST DISABLED FOR PORTABLE\n"); \
785 return; \
786 }
787
Brian Carlstrom934486c2011-07-12 23:42:50 -0700788} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700789
790namespace std {
791
792// TODO: isn't gtest supposed to be able to print STL types for itself?
793template <typename T>
794std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700795 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700796 return os;
797}
798
799} // namespace std
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700800
801#endif // ART_RUNTIME_COMMON_TEST_H_