blob: f15acf980ae83d93f4faf23a9b81cdcd4c7c476c [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
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"
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"
Ian Rogerse63db272014-07-15 15:36:11 -070033#include "base/stl_util.h"
Ian Rogerse63db272014-07-15 15:36:11 -070034#include "base/unix_file/fd_file.h"
35#include "class_linker.h"
36#include "compiler_callbacks.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070037#include "dex_file-inl.h"
Mathieu Chartier79c87da2017-10-10 11:54:29 -070038#include "dex_file_loader.h"
Ian Rogerse63db272014-07-15 15:36:11 -070039#include "gc/heap.h"
Steven Morelande431e272017-07-18 16:53:49 -070040#include "gc_root-inl.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070041#include "gtest/gtest.h"
Andreas Gampe81c6f8d2015-03-25 17:19:53 -070042#include "handle_scope-inl.h"
Andreas Gampe9b5cba42015-03-11 09:53:50 -070043#include "interpreter/unstarted_runtime.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070044#include "java_vm_ext.h"
Ian Rogerse63db272014-07-15 15:36:11 -070045#include "jni_internal.h"
Steven Morelande431e272017-07-18 16:53:49 -070046#include "mem_map.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070047#include "mirror/class-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070048#include "mirror/class_loader.h"
Mathieu Chartiere58991b2015-10-13 07:59:34 -070049#include "native/dalvik_system_DexFile.h"
Ian Rogerse63db272014-07-15 15:36:11 -070050#include "noop_compiler_callbacks.h"
51#include "os.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070052#include "primitive.h"
Ian Rogerse63db272014-07-15 15:36:11 -070053#include "runtime-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070054#include "scoped_thread_state_change-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070055#include "thread.h"
56#include "well_known_classes.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070057
58int main(int argc, char **argv) {
Andreas Gampe369810a2015-01-14 19:53:31 -080059 // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
60 // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
61 // everything else. In case you want to see all messages, comment out the line.
Nicolas Geoffraya7a47592015-11-24 09:17:30 +000062 setenv("ANDROID_LOG_TAGS", "*:e", 1);
Andreas Gampe369810a2015-01-14 19:53:31 -080063
Andreas Gampe51d80cc2017-06-21 21:05:13 -070064 art::InitLogging(argv, art::Runtime::Abort);
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070065 LOG(INFO) << "Running main() from common_runtime_test.cc...";
Elliott Hugheseb02a122012-06-12 11:35:40 -070066 testing::InitGoogleTest(&argc, argv);
67 return RUN_ALL_TESTS();
68}
Ian Rogerse63db272014-07-15 15:36:11 -070069
70namespace art {
71
Andreas Gampe46ee31b2016-12-14 10:11:49 -080072using android::base::StringPrintf;
73
Alex Lighta01b5242017-03-27 10:15:27 -070074static const uint8_t kBase64Map[256] = {
75 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
76 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
77 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
78 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
79 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
80 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
81 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
82 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
83 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
84 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
85 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
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, 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
97};
98
99uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
100 CHECK(dst_size != nullptr);
101 std::vector<uint8_t> tmp;
102 uint32_t t = 0, y = 0;
103 int g = 3;
104 for (size_t i = 0; src[i] != '\0'; ++i) {
105 uint8_t c = kBase64Map[src[i] & 0xFF];
106 if (c == 255) continue;
107 // the final = symbols are read and used to trim the remaining bytes
108 if (c == 254) {
109 c = 0;
110 // prevent g < 0 which would potentially allow an overflow later
111 if (--g < 0) {
112 *dst_size = 0;
113 return nullptr;
114 }
115 } else if (g != 3) {
116 // we only allow = to be at the end
117 *dst_size = 0;
118 return nullptr;
119 }
120 t = (t << 6) | c;
121 if (++y == 4) {
122 tmp.push_back((t >> 16) & 255);
123 if (g > 1) {
124 tmp.push_back((t >> 8) & 255);
125 }
126 if (g > 2) {
127 tmp.push_back(t & 255);
128 }
129 y = t = 0;
130 }
131 }
132 if (y != 0) {
133 *dst_size = 0;
134 return nullptr;
135 }
136 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
137 *dst_size = tmp.size();
138 std::copy(tmp.begin(), tmp.end(), dst.get());
139 return dst.release();
140}
141
Ian Rogerse63db272014-07-15 15:36:11 -0700142ScratchFile::ScratchFile() {
143 // ANDROID_DATA needs to be set
144 CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
145 "Are you subclassing RuntimeTest?";
146 filename_ = getenv("ANDROID_DATA");
147 filename_ += "/TmpFile-XXXXXX";
148 int fd = mkstemp(&filename_[0]);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000149 CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
Andreas Gampe4303ba92014-11-06 01:00:46 -0800150 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700151}
152
Mathieu Chartier866d8742016-09-21 15:24:18 -0700153ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
154 : ScratchFile(other.GetFilename() + suffix) {}
155
156ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
Ian Rogerse63db272014-07-15 15:36:11 -0700157 int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
158 CHECK_NE(-1, fd);
Andreas Gampe4303ba92014-11-06 01:00:46 -0800159 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700160}
161
162ScratchFile::ScratchFile(File* file) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700163 CHECK(file != nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700164 filename_ = file->GetPath();
165 file_.reset(file);
166}
167
Mathieu Chartier866d8742016-09-21 15:24:18 -0700168ScratchFile::ScratchFile(ScratchFile&& other) {
169 *this = std::move(other);
170}
171
172ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
173 if (GetFile() != other.GetFile()) {
174 std::swap(filename_, other.filename_);
175 std::swap(file_, other.file_);
176 }
177 return *this;
178}
179
Ian Rogerse63db272014-07-15 15:36:11 -0700180ScratchFile::~ScratchFile() {
181 Unlink();
182}
183
184int ScratchFile::GetFd() const {
185 return file_->Fd();
186}
187
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800188void ScratchFile::Close() {
Andreas Gampe4303ba92014-11-06 01:00:46 -0800189 if (file_.get() != nullptr) {
190 if (file_->FlushCloseOrErase() != 0) {
191 PLOG(WARNING) << "Error closing scratch file.";
192 }
193 }
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800194}
195
196void ScratchFile::Unlink() {
197 if (!OS::FileExists(filename_.c_str())) {
198 return;
199 }
200 Close();
Ian Rogerse63db272014-07-15 15:36:11 -0700201 int unlink_result = unlink(filename_.c_str());
202 CHECK_EQ(0, unlink_result);
203}
204
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700205static bool unstarted_initialized_ = false;
206
Andreas Gampe48864112017-01-19 17:23:17 -0800207CommonRuntimeTestImpl::CommonRuntimeTestImpl()
208 : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
209}
Mathieu Chartier91c91162016-01-15 09:48:15 -0800210
211CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800212 // Ensure the dex files are cleaned up before the runtime.
213 loaded_dex_files_.clear();
214 runtime_.reset();
215}
Ian Rogerse63db272014-07-15 15:36:11 -0700216
Mathieu Chartier91c91162016-01-15 09:48:15 -0800217void CommonRuntimeTestImpl::SetUpAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700218 if (IsHost()) {
219 // $ANDROID_ROOT is set on the device, but not necessarily on the host.
220 // But it needs to be set so that icu4c can find its locale data.
221 const char* android_root_from_env = getenv("ANDROID_ROOT");
222 if (android_root_from_env == nullptr) {
223 // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
224 const char* android_host_out = getenv("ANDROID_HOST_OUT");
225 if (android_host_out != nullptr) {
226 setenv("ANDROID_ROOT", android_host_out, 1);
227 } else {
228 // Build it from ANDROID_BUILD_TOP or cwd
229 std::string root;
230 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
231 if (android_build_top != nullptr) {
232 root += android_build_top;
233 } else {
234 // Not set by build server, so default to current directory
235 char* cwd = getcwd(nullptr, 0);
236 setenv("ANDROID_BUILD_TOP", cwd, 1);
237 root += cwd;
238 free(cwd);
239 }
240#if defined(__linux__)
241 root += "/out/host/linux-x86";
242#elif defined(__APPLE__)
243 root += "/out/host/darwin-x86";
244#else
245#error unsupported OS
246#endif
247 setenv("ANDROID_ROOT", root.c_str(), 1);
248 }
249 }
250 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
251
252 // Not set by build server, so default
253 if (getenv("ANDROID_HOST_OUT") == nullptr) {
254 setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
255 }
256 }
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700257}
Ian Rogerse63db272014-07-15 15:36:11 -0700258
Mathieu Chartier91c91162016-01-15 09:48:15 -0800259void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
Ian Rogerse63db272014-07-15 15:36:11 -0700260 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
Andreas Gampe5a79fde2014-08-06 13:12:26 -0700261 if (IsHost()) {
262 const char* tmpdir = getenv("TMPDIR");
263 if (tmpdir != nullptr && tmpdir[0] != 0) {
264 android_data = tmpdir;
265 } else {
266 android_data = "/tmp";
267 }
268 } else {
269 android_data = "/data/dalvik-cache";
270 }
271 android_data += "/art-data-XXXXXX";
Ian Rogerse63db272014-07-15 15:36:11 -0700272 if (mkdtemp(&android_data[0]) == nullptr) {
273 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
274 }
275 setenv("ANDROID_DATA", android_data.c_str(), 1);
276}
277
Mathieu Chartier91c91162016-01-15 09:48:15 -0800278void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
279 bool fail_on_error) {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700280 if (fail_on_error) {
281 ASSERT_EQ(rmdir(android_data.c_str()), 0);
282 } else {
283 rmdir(android_data.c_str());
284 }
285}
286
David Srbecky3e52aa42015-04-12 07:45:18 +0100287// Helper - find directory with the following format:
288// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
289static std::string GetAndroidToolsDir(const std::string& subdir1,
290 const std::string& subdir2,
291 const std::string& subdir3) {
292 std::string root;
293 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
294 if (android_build_top != nullptr) {
295 root = android_build_top;
296 } else {
297 // Not set by build server, so default to current directory
298 char* cwd = getcwd(nullptr, 0);
299 setenv("ANDROID_BUILD_TOP", cwd, 1);
300 root = cwd;
301 free(cwd);
302 }
303
304 std::string toolsdir = root + "/" + subdir1;
305 std::string founddir;
306 DIR* dir;
307 if ((dir = opendir(toolsdir.c_str())) != nullptr) {
308 float maxversion = 0;
309 struct dirent* entry;
310 while ((entry = readdir(dir)) != nullptr) {
311 std::string format = subdir2 + "-%f";
312 float version;
313 if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
314 if (version > maxversion) {
315 maxversion = version;
316 founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
317 }
318 }
319 }
320 closedir(dir);
321 }
322
323 if (founddir.empty()) {
Roland Levillain91d65e02016-01-19 15:59:16 +0000324 ADD_FAILURE() << "Cannot find Android tools directory.";
David Srbecky3e52aa42015-04-12 07:45:18 +0100325 }
326 return founddir;
327}
328
Mathieu Chartier91c91162016-01-15 09:48:15 -0800329std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
David Srbecky3e52aa42015-04-12 07:45:18 +0100330 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
331 "x86_64-linux-glibc2.15",
332 "x86_64-linux");
333}
334
Mathieu Chartier91c91162016-01-15 09:48:15 -0800335std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
David Srbecky3e52aa42015-04-12 07:45:18 +0100336 switch (isa) {
337 case kArm:
338 case kThumb2:
339 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
340 "arm-linux-androideabi",
341 "arm-linux-androideabi");
342 case kArm64:
343 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
344 "aarch64-linux-android",
345 "aarch64-linux-android");
346 case kX86:
347 case kX86_64:
348 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
349 "x86_64-linux-android",
350 "x86_64-linux-android");
351 case kMips:
352 case kMips64:
353 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
354 "mips64el-linux-android",
355 "mips64el-linux-android");
356 case kNone:
357 break;
358 }
359 ADD_FAILURE() << "Invalid isa " << isa;
360 return "";
361}
362
Mathieu Chartier91c91162016-01-15 09:48:15 -0800363std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800364 return GetCoreFileLocation("art");
365}
366
Mathieu Chartier91c91162016-01-15 09:48:15 -0800367std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800368 return GetCoreFileLocation("oat");
369}
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700370
Mathieu Chartier91c91162016-01-15 09:48:15 -0800371std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
372 const char* location) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800373 std::vector<std::unique_ptr<const DexFile>> dex_files;
Ian Rogerse63db272014-07-15 15:36:11 -0700374 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800375 MemMap::Init();
Aart Bik37d6a3b2016-06-21 18:30:10 -0700376 static constexpr bool kVerifyChecksum = true;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100377 if (!DexFileLoader::Open(
378 location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files)) {
Ian Rogerse63db272014-07-15 15:36:11 -0700379 LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800380 UNREACHABLE();
Ian Rogerse63db272014-07-15 15:36:11 -0700381 } else {
382 CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800383 return std::move(dex_files[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700384 }
385}
386
Mathieu Chartier91c91162016-01-15 09:48:15 -0800387void CommonRuntimeTestImpl::SetUp() {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700388 SetUpAndroidRoot();
389 SetUpAndroidData(android_data_);
Ian Rogerse63db272014-07-15 15:36:11 -0700390 dalvik_cache_.append(android_data_.c_str());
391 dalvik_cache_.append("/dalvik-cache");
392 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
393 ASSERT_EQ(mkdir_result, 0);
394
Ian Rogerse63db272014-07-15 15:36:11 -0700395 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
396 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
397
Ian Rogerse63db272014-07-15 15:36:11 -0700398
399 RuntimeOptions options;
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000400 std::string boot_class_path_string = "-Xbootclasspath";
401 for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
402 boot_class_path_string += ":";
403 boot_class_path_string += core_dex_file_name;
404 }
405
Richard Uhlerc2752592015-01-02 13:28:22 -0800406 options.push_back(std::make_pair(boot_class_path_string, nullptr));
Ian Rogerse63db272014-07-15 15:36:11 -0700407 options.push_back(std::make_pair("-Xcheck:jni", nullptr));
Richard Uhlerc2752592015-01-02 13:28:22 -0800408 options.push_back(std::make_pair(min_heap_string, nullptr));
409 options.push_back(std::make_pair(max_heap_string, nullptr));
Andreas Gampe1c5b42f2017-06-15 18:20:45 -0700410 options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
Andreas Gampe46c4c852017-06-21 19:49:08 -0700411 static bool gSlowDebugTestFlag = false;
412 RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700413
414 callbacks_.reset(new NoopCompilerCallbacks());
415
Ian Rogerse63db272014-07-15 15:36:11 -0700416 SetUpRuntimeOptions(&options);
Igor Murashkinaaebaa02015-01-26 10:55:53 -0800417
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700418 // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
419 if (callbacks_.get() != nullptr) {
420 options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
421 }
422
Richard Uhler66d874d2015-01-15 09:37:19 -0800423 PreRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700424 if (!Runtime::Create(options, false)) {
425 LOG(FATAL) << "Failed to create runtime";
426 return;
427 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800428 PostRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700429 runtime_.reset(Runtime::Current());
430 class_linker_ = runtime_->GetClassLinker();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700431
Andreas Gampea00f0122015-12-16 16:54:35 -0800432 // Runtime::Create acquired the mutator_lock_ that is normally given away when we
433 // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
434 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
435
436 // Get the boot class path from the runtime so it can be used in tests.
437 boot_class_path_ = class_linker_->GetBootClassPath();
438 ASSERT_FALSE(boot_class_path_.empty());
439 java_lang_dex_file_ = boot_class_path_[0];
440
441 FinalizeSetup();
Andreas Gampe46c4c852017-06-21 19:49:08 -0700442
443 // Ensure that we're really running with debug checks enabled.
444 CHECK(gSlowDebugTestFlag);
Andreas Gampea00f0122015-12-16 16:54:35 -0800445}
446
Mathieu Chartier91c91162016-01-15 09:48:15 -0800447void CommonRuntimeTestImpl::FinalizeSetup() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700448 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
449 // set up.
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700450 if (!unstarted_initialized_) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700451 interpreter::UnstartedRuntime::Initialize();
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700452 unstarted_initialized_ = true;
453 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700454
Andreas Gampea00f0122015-12-16 16:54:35 -0800455 {
456 ScopedObjectAccess soa(Thread::Current());
457 class_linker_->RunRootClinits();
458 }
Ian Rogerse63db272014-07-15 15:36:11 -0700459
460 // We're back in native, take the opportunity to initialize well known classes.
461 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
462
463 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
464 // pool is created by the runtime.
465 runtime_->GetHeap()->CreateThreadPool();
466 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Hiroshi Yamauchi4460a842015-03-09 11:57:48 -0700467 // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
468 runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
Ian Rogerse63db272014-07-15 15:36:11 -0700469}
470
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700471void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath, bool recursive) {
Alex Lighta59dd802014-07-02 16:28:08 -0700472 ASSERT_TRUE(dirpath != nullptr);
473 DIR* dir = opendir(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700474 ASSERT_TRUE(dir != nullptr);
475 dirent* e;
Alex Lighta59dd802014-07-02 16:28:08 -0700476 struct stat s;
Ian Rogerse63db272014-07-15 15:36:11 -0700477 while ((e = readdir(dir)) != nullptr) {
478 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
479 continue;
480 }
Jeff Haof0a3f092014-07-24 16:26:09 -0700481 std::string filename(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700482 filename.push_back('/');
483 filename.append(e->d_name);
Alex Lighta59dd802014-07-02 16:28:08 -0700484 int stat_result = lstat(filename.c_str(), &s);
485 ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
486 if (S_ISDIR(s.st_mode)) {
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700487 if (recursive) {
488 ClearDirectory(filename.c_str());
489 int rmdir_result = rmdir(filename.c_str());
490 ASSERT_EQ(0, rmdir_result) << filename;
491 }
Alex Lighta59dd802014-07-02 16:28:08 -0700492 } else {
493 int unlink_result = unlink(filename.c_str());
494 ASSERT_EQ(0, unlink_result) << filename;
495 }
Ian Rogerse63db272014-07-15 15:36:11 -0700496 }
497 closedir(dir);
Alex Lighta59dd802014-07-02 16:28:08 -0700498}
499
Mathieu Chartier91c91162016-01-15 09:48:15 -0800500void CommonRuntimeTestImpl::TearDown() {
Alex Lighta59dd802014-07-02 16:28:08 -0700501 const char* android_data = getenv("ANDROID_DATA");
502 ASSERT_TRUE(android_data != nullptr);
503 ClearDirectory(dalvik_cache_.c_str());
Ian Rogerse63db272014-07-15 15:36:11 -0700504 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
505 ASSERT_EQ(0, rmdir_cache_result);
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700506 TearDownAndroidData(android_data_, true);
Andreas Gampe3f41a012016-02-18 16:53:41 -0800507 dalvik_cache_.clear();
Ian Rogerse63db272014-07-15 15:36:11 -0700508
Andreas Gampe48864112017-01-19 17:23:17 -0800509 if (runtime_ != nullptr) {
510 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
511 }
Ian Rogerse63db272014-07-15 15:36:11 -0700512}
513
Andreas Gampec7d4a582015-09-30 11:52:02 -0700514static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
515 std::string path;
516 if (host) {
Ian Rogerse63db272014-07-15 15:36:11 -0700517 const char* host_dir = getenv("ANDROID_HOST_OUT");
518 CHECK(host_dir != nullptr);
Andreas Gampec7d4a582015-09-30 11:52:02 -0700519 path = host_dir;
520 } else {
521 path = GetAndroidRoot();
Ian Rogerse63db272014-07-15 15:36:11 -0700522 }
Andreas Gampec7d4a582015-09-30 11:52:02 -0700523
524 std::string suffix = host
525 ? "-hostdex" // The host version.
526 : "-testdex"; // The unstripped target version.
527
528 return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
529}
530
Mathieu Chartier91c91162016-01-15 09:48:15 -0800531std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
Andreas Gampec7d4a582015-09-30 11:52:02 -0700532 return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
533 GetDexFileName("core-libart", IsHost())});
Ian Rogerse63db272014-07-15 15:36:11 -0700534}
535
Mathieu Chartier91c91162016-01-15 09:48:15 -0800536std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700537 if (IsHost()) {
538 const char* host_dir = getenv("ANDROID_HOST_OUT");
539 CHECK(host_dir != nullptr);
540 return host_dir;
541 }
542 return GetAndroidRoot();
543}
544
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700545// Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
546#ifdef ART_TARGET
547#ifndef ART_TARGET_NATIVETEST_DIR
548#error "ART_TARGET_NATIVETEST_DIR not set."
549#endif
550// Wrap it as a string literal.
551#define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
552#else
553#define ART_TARGET_NATIVETEST_DIR_STRING ""
554#endif
555
Andreas Gampee1459ae2016-06-29 09:36:30 -0700556std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
Ian Rogerse63db272014-07-15 15:36:11 -0700557 CHECK(name != nullptr);
558 std::string filename;
559 if (IsHost()) {
560 filename += getenv("ANDROID_HOST_OUT");
561 filename += "/framework/";
562 } else {
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700563 filename += ART_TARGET_NATIVETEST_DIR_STRING;
Ian Rogerse63db272014-07-15 15:36:11 -0700564 }
565 filename += "art-gtest-";
566 filename += name;
567 filename += ".jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800568 return filename;
569}
570
Mathieu Chartier91c91162016-01-15 09:48:15 -0800571std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
572 const char* name) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800573 std::string filename = GetTestDexFileName(name);
Aart Bik37d6a3b2016-06-21 18:30:10 -0700574 static constexpr bool kVerifyChecksum = true;
Ian Rogerse63db272014-07-15 15:36:11 -0700575 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800576 std::vector<std::unique_ptr<const DexFile>> dex_files;
Nicolas Geoffray095c6c92017-10-19 13:59:55 +0100577 bool success = DexFileLoader::Open(filename.c_str(),
578 filename.c_str(),
579 /* verify */ true,
580 kVerifyChecksum,
581 &error_msg, &dex_files);
Ian Rogerse63db272014-07-15 15:36:11 -0700582 CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800583 for (auto& dex_file : dex_files) {
Ian Rogerse63db272014-07-15 15:36:11 -0700584 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
585 CHECK(dex_file->IsReadOnly());
586 }
Ian Rogerse63db272014-07-15 15:36:11 -0700587 return dex_files;
588}
589
Mathieu Chartier91c91162016-01-15 09:48:15 -0800590std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800591 std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
Ian Rogerse63db272014-07-15 15:36:11 -0700592 EXPECT_EQ(1U, vector.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800593 return std::move(vector[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700594}
595
Mathieu Chartier91c91162016-01-15 09:48:15 -0800596std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700597 ScopedObjectAccess soa(Thread::Current());
598
Calin Juravlec79470d2017-07-12 17:37:42 -0700599 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700600 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700601 soa.Decode<mirror::ClassLoader>(jclass_loader));
Calin Juravlec79470d2017-07-12 17:37:42 -0700602 return GetDexFiles(soa, class_loader);
603}
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700604
Calin Juravlec79470d2017-07-12 17:37:42 -0700605std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
606 ScopedObjectAccess& soa,
607 Handle<mirror::ClassLoader> class_loader) {
608 std::vector<const DexFile*> ret;
609
610 DCHECK(
611 (class_loader->GetClass() ==
612 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
613 (class_loader->GetClass() ==
614 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700615
616 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
617 // We need to get the DexPathList and loop through it.
Andreas Gampe08883de2016-11-08 13:20:52 -0800618 ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700619 ArtField* dex_file_field =
Andreas Gampe08883de2016-11-08 13:20:52 -0800620 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700621 ObjPtr<mirror::Object> dex_path_list =
Andreas Gampe08883de2016-11-08 13:20:52 -0800622 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
623 GetObject(class_loader.Get());
Mathieu Chartierc7853442015-03-27 14:35:38 -0700624 if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700625 // DexPathList has an array dexElements of Elements[] which each contain a dex file.
Mathieu Chartier3398c782016-09-30 10:27:43 -0700626 ObjPtr<mirror::Object> dex_elements_obj =
Andreas Gampe08883de2016-11-08 13:20:52 -0800627 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
628 GetObject(dex_path_list);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700629 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
630 // at the mCookie which is a DexFile vector.
631 if (dex_elements_obj != nullptr) {
Calin Juravlec79470d2017-07-12 17:37:42 -0700632 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700633 Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
634 hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
635 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700636 ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700637 if (element == nullptr) {
638 // Should never happen, fall back to java code to throw a NPE.
639 break;
640 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700641 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700642 if (dex_file != nullptr) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700643 ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700644 DCHECK(long_array != nullptr);
645 int32_t long_array_size = long_array->GetLength();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700646 for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700647 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
648 long_array->GetWithoutChecks(j)));
649 if (cp_dex_file == nullptr) {
650 LOG(WARNING) << "Null DexFile";
651 continue;
652 }
653 ret.push_back(cp_dex_file);
654 }
655 }
656 }
657 }
658 }
659
660 return ret;
661}
662
Mathieu Chartier91c91162016-01-15 09:48:15 -0800663const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700664 std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
665 DCHECK(!tmp.empty());
666 const DexFile* ret = tmp[0];
667 DCHECK(ret != nullptr);
668 return ret;
669}
670
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100671jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
672 const char* second_dex_name) {
673 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
674 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
675 std::vector<const DexFile*> class_path;
676 CHECK_NE(0U, first_dex_files.size());
677 CHECK_NE(0U, second_dex_files.size());
678 for (auto& dex_file : first_dex_files) {
679 class_path.push_back(dex_file.get());
680 loaded_dex_files_.push_back(std::move(dex_file));
681 }
682 for (auto& dex_file : second_dex_files) {
683 class_path.push_back(dex_file.get());
684 loaded_dex_files_.push_back(std::move(dex_file));
685 }
686
687 Thread* self = Thread::Current();
688 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
689 class_path);
690 self->SetClassLoaderOverride(class_loader);
691 return class_loader;
692}
693
Mathieu Chartier91c91162016-01-15 09:48:15 -0800694jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
Calin Juravle7865ac72017-06-28 11:03:12 -0700695 jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
696 Thread::Current()->SetClassLoaderOverride(class_loader);
697 return class_loader;
698}
699
700jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
701 jclass loader_class,
702 jobject parent_loader) {
703 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800704 std::vector<const DexFile*> class_path;
Ian Rogerse63db272014-07-15 15:36:11 -0700705 CHECK_NE(0U, dex_files.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800706 for (auto& dex_file : dex_files) {
707 class_path.push_back(dex_file.get());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800708 loaded_dex_files_.push_back(std::move(dex_file));
Ian Rogerse63db272014-07-15 15:36:11 -0700709 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700710 Thread* self = Thread::Current();
Calin Juravle7865ac72017-06-28 11:03:12 -0700711 ScopedObjectAccess soa(self);
712
713 jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
714 self,
715 class_path,
716 loader_class,
717 parent_loader);
718
719 {
720 // Verify we build the correct chain.
721
722 ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
723 // Verify that the result has the correct class.
724 CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
725 // Verify that the parent is not null. The boot class loader will be set up as a
726 // proper object.
727 ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
728 CHECK(actual_parent != nullptr);
729
730 if (parent_loader != nullptr) {
731 // We were given a parent. Verify that it's what we expect.
732 ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
733 CHECK_EQ(expected_parent, actual_parent);
734 } else {
735 // No parent given. The parent must be the BootClassLoader.
736 CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
737 }
738 }
739
740 return result;
741}
742
743jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
744 jobject parent_loader) {
745 return LoadDexInWellKnownClassLoader(dex_name,
746 WellKnownClasses::dalvik_system_PathClassLoader,
747 parent_loader);
748}
749
750jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
751 jobject parent_loader) {
752 return LoadDexInWellKnownClassLoader(dex_name,
753 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
754 parent_loader);
Ian Rogerse63db272014-07-15 15:36:11 -0700755}
756
Mathieu Chartier91c91162016-01-15 09:48:15 -0800757std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
Igor Murashkin37743352014-11-13 14:38:00 -0800758 CHECK(suffix != nullptr);
759
760 std::string location;
761 if (IsHost()) {
762 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700763 CHECK(host_dir != nullptr);
Richard Uhler67e1dc52017-02-06 16:50:17 +0000764 location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800765 } else {
Richard Uhler67e1dc52017-02-06 16:50:17 +0000766 location = StringPrintf("/data/art-test/core.%s", suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800767 }
768
769 return location;
770}
771
Calin Juravlec79470d2017-07-12 17:37:42 -0700772std::string CommonRuntimeTestImpl::CreateClassPath(
773 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
774 CHECK(!dex_files.empty());
775 std::string classpath = dex_files[0]->GetLocation();
776 for (size_t i = 1; i < dex_files.size(); i++) {
777 classpath += ":" + dex_files[i]->GetLocation();
778 }
779 return classpath;
780}
781
782std::string CommonRuntimeTestImpl::CreateClassPathWithChecksums(
783 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
784 CHECK(!dex_files.empty());
785 std::string classpath = dex_files[0]->GetLocation() + "*" +
786 std::to_string(dex_files[0]->GetLocationChecksum());
787 for (size_t i = 1; i < dex_files.size(); i++) {
788 classpath += ":" + dex_files[i]->GetLocation() + "*" +
789 std::to_string(dex_files[i]->GetLocationChecksum());
790 }
791 return classpath;
792}
793
Andreas Gampe26761f72017-07-20 18:00:39 -0700794void CommonRuntimeTestImpl::FillHeap(Thread* self,
795 ClassLinker* class_linker,
796 VariableSizedHandleScope* handle_scope) {
797 DCHECK(handle_scope != nullptr);
798
799 Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
800
801 // Class java.lang.Object.
802 Handle<mirror::Class> c(handle_scope->NewHandle(
803 class_linker->FindSystemClass(self, "Ljava/lang/Object;")));
804 // Array helps to fill memory faster.
805 Handle<mirror::Class> ca(handle_scope->NewHandle(
806 class_linker->FindSystemClass(self, "[Ljava/lang/Object;")));
807
808 // Start allocating with ~128K
809 size_t length = 128 * KB;
810 while (length > 40) {
811 const int32_t array_length = length / 4; // Object[] has elements of size 4.
812 MutableHandle<mirror::Object> h(handle_scope->NewHandle<mirror::Object>(
813 mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), array_length)));
814 if (self->IsExceptionPending() || h == nullptr) {
815 self->ClearException();
816
817 // Try a smaller length
818 length = length / 2;
819 // Use at most a quarter the reported free space.
820 size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
821 if (length * 4 > mem) {
822 length = mem / 4;
823 }
824 }
825 }
826
827 // Allocate simple objects till it fails.
828 while (!self->IsExceptionPending()) {
829 handle_scope->NewHandle<mirror::Object>(c->AllocObject(self));
830 }
831 self->ClearException();
832}
833
834void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *options) {
835 // Use a smaller heap
836 bool found = false;
837 for (std::pair<std::string, const void*>& pair : *options) {
838 if (pair.first.find("-Xmx") == 0) {
839 pair.first = "-Xmx4M"; // Smallest we can go.
840 found = true;
841 }
842 }
843 if (!found) {
844 options->emplace_back("-Xmx4M", nullptr);
845 }
846}
847
Ian Rogerse63db272014-07-15 15:36:11 -0700848CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700849 vm_->SetCheckJniAbortHook(Hook, &actual_);
Ian Rogerse63db272014-07-15 15:36:11 -0700850}
851
852CheckJniAbortCatcher::~CheckJniAbortCatcher() {
Ian Rogers68d8b422014-07-17 11:09:10 -0700853 vm_->SetCheckJniAbortHook(nullptr, nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700854 EXPECT_TRUE(actual_.empty()) << actual_;
855}
856
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700857void CheckJniAbortCatcher::Check(const std::string& expected_text) {
858 Check(expected_text.c_str());
859}
860
Ian Rogerse63db272014-07-15 15:36:11 -0700861void CheckJniAbortCatcher::Check(const char* expected_text) {
862 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
863 << "Expected to find: " << expected_text << "\n"
864 << "In the output : " << actual_;
865 actual_.clear();
866}
867
868void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
869 // We use += because when we're hooking the aborts like this, multiple problems can be found.
870 *reinterpret_cast<std::string*>(data) += reason;
871}
872
873} // namespace art