blob: 78d86d2f90af73276b91b0bb3f849ea9df680d70 [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()) {
Jeff Hao79fe5392013-04-24 18:41:58 -0700237 method_code = GetAbstractMethodErrorStub();
Ian Rogersf3e98552013-03-20 15:49:49 -0700238 } else {
239 // No code? You must mean to go into the interpreter.
240 method_code = GetInterpreterEntryPoint();
241 }
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700242 LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;
Brian Carlstromae826982011-11-09 01:33:42 -0800243 OatFile::OatMethod oat_method = CreateOatMethod(method_code,
244 kStackAlignment,
245 0,
246 0,
247 NULL,
248 NULL,
Jeff Hao74180ca2013-03-27 15:29:11 -0700249 NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800250 oat_method.LinkMethod(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700251 }
252 }
253
254 static void MakeExecutable(const void* code_start, size_t code_length) {
255 CHECK(code_start != NULL);
256 CHECK_NE(code_length, 0U);
257 uintptr_t data = reinterpret_cast<uintptr_t>(code_start);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700258 uintptr_t base = RoundDown(data, kPageSize);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700259 uintptr_t limit = RoundUp(data + code_length, kPageSize);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700260 uintptr_t len = limit - base;
261 int result = mprotect(reinterpret_cast<void*>(base), len, PROT_READ | PROT_WRITE | PROT_EXEC);
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800262 CHECK_EQ(result, 0);
Shih-wei Liao24782c62012-01-08 12:46:11 -0800263
Ian Rogers16341552011-10-10 11:33:06 -0700264 // Flush instruction cache
Shih-wei Liao24782c62012-01-08 12:46:11 -0800265 // Only uses __builtin___clear_cache if GCC >= 4.3.3
266#if GCC_VERSION >= 40303
Ian Rogers16341552011-10-10 11:33:06 -0700267 __builtin___clear_cache(reinterpret_cast<void*>(base), reinterpret_cast<void*>(base + len));
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800268#elif defined(__APPLE__)
Shih-wei Liao24782c62012-01-08 12:46:11 -0800269 // Currently, only Mac OS builds use GCC 4.2.*. Those host builds do not
270 // need to generate clear_cache on x86.
Brian Carlstrom7a00a3c2012-01-25 18:38:03 -0800271#else
272#error unsupported
Shih-wei Liao24782c62012-01-08 12:46:11 -0800273#endif
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700274 }
275
Elliott Hughes76160052012-12-12 16:31:20 -0800276 static void SetEnvironmentVariables(std::string& android_data) {
277 if (IsHost()) {
Elliott Hughes0af55432011-08-17 18:37:28 -0700278 // $ANDROID_ROOT is set on the device, but not on the host.
279 // We need to set this so that icu4c can find its locale data.
280 std::string root;
281 root += getenv("ANDROID_BUILD_TOP");
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800282#if defined(__linux__)
Elliott Hughes0af55432011-08-17 18:37:28 -0700283 root += "/out/host/linux-x86";
Elliott Hughesa0cb1202012-01-23 17:34:32 -0800284#elif defined(__APPLE__)
285 root += "/out/host/darwin-x86";
286#else
287#error unsupported OS
288#endif
Elliott Hughes0af55432011-08-17 18:37:28 -0700289 setenv("ANDROID_ROOT", root.c_str(), 1);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700290 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
Elliott Hughes0af55432011-08-17 18:37:28 -0700291 }
292
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700293 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of art-cache
Elliott Hughes76160052012-12-12 16:31:20 -0800294 android_data = (IsHost() ? "/tmp/art-data-XXXXXX" : "/data/art-cache/art-data-XXXXXX");
295 if (mkdtemp(&android_data[0]) == NULL) {
296 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700297 }
Elliott Hughes76160052012-12-12 16:31:20 -0800298 setenv("ANDROID_DATA", android_data.c_str(), 1);
299 }
300
301 protected:
302 static bool IsHost() {
303 return (getenv("ANDROID_BUILD_TOP") != NULL);
304 }
305
306 virtual void SetUp() {
307 SetEnvironmentVariables(android_data_);
Elliott Hughes34023802011-08-30 12:06:17 -0700308 art_cache_.append(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700309 art_cache_.append("/art-cache");
310 int mkdir_result = mkdir(art_cache_.c_str(), 0700);
311 ASSERT_EQ(mkdir_result, 0);
312
Brian Carlstroma004aa92012-02-08 18:05:09 -0800313 java_lang_dex_file_ = DexFile::Open(GetLibCoreDexFileName(), GetLibCoreDexFileName());
Brian Carlstrom654d9192013-04-30 18:35:32 -0700314 conscrypt_file_ = DexFile::Open(GetConscryptFileName(), GetConscryptFileName());
Brian Carlstroma004aa92012-02-08 18:05:09 -0800315 boot_class_path_.push_back(java_lang_dex_file_);
Brian Carlstrom654d9192013-04-30 18:35:32 -0700316 boot_class_path_.push_back(conscrypt_file_);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700317
Mathieu Chartier0051be62012-10-12 17:47:11 -0700318 std::string min_heap_string(StringPrintf("-Xms%zdm", Heap::kDefaultInitialSize / MB));
319 std::string max_heap_string(StringPrintf("-Xmx%zdm", Heap::kDefaultMaximumSize / MB));
Ian Rogers30fab402012-01-23 15:43:46 -0800320
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700321 Runtime::Options options;
Brian Carlstroma4a7b482011-10-16 15:29:16 -0700322 options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
Brian Carlstroma004aa92012-02-08 18:05:09 -0800323 options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700324 options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
Ian Rogers30fab402012-01-23 15:43:46 -0800325 options.push_back(std::make_pair(min_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
326 options.push_back(std::make_pair(max_heap_string.c_str(), reinterpret_cast<void*>(NULL)));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700327 if(!Runtime::Create(options, false)) {
328 LOG(FATAL) << "Failed to create runtime";
329 return;
330 }
331 runtime_.reset(Runtime::Current());
332 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
333 // give it away now and then switch to a more managable ScopedObjectAccess.
334 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
335 // Whilst we're in native take the opportunity to initialize well known classes.
336 WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
337 ScopedObjectAccess soa(Thread::Current());
Elliott Hughes90a33692011-08-30 13:27:07 -0700338 ASSERT_TRUE(runtime_.get() != NULL);
Carl Shapiro7a909592011-07-24 19:21:59 -0700339 class_linker_ = runtime_->GetClassLinker();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700340
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700341 InstructionSet instruction_set = kNone;
jeffhaoc0228b82012-08-29 18:15:05 -0700342#if defined(__arm__)
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700343 instruction_set = kThumb2;
jeffhaoc0228b82012-08-29 18:15:05 -0700344#elif defined(__mips__)
345 instruction_set = kMips;
346#elif defined(__i386__)
347 instruction_set = kX86;
Ian Rogers2c8f6532011-09-02 17:16:34 -0700348#endif
buzbeec531cef2012-10-18 07:09:20 -0700349
350 // TODO: make selectable
351#if defined(ART_USE_PORTABLE_COMPILER)
352 CompilerBackend compiler_backend = kPortable;
buzbeec531cef2012-10-18 07:09:20 -0700353#else
354 CompilerBackend compiler_backend = kQuick;
355#endif
356
Ian Rogers19846512012-02-24 11:42:47 -0800357 if (!runtime_->HasResolutionMethod()) {
358 runtime_->SetResolutionMethod(runtime_->CreateResolutionMethod());
359 }
Elliott Hughes362f9bc2011-10-17 18:56:41 -0700360 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
Ian Rogers4f0d07c2011-10-06 23:38:47 -0700361 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
362 if (!runtime_->HasCalleeSaveMethod(type)) {
363 runtime_->SetCalleeSaveMethod(
364 runtime_->CreateCalleeSaveMethod(instruction_set, type), type);
365 }
366 }
Ian Rogers19846512012-02-24 11:42:47 -0800367 class_linker_->FixupDexCaches(runtime_->GetResolutionMethod());
Elliott Hughese52e49b2012-04-02 16:05:44 -0700368 image_classes_.reset(new std::set<std::string>);
Anwar Ghuloumc4f105d2013-04-10 16:12:11 -0700369 compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, true, 2, false, false,
370 image_classes_.get(), true, true));
Ian Rogers2c8f6532011-09-02 17:16:34 -0700371
Mathieu Chartier02b6a782012-10-26 13:51:26 -0700372 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
373 // pool is created by the runtime.
374 runtime_->GetHeap()->CreateThreadPool();
375
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700376 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700377 }
378
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700379 virtual void TearDown() {
380 const char* android_data = getenv("ANDROID_DATA");
381 ASSERT_TRUE(android_data != NULL);
382 DIR* dir = opendir(art_cache_.c_str());
383 ASSERT_TRUE(dir != NULL);
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700384 dirent* e;
385 while ((e = readdir(dir)) != NULL) {
386 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700387 continue;
388 }
389 std::string filename(art_cache_);
390 filename.push_back('/');
Elliott Hughes4696b5b2012-10-30 10:35:10 -0700391 filename.append(e->d_name);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700392 int unlink_result = unlink(filename.c_str());
393 ASSERT_EQ(0, unlink_result);
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400394 }
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700395 closedir(dir);
396 int rmdir_cache_result = rmdir(art_cache_.c_str());
397 ASSERT_EQ(0, rmdir_cache_result);
Elliott Hughes34023802011-08-30 12:06:17 -0700398 int rmdir_data_result = rmdir(android_data_.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700399 ASSERT_EQ(0, rmdir_data_result);
Elliott Hughes0af55432011-08-17 18:37:28 -0700400
401 // icu4c has a fixed 10-element array "gCommonICUDataArray".
402 // If we run > 10 tests, we fill that array and u_setCommonData fails.
403 // There's a function to clear the array, but it's not public...
404 typedef void (*IcuCleanupFn)();
405 void* sym = dlsym(RTLD_DEFAULT, "u_cleanup_" U_ICU_VERSION_SHORT);
406 CHECK(sym != NULL);
407 IcuCleanupFn icu_cleanup_fn = reinterpret_cast<IcuCleanupFn>(sym);
408 (*icu_cleanup_fn)();
Ian Rogers0cfe1fb2011-08-26 03:29:44 -0700409
Ian Rogers1212a022013-03-04 10:48:41 -0800410 compiler_driver_.reset();
Elliott Hughese52e49b2012-04-02 16:05:44 -0700411 image_classes_.reset();
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800412 STLDeleteElements(&opened_dex_files_);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700413
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800414 Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700415 }
Jesse Wilsonac5b9e22011-07-27 15:11:13 -0400416
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700417 std::string GetLibCoreDexFileName() {
Brian Carlstrom265091e2013-01-30 14:08:26 -0800418 return GetDexFileName("core");
419 }
420
Brian Carlstrom654d9192013-04-30 18:35:32 -0700421 std::string GetConscryptFileName() {
422 return GetDexFileName("conscrypt");
423 }
424
Brian Carlstrom265091e2013-01-30 14:08:26 -0800425 std::string GetDexFileName(const std::string& jar_prefix) {
Elliott Hughes76160052012-12-12 16:31:20 -0800426 if (IsHost()) {
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700427 const char* host_dir = getenv("ANDROID_HOST_OUT");
428 CHECK(host_dir != NULL);
Brian Carlstrom265091e2013-01-30 14:08:26 -0800429 return StringPrintf("%s/framework/%s-hostdex.jar", host_dir, jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700430 }
Brian Carlstrom265091e2013-01-30 14:08:26 -0800431 return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700432 }
433
Brian Carlstrom3f47c122013-03-07 00:02:40 -0800434 std::string GetTestAndroidRoot() {
435 if (IsHost()) {
436 const char* host_dir = getenv("ANDROID_HOST_OUT");
437 CHECK(host_dir != NULL);
438 return host_dir;
439 }
440 return GetAndroidRoot();
441 }
442
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700443 const DexFile* OpenTestDexFile(const char* name) {
444 CHECK(name != NULL);
445 std::string filename;
Elliott Hughes76160052012-12-12 16:31:20 -0800446 if (IsHost()) {
Brian Carlstromb2793372012-03-17 18:27:16 -0700447 filename += getenv("ANDROID_HOST_OUT");
448 filename += "/framework/";
449 } else {
450 filename += "/data/nativetest/art/";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700451 }
Brian Carlstromb2793372012-03-17 18:27:16 -0700452 filename += "art-test-dex-";
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700453 filename += name;
454 filename += ".jar";
Brian Carlstroma004aa92012-02-08 18:05:09 -0800455 const DexFile* dex_file = DexFile::Open(filename, filename);
Brian Carlstrom69b15fb2011-09-03 12:25:21 -0700456 CHECK(dex_file != NULL) << "Failed to open " << filename;
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800457 opened_dex_files_.push_back(dex_file);
Brian Carlstrom9f30b382011-08-28 22:41:38 -0700458 return dex_file;
459 }
460
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700461 jobject LoadDex(const char* dex_name)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700462 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700463 const DexFile* dex_file = OpenTestDexFile(dex_name);
464 CHECK(dex_file != NULL);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700465 class_linker_->RegisterDexFile(*dex_file);
466 std::vector<const DexFile*> class_path;
467 class_path.push_back(dex_file);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700468 ScopedObjectAccessUnchecked soa(Thread::Current());
469 ScopedLocalRef<jobject> class_loader_local(soa.Env(),
470 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
471 jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800472 soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700473 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
474 return class_loader;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700475 }
476
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800477 void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
Elliott Hughes95572412011-12-13 18:14:20 -0800478 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800479 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstromaded5f72011-10-07 17:15:04 -0700480 CHECK(klass != NULL) << "Class not found " << class_name;
481 for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
482 CompileMethod(klass->GetDirectMethod(i));
483 }
484 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
485 CompileMethod(klass->GetVirtualMethod(i));
486 }
487 }
488
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800489 void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700490 CHECK(method != NULL);
Ian Rogers1212a022013-03-04 10:48:41 -0800491 compiler_driver_->CompileOne(method);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700492 MakeExecutable(method);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700493 }
494
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800495 void CompileDirectMethod(mirror::ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700496 const char* class_name,
497 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700498 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700499 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800500 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800501 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700502 CHECK(klass != NULL) << "Class not found " << class_name;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800503 mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700504 CHECK(method != NULL) << "Direct method not found: "
505 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700506 CompileMethod(method);
507 }
508
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800509 void CompileVirtualMethod(mirror::ClassLoader* class_loader,
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700510 const char* class_name,
511 const char* method_name,
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700512 const char* signature)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700513 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800514 std::string class_descriptor(DotToDescriptor(class_name));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800515 mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700516 CHECK(klass != NULL) << "Class not found " << class_name;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800517 mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
Elliott Hughes0f4c41d2011-09-04 14:58:03 -0700518 CHECK(method != NULL) << "Virtual method not found: "
519 << class_name << "." << method_name << signature;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700520 CompileMethod(method);
521 }
522
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800523 void ReserveImageSpace() {
524 // Reserve where the image will be loaded up front so that other parts of test set up don't
525 // accidentally end up colliding with the fixed memory address when we need to load the image.
Ian Rogersa40307e2013-02-22 11:32:44 -0800526 image_reservation_.reset(MemMap::MapAnonymous("image reservation", (byte*)ART_BASE_ADDRESS,
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800527 (size_t)100 * 1024 * 1024, // 100MB
528 PROT_NONE));
529 }
530
531 void UnreserveImageSpace() {
532 image_reservation_.reset();
533 }
534
Elliott Hughes34023802011-08-30 12:06:17 -0700535 std::string android_data_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700536 std::string art_cache_;
Brian Carlstroma004aa92012-02-08 18:05:09 -0800537 const DexFile* java_lang_dex_file_; // owned by runtime_
Brian Carlstrom654d9192013-04-30 18:35:32 -0700538 const DexFile* conscrypt_file_; // owned by runtime_
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700539 std::vector<const DexFile*> boot_class_path_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700540 UniquePtr<Runtime> runtime_;
Ian Rogers0e073f72011-09-09 10:45:46 -0700541 // Owned by the runtime
Carl Shapiro7a909592011-07-24 19:21:59 -0700542 ClassLinker* class_linker_;
Ian Rogers1212a022013-03-04 10:48:41 -0800543 UniquePtr<CompilerDriver> compiler_driver_;
Elliott Hughese52e49b2012-04-02 16:05:44 -0700544 UniquePtr<std::set<std::string> > image_classes_;
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700545
546 private:
Elliott Hughes4d6850c2012-01-18 15:55:06 -0800547 std::vector<const DexFile*> opened_dex_files_;
Brian Carlstrom700c8d32012-11-05 10:42:02 -0800548 UniquePtr<MemMap> image_reservation_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700549};
550
Elliott Hughesb264f082012-04-06 17:10:10 -0700551// Sets a CheckJni abort hook to catch failures. Note that this will cause CheckJNI to carry on
552// rather than aborting, so be careful!
553class CheckJniAbortCatcher {
554 public:
555 CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
556 vm_->check_jni_abort_hook = Hook;
557 vm_->check_jni_abort_hook_data = &actual_;
558 }
559
560 ~CheckJniAbortCatcher() {
561 vm_->check_jni_abort_hook = NULL;
562 vm_->check_jni_abort_hook_data = NULL;
Elliott Hughes56ef0422012-06-19 14:35:04 -0700563 EXPECT_TRUE(actual_.empty()) << actual_;
Elliott Hughesb264f082012-04-06 17:10:10 -0700564 }
565
566 void Check(const char* expected_text) {
567 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
568 << "Expected to find: " << expected_text << "\n"
569 << "In the output : " << actual_;
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700570 actual_.clear();
Elliott Hughesb264f082012-04-06 17:10:10 -0700571 }
572
573 private:
574 static void Hook(void* data, const std::string& reason) {
Elliott Hughes3f6635a2012-06-19 13:37:49 -0700575 // We use += because when we're hooking the aborts like this, multiple problems can be found.
576 *reinterpret_cast<std::string*>(data) += reason;
Elliott Hughesb264f082012-04-06 17:10:10 -0700577 }
578
579 JavaVMExt* vm_;
580 std::string actual_;
581
582 DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher);
583};
584
Brian Carlstrom265091e2013-01-30 14:08:26 -0800585// TODO: These tests were disabled for portable when we went to having
586// MCLinker link LLVM ELF output because we no longer just have code
587// blobs in memory. We'll need to dlopen to load and relocate
588// temporary output to resurrect these tests.
589#if defined(ART_USE_PORTABLE_COMPILER)
590#define TEST_DISABLED_FOR_PORTABLE() printf("WARNING: TEST DISABLED FOR PORTABLE\n"); return
591#else
592#define TEST_DISABLED_FOR_PORTABLE()
593#endif
594
Brian Carlstrom934486c2011-07-12 23:42:50 -0700595} // namespace art
Elliott Hughes34023802011-08-30 12:06:17 -0700596
597namespace std {
598
599// TODO: isn't gtest supposed to be able to print STL types for itself?
600template <typename T>
601std::ostream& operator<<(std::ostream& os, const std::vector<T>& rhs) {
Elliott Hughes14134a12011-09-30 16:55:51 -0700602 os << ::art::ToString(rhs);
Elliott Hughes34023802011-08-30 12:06:17 -0700603 return os;
604}
605
606} // namespace std