blob: 05b0e05a7b6be2468a4dc2273465be147cfbd58a [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 Carlstromb0460ea2011-07-29 10:08:05 -070017#include <dirent.h>
Elliott Hughes0af55432011-08-17 18:37:28 -070018#include <dlfcn.h>
Brian Carlstrom27ec9612011-09-19 20:20:38 -070019#include <sys/mman.h>
Brian Carlstromb0460ea2011-07-29 10:08:05 -070020#include <sys/stat.h>
21#include <sys/types.h>
22
Elliott Hughesf66330a2012-12-12 17:27:00 -080023#include "../../external/icu4c/common/unicode/uvernum.h"
Elliott Hughes76160052012-12-12 16:31:20 -080024#include "base/macros.h"
Elliott Hughes1aa246d2012-12-13 09:29:36 -080025#include "base/stl_util.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080026#include "base/stringprintf.h"
Elliott Hughes76160052012-12-12 16:31:20 -080027#include "base/unix_file/fd_file.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070028#include "class_linker.h"
Ian Rogers1212a022013-03-04 10:48:41 -080029#include "compiler/driver/compiler_driver.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070030#include "dex_file-inl.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070031#include "gtest/gtest.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070032#include "heap.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070033#include "instruction_set.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080034#include "mirror/class_loader.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070035#include "oat_file.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080036#include "object_utils.h"
Brian Carlstrom33f741e2011-10-03 11:24:05 -070037#include "os.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070038#include "runtime.h"
Jeff Hao58df3272013-04-22 15:28:53 -070039#include "runtime_support.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070040#include "scoped_thread_state_change.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080041#include "ScopedLocalRef.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070042#include "thread.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070043#include "UniquePtr.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070044#include "well_known_classes.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070045
Brian Carlstrom934486c2011-07-12 23:42:50 -070046namespace art {
47
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080048static const byte kBase64Map[256] = {
49 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
50 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
52 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
53 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
54 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Elliott Hughesa21039c2012-06-21 12:09:25 -070055 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
56 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080057 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Elliott Hughesa21039c2012-06-21 12:09:25 -070058 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
59 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080060 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
62 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
63 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
64 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
65 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
66 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
67 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
68 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
69 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
70 255, 255, 255, 255
71};
72
73byte* DecodeBase64(const char* src, size_t* dst_size) {
74 std::vector<byte> tmp;
Elliott Hughesa21039c2012-06-21 12:09:25 -070075 uint32_t t = 0, y = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080076 int g = 3;
77 for (size_t i = 0; src[i] != '\0'; ++i) {
78 byte c = kBase64Map[src[i] & 0xFF];
79 if (c == 255) continue;
80 // the final = symbols are read and used to trim the remaining bytes
81 if (c == 254) {
82 c = 0;
83 // prevent g < 0 which would potentially allow an overflow later
84 if (--g < 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -070085 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080086 return NULL;
87 }
88 } else if (g != 3) {
89 // we only allow = to be at the end
Brian Carlstrom51477332012-03-25 20:20:26 -070090 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080091 return NULL;
92 }
93 t = (t << 6) | c;
94 if (++y == 4) {
95 tmp.push_back((t >> 16) & 255);
96 if (g > 1) {
97 tmp.push_back((t >> 8) & 255);
98 }
99 if (g > 2) {
100 tmp.push_back(t & 255);
101 }
102 y = t = 0;
103 }
104 }
105 if (y != 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -0700106 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800107 return NULL;
108 }
109 UniquePtr<byte[]> dst(new byte[tmp.size()]);
110 if (dst_size != NULL) {
111 *dst_size = tmp.size();
Brian Carlstrom51477332012-03-25 20:20:26 -0700112 } else {
113 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800114 }
115 std::copy(tmp.begin(), tmp.end(), dst.get());
116 return dst.release();
117}
118
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700119static inline const DexFile* OpenDexFileBase64(const char* base64,
120 const std::string& location) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700121 // decode base64
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700122 CHECK(base64 != NULL);
123 size_t length;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800124 UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
125 CHECK(dex_bytes.get() != NULL);
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700126
127 // write to provided file
128 UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
129 CHECK(file.get() != NULL);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800130 if (!file->WriteFully(dex_bytes.get(), length)) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700131 PLOG(FATAL) << "Failed to write base64 as dex file";
132 }
133 file.reset();
134
135 // read dex file
Brian Carlstroma004aa92012-02-08 18:05:09 -0800136 const DexFile* dex_file = DexFile::Open(location, location);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700137 CHECK(dex_file != NULL);
Brian Carlstromf615a612011-07-23 12:50:34 -0700138 return dex_file;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700139}
140
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700141class ScratchFile {
142 public:
143 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700144 filename_ = getenv("ANDROID_DATA");
145 filename_ += "/TmpFile-XXXXXX";
Elliott Hughes76160052012-12-12 16:31:20 -0800146 int fd = mkstemp(&filename_[0]);
147 CHECK_NE(-1, fd);
148 file_.reset(new File(fd, GetFilename()));
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700149 }
150
151 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700152 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700153 CHECK_EQ(0, unlink_result);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700154 }
155
Brian Carlstroma004aa92012-02-08 18:05:09 -0800156 const std::string& GetFilename() const {
157 return filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700158 }
159
Elliott Hughes234da572011-11-03 22:13:06 -0700160 File* GetFile() const {
161 return file_.get();
162 }
163
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700164 int GetFd() const {
Elliott Hughes76160052012-12-12 16:31:20 -0800165 return file_->Fd();
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700166 }
167
168 private:
Elliott Hughes34023802011-08-30 12:06:17 -0700169 std::string filename_;
Elliott Hughes234da572011-11-03 22:13:06 -0700170 UniquePtr<File> file_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700171};
172
Brian Carlstromf734cf52011-08-17 16:28:14 -0700173class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700174 public:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800175 static void MakeExecutable(const mirror::ByteArray* code_array) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700176 CHECK(code_array != NULL);
177 MakeExecutable(code_array->GetData(), code_array->GetLength());
178 }
179
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700180 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700181 CHECK_NE(code.size(), 0U);
182 MakeExecutable(&code[0], code.size());
183 }
184
Brian Carlstromae826982011-11-09 01:33:42 -0800185 // Create an OatMethod based on pointers (for unit tests)
186 OatFile::OatMethod CreateOatMethod(const void* code,
187 const size_t frame_size_in_bytes,
188 const uint32_t core_spill_mask,
189 const uint32_t fp_spill_mask,
190 const uint32_t* mapping_table,
191 const uint16_t* vmap_table,
Jeff Hao74180ca2013-03-27 15:29:11 -0700192 const uint8_t* gc_map) {
Brian Carlstromae826982011-11-09 01:33:42 -0800193 return OatFile::OatMethod(NULL,
194 reinterpret_cast<uint32_t>(code),
195 frame_size_in_bytes,
196 core_spill_mask,
197 fp_spill_mask,
198 reinterpret_cast<uint32_t>(mapping_table),
199 reinterpret_cast<uint32_t>(vmap_table),
Jeff Hao74180ca2013-03-27 15:29:11 -0700200 reinterpret_cast<uint32_t>(gc_map)
Logan Chien0c717dd2012-03-28 18:31:07 +0800201 );
Brian Carlstromae826982011-11-09 01:33:42 -0800202 }
203
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800204 void MakeExecutable(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700205 CHECK(method != NULL);
Jeff Hao74180ca2013-03-27 15:29:11 -0700206 LOG(INFO) << "MakeExecutable " << PrettyMethod(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700207
Ian Rogersf3e98552013-03-20 15:49:49 -0700208 const CompiledMethod* compiled_method = NULL;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700209 if (!method->IsAbstract()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800210 const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700211 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogersf3e98552013-03-20 15:49:49 -0700212 compiled_method =
Ian Rogers1212a022013-03-04 10:48:41 -0800213 compiler_driver_->GetCompiledMethod(CompilerDriver::MethodReference(&dex_file,
214 method->GetDexMethodIndex()));
Logan Chienf7015fd2012-03-18 01:19:37 +0800215
Anwar Ghuloumc4f105d2013-04-10 16:12:11 -0700216#ifndef ART_LIGHT_MODE
Ian Rogersf3e98552013-03-20 15:49:49 -0700217 CHECK(compiled_method != NULL) << PrettyMethod(method);
218#endif
219 }
220 if (compiled_method != NULL) {
Logan Chien971bf3f2012-05-01 15:47:55 +0800221 const std::vector<uint8_t>& code = compiled_method->GetCode();
222 MakeExecutable(code);
223 const void* method_code = CompiledMethod::CodePointer(&code[0],
224 compiled_method->GetInstructionSet());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700225 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800226 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
227 compiled_method->GetFrameSizeInBytes(),
228 compiled_method->GetCoreSpillMask(),
229 compiled_method->GetFpSpillMask(),
230 &compiled_method->GetMappingTable()[0],
231 &compiled_method->GetVmapTable()[0],
Jeff Hao74180ca2013-03-27 15:29:11 -0700232 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800233 oat_method.LinkMethod(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700234 } else {
Ian Rogersf3e98552013-03-20 15:49:49 -0700235 const void* method_code;
236 if (method->IsAbstract()) {
237 MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
238 method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
239 } else {
240 // No code? You must mean to go into the interpreter.
241 method_code = GetInterpreterEntryPoint();
242 }
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700243 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800244 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
245 kStackAlignment,
246 0,
247 0,
248 NULL,
249 NULL,
Jeff Hao74180ca2013-03-27 15:29:11 -0700250 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800251 oat_method.LinkMethod(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700252 }
253 }
254
255 static void MakeExecutable(const void* code_start, size_t code_length) {
256 CHECK(code_start != NULL);
257 CHECK_NE(code_length, 0U);
258 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700259 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700260 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700261 uintptr_t len = limit - base;
262 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800263 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800264
Ian Rogers16341552011-10-10 11:33:06 -0700265 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800266 // Only uses __builtin___clear_cache if GCC >= 4.3.3
267#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700268 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800269#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800270 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
271 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800272#else
273#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800274#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700275 }
276
Elliott Hughes76160052012-12-12 16:31:20 -0800277 static void SetEnvironmentVariables(std::string& android_data) {
278 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700279 // $ANDROID_ROOT is set on the device, but not on the host.
280 // We need to set this so that icu4c can find its locale data.
281 std::string root;
282 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800283#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700284 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800285#elif defined(__APPLE__)
286 root += "/out/host/darwin-x86";
287#else
288#error unsupported OS
289#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700290 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700291 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700292 }
293
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700294 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
Elliott Hughes76160052012-12-12 16:31:20 -0800295 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
296 if (mkdtemp(&android_data[0]) == NULL) {
297 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700298 }
Elliott Hughes76160052012-12-12 16:31:20 -0800299 setenv("ANDROID_DATA", android_data.c_str(), 1);
300 }
301
302 protected:
303 static bool IsHost() {
304 return (getenv("ANDROID_BUILD_TOP") != NULL);
305 }
306
307 virtual void SetUp() {
308 SetEnvironmentVariables(android_data_);
Elliott Hughes34023802011-08-30 12:06:17 -0700309 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700310 art_cache_.append("/art-cache");
311 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
312 ASSERT_EQ(mkdir_result, 0);
313
Brian Carlstroma004aa92012-02-08 18:05:09 -0800314 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
315 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700316
Mathieu Chartier0051be62012-10-12 17:47:11 -0700317 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
318 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800319
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700320 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700321 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800322 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700323 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800324 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
325 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700326 if(!Runtime::Create(options, false)) {
327 LOG(FATAL) << "Failed to create runtime";
328 return;
329 }
330 runtime_.reset(Runtime::Current());
331 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
332 // give it away now and then switch to a more managable ScopedObjectAccess.
333 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
334 // Whilst we're in native take the opportunity to initialize well known classes.
335 WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
336 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes90a33692011-08-30 13:27:07 -0700337 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700338 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700339
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700340 InstructionSet instruction_set = kNone;
jeffhaoc0228b82012-08-29 18:15:05 -0700341#if defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700342 instruction_set = kThumb2;
jeffhaoc0228b82012-08-29 18:15:05 -0700343#elif defined(__mips__)
344 instruction_set = kMips;
345#elif defined(__i386__)
346 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700347#endif
buzbeec531cef2012-10-18 07:09:20 -0700348
349 // TODO: make selectable
350#if defined(ART_USE_PORTABLE_COMPILER)
351 CompilerBackend compiler_backend = kPortable;
buzbeec531cef2012-10-18 07:09:20 -0700352#else
353 CompilerBackend compiler_backend = kQuick;
354#endif
355
Ian Rogers1212a022013-03-04 10:48:41 -0800356 runtime_->SetJniDlsymLookupStub(CompilerDriver::CreateJniDlsymLookupStub(instruction_set));
357 runtime_->SetAbstractMethodErrorStubArray(CompilerDriver::CreateAbstractMethodErrorStub(instruction_set));
Ian Rogers19846512012-02-24 11:42:47 -0800358 if (!runtime_->HasResolutionMethod()) {
359 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
360 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700361 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700362 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
363 if (!runtime_->HasCalleeSaveMethod(type)) {
364 runtime_->SetCalleeSaveMethod(
365 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
366 }
367 }
Ian Rogers19846512012-02-24 11:42:47 -0800368 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700369 image_classes_.reset(new std::set<std::string>);
Anwar Ghuloumc4f105d2013-04-10 16:12:11 -0700370 compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, true, 2, false, false,
371 image_classes_.get(), true, true));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700372
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700373 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
374 // pool is created by the runtime.
375 runtime_->GetHeap()->CreateThreadPool();
376
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700377 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700378 }
379
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700380 virtual void TearDown() {
381 const char* android_data = getenv("ANDROID_DATA");
382 ASSERT_TRUE(android_data != NULL);
383 DIR* dir = opendir(art_cache_.c_str());
384 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700385 dirent* e;
386 while ((e = readdir(dir)) != NULL) {
387 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700388 continue;
389 }
390 std::string filename(art_cache_);
391 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700392 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700393 int unlink_result = unlink(filename.c_str());
394 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400395 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700396 closedir(dir);
397 int rmdir_cache_result = rmdir(art_cache_.c_str());
398 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700399 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700400 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700401
402 // icu4c has a fixed 10-element array "gCommonICUDataArray".
403 // If we run > 10 tests, we fill that array and u_setCommonData fails.
404 // There's a function to clear the array, but it's not public...
405 typedef void (*IcuCleanupFn)();
406 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
407 CHECK(sym != NULL);
408 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
409 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700410
Ian Rogers1212a022013-03-04 10:48:41 -0800411 compiler_driver_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700412 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800413 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700414
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800415 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700416 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400417
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700418 std::string GetLibCoreDexFileName() {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800419 return GetDexFileName("core");
420 }
421
422 std::string GetDexFileName(const std::string& jar_prefix) {
Elliott Hughes76160052012-12-12 16:31:20 -0800423 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700424 const char* host_dir = getenv("ANDROID_HOST_OUT");
425 CHECK(host_dir != NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800426 return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700427 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800428 return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700429 }
430
Brian Carlstrom3f47c122013-03-07 00:02:40 -0800431 std::string GetTestAndroidRoot() {
432 if (IsHost()) {
433 const char* host_dir = getenv("ANDROID_HOST_OUT");
434 CHECK(host_dir != NULL);
435 return host_dir;
436 }
437 return GetAndroidRoot();
438 }
439
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700440 const DexFile* OpenTestDexFile(const char* name) {
441 CHECK(name != NULL);
442 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800443 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700444 filename += getenv("ANDROID_HOST_OUT");
445 filename += "/framework/";
446 } else {
447 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700448 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700449 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700450 filename += name;
451 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800452 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700453 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800454 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700455 return dex_file;
456 }
457
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700458 jobject LoadDex(const char* dex_name)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700459 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700460 const DexFile* dex_file = OpenTestDexFile(dex_name);
461 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700462 class_linker_->RegisterDexFile(*dex_file);
463 std::vector<const DexFile*> class_path;
464 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700465 ScopedObjectAccessUnchecked soa(Thread::Current());
466 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
467 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
468 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800469 soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700470 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
471 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700472 }
473
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800474 void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800475 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800476 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700477 CHECK(klass != NULL) << "Class not found " << class_name;
478 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
479 CompileMethod(klass->GetDirectMethod(i));
480 }
481 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
482 CompileMethod(klass->GetVirtualMethod(i));
483 }
484 }
485
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800486 void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700487 CHECK(method != NULL);
Ian Rogers1212a022013-03-04 10:48:41 -0800488 compiler_driver_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700489 MakeExecutable(method);
490
Ian Rogers169c9a72011-11-13 20:13:17 -0800491 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700492 }
493
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800494 void CompileDirectMethod(mirror::ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700495 const char* class_name,
496 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700497 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700498 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800499 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800500 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700501 CHECK(klass != NULL) << "Class not found " << class_name;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800502 mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700503 CHECK(method != NULL) << "Direct method not found: "
504 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700505 CompileMethod(method);
506 }
507
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800508 void CompileVirtualMethod(mirror::ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700509 const char* class_name,
510 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700511 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700512 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800513 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800514 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700515 CHECK(klass != NULL) << "Class not found " << class_name;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800516 mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700517 CHECK(method != NULL) << "Virtual method not found: "
518 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700519 CompileMethod(method);
520 }
521
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800522 void ReserveImageSpace() {
523 // Reserve where the image will be loaded up front so that other parts of test set up don't
524 // accidentally end up colliding with the fixed memory address when we need to load the image.
Ian Rogersa40307e2013-02-22 11:32:44 -0800525 image_reservation_.reset(MemMap::MapAnonymous("image reservation", (byte*)ART_BASE_ADDRESS,
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800526 (size_t)100 * 1024 * 1024, // 100MB
527 PROT_NONE));
528 }
529
530 void UnreserveImageSpace() {
531 image_reservation_.reset();
532 }
533
Elliott Hughes34023802011-08-30 12:06:17 -0700534 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700535 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800536 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700537 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700538 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700539 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700540 ClassLinker* class_linker_;
Ian Rogers1212a022013-03-04 10:48:41 -0800541 UniquePtr<CompilerDriver> compiler_driver_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700542 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700543
544 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800545 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800546 UniquePtr<MemMap> image_reservation_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700547};
548
Elliott Hughesb264f082012-04-06 17:10:10 -0700549// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
550// rather than aborting, so be careful!
551class CheckJniAbortCatcher {
552 public:
553 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
554 vm_->check_jni_abort_hook = Hook;
555 vm_->check_jni_abort_hook_data = &actual_;
556 }
557
558 ~CheckJniAbortCatcher() {
559 vm_->check_jni_abort_hook = NULL;
560 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700561 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700562 }
563
564 void Check(const char* expected_text) {
565 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
566 << "Expected to find: " << expected_text << "\n"
567 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700568 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700569 }
570
571 private:
572 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700573 // We use += because when we're hooking the aborts like this, multiple problems can be found.
574 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700575 }
576
577 JavaVMExt* vm_;
578 std::string actual_;
579
580 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
581};
582
Brian Carlstrom265091e2013-01-30 14:08:26 -0800583// TODO: These tests were disabled for portable when we went to having
584// MCLinker link LLVM ELF output because we no longer just have code
585// blobs in memory. We'll need to dlopen to load and relocate
586// temporary output to resurrect these tests.
587#if defined(ART_USE_PORTABLE_COMPILER)
588#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
589#else
590#define TEST_DISABLED_FOR_PORTABLE()
591#endif
592
Brian Carlstrom934486c2011-07-12 23:42:50 -0700593} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700594
595namespace std {
596
597// TODO: isn't gtest supposed to be able to print STL types for itself?
598template <typename T>
599std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700600 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700601 return os;
602}
603
604} // namespace std