blob: 0c2e49010e2447e8fa826450180cd389444368b1 [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"
Mathieu Chartier79c87da2017-10-10 11:54:29 -070037#include "dex_file_loader.h"
Ian Rogerse63db272014-07-15 15:36:11 -070038#include "gc/heap.h"
Steven Morelande431e272017-07-18 16:53:49 -070039#include "gc_root-inl.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070040#include "gtest/gtest.h"
Andreas Gampe81c6f8d2015-03-25 17:19:53 -070041#include "handle_scope-inl.h"
Andreas Gampe9b5cba42015-03-11 09:53:50 -070042#include "interpreter/unstarted_runtime.h"
Andreas Gampec15a2f42017-04-21 12:09:39 -070043#include "java_vm_ext.h"
Ian Rogerse63db272014-07-15 15:36:11 -070044#include "jni_internal.h"
Steven Morelande431e272017-07-18 16:53:49 -070045#include "mem_map.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070046#include "mirror/class-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070047#include "mirror/class_loader.h"
Mathieu Chartiere58991b2015-10-13 07:59:34 -070048#include "native/dalvik_system_DexFile.h"
Ian Rogerse63db272014-07-15 15:36:11 -070049#include "noop_compiler_callbacks.h"
50#include "os.h"
Mathieu Chartiere401d142015-04-22 13:56:20 -070051#include "primitive.h"
Ian Rogerse63db272014-07-15 15:36:11 -070052#include "runtime-inl.h"
Mathieu Chartier0795f232016-09-27 18:43:30 -070053#include "scoped_thread_state_change-inl.h"
Ian Rogerse63db272014-07-15 15:36:11 -070054#include "thread.h"
55#include "well_known_classes.h"
Elliott Hugheseb02a122012-06-12 11:35:40 -070056
57int main(int argc, char **argv) {
Andreas Gampe369810a2015-01-14 19:53:31 -080058 // Gtests can be very noisy. For example, an executable with multiple tests will trigger native
59 // bridge warnings. The following line reduces the minimum log severity to ERROR and suppresses
60 // everything else. In case you want to see all messages, comment out the line.
Nicolas Geoffraya7a47592015-11-24 09:17:30 +000061 setenv("ANDROID_LOG_TAGS", "*:e", 1);
Andreas Gampe369810a2015-01-14 19:53:31 -080062
Andreas Gampe51d80cc2017-06-21 21:05:13 -070063 art::InitLogging(argv, art::Runtime::Abort);
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070064 LOG(INFO) << "Running main() from common_runtime_test.cc...";
Elliott Hugheseb02a122012-06-12 11:35:40 -070065 testing::InitGoogleTest(&argc, argv);
66 return RUN_ALL_TESTS();
67}
Ian Rogerse63db272014-07-15 15:36:11 -070068
69namespace art {
70
Andreas Gampe46ee31b2016-12-14 10:11:49 -080071using android::base::StringPrintf;
72
Alex Lighta01b5242017-03-27 10:15:27 -070073static const uint8_t kBase64Map[256] = {
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, 255, 255, 255, 255, 255,
77 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
78 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
79 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
80 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, // NOLINT
81 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // NOLINT
82 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
83 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // NOLINT
84 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, // NOLINT
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, 255, 255, 255, 255, 255, 255, 255, 255,
95 255, 255, 255, 255
96};
97
98uint8_t* DecodeBase64(const char* src, size_t* dst_size) {
99 CHECK(dst_size != nullptr);
100 std::vector<uint8_t> tmp;
101 uint32_t t = 0, y = 0;
102 int g = 3;
103 for (size_t i = 0; src[i] != '\0'; ++i) {
104 uint8_t c = kBase64Map[src[i] & 0xFF];
105 if (c == 255) continue;
106 // the final = symbols are read and used to trim the remaining bytes
107 if (c == 254) {
108 c = 0;
109 // prevent g < 0 which would potentially allow an overflow later
110 if (--g < 0) {
111 *dst_size = 0;
112 return nullptr;
113 }
114 } else if (g != 3) {
115 // we only allow = to be at the end
116 *dst_size = 0;
117 return nullptr;
118 }
119 t = (t << 6) | c;
120 if (++y == 4) {
121 tmp.push_back((t >> 16) & 255);
122 if (g > 1) {
123 tmp.push_back((t >> 8) & 255);
124 }
125 if (g > 2) {
126 tmp.push_back(t & 255);
127 }
128 y = t = 0;
129 }
130 }
131 if (y != 0) {
132 *dst_size = 0;
133 return nullptr;
134 }
135 std::unique_ptr<uint8_t[]> dst(new uint8_t[tmp.size()]);
136 *dst_size = tmp.size();
137 std::copy(tmp.begin(), tmp.end(), dst.get());
138 return dst.release();
139}
140
Ian Rogerse63db272014-07-15 15:36:11 -0700141ScratchFile::ScratchFile() {
142 // ANDROID_DATA needs to be set
143 CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
144 "Are you subclassing RuntimeTest?";
145 filename_ = getenv("ANDROID_DATA");
146 filename_ += "/TmpFile-XXXXXX";
147 int fd = mkstemp(&filename_[0]);
Andreas Gampe29d38e72016-03-23 15:31:51 +0000148 CHECK_NE(-1, fd) << strerror(errno) << " for " << filename_;
Andreas Gampe4303ba92014-11-06 01:00:46 -0800149 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700150}
151
Mathieu Chartier866d8742016-09-21 15:24:18 -0700152ScratchFile::ScratchFile(const ScratchFile& other, const char* suffix)
153 : ScratchFile(other.GetFilename() + suffix) {}
154
155ScratchFile::ScratchFile(const std::string& filename) : filename_(filename) {
Ian Rogerse63db272014-07-15 15:36:11 -0700156 int fd = open(filename_.c_str(), O_RDWR | O_CREAT, 0666);
157 CHECK_NE(-1, fd);
Andreas Gampe4303ba92014-11-06 01:00:46 -0800158 file_.reset(new File(fd, GetFilename(), true));
Ian Rogerse63db272014-07-15 15:36:11 -0700159}
160
161ScratchFile::ScratchFile(File* file) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700162 CHECK(file != nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700163 filename_ = file->GetPath();
164 file_.reset(file);
165}
166
Mathieu Chartier866d8742016-09-21 15:24:18 -0700167ScratchFile::ScratchFile(ScratchFile&& other) {
168 *this = std::move(other);
169}
170
171ScratchFile& ScratchFile::operator=(ScratchFile&& other) {
172 if (GetFile() != other.GetFile()) {
173 std::swap(filename_, other.filename_);
174 std::swap(file_, other.file_);
175 }
176 return *this;
177}
178
Ian Rogerse63db272014-07-15 15:36:11 -0700179ScratchFile::~ScratchFile() {
180 Unlink();
181}
182
183int ScratchFile::GetFd() const {
184 return file_->Fd();
185}
186
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800187void ScratchFile::Close() {
Andreas Gampe4303ba92014-11-06 01:00:46 -0800188 if (file_.get() != nullptr) {
189 if (file_->FlushCloseOrErase() != 0) {
190 PLOG(WARNING) << "Error closing scratch file.";
191 }
192 }
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800193}
194
195void ScratchFile::Unlink() {
196 if (!OS::FileExists(filename_.c_str())) {
197 return;
198 }
199 Close();
Ian Rogerse63db272014-07-15 15:36:11 -0700200 int unlink_result = unlink(filename_.c_str());
201 CHECK_EQ(0, unlink_result);
202}
203
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700204static bool unstarted_initialized_ = false;
205
Andreas Gampe48864112017-01-19 17:23:17 -0800206CommonRuntimeTestImpl::CommonRuntimeTestImpl()
207 : class_linker_(nullptr), java_lang_dex_file_(nullptr) {
208}
Mathieu Chartier91c91162016-01-15 09:48:15 -0800209
210CommonRuntimeTestImpl::~CommonRuntimeTestImpl() {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800211 // Ensure the dex files are cleaned up before the runtime.
212 loaded_dex_files_.clear();
213 runtime_.reset();
214}
Ian Rogerse63db272014-07-15 15:36:11 -0700215
Mathieu Chartier91c91162016-01-15 09:48:15 -0800216void CommonRuntimeTestImpl::SetUpAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700217 if (IsHost()) {
218 // $ANDROID_ROOT is set on the device, but not necessarily on the host.
219 // But it needs to be set so that icu4c can find its locale data.
220 const char* android_root_from_env = getenv("ANDROID_ROOT");
221 if (android_root_from_env == nullptr) {
222 // Use ANDROID_HOST_OUT for ANDROID_ROOT if it is set.
223 const char* android_host_out = getenv("ANDROID_HOST_OUT");
224 if (android_host_out != nullptr) {
225 setenv("ANDROID_ROOT", android_host_out, 1);
226 } else {
227 // Build it from ANDROID_BUILD_TOP or cwd
228 std::string root;
229 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
230 if (android_build_top != nullptr) {
231 root += android_build_top;
232 } else {
233 // Not set by build server, so default to current directory
234 char* cwd = getcwd(nullptr, 0);
235 setenv("ANDROID_BUILD_TOP", cwd, 1);
236 root += cwd;
237 free(cwd);
238 }
239#if defined(__linux__)
240 root += "/out/host/linux-x86";
241#elif defined(__APPLE__)
242 root += "/out/host/darwin-x86";
243#else
244#error unsupported OS
245#endif
246 setenv("ANDROID_ROOT", root.c_str(), 1);
247 }
248 }
249 setenv("LD_LIBRARY_PATH", ":", 0); // Required by java.lang.System.<clinit>.
250
251 // Not set by build server, so default
252 if (getenv("ANDROID_HOST_OUT") == nullptr) {
253 setenv("ANDROID_HOST_OUT", getenv("ANDROID_ROOT"), 1);
254 }
255 }
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700256}
Ian Rogerse63db272014-07-15 15:36:11 -0700257
Mathieu Chartier91c91162016-01-15 09:48:15 -0800258void CommonRuntimeTestImpl::SetUpAndroidData(std::string& android_data) {
Ian Rogerse63db272014-07-15 15:36:11 -0700259 // On target, Cannot use /mnt/sdcard because it is mounted noexec, so use subdir of dalvik-cache
Andreas Gampe5a79fde2014-08-06 13:12:26 -0700260 if (IsHost()) {
261 const char* tmpdir = getenv("TMPDIR");
262 if (tmpdir != nullptr && tmpdir[0] != 0) {
263 android_data = tmpdir;
264 } else {
265 android_data = "/tmp";
266 }
267 } else {
268 android_data = "/data/dalvik-cache";
269 }
270 android_data += "/art-data-XXXXXX";
Ian Rogerse63db272014-07-15 15:36:11 -0700271 if (mkdtemp(&android_data[0]) == nullptr) {
272 PLOG(FATAL) << "mkdtemp(\"" << &android_data[0] << "\") failed";
273 }
274 setenv("ANDROID_DATA", android_data.c_str(), 1);
275}
276
Mathieu Chartier91c91162016-01-15 09:48:15 -0800277void CommonRuntimeTestImpl::TearDownAndroidData(const std::string& android_data,
278 bool fail_on_error) {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700279 if (fail_on_error) {
280 ASSERT_EQ(rmdir(android_data.c_str()), 0);
281 } else {
282 rmdir(android_data.c_str());
283 }
284}
285
David Srbecky3e52aa42015-04-12 07:45:18 +0100286// Helper - find directory with the following format:
287// ${ANDROID_BUILD_TOP}/${subdir1}/${subdir2}-${version}/${subdir3}/bin/
288static std::string GetAndroidToolsDir(const std::string& subdir1,
289 const std::string& subdir2,
290 const std::string& subdir3) {
291 std::string root;
292 const char* android_build_top = getenv("ANDROID_BUILD_TOP");
293 if (android_build_top != nullptr) {
294 root = android_build_top;
295 } else {
296 // Not set by build server, so default to current directory
297 char* cwd = getcwd(nullptr, 0);
298 setenv("ANDROID_BUILD_TOP", cwd, 1);
299 root = cwd;
300 free(cwd);
301 }
302
303 std::string toolsdir = root + "/" + subdir1;
304 std::string founddir;
305 DIR* dir;
306 if ((dir = opendir(toolsdir.c_str())) != nullptr) {
307 float maxversion = 0;
308 struct dirent* entry;
309 while ((entry = readdir(dir)) != nullptr) {
310 std::string format = subdir2 + "-%f";
311 float version;
312 if (std::sscanf(entry->d_name, format.c_str(), &version) == 1) {
313 if (version > maxversion) {
314 maxversion = version;
315 founddir = toolsdir + "/" + entry->d_name + "/" + subdir3 + "/bin/";
316 }
317 }
318 }
319 closedir(dir);
320 }
321
322 if (founddir.empty()) {
Roland Levillain91d65e02016-01-19 15:59:16 +0000323 ADD_FAILURE() << "Cannot find Android tools directory.";
David Srbecky3e52aa42015-04-12 07:45:18 +0100324 }
325 return founddir;
326}
327
Mathieu Chartier91c91162016-01-15 09:48:15 -0800328std::string CommonRuntimeTestImpl::GetAndroidHostToolsDir() {
David Srbecky3e52aa42015-04-12 07:45:18 +0100329 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/host",
330 "x86_64-linux-glibc2.15",
331 "x86_64-linux");
332}
333
Mathieu Chartier91c91162016-01-15 09:48:15 -0800334std::string CommonRuntimeTestImpl::GetAndroidTargetToolsDir(InstructionSet isa) {
David Srbecky3e52aa42015-04-12 07:45:18 +0100335 switch (isa) {
336 case kArm:
337 case kThumb2:
338 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/arm",
339 "arm-linux-androideabi",
340 "arm-linux-androideabi");
341 case kArm64:
342 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/aarch64",
343 "aarch64-linux-android",
344 "aarch64-linux-android");
345 case kX86:
346 case kX86_64:
347 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/x86",
348 "x86_64-linux-android",
349 "x86_64-linux-android");
350 case kMips:
351 case kMips64:
352 return GetAndroidToolsDir("prebuilts/gcc/linux-x86/mips",
353 "mips64el-linux-android",
354 "mips64el-linux-android");
355 case kNone:
356 break;
357 }
358 ADD_FAILURE() << "Invalid isa " << isa;
359 return "";
360}
361
Mathieu Chartier91c91162016-01-15 09:48:15 -0800362std::string CommonRuntimeTestImpl::GetCoreArtLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800363 return GetCoreFileLocation("art");
364}
365
Mathieu Chartier91c91162016-01-15 09:48:15 -0800366std::string CommonRuntimeTestImpl::GetCoreOatLocation() {
Igor Murashkin37743352014-11-13 14:38:00 -0800367 return GetCoreFileLocation("oat");
368}
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700369
Mathieu Chartier91c91162016-01-15 09:48:15 -0800370std::unique_ptr<const DexFile> CommonRuntimeTestImpl::LoadExpectSingleDexFile(
371 const char* location) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800372 std::vector<std::unique_ptr<const DexFile>> dex_files;
Ian Rogerse63db272014-07-15 15:36:11 -0700373 std::string error_msg;
Richard Uhler66d874d2015-01-15 09:37:19 -0800374 MemMap::Init();
Aart Bik37d6a3b2016-06-21 18:30:10 -0700375 static constexpr bool kVerifyChecksum = true;
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700376 if (!DexFileLoader::Open(location, location, kVerifyChecksum, &error_msg, &dex_files)) {
Ian Rogerse63db272014-07-15 15:36:11 -0700377 LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n";
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800378 UNREACHABLE();
Ian Rogerse63db272014-07-15 15:36:11 -0700379 } else {
380 CHECK_EQ(1U, dex_files.size()) << "Expected only one dex file in " << location;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800381 return std::move(dex_files[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700382 }
383}
384
Mathieu Chartier91c91162016-01-15 09:48:15 -0800385void CommonRuntimeTestImpl::SetUp() {
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700386 SetUpAndroidRoot();
387 SetUpAndroidData(android_data_);
Ian Rogerse63db272014-07-15 15:36:11 -0700388 dalvik_cache_.append(android_data_.c_str());
389 dalvik_cache_.append("/dalvik-cache");
390 int mkdir_result = mkdir(dalvik_cache_.c_str(), 0700);
391 ASSERT_EQ(mkdir_result, 0);
392
Ian Rogerse63db272014-07-15 15:36:11 -0700393 std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
394 std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
395
Ian Rogerse63db272014-07-15 15:36:11 -0700396
397 RuntimeOptions options;
Narayan Kamathd1ef4362015-11-12 11:49:06 +0000398 std::string boot_class_path_string = "-Xbootclasspath";
399 for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
400 boot_class_path_string += ":";
401 boot_class_path_string += core_dex_file_name;
402 }
403
Richard Uhlerc2752592015-01-02 13:28:22 -0800404 options.push_back(std::make_pair(boot_class_path_string, nullptr));
Ian Rogerse63db272014-07-15 15:36:11 -0700405 options.push_back(std::make_pair("-Xcheck:jni", nullptr));
Richard Uhlerc2752592015-01-02 13:28:22 -0800406 options.push_back(std::make_pair(min_heap_string, nullptr));
407 options.push_back(std::make_pair(max_heap_string, nullptr));
Andreas Gampe1c5b42f2017-06-15 18:20:45 -0700408 options.push_back(std::make_pair("-XX:SlowDebug=true", nullptr));
Andreas Gampe46c4c852017-06-21 19:49:08 -0700409 static bool gSlowDebugTestFlag = false;
410 RegisterRuntimeDebugFlag(&gSlowDebugTestFlag);
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700411
412 callbacks_.reset(new NoopCompilerCallbacks());
413
Ian Rogerse63db272014-07-15 15:36:11 -0700414 SetUpRuntimeOptions(&options);
Igor Murashkinaaebaa02015-01-26 10:55:53 -0800415
Andreas Gampebb9c6b12015-03-29 13:56:36 -0700416 // Install compiler-callbacks if SetupRuntimeOptions hasn't deleted them.
417 if (callbacks_.get() != nullptr) {
418 options.push_back(std::make_pair("compilercallbacks", callbacks_.get()));
419 }
420
Richard Uhler66d874d2015-01-15 09:37:19 -0800421 PreRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700422 if (!Runtime::Create(options, false)) {
423 LOG(FATAL) << "Failed to create runtime";
424 return;
425 }
Richard Uhler66d874d2015-01-15 09:37:19 -0800426 PostRuntimeCreate();
Ian Rogerse63db272014-07-15 15:36:11 -0700427 runtime_.reset(Runtime::Current());
428 class_linker_ = runtime_->GetClassLinker();
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700429
Andreas Gampea00f0122015-12-16 16:54:35 -0800430 // Runtime::Create acquired the mutator_lock_ that is normally given away when we
431 // Runtime::Start, give it away now and then switch to a more managable ScopedObjectAccess.
432 Thread::Current()->TransitionFromRunnableToSuspended(kNative);
433
434 // Get the boot class path from the runtime so it can be used in tests.
435 boot_class_path_ = class_linker_->GetBootClassPath();
436 ASSERT_FALSE(boot_class_path_.empty());
437 java_lang_dex_file_ = boot_class_path_[0];
438
439 FinalizeSetup();
Andreas Gampe46c4c852017-06-21 19:49:08 -0700440
441 // Ensure that we're really running with debug checks enabled.
442 CHECK(gSlowDebugTestFlag);
Andreas Gampea00f0122015-12-16 16:54:35 -0800443}
444
Mathieu Chartier91c91162016-01-15 09:48:15 -0800445void CommonRuntimeTestImpl::FinalizeSetup() {
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700446 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this
447 // set up.
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700448 if (!unstarted_initialized_) {
Andreas Gampe799681b2015-05-15 19:24:12 -0700449 interpreter::UnstartedRuntime::Initialize();
Andreas Gampe9b5cba42015-03-11 09:53:50 -0700450 unstarted_initialized_ = true;
451 }
Andreas Gampe2969bcd2015-03-09 12:57:41 -0700452
Andreas Gampea00f0122015-12-16 16:54:35 -0800453 {
454 ScopedObjectAccess soa(Thread::Current());
455 class_linker_->RunRootClinits();
456 }
Ian Rogerse63db272014-07-15 15:36:11 -0700457
458 // We're back in native, take the opportunity to initialize well known classes.
459 WellKnownClasses::Init(Thread::Current()->GetJniEnv());
460
461 // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
462 // pool is created by the runtime.
463 runtime_->GetHeap()->CreateThreadPool();
464 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption before the test
Hiroshi Yamauchi4460a842015-03-09 11:57:48 -0700465 // Reduce timinig-dependent flakiness in OOME behavior (eg StubTest.AllocObject).
466 runtime_->GetHeap()->SetMinIntervalHomogeneousSpaceCompactionByOom(0U);
Ian Rogerse63db272014-07-15 15:36:11 -0700467}
468
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700469void CommonRuntimeTestImpl::ClearDirectory(const char* dirpath, bool recursive) {
Alex Lighta59dd802014-07-02 16:28:08 -0700470 ASSERT_TRUE(dirpath != nullptr);
471 DIR* dir = opendir(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700472 ASSERT_TRUE(dir != nullptr);
473 dirent* e;
Alex Lighta59dd802014-07-02 16:28:08 -0700474 struct stat s;
Ian Rogerse63db272014-07-15 15:36:11 -0700475 while ((e = readdir(dir)) != nullptr) {
476 if ((strcmp(e->d_name, ".") == 0) || (strcmp(e->d_name, "..") == 0)) {
477 continue;
478 }
Jeff Haof0a3f092014-07-24 16:26:09 -0700479 std::string filename(dirpath);
Ian Rogerse63db272014-07-15 15:36:11 -0700480 filename.push_back('/');
481 filename.append(e->d_name);
Alex Lighta59dd802014-07-02 16:28:08 -0700482 int stat_result = lstat(filename.c_str(), &s);
483 ASSERT_EQ(0, stat_result) << "unable to stat " << filename;
484 if (S_ISDIR(s.st_mode)) {
Mathieu Chartierf70fe3d2017-06-21 15:24:02 -0700485 if (recursive) {
486 ClearDirectory(filename.c_str());
487 int rmdir_result = rmdir(filename.c_str());
488 ASSERT_EQ(0, rmdir_result) << filename;
489 }
Alex Lighta59dd802014-07-02 16:28:08 -0700490 } else {
491 int unlink_result = unlink(filename.c_str());
492 ASSERT_EQ(0, unlink_result) << filename;
493 }
Ian Rogerse63db272014-07-15 15:36:11 -0700494 }
495 closedir(dir);
Alex Lighta59dd802014-07-02 16:28:08 -0700496}
497
Mathieu Chartier91c91162016-01-15 09:48:15 -0800498void CommonRuntimeTestImpl::TearDown() {
Alex Lighta59dd802014-07-02 16:28:08 -0700499 const char* android_data = getenv("ANDROID_DATA");
500 ASSERT_TRUE(android_data != nullptr);
501 ClearDirectory(dalvik_cache_.c_str());
Ian Rogerse63db272014-07-15 15:36:11 -0700502 int rmdir_cache_result = rmdir(dalvik_cache_.c_str());
503 ASSERT_EQ(0, rmdir_cache_result);
Andreas Gampe7747c8d2014-08-06 14:53:03 -0700504 TearDownAndroidData(android_data_, true);
Andreas Gampe3f41a012016-02-18 16:53:41 -0800505 dalvik_cache_.clear();
Ian Rogerse63db272014-07-15 15:36:11 -0700506
Andreas Gampe48864112017-01-19 17:23:17 -0800507 if (runtime_ != nullptr) {
508 runtime_->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
509 }
Ian Rogerse63db272014-07-15 15:36:11 -0700510}
511
Andreas Gampec7d4a582015-09-30 11:52:02 -0700512static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
513 std::string path;
514 if (host) {
Ian Rogerse63db272014-07-15 15:36:11 -0700515 const char* host_dir = getenv("ANDROID_HOST_OUT");
516 CHECK(host_dir != nullptr);
Andreas Gampec7d4a582015-09-30 11:52:02 -0700517 path = host_dir;
518 } else {
519 path = GetAndroidRoot();
Ian Rogerse63db272014-07-15 15:36:11 -0700520 }
Andreas Gampec7d4a582015-09-30 11:52:02 -0700521
522 std::string suffix = host
523 ? "-hostdex" // The host version.
524 : "-testdex"; // The unstripped target version.
525
526 return StringPrintf("%s/framework/%s%s.jar", path.c_str(), jar_prefix.c_str(), suffix.c_str());
527}
528
Mathieu Chartier91c91162016-01-15 09:48:15 -0800529std::vector<std::string> CommonRuntimeTestImpl::GetLibCoreDexFileNames() {
Andreas Gampec7d4a582015-09-30 11:52:02 -0700530 return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
531 GetDexFileName("core-libart", IsHost())});
Ian Rogerse63db272014-07-15 15:36:11 -0700532}
533
Mathieu Chartier91c91162016-01-15 09:48:15 -0800534std::string CommonRuntimeTestImpl::GetTestAndroidRoot() {
Ian Rogerse63db272014-07-15 15:36:11 -0700535 if (IsHost()) {
536 const char* host_dir = getenv("ANDROID_HOST_OUT");
537 CHECK(host_dir != nullptr);
538 return host_dir;
539 }
540 return GetAndroidRoot();
541}
542
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700543// Check that for target builds we have ART_TARGET_NATIVETEST_DIR set.
544#ifdef ART_TARGET
545#ifndef ART_TARGET_NATIVETEST_DIR
546#error "ART_TARGET_NATIVETEST_DIR not set."
547#endif
548// Wrap it as a string literal.
549#define ART_TARGET_NATIVETEST_DIR_STRING STRINGIFY(ART_TARGET_NATIVETEST_DIR) "/"
550#else
551#define ART_TARGET_NATIVETEST_DIR_STRING ""
552#endif
553
Andreas Gampee1459ae2016-06-29 09:36:30 -0700554std::string CommonRuntimeTestImpl::GetTestDexFileName(const char* name) const {
Ian Rogerse63db272014-07-15 15:36:11 -0700555 CHECK(name != nullptr);
556 std::string filename;
557 if (IsHost()) {
558 filename += getenv("ANDROID_HOST_OUT");
559 filename += "/framework/";
560 } else {
Andreas Gampe1fe5e5c2014-07-11 21:14:35 -0700561 filename += ART_TARGET_NATIVETEST_DIR_STRING;
Ian Rogerse63db272014-07-15 15:36:11 -0700562 }
563 filename += "art-gtest-";
564 filename += name;
565 filename += ".jar";
Richard Uhler66d874d2015-01-15 09:37:19 -0800566 return filename;
567}
568
Mathieu Chartier91c91162016-01-15 09:48:15 -0800569std::vector<std::unique_ptr<const DexFile>> CommonRuntimeTestImpl::OpenTestDexFiles(
570 const char* name) {
Richard Uhler66d874d2015-01-15 09:37:19 -0800571 std::string filename = GetTestDexFileName(name);
Aart Bik37d6a3b2016-06-21 18:30:10 -0700572 static constexpr bool kVerifyChecksum = true;
Ian Rogerse63db272014-07-15 15:36:11 -0700573 std::string error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800574 std::vector<std::unique_ptr<const DexFile>> dex_files;
Mathieu Chartier79c87da2017-10-10 11:54:29 -0700575 bool success = DexFileLoader::Open(
Aart Bik37d6a3b2016-06-21 18:30:10 -0700576 filename.c_str(), filename.c_str(), kVerifyChecksum, &error_msg, &dex_files);
Ian Rogerse63db272014-07-15 15:36:11 -0700577 CHECK(success) << "Failed to open '" << filename << "': " << error_msg;
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800578 for (auto& dex_file : dex_files) {
Ian Rogerse63db272014-07-15 15:36:11 -0700579 CHECK_EQ(PROT_READ, dex_file->GetPermissions());
580 CHECK(dex_file->IsReadOnly());
581 }
Ian Rogerse63db272014-07-15 15:36:11 -0700582 return dex_files;
583}
584
Mathieu Chartier91c91162016-01-15 09:48:15 -0800585std::unique_ptr<const DexFile> CommonRuntimeTestImpl::OpenTestDexFile(const char* name) {
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800586 std::vector<std::unique_ptr<const DexFile>> vector = OpenTestDexFiles(name);
Ian Rogerse63db272014-07-15 15:36:11 -0700587 EXPECT_EQ(1U, vector.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800588 return std::move(vector[0]);
Ian Rogerse63db272014-07-15 15:36:11 -0700589}
590
Mathieu Chartier91c91162016-01-15 09:48:15 -0800591std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700592 ScopedObjectAccess soa(Thread::Current());
593
Calin Juravlec79470d2017-07-12 17:37:42 -0700594 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700595 Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
Mathieu Chartier0795f232016-09-27 18:43:30 -0700596 soa.Decode<mirror::ClassLoader>(jclass_loader));
Calin Juravlec79470d2017-07-12 17:37:42 -0700597 return GetDexFiles(soa, class_loader);
598}
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700599
Calin Juravlec79470d2017-07-12 17:37:42 -0700600std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(
601 ScopedObjectAccess& soa,
602 Handle<mirror::ClassLoader> class_loader) {
603 std::vector<const DexFile*> ret;
604
605 DCHECK(
606 (class_loader->GetClass() ==
607 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)) ||
608 (class_loader->GetClass() ==
609 soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_DelegateLastClassLoader)));
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700610
611 // The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
612 // We need to get the DexPathList and loop through it.
Andreas Gampe08883de2016-11-08 13:20:52 -0800613 ArtField* cookie_field = jni::DecodeArtField(WellKnownClasses::dalvik_system_DexFile_cookie);
Mathieu Chartierc7853442015-03-27 14:35:38 -0700614 ArtField* dex_file_field =
Andreas Gampe08883de2016-11-08 13:20:52 -0800615 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
Mathieu Chartier3398c782016-09-30 10:27:43 -0700616 ObjPtr<mirror::Object> dex_path_list =
Andreas Gampe08883de2016-11-08 13:20:52 -0800617 jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList)->
618 GetObject(class_loader.Get());
Mathieu Chartierc7853442015-03-27 14:35:38 -0700619 if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700620 // DexPathList has an array dexElements of Elements[] which each contain a dex file.
Mathieu Chartier3398c782016-09-30 10:27:43 -0700621 ObjPtr<mirror::Object> dex_elements_obj =
Andreas Gampe08883de2016-11-08 13:20:52 -0800622 jni::DecodeArtField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
623 GetObject(dex_path_list);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700624 // Loop through each dalvik.system.DexPathList$Element's dalvik.system.DexFile and look
625 // at the mCookie which is a DexFile vector.
626 if (dex_elements_obj != nullptr) {
Calin Juravlec79470d2017-07-12 17:37:42 -0700627 StackHandleScope<1> hs(soa.Self());
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700628 Handle<mirror::ObjectArray<mirror::Object>> dex_elements =
629 hs.NewHandle(dex_elements_obj->AsObjectArray<mirror::Object>());
630 for (int32_t i = 0; i < dex_elements->GetLength(); ++i) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700631 ObjPtr<mirror::Object> element = dex_elements->GetWithoutChecks(i);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700632 if (element == nullptr) {
633 // Should never happen, fall back to java code to throw a NPE.
634 break;
635 }
Mathieu Chartier3398c782016-09-30 10:27:43 -0700636 ObjPtr<mirror::Object> dex_file = dex_file_field->GetObject(element);
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700637 if (dex_file != nullptr) {
Mathieu Chartier3398c782016-09-30 10:27:43 -0700638 ObjPtr<mirror::LongArray> long_array = cookie_field->GetObject(dex_file)->AsLongArray();
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700639 DCHECK(long_array != nullptr);
640 int32_t long_array_size = long_array->GetLength();
Mathieu Chartiere58991b2015-10-13 07:59:34 -0700641 for (int32_t j = kDexFileIndexStart; j < long_array_size; ++j) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700642 const DexFile* cp_dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(
643 long_array->GetWithoutChecks(j)));
644 if (cp_dex_file == nullptr) {
645 LOG(WARNING) << "Null DexFile";
646 continue;
647 }
648 ret.push_back(cp_dex_file);
649 }
650 }
651 }
652 }
653 }
654
655 return ret;
656}
657
Mathieu Chartier91c91162016-01-15 09:48:15 -0800658const DexFile* CommonRuntimeTestImpl::GetFirstDexFile(jobject jclass_loader) {
Andreas Gampe81c6f8d2015-03-25 17:19:53 -0700659 std::vector<const DexFile*> tmp(GetDexFiles(jclass_loader));
660 DCHECK(!tmp.empty());
661 const DexFile* ret = tmp[0];
662 DCHECK(ret != nullptr);
663 return ret;
664}
665
Nicolas Geoffrayd01f60c2016-10-28 14:45:48 +0100666jobject CommonRuntimeTestImpl::LoadMultiDex(const char* first_dex_name,
667 const char* second_dex_name) {
668 std::vector<std::unique_ptr<const DexFile>> first_dex_files = OpenTestDexFiles(first_dex_name);
669 std::vector<std::unique_ptr<const DexFile>> second_dex_files = OpenTestDexFiles(second_dex_name);
670 std::vector<const DexFile*> class_path;
671 CHECK_NE(0U, first_dex_files.size());
672 CHECK_NE(0U, second_dex_files.size());
673 for (auto& dex_file : first_dex_files) {
674 class_path.push_back(dex_file.get());
675 loaded_dex_files_.push_back(std::move(dex_file));
676 }
677 for (auto& dex_file : second_dex_files) {
678 class_path.push_back(dex_file.get());
679 loaded_dex_files_.push_back(std::move(dex_file));
680 }
681
682 Thread* self = Thread::Current();
683 jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self,
684 class_path);
685 self->SetClassLoaderOverride(class_loader);
686 return class_loader;
687}
688
Mathieu Chartier91c91162016-01-15 09:48:15 -0800689jobject CommonRuntimeTestImpl::LoadDex(const char* dex_name) {
Calin Juravle7865ac72017-06-28 11:03:12 -0700690 jobject class_loader = LoadDexInPathClassLoader(dex_name, nullptr);
691 Thread::Current()->SetClassLoaderOverride(class_loader);
692 return class_loader;
693}
694
695jobject CommonRuntimeTestImpl::LoadDexInWellKnownClassLoader(const std::string& dex_name,
696 jclass loader_class,
697 jobject parent_loader) {
698 std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles(dex_name.c_str());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800699 std::vector<const DexFile*> class_path;
Ian Rogerse63db272014-07-15 15:36:11 -0700700 CHECK_NE(0U, dex_files.size());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800701 for (auto& dex_file : dex_files) {
702 class_path.push_back(dex_file.get());
Richard Uhlerfbef44d2014-12-23 09:48:51 -0800703 loaded_dex_files_.push_back(std::move(dex_file));
Ian Rogerse63db272014-07-15 15:36:11 -0700704 }
Ian Rogers68d8b422014-07-17 11:09:10 -0700705 Thread* self = Thread::Current();
Calin Juravle7865ac72017-06-28 11:03:12 -0700706 ScopedObjectAccess soa(self);
707
708 jobject result = Runtime::Current()->GetClassLinker()->CreateWellKnownClassLoader(
709 self,
710 class_path,
711 loader_class,
712 parent_loader);
713
714 {
715 // Verify we build the correct chain.
716
717 ObjPtr<mirror::ClassLoader> actual_class_loader = soa.Decode<mirror::ClassLoader>(result);
718 // Verify that the result has the correct class.
719 CHECK_EQ(soa.Decode<mirror::Class>(loader_class), actual_class_loader->GetClass());
720 // Verify that the parent is not null. The boot class loader will be set up as a
721 // proper object.
722 ObjPtr<mirror::ClassLoader> actual_parent(actual_class_loader->GetParent());
723 CHECK(actual_parent != nullptr);
724
725 if (parent_loader != nullptr) {
726 // We were given a parent. Verify that it's what we expect.
727 ObjPtr<mirror::ClassLoader> expected_parent = soa.Decode<mirror::ClassLoader>(parent_loader);
728 CHECK_EQ(expected_parent, actual_parent);
729 } else {
730 // No parent given. The parent must be the BootClassLoader.
731 CHECK(Runtime::Current()->GetClassLinker()->IsBootClassLoader(soa, actual_parent));
732 }
733 }
734
735 return result;
736}
737
738jobject CommonRuntimeTestImpl::LoadDexInPathClassLoader(const std::string& dex_name,
739 jobject parent_loader) {
740 return LoadDexInWellKnownClassLoader(dex_name,
741 WellKnownClasses::dalvik_system_PathClassLoader,
742 parent_loader);
743}
744
745jobject CommonRuntimeTestImpl::LoadDexInDelegateLastClassLoader(const std::string& dex_name,
746 jobject parent_loader) {
747 return LoadDexInWellKnownClassLoader(dex_name,
748 WellKnownClasses::dalvik_system_DelegateLastClassLoader,
749 parent_loader);
Ian Rogerse63db272014-07-15 15:36:11 -0700750}
751
Mathieu Chartier91c91162016-01-15 09:48:15 -0800752std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
Igor Murashkin37743352014-11-13 14:38:00 -0800753 CHECK(suffix != nullptr);
754
755 std::string location;
756 if (IsHost()) {
757 const char* host_dir = getenv("ANDROID_HOST_OUT");
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700758 CHECK(host_dir != nullptr);
Richard Uhler67e1dc52017-02-06 16:50:17 +0000759 location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800760 } else {
Richard Uhler67e1dc52017-02-06 16:50:17 +0000761 location = StringPrintf("/data/art-test/core.%s", suffix);
Igor Murashkin37743352014-11-13 14:38:00 -0800762 }
763
764 return location;
765}
766
Calin Juravlec79470d2017-07-12 17:37:42 -0700767std::string CommonRuntimeTestImpl::CreateClassPath(
768 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
769 CHECK(!dex_files.empty());
770 std::string classpath = dex_files[0]->GetLocation();
771 for (size_t i = 1; i < dex_files.size(); i++) {
772 classpath += ":" + dex_files[i]->GetLocation();
773 }
774 return classpath;
775}
776
777std::string CommonRuntimeTestImpl::CreateClassPathWithChecksums(
778 const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
779 CHECK(!dex_files.empty());
780 std::string classpath = dex_files[0]->GetLocation() + "*" +
781 std::to_string(dex_files[0]->GetLocationChecksum());
782 for (size_t i = 1; i < dex_files.size(); i++) {
783 classpath += ":" + dex_files[i]->GetLocation() + "*" +
784 std::to_string(dex_files[i]->GetLocationChecksum());
785 }
786 return classpath;
787}
788
Andreas Gampe26761f72017-07-20 18:00:39 -0700789void CommonRuntimeTestImpl::FillHeap(Thread* self,
790 ClassLinker* class_linker,
791 VariableSizedHandleScope* handle_scope) {
792 DCHECK(handle_scope != nullptr);
793
794 Runtime::Current()->GetHeap()->SetIdealFootprint(1 * GB);
795
796 // Class java.lang.Object.
797 Handle<mirror::Class> c(handle_scope->NewHandle(
798 class_linker->FindSystemClass(self, "Ljava/lang/Object;")));
799 // Array helps to fill memory faster.
800 Handle<mirror::Class> ca(handle_scope->NewHandle(
801 class_linker->FindSystemClass(self, "[Ljava/lang/Object;")));
802
803 // Start allocating with ~128K
804 size_t length = 128 * KB;
805 while (length > 40) {
806 const int32_t array_length = length / 4; // Object[] has elements of size 4.
807 MutableHandle<mirror::Object> h(handle_scope->NewHandle<mirror::Object>(
808 mirror::ObjectArray<mirror::Object>::Alloc(self, ca.Get(), array_length)));
809 if (self->IsExceptionPending() || h == nullptr) {
810 self->ClearException();
811
812 // Try a smaller length
813 length = length / 2;
814 // Use at most a quarter the reported free space.
815 size_t mem = Runtime::Current()->GetHeap()->GetFreeMemory();
816 if (length * 4 > mem) {
817 length = mem / 4;
818 }
819 }
820 }
821
822 // Allocate simple objects till it fails.
823 while (!self->IsExceptionPending()) {
824 handle_scope->NewHandle<mirror::Object>(c->AllocObject(self));
825 }
826 self->ClearException();
827}
828
829void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *options) {
830 // Use a smaller heap
831 bool found = false;
832 for (std::pair<std::string, const void*>& pair : *options) {
833 if (pair.first.find("-Xmx") == 0) {
834 pair.first = "-Xmx4M"; // Smallest we can go.
835 found = true;
836 }
837 }
838 if (!found) {
839 options->emplace_back("-Xmx4M", nullptr);
840 }
841}
842
Ian Rogerse63db272014-07-15 15:36:11 -0700843CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
Ian Rogers68d8b422014-07-17 11:09:10 -0700844 vm_->SetCheckJniAbortHook(Hook, &actual_);
Ian Rogerse63db272014-07-15 15:36:11 -0700845}
846
847CheckJniAbortCatcher::~CheckJniAbortCatcher() {
Ian Rogers68d8b422014-07-17 11:09:10 -0700848 vm_->SetCheckJniAbortHook(nullptr, nullptr);
Ian Rogerse63db272014-07-15 15:36:11 -0700849 EXPECT_TRUE(actual_.empty()) << actual_;
850}
851
Igor Murashkin367f3dd2016-09-01 17:00:24 -0700852void CheckJniAbortCatcher::Check(const std::string& expected_text) {
853 Check(expected_text.c_str());
854}
855
Ian Rogerse63db272014-07-15 15:36:11 -0700856void CheckJniAbortCatcher::Check(const char* expected_text) {
857 EXPECT_TRUE(actual_.find(expected_text) != std::string::npos) << "\n"
858 << "Expected to find: " << expected_text << "\n"
859 << "In the output : " << actual_;
860 actual_.clear();
861}
862
863void CheckJniAbortCatcher::Hook(void* data, const std::string& reason) {
864 // We use += because when we're hooking the aborts like this, multiple problems can be found.
865 *reinterpret_cast<std::string*>(data) += reason;
866}
867
868} // namespace art