blob: 29b376a21ccb4e5a25e1415215c616a99e750e64 [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>
24#include "nativehelper/ScopedLocalRef.h"
Ian Rogerse63db272014-07-15 15:36:11 -070025
26#include "../../external/icu/icu4c/source/common/unicode/uvernum.h"
Andreas Gampe46ee31b2016-12-14 10:11:49 -080027#include "android-base/stringprintf.h"
28
Mathieu Chartiere401d142015-04-22 13:56:20 -070029#include "art_field-inl.h"
Elliott Hughes07ed66b2012-12-12 18:34:25 -080030#include "base/logging.h"
Steven Morelande431e272017-07-18 16:53:49 -070031#include "base/macros.h"
Ian Rogerse63db272014-07-15 15:36:11 -070032#include "base/stl_util.h"
Ian Rogerse63db272014-07-15 15:36:11 -070033#include "base/unix_file/fd_file.h"
34#include "class_linker.h"
35#include "compiler_callbacks.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070036#include "dex_file-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070037#include "gc/heap.h"
Steven Morelande431e272017-07-18 16:53:49 -070038#include "gc_root-inl.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070039#include "gtest/gtest.h"
Andreas Gampe81c6f8d2015-03-25 17:19:53 -070040#include "handle_scope-inl.h"
Andreas Gampe9b5cba42015-03-11 09:53:50 -070041#include "interpreter/unstarted_runtime.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070042#include "java_vm_ext.h"
Ian Rogerse63db272014-07-15 15:36:11 -070043#include "jni_internal.h"
Steven Morelande431e272017-07-18 16:53:49 -070044#include "mem_map.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070045#include "mirror/class-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070046#include "mirror/class_loader.h"
Mathieu Chartiere58991b2015-10-13 07:59:34 -070047#include "native/dalvik_system_DexFile.h"
Ian Rogerse63db272014-07-15 15:36:11 -070048#include "noop_compiler_callbacks.h"
49#include "os.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070050#include "primitive.h"
Ian Rogerse63db272014-07-15 15:36:11 -070051#include "runtime-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070052#include "scoped_thread_state_change-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070053#include "thread.h"
54#include "well_known_classes.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070055
56int main(int argc, char **argv) {
Andreas Gampe369810a2015-01-14 19:53:31 -080057 // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
58 // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
59 // everything else. In case you want to see all messages, comment out the line.
Nicolas Geoffraya7a47592015-11-24 09:17:30 +000060 setenv("ANDROID_LOG_TAGS", "*:e", 1);
Andreas Gampe369810a2015-01-14 19:53:31 -080061
Andreas Gampe51d80cc2017-06-21 21:05:13 -070062 art::InitLogging(argv, art::Runtime::Abort);
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070063 LOG(INFO) << "Running main() from common_runtime_test.cc...";
Elliott Hugheseb02a122012-06-12 11:35:40 -070064 testing::InitGoogleTest(&argc, argv);
65 return RUN_ALL_TESTS();
66}
Ian Rogerse63db272014-07-15 15:36:11 -070067
68namespace art {
69
Andreas Gampe46ee31b2016-12-14 10:11:49 -080070using android::base::StringPrintf;
71
Alex Lighta01b5242017-03-27 10:15:27 -070072static const uint8_t kBase64Map[256] = {
73 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
74 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
76 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
77 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
78 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
79 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
80 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
81 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
82 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
83 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
84 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
85 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
86 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
87 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
88 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
95};
96
97uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
98 CHECK(dst_size != nullptr);
99 std::vector<uint8_t> tmp;
100 uint32_t t = 0, y = 0;
101 int g = 3;
102 for (size_t i = 0; src[i] != '\0'; ++i) {
103 uint8_t c = kBase64Map[src[i] & 0xFF];
104 if (c == 255) continue;
105 // the final = symbols are read and used to trim the remaining bytes
106 if (c == 254) {
107 c = 0;
108 // prevent g < 0 which would potentially allow an overflow later
109 if (--g < 0) {
110 *dst_size = 0;
111 return nullptr;
112 }
113 } else if (g != 3) {
114 // we only allow = to be at the end
115 *dst_size = 0;
116 return nullptr;
117 }
118 t = (t << 6) | c;
119 if (++y == 4) {
120 tmp.push_back((t >> 16) & 255);
121 if (g > 1) {
122 tmp.push_back((t >> 8) & 255);
123 }
124 if (g > 2) {
125 tmp.push_back(t & 255);
126 }
127 y = t = 0;
128 }
129 }
130 if (y != 0) {
131 *dst_size = 0;
132 return nullptr;
133 }
134 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
135 *dst_size = tmp.size();
136 std::copy(tmp.begin(), tmp.end(), dst.get());
137 return dst.release();
138}
139
Ian Rogerse63db272014-07-15 15:36:11 -0700140ScratchFile::ScratchFile() {
141 // ANDROID_DATA needs to be set
142 CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
143 "Are you subclassing RuntimeTest?";
144 filename_ = getenv("ANDROID_DATA");
145 filename_ += "/TmpFile-XXXXXX";
146 int fd = mkstemp(&filename_[0]);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000147 CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
Andreas Gampe4303ba92014-11-06 01:00:46 -0800148 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700149}
150
Mathieu Chartier866d8742016-09-21 15:24:18 -0700151ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
152 : ScratchFile(other.GetFilename() + suffix) {}
153
154ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
Ian Rogerse63db272014-07-15 15:36:11 -0700155 int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
156 CHECK_NE(-1, fd);
Andreas Gampe4303ba92014-11-06 01:00:46 -0800157 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700158}
159
160ScratchFile::ScratchFile(File* file) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700161 CHECK(file != nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700162 filename_ = file->GetPath();
163 file_.reset(file);
164}
165
Mathieu Chartier866d8742016-09-21 15:24:18 -0700166ScratchFile::ScratchFile(ScratchFile&& other) {
167 *this = std::move(other);
168}
169
170ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
171 if (GetFile() != other.GetFile()) {
172 std::swap(filename_, other.filename_);
173 std::swap(file_, other.file_);
174 }
175 return *this;
176}
177
Ian Rogerse63db272014-07-15 15:36:11 -0700178ScratchFile::~ScratchFile() {
179 Unlink();
180}
181
182int ScratchFile::GetFd() const {
183 return file_->Fd();
184}
185
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800186void ScratchFile::Close() {
Andreas Gampe4303ba92014-11-06 01:00:46 -0800187 if (file_.get() != nullptr) {
188 if (file_->FlushCloseOrErase() != 0) {
189 PLOG(WARNING) << "Error closing scratch file.";
190 }
191 }
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800192}
193
194void ScratchFile::Unlink() {
195 if (!OS::FileExists(filename_.c_str())) {
196 return;
197 }
198 Close();
Ian Rogerse63db272014-07-15 15:36:11 -0700199 int unlink_result = unlink(filename_.c_str());
200 CHECK_EQ(0, unlink_result);
201}
202
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700203static bool unstarted_initialized_ = false;
204
Andreas Gampe48864112017-01-19 17:23:17 -0800205CommonRuntimeTestImpl::CommonRuntimeTestImpl()
206 : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
207}
Mathieu Chartier91c91162016-01-15 09:48:15 -0800208
209CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800210 // Ensure the dex files are cleaned up before the runtime.
211 loaded_dex_files_.clear();
212 runtime_.reset();
213}
Ian Rogerse63db272014-07-15 15:36:11 -0700214
Mathieu Chartier91c91162016-01-15 09:48:15 -0800215void CommonRuntimeTestImpl::SetUpAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700216 if (IsHost()) {
217 // $ANDROID_ROOT is set on the device, but not necessarily on the host.
218 // But it needs to be set so that icu4c can find its locale data.
219 const char* android_root_from_env = getenv("ANDROID_ROOT");
220 if (android_root_from_env == nullptr) {
221 // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
222 const char* android_host_out = getenv("ANDROID_HOST_OUT");
223 if (android_host_out != nullptr) {
224 setenv("ANDROID_ROOT", android_host_out, 1);
225 } else {
226 // Build it from ANDROID_BUILD_TOP or cwd
227 std::string root;
228 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
229 if (android_build_top != nullptr) {
230 root += android_build_top;
231 } else {
232 // Not set by build server, so default to current directory
233 char* cwd = getcwd(nullptr, 0);
234 setenv("ANDROID_BUILD_TOP", cwd, 1);
235 root += cwd;
236 free(cwd);
237 }
238#if defined(__linux__)
239 root += "/out/host/linux-x86";
240#elif defined(__APPLE__)
241 root += "/out/host/darwin-x86";
242#else
243#error unsupported OS
244#endif
245 setenv("ANDROID_ROOT", root.c_str(), 1);
246 }
247 }
248 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
249
250 // Not set by build server, so default
251 if (getenv("ANDROID_HOST_OUT") == nullptr) {
252 setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
253 }
254 }
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700255}
Ian Rogerse63db272014-07-15 15:36:11 -0700256
Mathieu Chartier91c91162016-01-15 09:48:15 -0800257void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
Ian Rogerse63db272014-07-15 15:36:11 -0700258 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
Andreas Gampe5a79fde2014-08-06 13:12:26 -0700259 if (IsHost()) {
260 const char* tmpdir = getenv("TMPDIR");
261 if (tmpdir != nullptr && tmpdir[0] != 0) {
262 android_data = tmpdir;
263 } else {
264 android_data = "/tmp";
265 }
266 } else {
267 android_data = "/data/dalvik-cache";
268 }
269 android_data += "/art-data-XXXXXX";
Ian Rogerse63db272014-07-15 15:36:11 -0700270 if (mkdtemp(&android_data[0]) == nullptr) {
271 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
272 }
273 setenv("ANDROID_DATA", android_data.c_str(), 1);
274}
275
Mathieu Chartier91c91162016-01-15 09:48:15 -0800276void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
277 bool fail_on_error) {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700278 if (fail_on_error) {
279 ASSERT_EQ(rmdir(android_data.c_str()), 0);
280 } else {
281 rmdir(android_data.c_str());
282 }
283}
284
David Srbecky3e52aa42015-04-12 07:45:18 +0100285// Helper - find directory with the following format:
286// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
287static std::string GetAndroidToolsDir(const std::string& subdir1,
288 const std::string& subdir2,
289 const std::string& subdir3) {
290 std::string root;
291 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
292 if (android_build_top != nullptr) {
293 root = android_build_top;
294 } else {
295 // Not set by build server, so default to current directory
296 char* cwd = getcwd(nullptr, 0);
297 setenv("ANDROID_BUILD_TOP", cwd, 1);
298 root = cwd;
299 free(cwd);
300 }
301
302 std::string toolsdir = root + "/" + subdir1;
303 std::string founddir;
304 DIR* dir;
305 if ((dir = opendir(toolsdir.c_str())) != nullptr) {
306 float maxversion = 0;
307 struct dirent* entry;
308 while ((entry = readdir(dir)) != nullptr) {
309 std::string format = subdir2 + "-%f";
310 float version;
311 if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
312 if (version > maxversion) {
313 maxversion = version;
314 founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
315 }
316 }
317 }
318 closedir(dir);
319 }
320
321 if (founddir.empty()) {
Roland Levillain91d65e02016-01-19 15:59:16 +0000322 ADD_FAILURE() << "Cannot find Android tools directory.";
David Srbecky3e52aa42015-04-12 07:45:18 +0100323 }
324 return founddir;
325}
326
Mathieu Chartier91c91162016-01-15 09:48:15 -0800327std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
David Srbecky3e52aa42015-04-12 07:45:18 +0100328 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
329 "x86_64-linux-glibc2.15",
330 "x86_64-linux");
331}
332
Mathieu Chartier91c91162016-01-15 09:48:15 -0800333std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
David Srbecky3e52aa42015-04-12 07:45:18 +0100334 switch (isa) {
335 case kArm:
336 case kThumb2:
337 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
338 "arm-linux-androideabi",
339 "arm-linux-androideabi");
340 case kArm64:
341 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
342 "aarch64-linux-android",
343 "aarch64-linux-android");
344 case kX86:
345 case kX86_64:
346 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
347 "x86_64-linux-android",
348 "x86_64-linux-android");
349 case kMips:
350 case kMips64:
351 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
352 "mips64el-linux-android",
353 "mips64el-linux-android");
354 case kNone:
355 break;
356 }
357 ADD_FAILURE() << "Invalid isa " << isa;
358 return "";
359}
360
Mathieu Chartier91c91162016-01-15 09:48:15 -0800361std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800362 return GetCoreFileLocation("art");
363}
364
Mathieu Chartier91c91162016-01-15 09:48:15 -0800365std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800366 return GetCoreFileLocation("oat");
367}
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700368
Mathieu Chartier91c91162016-01-15 09:48:15 -0800369std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
370 const char* location) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800371 std::vector<std::unique_ptr<const DexFile>> dex_files;
Ian Rogerse63db272014-07-15 15:36:11 -0700372 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800373 MemMap::Init();
Aart Bik37d6a3b2016-06-21 18:30:10 -0700374 static constexpr bool kVerifyChecksum = true;
375 if (!DexFile::Open(location, location, kVerifyChecksum, &error_msg, &dex_files)) {
Ian Rogerse63db272014-07-15 15:36:11 -0700376 LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800377 UNREACHABLE();
Ian Rogerse63db272014-07-15 15:36:11 -0700378 } else {
379 CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800380 return std::move(dex_files[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700381 }
382}
383
Mathieu Chartier91c91162016-01-15 09:48:15 -0800384void CommonRuntimeTestImpl::SetUp() {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700385 SetUpAndroidRoot();
386 SetUpAndroidData(android_data_);
Ian Rogerse63db272014-07-15 15:36:11 -0700387 dalvik_cache_.append(android_data_.c_str());
388 dalvik_cache_.append("/dalvik-cache");
389 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
390 ASSERT_EQ(mkdir_result, 0);
391
Ian Rogerse63db272014-07-15 15:36:11 -0700392 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
393 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
394
Ian Rogerse63db272014-07-15 15:36:11 -0700395
396 RuntimeOptions options;
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000397 std::string boot_class_path_string = "-Xbootclasspath";
398 for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
399 boot_class_path_string += ":";
400 boot_class_path_string += core_dex_file_name;
401 }
402
Richard Uhlerc2752592015-01-02 13:28:22 -0800403 options.push_back(std::make_pair(boot_class_path_string, nullptr));
Ian Rogerse63db272014-07-15 15:36:11 -0700404 options.push_back(std::make_pair("-Xcheck:jni", nullptr));
Richard Uhlerc2752592015-01-02 13:28:22 -0800405 options.push_back(std::make_pair(min_heap_string, nullptr));
406 options.push_back(std::make_pair(max_heap_string, nullptr));
Andreas Gampe1c5b42f2017-06-15 18:20:45 -0700407 options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
Andreas Gampe46c4c852017-06-21 19:49:08 -0700408 static bool gSlowDebugTestFlag = false;
409 RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700410
411 callbacks_.reset(new NoopCompilerCallbacks());
412
Ian Rogerse63db272014-07-15 15:36:11 -0700413 SetUpRuntimeOptions(&options);
Igor Murashkinaaebaa02015-01-26 10:55:53 -0800414
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700415 // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
416 if (callbacks_.get() != nullptr) {
417 options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
418 }
419
Richard Uhler66d874d2015-01-15 09:37:19 -0800420 PreRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700421 if (!Runtime::Create(options, false)) {
422 LOG(FATAL) << "Failed to create runtime";
423 return;
424 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800425 PostRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700426 runtime_.reset(Runtime::Current());
427 class_linker_ = runtime_->GetClassLinker();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700428
Andreas Gampea00f0122015-12-16 16:54:35 -0800429 // Runtime::Create acquired the mutator_lock_ that is normally given away when we
430 // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
431 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
432
433 // Get the boot class path from the runtime so it can be used in tests.
434 boot_class_path_ = class_linker_->GetBootClassPath();
435 ASSERT_FALSE(boot_class_path_.empty());
436 java_lang_dex_file_ = boot_class_path_[0];
437
438 FinalizeSetup();
Andreas Gampe46c4c852017-06-21 19:49:08 -0700439
440 // Ensure that we're really running with debug checks enabled.
441 CHECK(gSlowDebugTestFlag);
Andreas Gampea00f0122015-12-16 16:54:35 -0800442}
443
Mathieu Chartier91c91162016-01-15 09:48:15 -0800444void CommonRuntimeTestImpl::FinalizeSetup() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700445 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
446 // set up.
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700447 if (!unstarted_initialized_) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700448 interpreter::UnstartedRuntime::Initialize();
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700449 unstarted_initialized_ = true;
450 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700451
Andreas Gampea00f0122015-12-16 16:54:35 -0800452 {
453 ScopedObjectAccess soa(Thread::Current());
454 class_linker_->RunRootClinits();
455 }
Ian Rogerse63db272014-07-15 15:36:11 -0700456
457 // We're back in native, take the opportunity to initialize well known classes.
458 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
459
460 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
461 // pool is created by the runtime.
462 runtime_->GetHeap()->CreateThreadPool();
463 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Hiroshi Yamauchi4460a842015-03-09 11:57:48 -0700464 // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
465 runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
Ian Rogerse63db272014-07-15 15:36:11 -0700466}
467
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700468void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath, bool recursive) {
Alex Lighta59dd802014-07-02 16:28:08 -0700469 ASSERT_TRUE(dirpath != nullptr);
470 DIR* dir = opendir(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700471 ASSERT_TRUE(dir != nullptr);
472 dirent* e;
Alex Lighta59dd802014-07-02 16:28:08 -0700473 struct stat s;
Ian Rogerse63db272014-07-15 15:36:11 -0700474 while ((e = readdir(dir)) != nullptr) {
475 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
476 continue;
477 }
Jeff Haof0a3f092014-07-24 16:26:09 -0700478 std::string filename(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700479 filename.push_back('/');
480 filename.append(e->d_name);
Alex Lighta59dd802014-07-02 16:28:08 -0700481 int stat_result = lstat(filename.c_str(), &s);
482 ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
483 if (S_ISDIR(s.st_mode)) {
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700484 if (recursive) {
485 ClearDirectory(filename.c_str());
486 int rmdir_result = rmdir(filename.c_str());
487 ASSERT_EQ(0, rmdir_result) << filename;
488 }
Alex Lighta59dd802014-07-02 16:28:08 -0700489 } else {
490 int unlink_result = unlink(filename.c_str());
491 ASSERT_EQ(0, unlink_result) << filename;
492 }
Ian Rogerse63db272014-07-15 15:36:11 -0700493 }
494 closedir(dir);
Alex Lighta59dd802014-07-02 16:28:08 -0700495}
496
Mathieu Chartier91c91162016-01-15 09:48:15 -0800497void CommonRuntimeTestImpl::TearDown() {
Alex Lighta59dd802014-07-02 16:28:08 -0700498 const char* android_data = getenv("ANDROID_DATA");
499 ASSERT_TRUE(android_data != nullptr);
500 ClearDirectory(dalvik_cache_.c_str());
Ian Rogerse63db272014-07-15 15:36:11 -0700501 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
502 ASSERT_EQ(0, rmdir_cache_result);
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700503 TearDownAndroidData(android_data_, true);
Andreas Gampe3f41a012016-02-18 16:53:41 -0800504 dalvik_cache_.clear();
Ian Rogerse63db272014-07-15 15:36:11 -0700505
Andreas Gampe48864112017-01-19 17:23:17 -0800506 if (runtime_ != nullptr) {
507 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
508 }
Ian Rogerse63db272014-07-15 15:36:11 -0700509}
510
Andreas Gampec7d4a582015-09-30 11:52:02 -0700511static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
512 std::string path;
513 if (host) {
Ian Rogerse63db272014-07-15 15:36:11 -0700514 const char* host_dir = getenv("ANDROID_HOST_OUT");
515 CHECK(host_dir != nullptr);
Andreas Gampec7d4a582015-09-30 11:52:02 -0700516 path = host_dir;
517 } else {
518 path = GetAndroidRoot();
Ian Rogerse63db272014-07-15 15:36:11 -0700519 }
Andreas Gampec7d4a582015-09-30 11:52:02 -0700520
521 std::string suffix = host
522 ? "-hostdex" // The host version.
523 : "-testdex"; // The unstripped target version.
524
525 return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
526}
527
Mathieu Chartier91c91162016-01-15 09:48:15 -0800528std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
Andreas Gampec7d4a582015-09-30 11:52:02 -0700529 return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
530 GetDexFileName("core-libart", IsHost())});
Ian Rogerse63db272014-07-15 15:36:11 -0700531}
532
Mathieu Chartier91c91162016-01-15 09:48:15 -0800533std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700534 if (IsHost()) {
535 const char* host_dir = getenv("ANDROID_HOST_OUT");
536 CHECK(host_dir != nullptr);
537 return host_dir;
538 }
539 return GetAndroidRoot();
540}
541
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700542// Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
543#ifdef ART_TARGET
544#ifndef ART_TARGET_NATIVETEST_DIR
545#error "ART_TARGET_NATIVETEST_DIR not set."
546#endif
547// Wrap it as a string literal.
548#define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
549#else
550#define ART_TARGET_NATIVETEST_DIR_STRING ""
551#endif
552
Andreas Gampee1459ae2016-06-29 09:36:30 -0700553std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
Ian Rogerse63db272014-07-15 15:36:11 -0700554 CHECK(name != nullptr);
555 std::string filename;
556 if (IsHost()) {
557 filename += getenv("ANDROID_HOST_OUT");
558 filename += "/framework/";
559 } else {
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700560 filename += ART_TARGET_NATIVETEST_DIR_STRING;
Ian Rogerse63db272014-07-15 15:36:11 -0700561 }
562 filename += "art-gtest-";
563 filename += name;
564 filename += ".jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800565 return filename;
566}
567
Mathieu Chartier91c91162016-01-15 09:48:15 -0800568std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
569 const char* name) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800570 std::string filename = GetTestDexFileName(name);
Aart Bik37d6a3b2016-06-21 18:30:10 -0700571 static constexpr bool kVerifyChecksum = true;
Ian Rogerse63db272014-07-15 15:36:11 -0700572 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800573 std::vector<std::unique_ptr<const DexFile>> dex_files;
Aart Bik37d6a3b2016-06-21 18:30:10 -0700574 bool success = DexFile::Open(
575 filename.c_str(), filename.c_str(), kVerifyChecksum, &error_msg, &dex_files);
Ian Rogerse63db272014-07-15 15:36:11 -0700576 CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800577 for (auto& dex_file : dex_files) {
Ian Rogerse63db272014-07-15 15:36:11 -0700578 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
579 CHECK(dex_file->IsReadOnly());
580 }
Ian Rogerse63db272014-07-15 15:36:11 -0700581 return dex_files;
582}
583
Mathieu Chartier91c91162016-01-15 09:48:15 -0800584std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800585 std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
Ian Rogerse63db272014-07-15 15:36:11 -0700586 EXPECT_EQ(1U, vector.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800587 return std::move(vector[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700588}
589
Mathieu Chartier91c91162016-01-15 09:48:15 -0800590std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700591 ScopedObjectAccess soa(Thread::Current());
592
Calin Juravlec79470d2017-07-12 17:37:42 -0700593 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700594 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700595 soa.Decode<mirror::ClassLoader>(jclass_loader));
Calin Juravlec79470d2017-07-12 17:37:42 -0700596 return GetDexFiles(soa, class_loader);
597}
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700598
Calin Juravlec79470d2017-07-12 17:37:42 -0700599std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
600 ScopedObjectAccess& soa,
601 Handle<mirror::ClassLoader> class_loader) {
602 std::vector<const DexFile*> ret;
603
604 DCHECK(
605 (class_loader->GetClass() ==
606 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
607 (class_loader->GetClass() ==
608 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700609
610 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
611 // We need to get the DexPathList and loop through it.
Andreas Gampe08883de2016-11-08 13:20:52 -0800612 ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700613 ArtField* dex_file_field =
Andreas Gampe08883de2016-11-08 13:20:52 -0800614 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700615 ObjPtr<mirror::Object> dex_path_list =
Andreas Gampe08883de2016-11-08 13:20:52 -0800616 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
617 GetObject(class_loader.Get());
Mathieu Chartierc7853442015-03-27 14:35:38 -0700618 if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700619 // DexPathList has an array dexElements of Elements[] which each contain a dex file.
Mathieu Chartier3398c782016-09-30 10:27:43 -0700620 ObjPtr<mirror::Object> dex_elements_obj =
Andreas Gampe08883de2016-11-08 13:20:52 -0800621 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
622 GetObject(dex_path_list);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700623 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
624 // at the mCookie which is a DexFile vector.
625 if (dex_elements_obj != nullptr) {
Calin Juravlec79470d2017-07-12 17:37:42 -0700626 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700627 Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
628 hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
629 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700630 ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700631 if (element == nullptr) {
632 // Should never happen, fall back to java code to throw a NPE.
633 break;
634 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700635 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700636 if (dex_file != nullptr) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700637 ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700638 DCHECK(long_array != nullptr);
639 int32_t long_array_size = long_array->GetLength();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700640 for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700641 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
642 long_array->GetWithoutChecks(j)));
643 if (cp_dex_file == nullptr) {
644 LOG(WARNING) << "Null DexFile";
645 continue;
646 }
647 ret.push_back(cp_dex_file);
648 }
649 }
650 }
651 }
652 }
653
654 return ret;
655}
656
Mathieu Chartier91c91162016-01-15 09:48:15 -0800657const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700658 std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
659 DCHECK(!tmp.empty());
660 const DexFile* ret = tmp[0];
661 DCHECK(ret != nullptr);
662 return ret;
663}
664
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100665jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
666 const char* second_dex_name) {
667 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
668 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
669 std::vector<const DexFile*> class_path;
670 CHECK_NE(0U, first_dex_files.size());
671 CHECK_NE(0U, second_dex_files.size());
672 for (auto& dex_file : first_dex_files) {
673 class_path.push_back(dex_file.get());
674 loaded_dex_files_.push_back(std::move(dex_file));
675 }
676 for (auto& dex_file : second_dex_files) {
677 class_path.push_back(dex_file.get());
678 loaded_dex_files_.push_back(std::move(dex_file));
679 }
680
681 Thread* self = Thread::Current();
682 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
683 class_path);
684 self->SetClassLoaderOverride(class_loader);
685 return class_loader;
686}
687
Mathieu Chartier91c91162016-01-15 09:48:15 -0800688jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
Calin Juravle7865ac72017-06-28 11:03:12 -0700689 jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
690 Thread::Current()->SetClassLoaderOverride(class_loader);
691 return class_loader;
692}
693
694jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
695 jclass loader_class,
696 jobject parent_loader) {
697 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800698 std::vector<const DexFile*> class_path;
Ian Rogerse63db272014-07-15 15:36:11 -0700699 CHECK_NE(0U, dex_files.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800700 for (auto& dex_file : dex_files) {
701 class_path.push_back(dex_file.get());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800702 loaded_dex_files_.push_back(std::move(dex_file));
Ian Rogerse63db272014-07-15 15:36:11 -0700703 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700704 Thread* self = Thread::Current();
Calin Juravle7865ac72017-06-28 11:03:12 -0700705 ScopedObjectAccess soa(self);
706
707 jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
708 self,
709 class_path,
710 loader_class,
711 parent_loader);
712
713 {
714 // Verify we build the correct chain.
715
716 ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
717 // Verify that the result has the correct class.
718 CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
719 // Verify that the parent is not null. The boot class loader will be set up as a
720 // proper object.
721 ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
722 CHECK(actual_parent != nullptr);
723
724 if (parent_loader != nullptr) {
725 // We were given a parent. Verify that it's what we expect.
726 ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
727 CHECK_EQ(expected_parent, actual_parent);
728 } else {
729 // No parent given. The parent must be the BootClassLoader.
730 CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
731 }
732 }
733
734 return result;
735}
736
737jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
738 jobject parent_loader) {
739 return LoadDexInWellKnownClassLoader(dex_name,
740 WellKnownClasses::dalvik_system_PathClassLoader,
741 parent_loader);
742}
743
744jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
745 jobject parent_loader) {
746 return LoadDexInWellKnownClassLoader(dex_name,
747 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
748 parent_loader);
Ian Rogerse63db272014-07-15 15:36:11 -0700749}
750
Mathieu Chartier91c91162016-01-15 09:48:15 -0800751std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
Igor Murashkin37743352014-11-13 14:38:00 -0800752 CHECK(suffix != nullptr);
753
754 std::string location;
755 if (IsHost()) {
756 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700757 CHECK(host_dir != nullptr);
Richard Uhler67e1dc52017-02-06 16:50:17 +0000758 location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800759 } else {
Richard Uhler67e1dc52017-02-06 16:50:17 +0000760 location = StringPrintf("/data/art-test/core.%s", suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800761 }
762
763 return location;
764}
765
Calin Juravlec79470d2017-07-12 17:37:42 -0700766std::string CommonRuntimeTestImpl::CreateClassPath(
767 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
768 CHECK(!dex_files.empty());
769 std::string classpath = dex_files[0]->GetLocation();
770 for (size_t i = 1; i < dex_files.size(); i++) {
771 classpath += ":" + dex_files[i]->GetLocation();
772 }
773 return classpath;
774}
775
776std::string CommonRuntimeTestImpl::CreateClassPathWithChecksums(
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 std::to_string(dex_files[0]->GetLocationChecksum());
781 for (size_t i = 1; i < dex_files.size(); i++) {
782 classpath += ":" + dex_files[i]->GetLocation() + "*" +
783 std::to_string(dex_files[i]->GetLocationChecksum());
784 }
785 return classpath;
786}
787
Andreas Gampe26761f72017-07-20 18:00:39 -0700788void CommonRuntimeTestImpl::FillHeap(Thread* self,
789 ClassLinker* class_linker,
790 VariableSizedHandleScope* handle_scope) {
791 DCHECK(handle_scope != nullptr);
792
793 Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
794
795 // Class java.lang.Object.
796 Handle<mirror::Class> c(handle_scope->NewHandle(
797 class_linker->FindSystemClass(self, "Ljava/lang/Object;")));
798 // Array helps to fill memory faster.
799 Handle<mirror::Class> ca(handle_scope->NewHandle(
800 class_linker->FindSystemClass(self, "[Ljava/lang/Object;")));
801
802 // Start allocating with ~128K
803 size_t length = 128 * KB;
804 while (length > 40) {
805 const int32_t array_length = length / 4; // Object[] has elements of size 4.
806 MutableHandle<mirror::Object> h(handle_scope->NewHandle<mirror::Object>(
807 mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), array_length)));
808 if (self->IsExceptionPending() || h == nullptr) {
809 self->ClearException();
810
811 // Try a smaller length
812 length = length / 2;
813 // Use at most a quarter the reported free space.
814 size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
815 if (length * 4 > mem) {
816 length = mem / 4;
817 }
818 }
819 }
820
821 // Allocate simple objects till it fails.
822 while (!self->IsExceptionPending()) {
823 handle_scope->NewHandle<mirror::Object>(c->AllocObject(self));
824 }
825 self->ClearException();
826}
827
828void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *options) {
829 // Use a smaller heap
830 bool found = false;
831 for (std::pair<std::string, const void*>& pair : *options) {
832 if (pair.first.find("-Xmx") == 0) {
833 pair.first = "-Xmx4M"; // Smallest we can go.
834 found = true;
835 }
836 }
837 if (!found) {
838 options->emplace_back("-Xmx4M", nullptr);
839 }
840}
841
Ian Rogerse63db272014-07-15 15:36:11 -0700842CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700843 vm_->SetCheckJniAbortHook(Hook, &actual_);
Ian Rogerse63db272014-07-15 15:36:11 -0700844}
845
846CheckJniAbortCatcher::~CheckJniAbortCatcher() {
Ian Rogers68d8b422014-07-17 11:09:10 -0700847 vm_->SetCheckJniAbortHook(nullptr, nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700848 EXPECT_TRUE(actual_.empty()) << actual_;
849}
850
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700851void CheckJniAbortCatcher::Check(const std::string& expected_text) {
852 Check(expected_text.c_str());
853}
854
Ian Rogerse63db272014-07-15 15:36:11 -0700855void CheckJniAbortCatcher::Check(const char* expected_text) {
856 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
857 << "Expected to find: " << expected_text << "\n"
858 << "In the output : " << actual_;
859 actual_.clear();
860}
861
862void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
863 // We use += because when we're hooking the aborts like this, multiple problems can be found.
864 *reinterpret_cast<std::string*>(data) += reason;
865}
866
867} // namespace art