blob: 731e1af3807a2f65e7fc8cabda1d9abeee4faa17 [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"
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,
Jeff Hao74180ca2013-03-27 15:29:11 -0700191 const uint8_t* gc_map) {
Brian Carlstromae826982011-11-09 01:33:42 -0800192 return OatFile::OatMethod(NULL,
193 reinterpret_cast<uint32_t>(code),
194 frame_size_in_bytes,
195 core_spill_mask,
196 fp_spill_mask,
197 reinterpret_cast<uint32_t>(mapping_table),
198 reinterpret_cast<uint32_t>(vmap_table),
Jeff Hao74180ca2013-03-27 15:29:11 -0700199 reinterpret_cast<uint32_t>(gc_map)
Ian Rogersc928de92013-02-27 14:30:44 -0800200#if defined(ART_USE_PORTABLE_COMPILER)
Logan Chien971bf3f2012-05-01 15:47:55 +0800201 , 0
Logan Chien0c717dd2012-03-28 18:31:07 +0800202#endif
203 );
Brian Carlstromae826982011-11-09 01:33:42 -0800204 }
205
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800206 void MakeExecutable(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700207 CHECK(method != NULL);
Jeff Hao74180ca2013-03-27 15:29:11 -0700208 LOG(INFO) << "MakeExecutable " << PrettyMethod(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700209
Ian Rogersf3e98552013-03-20 15:49:49 -0700210 const CompiledMethod* compiled_method = NULL;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700211 if (!method->IsAbstract()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800212 const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700213 const DexFile& dex_file = *dex_cache->GetDexFile();
Ian Rogersf3e98552013-03-20 15:49:49 -0700214 compiled_method =
Ian Rogers1212a022013-03-04 10:48:41 -0800215 compiler_driver_->GetCompiledMethod(CompilerDriver::MethodReference(&dex_file,
216 method->GetDexMethodIndex()));
Logan Chienf7015fd2012-03-18 01:19:37 +0800217
Ian Rogersf3e98552013-03-20 15:49:49 -0700218#ifndef ART_SLOW_MODE
219 CHECK(compiled_method != NULL) << PrettyMethod(method);
220#endif
221 }
222 if (compiled_method != NULL) {
Logan Chien971bf3f2012-05-01 15:47:55 +0800223 const std::vector<uint8_t>& code = compiled_method->GetCode();
224 MakeExecutable(code);
225 const void* method_code = CompiledMethod::CodePointer(&code[0],
226 compiled_method->GetInstructionSet());
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700227 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800228 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
229 compiled_method->GetFrameSizeInBytes(),
230 compiled_method->GetCoreSpillMask(),
231 compiled_method->GetFpSpillMask(),
232 &compiled_method->GetMappingTable()[0],
233 &compiled_method->GetVmapTable()[0],
Jeff Hao74180ca2013-03-27 15:29:11 -0700234 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800235 oat_method.LinkMethod(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700236 } else {
Ian Rogersf3e98552013-03-20 15:49:49 -0700237 const void* method_code;
238 if (method->IsAbstract()) {
239 MakeExecutable(runtime_->GetAbstractMethodErrorStubArray());
240 method_code = runtime_->GetAbstractMethodErrorStubArray()->GetData();
241 } else {
242 // No code? You must mean to go into the interpreter.
243 method_code = GetInterpreterEntryPoint();
244 }
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700245 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800246 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
247 kStackAlignment,
248 0,
249 0,
250 NULL,
251 NULL,
Jeff Hao74180ca2013-03-27 15:29:11 -0700252 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800253 oat_method.LinkMethod(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700254 }
255 }
256
257 static void MakeExecutable(const void* code_start, size_t code_length) {
258 CHECK(code_start != NULL);
259 CHECK_NE(code_length, 0U);
260 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700261 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700262 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700263 uintptr_t len = limit - base;
264 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800265 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800266
Ian Rogers16341552011-10-10 11:33:06 -0700267 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800268 // Only uses __builtin___clear_cache if GCC >= 4.3.3
269#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700270 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800271#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800272 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
273 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800274#else
275#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800276#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700277 }
278
Elliott Hughes76160052012-12-12 16:31:20 -0800279 static void SetEnvironmentVariables(std::string& android_data) {
280 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700281 // $ANDROID_ROOT is set on the device, but not on the host.
282 // We need to set this so that icu4c can find its locale data.
283 std::string root;
284 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800285#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700286 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800287#elif defined(__APPLE__)
288 root += "/out/host/darwin-x86";
289#else
290#error unsupported OS
291#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700292 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700293 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700294 }
295
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700296 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
Elliott Hughes76160052012-12-12 16:31:20 -0800297 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
298 if (mkdtemp(&android_data[0]) == NULL) {
299 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700300 }
Elliott Hughes76160052012-12-12 16:31:20 -0800301 setenv("ANDROID_DATA", android_data.c_str(), 1);
302 }
303
304 protected:
305 static bool IsHost() {
306 return (getenv("ANDROID_BUILD_TOP") != NULL);
307 }
308
309 virtual void SetUp() {
310 SetEnvironmentVariables(android_data_);
Elliott Hughes34023802011-08-30 12:06:17 -0700311 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700312 art_cache_.append("/art-cache");
313 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
314 ASSERT_EQ(mkdir_result, 0);
315
Brian Carlstroma004aa92012-02-08 18:05:09 -0800316 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
317 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700318
Mathieu Chartier0051be62012-10-12 17:47:11 -0700319 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
320 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800321
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700322 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700323 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800324 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700325 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800326 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
327 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700328 if(!Runtime::Create(options, false)) {
329 LOG(FATAL) << "Failed to create runtime";
330 return;
331 }
332 runtime_.reset(Runtime::Current());
333 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
334 // give it away now and then switch to a more managable ScopedObjectAccess.
335 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
336 // Whilst we're in native take the opportunity to initialize well known classes.
337 WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
338 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes90a33692011-08-30 13:27:07 -0700339 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700340 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700341
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700342 InstructionSet instruction_set = kNone;
jeffhaoc0228b82012-08-29 18:15:05 -0700343#if defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700344 instruction_set = kThumb2;
jeffhaoc0228b82012-08-29 18:15:05 -0700345#elif defined(__mips__)
346 instruction_set = kMips;
347#elif defined(__i386__)
348 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700349#endif
buzbeec531cef2012-10-18 07:09:20 -0700350
351 // TODO: make selectable
352#if defined(ART_USE_PORTABLE_COMPILER)
353 CompilerBackend compiler_backend = kPortable;
buzbeec531cef2012-10-18 07:09:20 -0700354#else
355 CompilerBackend compiler_backend = kQuick;
356#endif
357
Ian Rogers1212a022013-03-04 10:48:41 -0800358 runtime_->SetJniDlsymLookupStub(CompilerDriver::CreateJniDlsymLookupStub(instruction_set));
359 runtime_->SetAbstractMethodErrorStubArray(CompilerDriver::CreateAbstractMethodErrorStub(instruction_set));
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700360 for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700361 Runtime::TrampolineType type = Runtime::TrampolineType(i);
362 if (!runtime_->HasResolutionStubArray(type)) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700363 runtime_->SetResolutionStubArray(
Ian Rogers1212a022013-03-04 10:48:41 -0800364 CompilerDriver::CreateResolutionStub(instruction_set, type), type);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700365 }
366 }
Ian Rogers19846512012-02-24 11:42:47 -0800367 if (!runtime_->HasResolutionMethod()) {
368 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
369 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700370 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700371 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
372 if (!runtime_->HasCalleeSaveMethod(type)) {
373 runtime_->SetCalleeSaveMethod(
374 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
375 }
376 }
Ian Rogers19846512012-02-24 11:42:47 -0800377 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700378 image_classes_.reset(new std::set<std::string>);
Ian Rogers1212a022013-03-04 10:48:41 -0800379 compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, true, 2, false, image_classes_.get(),
380 true, true));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700381
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700382 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
383 // pool is created by the runtime.
384 runtime_->GetHeap()->CreateThreadPool();
385
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700386 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700387 }
388
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700389 virtual void TearDown() {
390 const char* android_data = getenv("ANDROID_DATA");
391 ASSERT_TRUE(android_data != NULL);
392 DIR* dir = opendir(art_cache_.c_str());
393 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700394 dirent* e;
395 while ((e = readdir(dir)) != NULL) {
396 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700397 continue;
398 }
399 std::string filename(art_cache_);
400 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700401 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700402 int unlink_result = unlink(filename.c_str());
403 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400404 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700405 closedir(dir);
406 int rmdir_cache_result = rmdir(art_cache_.c_str());
407 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700408 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700409 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700410
411 // icu4c has a fixed 10-element array "gCommonICUDataArray".
412 // If we run > 10 tests, we fill that array and u_setCommonData fails.
413 // There's a function to clear the array, but it's not public...
414 typedef void (*IcuCleanupFn)();
415 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
416 CHECK(sym != NULL);
417 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
418 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700419
Ian Rogers1212a022013-03-04 10:48:41 -0800420 compiler_driver_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700421 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800422 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700423
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800424 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700425 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400426
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700427 std::string GetLibCoreDexFileName() {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800428 return GetDexFileName("core");
429 }
430
431 std::string GetDexFileName(const std::string& jar_prefix) {
Elliott Hughes76160052012-12-12 16:31:20 -0800432 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700433 const char* host_dir = getenv("ANDROID_HOST_OUT");
434 CHECK(host_dir != NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800435 return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700436 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800437 return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700438 }
439
Brian Carlstrom3f47c122013-03-07 00:02:40 -0800440 std::string GetTestAndroidRoot() {
441 if (IsHost()) {
442 const char* host_dir = getenv("ANDROID_HOST_OUT");
443 CHECK(host_dir != NULL);
444 return host_dir;
445 }
446 return GetAndroidRoot();
447 }
448
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700449 const DexFile* OpenTestDexFile(const char* name) {
450 CHECK(name != NULL);
451 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800452 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700453 filename += getenv("ANDROID_HOST_OUT");
454 filename += "/framework/";
455 } else {
456 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700457 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700458 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700459 filename += name;
460 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800461 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700462 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800463 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700464 return dex_file;
465 }
466
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700467 jobject LoadDex(const char* dex_name)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700468 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700469 const DexFile* dex_file = OpenTestDexFile(dex_name);
470 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700471 class_linker_->RegisterDexFile(*dex_file);
472 std::vector<const DexFile*> class_path;
473 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700474 ScopedObjectAccessUnchecked soa(Thread::Current());
475 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
476 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
477 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800478 soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700479 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
480 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700481 }
482
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800483 void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800484 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800485 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700486 CHECK(klass != NULL) << "Class not found " << class_name;
487 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
488 CompileMethod(klass->GetDirectMethod(i));
489 }
490 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
491 CompileMethod(klass->GetVirtualMethod(i));
492 }
493 }
494
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800495 void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700496 CHECK(method != NULL);
Ian Rogers1212a022013-03-04 10:48:41 -0800497 compiler_driver_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700498 MakeExecutable(method);
499
Ian Rogers169c9a72011-11-13 20:13:17 -0800500 MakeExecutable(runtime_->GetJniDlsymLookupStub());
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700501 }
502
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800503 void CompileDirectMethod(mirror::ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700504 const char* class_name,
505 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700506 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700507 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800508 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800509 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700510 CHECK(klass != NULL) << "Class not found " << class_name;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800511 mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700512 CHECK(method != NULL) << "Direct method not found: "
513 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700514 CompileMethod(method);
515 }
516
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800517 void CompileVirtualMethod(mirror::ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700518 const char* class_name,
519 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700520 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700521 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800522 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800523 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700524 CHECK(klass != NULL) << "Class not found " << class_name;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800525 mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700526 CHECK(method != NULL) << "Virtual method not found: "
527 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700528 CompileMethod(method);
529 }
530
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800531 void ReserveImageSpace() {
532 // Reserve where the image will be loaded up front so that other parts of test set up don't
533 // accidentally end up colliding with the fixed memory address when we need to load the image.
Ian Rogersa40307e2013-02-22 11:32:44 -0800534 image_reservation_.reset(MemMap::MapAnonymous("image reservation", (byte*)ART_BASE_ADDRESS,
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800535 (size_t)100 * 1024 * 1024, // 100MB
536 PROT_NONE));
537 }
538
539 void UnreserveImageSpace() {
540 image_reservation_.reset();
541 }
542
Elliott Hughes34023802011-08-30 12:06:17 -0700543 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700544 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800545 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700546 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700547 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700548 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700549 ClassLinker* class_linker_;
Ian Rogers1212a022013-03-04 10:48:41 -0800550 UniquePtr<CompilerDriver> compiler_driver_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700551 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700552
553 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800554 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800555 UniquePtr<MemMap> image_reservation_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700556};
557
Elliott Hughesb264f082012-04-06 17:10:10 -0700558// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
559// rather than aborting, so be careful!
560class CheckJniAbortCatcher {
561 public:
562 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
563 vm_->check_jni_abort_hook = Hook;
564 vm_->check_jni_abort_hook_data = &actual_;
565 }
566
567 ~CheckJniAbortCatcher() {
568 vm_->check_jni_abort_hook = NULL;
569 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700570 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700571 }
572
573 void Check(const char* expected_text) {
574 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
575 << "Expected to find: " << expected_text << "\n"
576 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700577 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700578 }
579
580 private:
581 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700582 // We use += because when we're hooking the aborts like this, multiple problems can be found.
583 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700584 }
585
586 JavaVMExt* vm_;
587 std::string actual_;
588
589 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
590};
591
Brian Carlstrom265091e2013-01-30 14:08:26 -0800592// TODO: These tests were disabled for portable when we went to having
593// MCLinker link LLVM ELF output because we no longer just have code
594// blobs in memory. We'll need to dlopen to load and relocate
595// temporary output to resurrect these tests.
596#if defined(ART_USE_PORTABLE_COMPILER)
597#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
598#else
599#define TEST_DISABLED_FOR_PORTABLE()
600#endif
601
Brian Carlstrom934486c2011-07-12 23:42:50 -0700602} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700603
604namespace std {
605
606// TODO: isn't gtest supposed to be able to print STL types for itself?
607template <typename T>
608std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700609 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700610 return os;
611}
612
613} // namespace std