blob: 39dbebfdf24da5a2d2621213966288df9237bf5b [file] [log] [blame]
Elliott Hugheseb02a122012-06-12 11:35:40 -07001/*
2 * Copyright (C) 2012 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 */
16
Ian Rogerse63db272014-07-15 15:36:11 -070017#include "common_runtime_test.h"
18
19#include <dirent.h>
20#include <dlfcn.h>
21#include <fcntl.h>
Andreas Gampe369810a2015-01-14 19:53:31 -080022#include <stdlib.h>
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070023#include <cstdio>
Andreas Gampe373a9b52017-10-18 09:01:57 -070024#include "nativehelper/scoped_local_ref.h"
Ian Rogerse63db272014-07-15 15:36:11 -070025
Andreas Gampe46ee31b2016-12-14 10:11:49 -080026#include "android-base/stringprintf.h"
Andreas Gampefdb7a612017-11-01 15:11:13 -070027#include <unicode/uvernum.h>
Andreas Gampe46ee31b2016-12-14 10:11:49 -080028
Mathieu Chartiere401d142015-04-22 13:56:20 -070029#include "art_field-inl.h"
David Sehr891a50e2017-10-27 17:01:07 -070030#include "base/file_utils.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080031#include "base/logging.h"
Steven Morelande431e272017-07-18 16:53:49 -070032#include "base/macros.h"
Andreas Gampedcc528d2017-12-07 13:37:10 -080033#include "base/runtime_debug.h"
Ian Rogerse63db272014-07-15 15:36:11 -070034#include "base/stl_util.h"
Ian Rogerse63db272014-07-15 15:36:11 -070035#include "base/unix_file/fd_file.h"
36#include "class_linker.h"
37#include "compiler_callbacks.h"
David Sehr013fd802018-01-11 22:55:24 -080038#include "dex/art_dex_file_loader.h"
David Sehr9e734c72018-01-04 17:56:19 -080039#include "dex/dex_file-inl.h"
40#include "dex/dex_file_loader.h"
Ian Rogerse63db272014-07-15 15:36:11 -070041#include "gc/heap.h"
Steven Morelande431e272017-07-18 16:53:49 -070042#include "gc_root-inl.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070043#include "gtest/gtest.h"
Andreas Gampe81c6f8d2015-03-25 17:19:53 -070044#include "handle_scope-inl.h"
Andreas Gampe9b5cba42015-03-11 09:53:50 -070045#include "interpreter/unstarted_runtime.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070046#include "java_vm_ext.h"
Ian Rogerse63db272014-07-15 15:36:11 -070047#include "jni_internal.h"
Steven Morelande431e272017-07-18 16:53:49 -070048#include "mem_map.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070049#include "mirror/class-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070050#include "mirror/class_loader.h"
Mathieu Chartiere58991b2015-10-13 07:59:34 -070051#include "native/dalvik_system_DexFile.h"
Ian Rogerse63db272014-07-15 15:36:11 -070052#include "noop_compiler_callbacks.h"
53#include "os.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070054#include "primitive.h"
Ian Rogerse63db272014-07-15 15:36:11 -070055#include "runtime-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070056#include "scoped_thread_state_change-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070057#include "thread.h"
58#include "well_known_classes.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070059
60int main(int argc, char **argv) {
Andreas Gampe369810a2015-01-14 19:53:31 -080061 // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
62 // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
63 // everything else. In case you want to see all messages, comment out the line.
Nicolas Geoffraya7a47592015-11-24 09:17:30 +000064 setenv("ANDROID_LOG_TAGS", "*:e", 1);
Andreas Gampe369810a2015-01-14 19:53:31 -080065
Andreas Gampe51d80cc2017-06-21 21:05:13 -070066 art::InitLogging(argv, art::Runtime::Abort);
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070067 LOG(INFO) << "Running main() from common_runtime_test.cc...";
Elliott Hugheseb02a122012-06-12 11:35:40 -070068 testing::InitGoogleTest(&argc, argv);
69 return RUN_ALL_TESTS();
70}
Ian Rogerse63db272014-07-15 15:36:11 -070071
72namespace art {
73
Andreas Gampe46ee31b2016-12-14 10:11:49 -080074using android::base::StringPrintf;
75
Alex Lighta01b5242017-03-27 10:15:27 -070076static const uint8_t kBase64Map[256] = {
77 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
78 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
79 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
80 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
81 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
82 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
Igor Murashkin5573c372017-11-16 13:34:30 -080083 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
84 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
Alex Lighta01b5242017-03-27 10:15:27 -070085 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
Igor Murashkin5573c372017-11-16 13:34:30 -080086 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
87 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
Alex Lighta01b5242017-03-27 10:15:27 -070088 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
89 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
91 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
92 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
93 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
94 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
95 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
96 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
97 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
98 255, 255, 255, 255
99};
100
101uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
102 CHECK(dst_size != nullptr);
103 std::vector<uint8_t> tmp;
104 uint32_t t = 0, y = 0;
105 int g = 3;
106 for (size_t i = 0; src[i] != '\0'; ++i) {
107 uint8_t c = kBase64Map[src[i] & 0xFF];
108 if (c == 255) continue;
109 // the final = symbols are read and used to trim the remaining bytes
110 if (c == 254) {
111 c = 0;
112 // prevent g < 0 which would potentially allow an overflow later
113 if (--g < 0) {
114 *dst_size = 0;
115 return nullptr;
116 }
117 } else if (g != 3) {
118 // we only allow = to be at the end
119 *dst_size = 0;
120 return nullptr;
121 }
122 t = (t << 6) | c;
123 if (++y == 4) {
124 tmp.push_back((t >> 16) & 255);
125 if (g > 1) {
126 tmp.push_back((t >> 8) & 255);
127 }
128 if (g > 2) {
129 tmp.push_back(t & 255);
130 }
131 y = t = 0;
132 }
133 }
134 if (y != 0) {
135 *dst_size = 0;
136 return nullptr;
137 }
138 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
139 *dst_size = tmp.size();
140 std::copy(tmp.begin(), tmp.end(), dst.get());
141 return dst.release();
142}
143
Ian Rogerse63db272014-07-15 15:36:11 -0700144ScratchFile::ScratchFile() {
145 // ANDROID_DATA needs to be set
146 CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
147 "Are you subclassing RuntimeTest?";
148 filename_ = getenv("ANDROID_DATA");
149 filename_ += "/TmpFile-XXXXXX";
150 int fd = mkstemp(&filename_[0]);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000151 CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
Andreas Gampe4303ba92014-11-06 01:00:46 -0800152 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700153}
154
Mathieu Chartier866d8742016-09-21 15:24:18 -0700155ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
156 : ScratchFile(other.GetFilename() + suffix) {}
157
158ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
Ian Rogerse63db272014-07-15 15:36:11 -0700159 int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
160 CHECK_NE(-1, fd);
Andreas Gampe4303ba92014-11-06 01:00:46 -0800161 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700162}
163
164ScratchFile::ScratchFile(File* file) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700165 CHECK(file != nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700166 filename_ = file->GetPath();
167 file_.reset(file);
168}
169
Mathieu Chartier866d8742016-09-21 15:24:18 -0700170ScratchFile::ScratchFile(ScratchFile&& other) {
171 *this = std::move(other);
172}
173
174ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
175 if (GetFile() != other.GetFile()) {
176 std::swap(filename_, other.filename_);
177 std::swap(file_, other.file_);
178 }
179 return *this;
180}
181
Ian Rogerse63db272014-07-15 15:36:11 -0700182ScratchFile::~ScratchFile() {
183 Unlink();
184}
185
186int ScratchFile::GetFd() const {
187 return file_->Fd();
188}
189
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800190void ScratchFile::Close() {
Andreas Gampe4303ba92014-11-06 01:00:46 -0800191 if (file_.get() != nullptr) {
192 if (file_->FlushCloseOrErase() != 0) {
193 PLOG(WARNING) << "Error closing scratch file.";
194 }
195 }
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800196}
197
198void ScratchFile::Unlink() {
199 if (!OS::FileExists(filename_.c_str())) {
200 return;
201 }
202 Close();
Ian Rogerse63db272014-07-15 15:36:11 -0700203 int unlink_result = unlink(filename_.c_str());
204 CHECK_EQ(0, unlink_result);
205}
206
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700207static bool unstarted_initialized_ = false;
208
Andreas Gampe48864112017-01-19 17:23:17 -0800209CommonRuntimeTestImpl::CommonRuntimeTestImpl()
210 : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
211}
Mathieu Chartier91c91162016-01-15 09:48:15 -0800212
213CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800214 // Ensure the dex files are cleaned up before the runtime.
215 loaded_dex_files_.clear();
216 runtime_.reset();
217}
Ian Rogerse63db272014-07-15 15:36:11 -0700218
Mathieu Chartier91c91162016-01-15 09:48:15 -0800219void CommonRuntimeTestImpl::SetUpAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700220 if (IsHost()) {
221 // $ANDROID_ROOT is set on the device, but not necessarily on the host.
222 // But it needs to be set so that icu4c can find its locale data.
223 const char* android_root_from_env = getenv("ANDROID_ROOT");
224 if (android_root_from_env == nullptr) {
225 // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
226 const char* android_host_out = getenv("ANDROID_HOST_OUT");
227 if (android_host_out != nullptr) {
228 setenv("ANDROID_ROOT", android_host_out, 1);
229 } else {
230 // Build it from ANDROID_BUILD_TOP or cwd
231 std::string root;
232 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
233 if (android_build_top != nullptr) {
234 root += android_build_top;
235 } else {
236 // Not set by build server, so default to current directory
237 char* cwd = getcwd(nullptr, 0);
238 setenv("ANDROID_BUILD_TOP", cwd, 1);
239 root += cwd;
240 free(cwd);
241 }
242#if defined(__linux__)
243 root += "/out/host/linux-x86";
244#elif defined(__APPLE__)
245 root += "/out/host/darwin-x86";
246#else
247#error unsupported OS
248#endif
249 setenv("ANDROID_ROOT", root.c_str(), 1);
250 }
251 }
252 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
253
254 // Not set by build server, so default
255 if (getenv("ANDROID_HOST_OUT") == nullptr) {
256 setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
257 }
258 }
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700259}
Ian Rogerse63db272014-07-15 15:36:11 -0700260
Mathieu Chartier91c91162016-01-15 09:48:15 -0800261void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
Ian Rogerse63db272014-07-15 15:36:11 -0700262 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
Andreas Gampe5a79fde2014-08-06 13:12:26 -0700263 if (IsHost()) {
264 const char* tmpdir = getenv("TMPDIR");
265 if (tmpdir != nullptr && tmpdir[0] != 0) {
266 android_data = tmpdir;
267 } else {
268 android_data = "/tmp";
269 }
270 } else {
271 android_data = "/data/dalvik-cache";
272 }
273 android_data += "/art-data-XXXXXX";
Ian Rogerse63db272014-07-15 15:36:11 -0700274 if (mkdtemp(&android_data[0]) == nullptr) {
275 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
276 }
277 setenv("ANDROID_DATA", android_data.c_str(), 1);
278}
279
Mathieu Chartier91c91162016-01-15 09:48:15 -0800280void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
281 bool fail_on_error) {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700282 if (fail_on_error) {
283 ASSERT_EQ(rmdir(android_data.c_str()), 0);
284 } else {
285 rmdir(android_data.c_str());
286 }
287}
288
David Srbecky3e52aa42015-04-12 07:45:18 +0100289// Helper - find directory with the following format:
290// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
291static std::string GetAndroidToolsDir(const std::string& subdir1,
292 const std::string& subdir2,
293 const std::string& subdir3) {
294 std::string root;
295 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
296 if (android_build_top != nullptr) {
297 root = android_build_top;
298 } else {
299 // Not set by build server, so default to current directory
300 char* cwd = getcwd(nullptr, 0);
301 setenv("ANDROID_BUILD_TOP", cwd, 1);
302 root = cwd;
303 free(cwd);
304 }
305
306 std::string toolsdir = root + "/" + subdir1;
307 std::string founddir;
308 DIR* dir;
309 if ((dir = opendir(toolsdir.c_str())) != nullptr) {
310 float maxversion = 0;
311 struct dirent* entry;
312 while ((entry = readdir(dir)) != nullptr) {
313 std::string format = subdir2 + "-%f";
314 float version;
315 if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
316 if (version > maxversion) {
317 maxversion = version;
318 founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
319 }
320 }
321 }
322 closedir(dir);
323 }
324
325 if (founddir.empty()) {
Roland Levillain91d65e02016-01-19 15:59:16 +0000326 ADD_FAILURE() << "Cannot find Android tools directory.";
David Srbecky3e52aa42015-04-12 07:45:18 +0100327 }
328 return founddir;
329}
330
Mathieu Chartier91c91162016-01-15 09:48:15 -0800331std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
David Srbecky3e52aa42015-04-12 07:45:18 +0100332 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
333 "x86_64-linux-glibc2.15",
334 "x86_64-linux");
335}
336
Mathieu Chartier91c91162016-01-15 09:48:15 -0800337std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
David Srbecky3e52aa42015-04-12 07:45:18 +0100338 switch (isa) {
Vladimir Marko33bff252017-11-01 14:35:42 +0000339 case InstructionSet::kArm:
340 case InstructionSet::kThumb2:
David Srbecky3e52aa42015-04-12 07:45:18 +0100341 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
342 "arm-linux-androideabi",
343 "arm-linux-androideabi");
Vladimir Marko33bff252017-11-01 14:35:42 +0000344 case InstructionSet::kArm64:
David Srbecky3e52aa42015-04-12 07:45:18 +0100345 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
346 "aarch64-linux-android",
347 "aarch64-linux-android");
Vladimir Marko33bff252017-11-01 14:35:42 +0000348 case InstructionSet::kX86:
349 case InstructionSet::kX86_64:
David Srbecky3e52aa42015-04-12 07:45:18 +0100350 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
351 "x86_64-linux-android",
352 "x86_64-linux-android");
Vladimir Marko33bff252017-11-01 14:35:42 +0000353 case InstructionSet::kMips:
354 case InstructionSet::kMips64:
David Srbecky3e52aa42015-04-12 07:45:18 +0100355 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
356 "mips64el-linux-android",
357 "mips64el-linux-android");
Vladimir Marko33bff252017-11-01 14:35:42 +0000358 case InstructionSet::kNone:
David Srbecky3e52aa42015-04-12 07:45:18 +0100359 break;
360 }
361 ADD_FAILURE() << "Invalid isa " << isa;
362 return "";
363}
364
Mathieu Chartier91c91162016-01-15 09:48:15 -0800365std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800366 return GetCoreFileLocation("art");
367}
368
Mathieu Chartier91c91162016-01-15 09:48:15 -0800369std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800370 return GetCoreFileLocation("oat");
371}
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700372
Mathieu Chartier91c91162016-01-15 09:48:15 -0800373std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
374 const char* location) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800375 std::vector<std::unique_ptr<const DexFile>> dex_files;
Ian Rogerse63db272014-07-15 15:36:11 -0700376 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800377 MemMap::Init();
Aart Bik37d6a3b2016-06-21 18:30:10 -0700378 static constexpr bool kVerifyChecksum = true;
David Sehr013fd802018-01-11 22:55:24 -0800379 const ArtDexFileLoader dex_file_loader;
380 if (!dex_file_loader.Open(
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100381 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files)) {
Ian Rogerse63db272014-07-15 15:36:11 -0700382 LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800383 UNREACHABLE();
Ian Rogerse63db272014-07-15 15:36:11 -0700384 } else {
385 CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800386 return std::move(dex_files[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700387 }
388}
389
Mathieu Chartier91c91162016-01-15 09:48:15 -0800390void CommonRuntimeTestImpl::SetUp() {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700391 SetUpAndroidRoot();
392 SetUpAndroidData(android_data_);
Ian Rogerse63db272014-07-15 15:36:11 -0700393 dalvik_cache_.append(android_data_.c_str());
394 dalvik_cache_.append("/dalvik-cache");
395 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
396 ASSERT_EQ(mkdir_result, 0);
397
Ian Rogerse63db272014-07-15 15:36:11 -0700398 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
399 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
400
Ian Rogerse63db272014-07-15 15:36:11 -0700401
402 RuntimeOptions options;
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000403 std::string boot_class_path_string = "-Xbootclasspath";
404 for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
405 boot_class_path_string += ":";
406 boot_class_path_string += core_dex_file_name;
407 }
408
Richard Uhlerc2752592015-01-02 13:28:22 -0800409 options.push_back(std::make_pair(boot_class_path_string, nullptr));
Ian Rogerse63db272014-07-15 15:36:11 -0700410 options.push_back(std::make_pair("-Xcheck:jni", nullptr));
Richard Uhlerc2752592015-01-02 13:28:22 -0800411 options.push_back(std::make_pair(min_heap_string, nullptr));
412 options.push_back(std::make_pair(max_heap_string, nullptr));
Andreas Gampe1c5b42f2017-06-15 18:20:45 -0700413 options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
Andreas Gampe46c4c852017-06-21 19:49:08 -0700414 static bool gSlowDebugTestFlag = false;
415 RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700416
417 callbacks_.reset(new NoopCompilerCallbacks());
418
Ian Rogerse63db272014-07-15 15:36:11 -0700419 SetUpRuntimeOptions(&options);
Igor Murashkinaaebaa02015-01-26 10:55:53 -0800420
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700421 // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
422 if (callbacks_.get() != nullptr) {
423 options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
424 }
425
Richard Uhler66d874d2015-01-15 09:37:19 -0800426 PreRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700427 if (!Runtime::Create(options, false)) {
428 LOG(FATAL) << "Failed to create runtime";
429 return;
430 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800431 PostRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700432 runtime_.reset(Runtime::Current());
433 class_linker_ = runtime_->GetClassLinker();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700434
Andreas Gampea00f0122015-12-16 16:54:35 -0800435 // Runtime::Create acquired the mutator_lock_ that is normally given away when we
436 // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
437 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
438
439 // Get the boot class path from the runtime so it can be used in tests.
440 boot_class_path_ = class_linker_->GetBootClassPath();
441 ASSERT_FALSE(boot_class_path_.empty());
442 java_lang_dex_file_ = boot_class_path_[0];
443
444 FinalizeSetup();
Andreas Gampe46c4c852017-06-21 19:49:08 -0700445
446 // Ensure that we're really running with debug checks enabled.
447 CHECK(gSlowDebugTestFlag);
Andreas Gampea00f0122015-12-16 16:54:35 -0800448}
449
Mathieu Chartier91c91162016-01-15 09:48:15 -0800450void CommonRuntimeTestImpl::FinalizeSetup() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700451 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
452 // set up.
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700453 if (!unstarted_initialized_) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700454 interpreter::UnstartedRuntime::Initialize();
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700455 unstarted_initialized_ = true;
456 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700457
Andreas Gampea00f0122015-12-16 16:54:35 -0800458 {
459 ScopedObjectAccess soa(Thread::Current());
460 class_linker_->RunRootClinits();
461 }
Ian Rogerse63db272014-07-15 15:36:11 -0700462
463 // We're back in native, take the opportunity to initialize well known classes.
464 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
465
466 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
467 // pool is created by the runtime.
468 runtime_->GetHeap()->CreateThreadPool();
469 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Hiroshi Yamauchi4460a842015-03-09 11:57:48 -0700470 // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
471 runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
Ian Rogerse63db272014-07-15 15:36:11 -0700472}
473
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700474void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath, bool recursive) {
Alex Lighta59dd802014-07-02 16:28:08 -0700475 ASSERT_TRUE(dirpath != nullptr);
476 DIR* dir = opendir(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700477 ASSERT_TRUE(dir != nullptr);
478 dirent* e;
Alex Lighta59dd802014-07-02 16:28:08 -0700479 struct stat s;
Ian Rogerse63db272014-07-15 15:36:11 -0700480 while ((e = readdir(dir)) != nullptr) {
481 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
482 continue;
483 }
Jeff Haof0a3f092014-07-24 16:26:09 -0700484 std::string filename(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700485 filename.push_back('/');
486 filename.append(e->d_name);
Alex Lighta59dd802014-07-02 16:28:08 -0700487 int stat_result = lstat(filename.c_str(), &s);
488 ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
489 if (S_ISDIR(s.st_mode)) {
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700490 if (recursive) {
491 ClearDirectory(filename.c_str());
492 int rmdir_result = rmdir(filename.c_str());
493 ASSERT_EQ(0, rmdir_result) << filename;
494 }
Alex Lighta59dd802014-07-02 16:28:08 -0700495 } else {
496 int unlink_result = unlink(filename.c_str());
497 ASSERT_EQ(0, unlink_result) << filename;
498 }
Ian Rogerse63db272014-07-15 15:36:11 -0700499 }
500 closedir(dir);
Alex Lighta59dd802014-07-02 16:28:08 -0700501}
502
Mathieu Chartier91c91162016-01-15 09:48:15 -0800503void CommonRuntimeTestImpl::TearDown() {
Alex Lighta59dd802014-07-02 16:28:08 -0700504 const char* android_data = getenv("ANDROID_DATA");
505 ASSERT_TRUE(android_data != nullptr);
506 ClearDirectory(dalvik_cache_.c_str());
Ian Rogerse63db272014-07-15 15:36:11 -0700507 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
508 ASSERT_EQ(0, rmdir_cache_result);
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700509 TearDownAndroidData(android_data_, true);
Andreas Gampe3f41a012016-02-18 16:53:41 -0800510 dalvik_cache_.clear();
Ian Rogerse63db272014-07-15 15:36:11 -0700511
Andreas Gampe48864112017-01-19 17:23:17 -0800512 if (runtime_ != nullptr) {
513 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
514 }
Ian Rogerse63db272014-07-15 15:36:11 -0700515}
516
Andreas Gampec7d4a582015-09-30 11:52:02 -0700517static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
518 std::string path;
519 if (host) {
Ian Rogerse63db272014-07-15 15:36:11 -0700520 const char* host_dir = getenv("ANDROID_HOST_OUT");
521 CHECK(host_dir != nullptr);
Andreas Gampec7d4a582015-09-30 11:52:02 -0700522 path = host_dir;
523 } else {
524 path = GetAndroidRoot();
Ian Rogerse63db272014-07-15 15:36:11 -0700525 }
Andreas Gampec7d4a582015-09-30 11:52:02 -0700526
527 std::string suffix = host
528 ? "-hostdex" // The host version.
529 : "-testdex"; // The unstripped target version.
530
531 return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
532}
533
Mathieu Chartier91c91162016-01-15 09:48:15 -0800534std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
Andreas Gampec7d4a582015-09-30 11:52:02 -0700535 return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
536 GetDexFileName("core-libart", IsHost())});
Ian Rogerse63db272014-07-15 15:36:11 -0700537}
538
Mathieu Chartier91c91162016-01-15 09:48:15 -0800539std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700540 if (IsHost()) {
541 const char* host_dir = getenv("ANDROID_HOST_OUT");
542 CHECK(host_dir != nullptr);
543 return host_dir;
544 }
545 return GetAndroidRoot();
546}
547
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700548// Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
549#ifdef ART_TARGET
550#ifndef ART_TARGET_NATIVETEST_DIR
551#error "ART_TARGET_NATIVETEST_DIR not set."
552#endif
553// Wrap it as a string literal.
554#define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
555#else
556#define ART_TARGET_NATIVETEST_DIR_STRING ""
557#endif
558
Andreas Gampee1459ae2016-06-29 09:36:30 -0700559std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
Ian Rogerse63db272014-07-15 15:36:11 -0700560 CHECK(name != nullptr);
561 std::string filename;
562 if (IsHost()) {
563 filename += getenv("ANDROID_HOST_OUT");
564 filename += "/framework/";
565 } else {
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700566 filename += ART_TARGET_NATIVETEST_DIR_STRING;
Ian Rogerse63db272014-07-15 15:36:11 -0700567 }
568 filename += "art-gtest-";
569 filename += name;
570 filename += ".jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800571 return filename;
572}
573
Mathieu Chartier91c91162016-01-15 09:48:15 -0800574std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
575 const char* name) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800576 std::string filename = GetTestDexFileName(name);
Aart Bik37d6a3b2016-06-21 18:30:10 -0700577 static constexpr bool kVerifyChecksum = true;
Ian Rogerse63db272014-07-15 15:36:11 -0700578 std::string error_msg;
David Sehr013fd802018-01-11 22:55:24 -0800579 const ArtDexFileLoader dex_file_loader;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800580 std::vector<std::unique_ptr<const DexFile>> dex_files;
David Sehr013fd802018-01-11 22:55:24 -0800581 bool success = dex_file_loader.Open(filename.c_str(),
582 filename.c_str(),
583 /* verify */ true,
584 kVerifyChecksum,
585 &error_msg, &dex_files);
Ian Rogerse63db272014-07-15 15:36:11 -0700586 CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800587 for (auto& dex_file : dex_files) {
Ian Rogerse63db272014-07-15 15:36:11 -0700588 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
589 CHECK(dex_file->IsReadOnly());
590 }
Ian Rogerse63db272014-07-15 15:36:11 -0700591 return dex_files;
592}
593
Mathieu Chartier91c91162016-01-15 09:48:15 -0800594std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800595 std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
Ian Rogerse63db272014-07-15 15:36:11 -0700596 EXPECT_EQ(1U, vector.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800597 return std::move(vector[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700598}
599
Mathieu Chartier91c91162016-01-15 09:48:15 -0800600std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700601 ScopedObjectAccess soa(Thread::Current());
602
Calin Juravlec79470d2017-07-12 17:37:42 -0700603 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700604 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700605 soa.Decode<mirror::ClassLoader>(jclass_loader));
Calin Juravlec79470d2017-07-12 17:37:42 -0700606 return GetDexFiles(soa, class_loader);
607}
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700608
Calin Juravlec79470d2017-07-12 17:37:42 -0700609std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
610 ScopedObjectAccess& soa,
611 Handle<mirror::ClassLoader> class_loader) {
612 std::vector<const DexFile*> ret;
613
614 DCHECK(
615 (class_loader->GetClass() ==
616 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
617 (class_loader->GetClass() ==
618 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700619
620 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
621 // We need to get the DexPathList and loop through it.
Andreas Gampe08883de2016-11-08 13:20:52 -0800622 ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700623 ArtField* dex_file_field =
Andreas Gampe08883de2016-11-08 13:20:52 -0800624 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700625 ObjPtr<mirror::Object> dex_path_list =
Andreas Gampe08883de2016-11-08 13:20:52 -0800626 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
627 GetObject(class_loader.Get());
Mathieu Chartierc7853442015-03-27 14:35:38 -0700628 if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700629 // DexPathList has an array dexElements of Elements[] which each contain a dex file.
Mathieu Chartier3398c782016-09-30 10:27:43 -0700630 ObjPtr<mirror::Object> dex_elements_obj =
Andreas Gampe08883de2016-11-08 13:20:52 -0800631 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
632 GetObject(dex_path_list);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700633 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
634 // at the mCookie which is a DexFile vector.
635 if (dex_elements_obj != nullptr) {
Calin Juravlec79470d2017-07-12 17:37:42 -0700636 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700637 Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
638 hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
639 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700640 ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700641 if (element == nullptr) {
642 // Should never happen, fall back to java code to throw a NPE.
643 break;
644 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700645 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700646 if (dex_file != nullptr) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700647 ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700648 DCHECK(long_array != nullptr);
649 int32_t long_array_size = long_array->GetLength();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700650 for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700651 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
652 long_array->GetWithoutChecks(j)));
653 if (cp_dex_file == nullptr) {
654 LOG(WARNING) << "Null DexFile";
655 continue;
656 }
657 ret.push_back(cp_dex_file);
658 }
659 }
660 }
661 }
662 }
663
664 return ret;
665}
666
Mathieu Chartier91c91162016-01-15 09:48:15 -0800667const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700668 std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
669 DCHECK(!tmp.empty());
670 const DexFile* ret = tmp[0];
671 DCHECK(ret != nullptr);
672 return ret;
673}
674
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100675jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
676 const char* second_dex_name) {
677 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
678 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
679 std::vector<const DexFile*> class_path;
680 CHECK_NE(0U, first_dex_files.size());
681 CHECK_NE(0U, second_dex_files.size());
682 for (auto& dex_file : first_dex_files) {
683 class_path.push_back(dex_file.get());
684 loaded_dex_files_.push_back(std::move(dex_file));
685 }
686 for (auto& dex_file : second_dex_files) {
687 class_path.push_back(dex_file.get());
688 loaded_dex_files_.push_back(std::move(dex_file));
689 }
690
691 Thread* self = Thread::Current();
692 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
693 class_path);
694 self->SetClassLoaderOverride(class_loader);
695 return class_loader;
696}
697
Mathieu Chartier91c91162016-01-15 09:48:15 -0800698jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
Calin Juravle7865ac72017-06-28 11:03:12 -0700699 jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
700 Thread::Current()->SetClassLoaderOverride(class_loader);
701 return class_loader;
702}
703
704jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
705 jclass loader_class,
706 jobject parent_loader) {
707 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800708 std::vector<const DexFile*> class_path;
Ian Rogerse63db272014-07-15 15:36:11 -0700709 CHECK_NE(0U, dex_files.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800710 for (auto& dex_file : dex_files) {
711 class_path.push_back(dex_file.get());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800712 loaded_dex_files_.push_back(std::move(dex_file));
Ian Rogerse63db272014-07-15 15:36:11 -0700713 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700714 Thread* self = Thread::Current();
Calin Juravle7865ac72017-06-28 11:03:12 -0700715 ScopedObjectAccess soa(self);
716
717 jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
718 self,
719 class_path,
720 loader_class,
721 parent_loader);
722
723 {
724 // Verify we build the correct chain.
725
726 ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
727 // Verify that the result has the correct class.
728 CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
729 // Verify that the parent is not null. The boot class loader will be set up as a
730 // proper object.
731 ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
732 CHECK(actual_parent != nullptr);
733
734 if (parent_loader != nullptr) {
735 // We were given a parent. Verify that it's what we expect.
736 ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
737 CHECK_EQ(expected_parent, actual_parent);
738 } else {
739 // No parent given. The parent must be the BootClassLoader.
740 CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
741 }
742 }
743
744 return result;
745}
746
747jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
748 jobject parent_loader) {
749 return LoadDexInWellKnownClassLoader(dex_name,
750 WellKnownClasses::dalvik_system_PathClassLoader,
751 parent_loader);
752}
753
754jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
755 jobject parent_loader) {
756 return LoadDexInWellKnownClassLoader(dex_name,
757 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
758 parent_loader);
Ian Rogerse63db272014-07-15 15:36:11 -0700759}
760
Mathieu Chartier91c91162016-01-15 09:48:15 -0800761std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
Igor Murashkin37743352014-11-13 14:38:00 -0800762 CHECK(suffix != nullptr);
763
764 std::string location;
765 if (IsHost()) {
766 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700767 CHECK(host_dir != nullptr);
Richard Uhler67e1dc52017-02-06 16:50:17 +0000768 location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800769 } else {
Richard Uhler67e1dc52017-02-06 16:50:17 +0000770 location = StringPrintf("/data/art-test/core.%s", suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800771 }
772
773 return location;
774}
775
Calin Juravlec79470d2017-07-12 17:37:42 -0700776std::string CommonRuntimeTestImpl::CreateClassPath(
777 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
778 CHECK(!dex_files.empty());
779 std::string classpath = dex_files[0]->GetLocation();
780 for (size_t i = 1; i < dex_files.size(); i++) {
781 classpath += ":" + dex_files[i]->GetLocation();
782 }
783 return classpath;
784}
785
786std::string CommonRuntimeTestImpl::CreateClassPathWithChecksums(
787 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
788 CHECK(!dex_files.empty());
789 std::string classpath = dex_files[0]->GetLocation() + "*" +
790 std::to_string(dex_files[0]->GetLocationChecksum());
791 for (size_t i = 1; i < dex_files.size(); i++) {
792 classpath += ":" + dex_files[i]->GetLocation() + "*" +
793 std::to_string(dex_files[i]->GetLocationChecksum());
794 }
795 return classpath;
796}
797
Andreas Gampe26761f72017-07-20 18:00:39 -0700798void CommonRuntimeTestImpl::FillHeap(Thread* self,
799 ClassLinker* class_linker,
800 VariableSizedHandleScope* handle_scope) {
801 DCHECK(handle_scope != nullptr);
802
803 Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
804
805 // Class java.lang.Object.
806 Handle<mirror::Class> c(handle_scope->NewHandle(
807 class_linker->FindSystemClass(self, "Ljava/lang/Object;")));
808 // Array helps to fill memory faster.
809 Handle<mirror::Class> ca(handle_scope->NewHandle(
810 class_linker->FindSystemClass(self, "[Ljava/lang/Object;")));
811
812 // Start allocating with ~128K
813 size_t length = 128 * KB;
814 while (length > 40) {
815 const int32_t array_length = length / 4; // Object[] has elements of size 4.
816 MutableHandle<mirror::Object> h(handle_scope->NewHandle<mirror::Object>(
817 mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), array_length)));
818 if (self->IsExceptionPending() || h == nullptr) {
819 self->ClearException();
820
821 // Try a smaller length
822 length = length / 2;
823 // Use at most a quarter the reported free space.
824 size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
825 if (length * 4 > mem) {
826 length = mem / 4;
827 }
828 }
829 }
830
831 // Allocate simple objects till it fails.
832 while (!self->IsExceptionPending()) {
833 handle_scope->NewHandle<mirror::Object>(c->AllocObject(self));
834 }
835 self->ClearException();
836}
837
838void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *options) {
839 // Use a smaller heap
840 bool found = false;
841 for (std::pair<std::string, const void*>& pair : *options) {
842 if (pair.first.find("-Xmx") == 0) {
843 pair.first = "-Xmx4M"; // Smallest we can go.
844 found = true;
845 }
846 }
847 if (!found) {
848 options->emplace_back("-Xmx4M", nullptr);
849 }
850}
851
Ian Rogerse63db272014-07-15 15:36:11 -0700852CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700853 vm_->SetCheckJniAbortHook(Hook, &actual_);
Ian Rogerse63db272014-07-15 15:36:11 -0700854}
855
856CheckJniAbortCatcher::~CheckJniAbortCatcher() {
Ian Rogers68d8b422014-07-17 11:09:10 -0700857 vm_->SetCheckJniAbortHook(nullptr, nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700858 EXPECT_TRUE(actual_.empty()) << actual_;
859}
860
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700861void CheckJniAbortCatcher::Check(const std::string& expected_text) {
862 Check(expected_text.c_str());
863}
864
Ian Rogerse63db272014-07-15 15:36:11 -0700865void CheckJniAbortCatcher::Check(const char* expected_text) {
866 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
867 << "Expected to find: " << expected_text << "\n"
868 << "In the output : " << actual_;
869 actual_.clear();
870}
871
872void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
873 // We use += because when we're hooking the aborts like this, multiple problems can be found.
874 *reinterpret_cast<std::string*>(data) += reason;
875}
876
877} // namespace art