blob: 46a8309c2a0b635f515741e863e82a7b771467e0 [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"
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070029#include "compiler.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070030#include "dex_file.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"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070039#include "scoped_thread_state_change.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080040#include "ScopedLocalRef.h"
Elliott Hughes90a33692011-08-30 13:27:07 -070041#include "thread.h"
Elliott Hughes0f3c5532012-03-30 14:51:51 -070042#include "UniquePtr.h"
Ian Rogers00f7d0e2012-07-19 15:28:27 -070043#include "well_known_classes.h"
Elliott Hughes0af55432011-08-17 18:37:28 -070044
Brian Carlstrom934486c2011-07-12 23:42:50 -070045namespace art {
46
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080047static const byte kBase64Map[256] = {
48 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
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, 62, 255, 255, 255, 63,
52 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
53 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Elliott Hughesa21039c2012-06-21 12:09:25 -070054 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
55 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080056 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Elliott Hughesa21039c2012-06-21 12:09:25 -070057 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
58 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080059 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, 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
70};
71
72byte* DecodeBase64(const char* src, size_t* dst_size) {
73 std::vector<byte> tmp;
Elliott Hughesa21039c2012-06-21 12:09:25 -070074 uint32_t t = 0, y = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080075 int g = 3;
76 for (size_t i = 0; src[i] != '\0'; ++i) {
77 byte c = kBase64Map[src[i] & 0xFF];
78 if (c == 255) continue;
79 // the final = symbols are read and used to trim the remaining bytes
80 if (c == 254) {
81 c = 0;
82 // prevent g < 0 which would potentially allow an overflow later
83 if (--g < 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -070084 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080085 return NULL;
86 }
87 } else if (g != 3) {
88 // we only allow = to be at the end
Brian Carlstrom51477332012-03-25 20:20:26 -070089 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -080090 return NULL;
91 }
92 t = (t << 6) | c;
93 if (++y == 4) {
94 tmp.push_back((t >> 16) & 255);
95 if (g > 1) {
96 tmp.push_back((t >> 8) & 255);
97 }
98 if (g > 2) {
99 tmp.push_back(t & 255);
100 }
101 y = t = 0;
102 }
103 }
104 if (y != 0) {
Brian Carlstrom51477332012-03-25 20:20:26 -0700105 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800106 return NULL;
107 }
108 UniquePtr<byte[]> dst(new byte[tmp.size()]);
109 if (dst_size != NULL) {
110 *dst_size = tmp.size();
Brian Carlstrom51477332012-03-25 20:20:26 -0700111 } else {
112 *dst_size = 0;
Brian Carlstromb9cc1ca2012-01-27 00:57:42 -0800113 }
114 std::copy(tmp.begin(), tmp.end(), dst.get());
115 return dst.release();
116}
117
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700118static inline const DexFile* OpenDexFileBase64(const char* base64,
119 const std::string& location) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700120 // decode base64
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700121 CHECK(base64 != NULL);
122 size_t length;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800123 UniquePtr<byte[]> dex_bytes(DecodeBase64(base64, &length));
124 CHECK(dex_bytes.get() != NULL);
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700125
126 // write to provided file
127 UniquePtr<File> file(OS::OpenFile(location.c_str(), true));
128 CHECK(file.get() != NULL);
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800129 if (!file->WriteFully(dex_bytes.get(), length)) {
Brian Carlstrom33f741e2011-10-03 11:24:05 -0700130 PLOG(FATAL) << "Failed to write base64 as dex file";
131 }
132 file.reset();
133
134 // read dex file
Brian Carlstroma004aa92012-02-08 18:05:09 -0800135 const DexFile* dex_file = DexFile::Open(location, location);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700136 CHECK(dex_file != NULL);
Brian Carlstromf615a612011-07-23 12:50:34 -0700137 return dex_file;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700138}
139
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700140class ScratchFile {
141 public:
142 ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700143 filename_ = getenv("ANDROID_DATA");
144 filename_ += "/TmpFile-XXXXXX";
Elliott Hughes76160052012-12-12 16:31:20 -0800145 int fd = mkstemp(&filename_[0]);
146 CHECK_NE(-1, fd);
147 file_.reset(new File(fd, GetFilename()));
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700148 }
149
150 ~ScratchFile() {
Elliott Hughes34023802011-08-30 12:06:17 -0700151 int unlink_result = unlink(filename_.c_str());
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700152 CHECK_EQ(0, unlink_result);
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700153 }
154
Brian Carlstroma004aa92012-02-08 18:05:09 -0800155 const std::string& GetFilename() const {
156 return filename_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700157 }
158
Elliott Hughes234da572011-11-03 22:13:06 -0700159 File* GetFile() const {
160 return file_.get();
161 }
162
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700163 int GetFd() const {
Elliott Hughes76160052012-12-12 16:31:20 -0800164 return file_->Fd();
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700165 }
166
167 private:
Elliott Hughes34023802011-08-30 12:06:17 -0700168 std::string filename_;
Elliott Hughes234da572011-11-03 22:13:06 -0700169 UniquePtr<File> file_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700170};
171
Brian Carlstromf734cf52011-08-17 16:28:14 -0700172class CommonTest : public testing::Test {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700173 public:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800174 static void MakeExecutable(const mirror::ByteArray* code_array) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700175 CHECK(code_array != NULL);
176 MakeExecutable(code_array->GetData(), code_array->GetLength());
177 }
178
Shih-wei Liao1cb0ae72012-03-16 15:30:19 -0700179 static void MakeExecutable(const std::vector<uint8_t>& code) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700180 CHECK_NE(code.size(), 0U);
181 MakeExecutable(&code[0], code.size());
182 }
183
Brian Carlstromae826982011-11-09 01:33:42 -0800184 // Create an OatMethod based on pointers (for unit tests)
185 OatFile::OatMethod CreateOatMethod(const void* code,
186 const size_t frame_size_in_bytes,
187 const uint32_t core_spill_mask,
188 const uint32_t fp_spill_mask,
189 const uint32_t* mapping_table,
190 const uint16_t* vmap_table,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800191 const uint8_t* gc_map,
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800192 const mirror::AbstractMethod::InvokeStub* invoke_stub) {
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),
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800200 reinterpret_cast<uint32_t>(gc_map),
Logan Chien0c717dd2012-03-28 18:31:07 +0800201 reinterpret_cast<uint32_t>(invoke_stub)
202#if defined(ART_USE_LLVM_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800203 , 0
Logan Chien0c717dd2012-03-28 18:31:07 +0800204#endif
205 );
Brian Carlstromae826982011-11-09 01:33:42 -0800206 }
207
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800208 void MakeExecutable(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700209 CHECK(method != NULL);
210
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800211 MethodHelper mh(method);
Ian Rogers0571d352011-11-03 19:51:38 -0700212 const CompiledInvokeStub* compiled_invoke_stub =
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800213 compiler_->FindInvokeStub(mh.IsStatic(), mh.GetShorty());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700214 CHECK(compiled_invoke_stub != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800215
Logan Chien971bf3f2012-05-01 15:47:55 +0800216 const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
217 MakeExecutable(invoke_stub);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800218 const mirror::AbstractMethod::InvokeStub* method_invoke_stub =
219 reinterpret_cast<const mirror::AbstractMethod::InvokeStub*>(
Logan Chien4284bb92012-06-06 15:30:44 +0800220 CompiledCode::CodePointer(&invoke_stub[0],
221 compiled_invoke_stub->GetInstructionSet()));
Logan Chienf7015fd2012-03-18 01:19:37 +0800222
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700223 LOG(INFO) << "MakeExecutable " << PrettyMethod(method)
224 << " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
225
226 if (!method->IsAbstract()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800227 const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700228 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogers0571d352011-11-03 19:51:38 -0700229 const CompiledMethod* compiled_method =
230 compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
231 method->GetDexMethodIndex()));
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700232 CHECK(compiled_method != NULL) << PrettyMethod(method);
Logan Chienf7015fd2012-03-18 01:19:37 +0800233
Logan Chien971bf3f2012-05-01 15:47:55 +0800234 const std::vector<uint8_t>& code = compiled_method->GetCode();
235 MakeExecutable(code);
236 const void* method_code = CompiledMethod::CodePointer(&code[0],
237 compiled_method->GetInstructionSet());
Logan Chienf7015fd2012-03-18 01:19:37 +0800238
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700239 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Logan Chienf7015fd2012-03-18 01:19:37 +0800240
Brian Carlstromae826982011-11-09 01:33:42 -0800241 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
242 compiled_method->GetFrameSizeInBytes(),
243 compiled_method->GetCoreSpillMask(),
244 compiled_method->GetFpSpillMask(),
245 &compiled_method->GetMappingTable()[0],
246 &compiled_method->GetVmapTable()[0],
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800247 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800248 method_invoke_stub);
249 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700250 } else {
251 MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
252 const void* method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
253 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800254 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
255 kStackAlignment,
256 0,
257 0,
258 NULL,
259 NULL,
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800260 NULL,
Brian Carlstromae826982011-11-09 01:33:42 -0800261 method_invoke_stub);
262 oat_method.LinkMethodPointers(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700263 }
264 }
265
266 static void MakeExecutable(const void* code_start, size_t code_length) {
267 CHECK(code_start != NULL);
268 CHECK_NE(code_length, 0U);
269 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700270 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700271 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700272 uintptr_t len = limit - base;
273 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800274 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800275
Ian Rogers16341552011-10-10 11:33:06 -0700276 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800277 // Only uses __builtin___clear_cache if GCC >= 4.3.3
278#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700279 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800280#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800281 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
282 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800283#else
284#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800285#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700286 }
287
Elliott Hughes76160052012-12-12 16:31:20 -0800288 static void SetEnvironmentVariables(std::string& android_data) {
289 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700290 // $ANDROID_ROOT is set on the device, but not on the host.
291 // We need to set this so that icu4c can find its locale data.
292 std::string root;
293 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800294#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700295 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800296#elif defined(__APPLE__)
297 root += "/out/host/darwin-x86";
298#else
299#error unsupported OS
300#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700301 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700302 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700303 }
304
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700305 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
Elliott Hughes76160052012-12-12 16:31:20 -0800306 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
307 if (mkdtemp(&android_data[0]) == NULL) {
308 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700309 }
Elliott Hughes76160052012-12-12 16:31:20 -0800310 setenv("ANDROID_DATA", android_data.c_str(), 1);
311 }
312
313 protected:
314 static bool IsHost() {
315 return (getenv("ANDROID_BUILD_TOP") != NULL);
316 }
317
318 virtual void SetUp() {
319 SetEnvironmentVariables(android_data_);
Elliott Hughes34023802011-08-30 12:06:17 -0700320 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700321 art_cache_.append("/art-cache");
322 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
323 ASSERT_EQ(mkdir_result, 0);
324
Brian Carlstroma004aa92012-02-08 18:05:09 -0800325 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
326 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700327
Mathieu Chartier0051be62012-10-12 17:47:11 -0700328 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
329 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800330
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700331 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700332 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800333 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700334 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800335 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
336 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700337 if(!Runtime::Create(options, false)) {
338 LOG(FATAL) << "Failed to create runtime";
339 return;
340 }
341 runtime_.reset(Runtime::Current());
342 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
343 // give it away now and then switch to a more managable ScopedObjectAccess.
344 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
345 // Whilst we're in native take the opportunity to initialize well known classes.
346 WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
347 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes90a33692011-08-30 13:27:07 -0700348 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700349 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700350
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700351 InstructionSet instruction_set = kNone;
jeffhaoc0228b82012-08-29 18:15:05 -0700352#if defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700353 instruction_set = kThumb2;
jeffhaoc0228b82012-08-29 18:15:05 -0700354#elif defined(__mips__)
355 instruction_set = kMips;
356#elif defined(__i386__)
357 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700358#endif
buzbeec531cef2012-10-18 07:09:20 -0700359
360 // TODO: make selectable
361#if defined(ART_USE_PORTABLE_COMPILER)
362 CompilerBackend compiler_backend = kPortable;
363#elif defined(ART_USE_LLVM_COMPILER)
364 CompilerBackend compiler_backend = kIceland; // TODO: remove
365#else
366 CompilerBackend compiler_backend = kQuick;
367#endif
368
Elliott Hughes8add92d2012-01-18 18:18:43 -0800369 runtime_->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700370 runtime_->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700371 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700372 Runtime::TrampolineType type = Runtime::TrampolineType(i);
373 if (!runtime_->HasResolutionStubArray(type)) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700374 runtime_->SetResolutionStubArray(
375 Compiler::CreateResolutionStub(instruction_set, type), type);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700376 }
377 }
Ian Rogers19846512012-02-24 11:42:47 -0800378 if (!runtime_->HasResolutionMethod()) {
379 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
380 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700381 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700382 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
383 if (!runtime_->HasCalleeSaveMethod(type)) {
384 runtime_->SetCalleeSaveMethod(
385 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
386 }
387 }
Ian Rogers19846512012-02-24 11:42:47 -0800388 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700389 image_classes_.reset(new std::set<std::string>);
buzbeec531cef2012-10-18 07:09:20 -0700390 compiler_.reset(new Compiler(compiler_backend, instruction_set, true, 2, false, image_classes_.get(),
Brian Carlstromba0668e2012-03-26 13:14:07 -0700391 true, true));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700392
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700393 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
394 // pool is created by the runtime.
395 runtime_->GetHeap()->CreateThreadPool();
396
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700397 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700398 }
399
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700400 virtual void TearDown() {
401 const char* android_data = getenv("ANDROID_DATA");
402 ASSERT_TRUE(android_data != NULL);
403 DIR* dir = opendir(art_cache_.c_str());
404 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700405 dirent* e;
406 while ((e = readdir(dir)) != NULL) {
407 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700408 continue;
409 }
410 std::string filename(art_cache_);
411 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700412 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700413 int unlink_result = unlink(filename.c_str());
414 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400415 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700416 closedir(dir);
417 int rmdir_cache_result = rmdir(art_cache_.c_str());
418 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700419 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700420 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700421
422 // icu4c has a fixed 10-element array "gCommonICUDataArray".
423 // If we run > 10 tests, we fill that array and u_setCommonData fails.
424 // There's a function to clear the array, but it's not public...
425 typedef void (*IcuCleanupFn)();
426 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
427 CHECK(sym != NULL);
428 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
429 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700430
Ian Rogers0e073f72011-09-09 10:45:46 -0700431 compiler_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700432 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800433 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700434
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800435 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700436 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400437
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700438 std::string GetLibCoreDexFileName() {
Elliott Hughes76160052012-12-12 16:31:20 -0800439 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700440 const char* host_dir = getenv("ANDROID_HOST_OUT");
441 CHECK(host_dir != NULL);
442 return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
443 }
Brian Carlstroma56fcd62012-02-04 21:23:01 -0800444 return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700445 }
446
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700447 const DexFile* OpenTestDexFile(const char* name) {
448 CHECK(name != NULL);
449 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800450 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700451 filename += getenv("ANDROID_HOST_OUT");
452 filename += "/framework/";
453 } else {
454 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700455 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700456 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700457 filename += name;
458 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800459 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700460 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800461 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700462 return dex_file;
463 }
464
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700465 jobject LoadDex(const char* dex_name)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700466 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700467 const DexFile* dex_file = OpenTestDexFile(dex_name);
468 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700469 class_linker_->RegisterDexFile(*dex_file);
470 std::vector<const DexFile*> class_path;
471 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700472 ScopedObjectAccessUnchecked soa(Thread::Current());
473 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
474 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
475 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800476 soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700477 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
478 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700479 }
480
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800481 void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800482 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800483 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700484 CHECK(klass != NULL) << "Class not found " << class_name;
485 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
486 CompileMethod(klass->GetDirectMethod(i));
487 }
488 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
489 CompileMethod(klass->GetVirtualMethod(i));
490 }
491 }
492
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800493 void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700494 CHECK(method != NULL);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700495 compiler_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700496 MakeExecutable(method);
497
Ian Rogers169c9a72011-11-13 20:13:17 -0800498 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700499 }
500
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800501 void CompileDirectMethod(mirror::ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700502 const char* class_name,
503 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700504 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700505 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800506 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800507 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700508 CHECK(klass != NULL) << "Class not found " << class_name;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800509 mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700510 CHECK(method != NULL) << "Direct method not found: "
511 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700512 CompileMethod(method);
513 }
514
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800515 void CompileVirtualMethod(mirror::ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700516 const char* class_name,
517 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700518 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700519 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800520 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800521 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700522 CHECK(klass != NULL) << "Class not found " << class_name;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800523 mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700524 CHECK(method != NULL) << "Virtual method not found: "
525 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700526 CompileMethod(method);
527 }
528
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800529 void ReserveImageSpace() {
530 // Reserve where the image will be loaded up front so that other parts of test set up don't
531 // accidentally end up colliding with the fixed memory address when we need to load the image.
532 image_reservation_.reset(MemMap::MapAnonymous("Image reservation", (byte*)ART_BASE_ADDRESS,
533 (size_t)100 * 1024 * 1024, // 100MB
534 PROT_NONE));
535 }
536
537 void UnreserveImageSpace() {
538 image_reservation_.reset();
539 }
540
Elliott Hughes34023802011-08-30 12:06:17 -0700541 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700542 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800543 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700544 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700545 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700546 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700547 ClassLinker* class_linker_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700548 UniquePtr<Compiler> compiler_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700549 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700550
551 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800552 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800553 UniquePtr<MemMap> image_reservation_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700554};
555
Elliott Hughesb264f082012-04-06 17:10:10 -0700556// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
557// rather than aborting, so be careful!
558class CheckJniAbortCatcher {
559 public:
560 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
561 vm_->check_jni_abort_hook = Hook;
562 vm_->check_jni_abort_hook_data = &actual_;
563 }
564
565 ~CheckJniAbortCatcher() {
566 vm_->check_jni_abort_hook = NULL;
567 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700568 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700569 }
570
571 void Check(const char* expected_text) {
572 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
573 << "Expected to find: " << expected_text << "\n"
574 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700575 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700576 }
577
578 private:
579 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700580 // We use += because when we're hooking the aborts like this, multiple problems can be found.
581 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700582 }
583
584 JavaVMExt* vm_;
585 std::string actual_;
586
587 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
588};
589
Brian Carlstrom934486c2011-07-12 23:42:50 -0700590} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700591
592namespace std {
593
594// TODO: isn't gtest supposed to be able to print STL types for itself?
595template <typename T>
596std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700597 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700598 return os;
599}
600
601} // namespace std