Merge "Revert "Revert^2 "JVMTI PopFrame support"""
diff --git a/.vpython b/.vpython
new file mode 100644
index 0000000..ed00723
--- /dev/null
+++ b/.vpython
@@ -0,0 +1,25 @@
+# This is a vpython "spec" file.
+#
+# It describes patterns for python wheel dependencies of the python scripts in
+# the chromium repo, particularly for dependencies that have compiled components
+# (since pure-python dependencies can be easily vendored into third_party).
+#
+# When vpython is invoked, it finds this file and builds a python VirtualEnv,
+# containing all of the dependencies described in this file, fetching them from
+# CIPD (the "Chrome Infrastructure Package Deployer" service). Unlike `pip`,
+# this never requires the end-user machine to have a working python extension
+# compilation environment. All of these packages are built using:
+# https://chromium.googlesource.com/infra/infra/+/master/infra/tools/dockerbuild/
+#
+# All python scripts in the repo share this same spec, to avoid dependency
+# fragmentation.
+#
+# If you have depot_tools installed in your $PATH, you can invoke python scripts
+# in this repo by running them as you normally would run them, except
+# substituting `vpython` instead of `python` on the command line, e.g.:
+# vpython path/to/script.py some --arguments
+#
+# Read more about `vpython` and how to modify this file here:
+# https://chromium.googlesource.com/infra/infra/+/master/doc/users/vpython.md
+
+python_version: "2.7"
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index b97feff..c6fdf27 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -233,10 +233,10 @@
ART_GTEST_dexoptanalyzer_test_HOST_DEPS := \
$(ART_GTEST_dex2oat_environment_tests_HOST_DEPS) \
- dexoptanalyzerd-host
+ $(HOST_OUT_EXECUTABLES)/dexoptanalyzerd
ART_GTEST_dexoptanalyzer_test_TARGET_DEPS := \
$(ART_GTEST_dex2oat_environment_tests_TARGET_DEPS) \
- dexoptanalyzerd-target
+ $(TARGET_OUT_EXECUTABLES)/dexoptanalyzerd
ART_GTEST_image_space_test_HOST_DEPS := \
$(ART_GTEST_dex2oat_environment_tests_HOST_DEPS)
@@ -245,68 +245,68 @@
ART_GTEST_dex2oat_test_HOST_DEPS := \
$(ART_GTEST_dex2oat_environment_tests_HOST_DEPS) \
- dex2oatd-host
+ $(HOST_OUT_EXECUTABLES)/dex2oatd
ART_GTEST_dex2oat_test_TARGET_DEPS := \
$(ART_GTEST_dex2oat_environment_tests_TARGET_DEPS) \
- dex2oatd-target
+ $(TARGET_OUT_EXECUTABLES)/dex2oatd
ART_GTEST_dex2oat_image_test_HOST_DEPS := \
$(ART_GTEST_dex2oat_environment_tests_HOST_DEPS) \
- dex2oatd-host
+ $(HOST_OUT_EXECUTABLES)/dex2oatd
ART_GTEST_dex2oat_image_test_TARGET_DEPS := \
$(ART_GTEST_dex2oat_environment_tests_TARGET_DEPS) \
- dex2oatd-target
+ $(TARGET_OUT_EXECUTABLES)/dex2oatd
# TODO: document why this is needed.
ART_GTEST_proxy_test_HOST_DEPS := $(HOST_CORE_IMAGE_DEFAULT_64) $(HOST_CORE_IMAGE_DEFAULT_32)
# The dexdiag test requires the dexdiag utility.
-ART_GTEST_dexdiag_test_HOST_DEPS := dexdiag-host
-ART_GTEST_dexdiag_test_TARGET_DEPS := dexdiag-target
+ART_GTEST_dexdiag_test_HOST_DEPS := $(HOST_OUT_EXECUTABLES)/dexdiag
+ART_GTEST_dexdiag_test_TARGET_DEPS := $(TARGET_OUT_EXECUTABLES)/dexdiag
# The dexdump test requires an image and the dexdump utility.
# TODO: rename into dexdump when migration completes
ART_GTEST_dexdump_test_HOST_DEPS := \
$(HOST_CORE_IMAGE_DEFAULT_64) \
$(HOST_CORE_IMAGE_DEFAULT_32) \
- dexdump2-host
+ $(HOST_OUT_EXECUTABLES)/dexdump2
ART_GTEST_dexdump_test_TARGET_DEPS := \
$(TARGET_CORE_IMAGE_DEFAULT_64) \
$(TARGET_CORE_IMAGE_DEFAULT_32) \
- dexdump2-target
+ $(TARGET_OUT_EXECUTABLES)/dexdump2
# The dexanalyze test requires an image and the dexanalyze utility.
ART_GTEST_dexanalyze_test_HOST_DEPS := \
$(HOST_CORE_IMAGE_DEFAULT_64) \
$(HOST_CORE_IMAGE_DEFAULT_32) \
- dexanalyze-host
+ $(HOST_OUT_EXECUTABLES)/dexanalyze
ART_GTEST_dexanalyze_test_TARGET_DEPS := \
$(TARGET_CORE_IMAGE_DEFAULT_64) \
$(TARGET_CORE_IMAGE_DEFAULT_32) \
- dexanalyze-target
+ $(TARGET_OUT_EXECUTABLES)/dexanalyze
# The dexlayout test requires an image and the dexlayout utility.
# TODO: rename into dexdump when migration completes
ART_GTEST_dexlayout_test_HOST_DEPS := \
$(HOST_CORE_IMAGE_DEFAULT_64) \
$(HOST_CORE_IMAGE_DEFAULT_32) \
- dexlayoutd-host \
- dexdump2-host
+ $(HOST_OUT_EXECUTABLES)/dexlayoutd \
+ $(HOST_OUT_EXECUTABLES)/dexdump2
ART_GTEST_dexlayout_test_TARGET_DEPS := \
$(TARGET_CORE_IMAGE_DEFAULT_64) \
$(TARGET_CORE_IMAGE_DEFAULT_32) \
- dexlayoutd-target \
- dexdump2-target
+ $(TARGET_OUT_EXECUTABLES)/dexlayoutd \
+ $(TARGET_OUT_EXECUTABLES)/dexdump2
# The dexlist test requires an image and the dexlist utility.
ART_GTEST_dexlist_test_HOST_DEPS := \
$(HOST_CORE_IMAGE_DEFAULT_64) \
$(HOST_CORE_IMAGE_DEFAULT_32) \
- dexlist-host
+ $(HOST_OUT_EXECUTABLES)/dexlist
ART_GTEST_dexlist_test_TARGET_DEPS := \
$(TARGET_CORE_IMAGE_DEFAULT_64) \
$(TARGET_CORE_IMAGE_DEFAULT_32) \
- dexlist-target
+ $(TARGET_OUT_EXECUTABLES)/dexlist
# The imgdiag test has dependencies on core.oat since it needs to load it during the test.
# For the host, also add the installed tool (in the base size, that should suffice). For the
@@ -314,46 +314,46 @@
ART_GTEST_imgdiag_test_HOST_DEPS := \
$(HOST_CORE_IMAGE_DEFAULT_64) \
$(HOST_CORE_IMAGE_DEFAULT_32) \
- imgdiagd-host
+ $(HOST_OUT_EXECUTABLES)/imgdiagd
ART_GTEST_imgdiag_test_TARGET_DEPS := \
$(TARGET_CORE_IMAGE_DEFAULT_64) \
$(TARGET_CORE_IMAGE_DEFAULT_32) \
- imgdiagd-target
+ $(TARGET_OUT_EXECUTABLES)/imgdiagd
# Dex analyze test requires dexanalyze.
ART_GTEST_dexanalyze_test_HOST_DEPS := \
- dexanalyze-host
+ $(HOST_OUT_EXECUTABLES)/dexanalyze
ART_GTEST_dexanalyze_test_TARGET_DEPS := \
- dexanalyze-target
+ $(TARGET_OUT_EXECUTABLES)/dexanalyze
# Oatdump test requires an image and oatfile to dump.
ART_GTEST_oatdump_test_HOST_DEPS := \
$(HOST_CORE_IMAGE_DEFAULT_64) \
$(HOST_CORE_IMAGE_DEFAULT_32) \
- oatdumpd-host \
- oatdumpds-host \
- dexdump2-host
+ $(HOST_OUT_EXECUTABLES)/oatdumpd \
+ $(HOST_OUT_EXECUTABLES)/oatdumpds \
+ $(HOST_OUT_EXECUTABLES)/dexdump2
ART_GTEST_oatdump_test_TARGET_DEPS := \
$(TARGET_CORE_IMAGE_DEFAULT_64) \
$(TARGET_CORE_IMAGE_DEFAULT_32) \
- oatdumpd-target \
- dexdump2-target
+ $(TARGET_OUT_EXECUTABLES)/oatdumpd \
+ $(TARGET_OUT_EXECUTABLES)/dexdump2
ART_GTEST_oatdump_image_test_HOST_DEPS := $(ART_GTEST_oatdump_test_HOST_DEPS)
ART_GTEST_oatdump_image_test_TARGET_DEPS := $(ART_GTEST_oatdump_test_TARGET_DEPS)
ART_GTEST_oatdump_app_test_HOST_DEPS := $(ART_GTEST_oatdump_test_HOST_DEPS) \
- dex2oatd-host \
- dex2oatds-host
+ $(HOST_OUT_EXECUTABLES)/dex2oatd \
+ $(HOST_OUT_EXECUTABLES)/dex2oatds
ART_GTEST_oatdump_app_test_TARGET_DEPS := $(ART_GTEST_oatdump_test_TARGET_DEPS) \
- dex2oatd-target
+ $(TARGET_OUT_EXECUTABLES)/dex2oatd
# Profile assistant tests requires profman utility.
-ART_GTEST_profile_assistant_test_HOST_DEPS := profmand-host
-ART_GTEST_profile_assistant_test_TARGET_DEPS := profmand-target
+ART_GTEST_profile_assistant_test_HOST_DEPS := $(HOST_OUT_EXECUTABLES)/profmand
+ART_GTEST_profile_assistant_test_TARGET_DEPS := $(TARGET_OUT_EXECUTABLES)/profmand
ART_GTEST_hiddenapi_test_HOST_DEPS := \
$(HOST_CORE_IMAGE_DEFAULT_64) \
$(HOST_CORE_IMAGE_DEFAULT_32) \
- hiddenapid-host
+ $(HOST_OUT_EXECUTABLES)/hiddenapid
# The path for which all the source files are relative, not actually the current directory.
LOCAL_PATH := art
@@ -482,7 +482,10 @@
# $(2): path relative to $OUT to the test binary
# $(3): 2ND_ or undefined - used to differentiate between the primary and secondary architecture.
define define-art-gtest-rule-host
- gtest_rule := test-art-host-gtest-$(1)$$($(3)ART_PHONY_TEST_HOST_SUFFIX)
+ gtest_suffix := $(1)$$($(3)ART_PHONY_TEST_HOST_SUFFIX)
+ gtest_rule := test-art-host-gtest-$$(gtest_suffix)
+ gtest_output := $(call intermediates-dir-for,PACKAGING,art-host-gtest,HOST)/$$(gtest_suffix).xml
+ $$(call dist-for-goals,$$(gtest_rule),$$(gtest_output):gtest/$$(gtest_suffix))
gtest_exe := $(OUT_DIR)/$(2)
# Dependencies for all host gtests.
gtest_deps := $$(HOST_CORE_DEX_LOCATIONS) \
@@ -491,20 +494,20 @@
$$(gtest_exe) \
$$(ART_GTEST_$(1)_HOST_DEPS) \
$(foreach file,$(ART_GTEST_$(1)_DEX_DEPS),$(ART_TEST_HOST_GTEST_$(file)_DEX))
- ifneq (,$(DIST_DIR))
- gtest_xml_output := --gtest_output=xml:$(DIST_DIR)/gtest/$(1)$$($(3)ART_PHONY_TEST_HOST_SUFFIX).xml
- else
- gtest_xml_output :=
- endif
ART_TEST_HOST_GTEST_DEPENDENCIES += $$(gtest_deps)
.PHONY: $$(gtest_rule)
+$$(gtest_rule): $$(gtest_output)
+
+# Re-run the tests, even if nothing changed. Until the build system has a dedicated "no cache"
+# option, claim to write a file that is never produced.
+$$(gtest_output): .KATI_IMPLICIT_OUTPUTS := $$(gtest_output)-nocache
+$$(gtest_output): NAME := $$(gtest_rule)
ifeq (,$(SANITIZE_HOST))
-$$(gtest_rule): PRIVATE_XML_OUTPUT := $$(gtest_xml_output)
-$$(gtest_rule): $$(gtest_exe) $$(gtest_deps)
- $(hide) ($$(call ART_TEST_SKIP,$$@) && $$< $$(PRIVATE_XML_OUTPUT) && \
- $$(call ART_TEST_PASSED,$$@)) || $$(call ART_TEST_FAILED,$$@)
+$$(gtest_output): $$(gtest_exe) $$(gtest_deps)
+ $(hide) ($$(call ART_TEST_SKIP,$$(NAME)) && $$< --gtest_output=xml:$$@ && \
+ $$(call ART_TEST_PASSED,$$(NAME))) || $$(call ART_TEST_FAILED,$$(NAME))
else
# Note: envsetup currently exports ASAN_OPTIONS=detect_leaks=0 to suppress leak detection, as some
# build tools (e.g., ninja) intentionally leak. We want leak checks when we run our tests, so
@@ -513,14 +516,13 @@
# (with the x86-64 ABI, as this allows symbolization of both x86 and x86-64). We don't do this in
# general as it loses all the color output, and we have our own symbolization step when not running
# under ASAN.
-$$(gtest_rule): PRIVATE_XML_OUTPUT := $$(gtest_xml_output)
-$$(gtest_rule): $$(gtest_exe) $$(gtest_deps)
- $(hide) ($$(call ART_TEST_SKIP,$$@) && set -o pipefail && \
- ASAN_OPTIONS=detect_leaks=1 $$< $$(PRIVATE_XML_OUTPUT) 2>&1 | tee $$<.tmp.out >&2 && \
- { $$(call ART_TEST_PASSED,$$@) ; rm $$<.tmp.out ; }) || \
+$$(gtest_output): $$(gtest_exe) $$(gtest_deps)
+ $(hide) ($$(call ART_TEST_SKIP,$$(NAME)) && set -o pipefail && \
+ ASAN_OPTIONS=detect_leaks=1 $$< --gtest_output=xml:$$@ 2>&1 | tee $$<.tmp.out >&2 && \
+ { $$(call ART_TEST_PASSED,$$(NAME)) ; rm $$<.tmp.out ; }) || \
( grep -q AddressSanitizer $$<.tmp.out && export ANDROID_BUILD_TOP=`pwd` && \
{ echo "ABI: 'x86_64'" | cat - $$<.tmp.out | development/scripts/stack | tail -n 3000 ; } ; \
- rm $$<.tmp.out ; $$(call ART_TEST_FAILED,$$@))
+ rm $$<.tmp.out ; $$(call ART_TEST_FAILED,$$(NAME)))
endif
ART_TEST_HOST_GTEST$$($(3)ART_PHONY_TEST_HOST_SUFFIX)_RULES += $$(gtest_rule)
@@ -531,7 +533,9 @@
# Clear locally defined variables.
gtest_deps :=
gtest_exe :=
+ gtest_output :=
gtest_rule :=
+ gtest_suffix :=
endef # define-art-gtest-rule-host
# Define the rules to build and run host and target gtests.
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index b4aa327..690802b 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1010,25 +1010,6 @@
base_img = base_img.substr(0, last_img_slash + 1);
- // Note: we have some special case here for our testing. We have to inject the differentiating
- // parts for the different core images.
- std::string infix; // Empty infix by default.
- {
- // Check the first name.
- std::string dex_file = oat_filenames_[0];
- size_t last_dex_slash = dex_file.rfind('/');
- if (last_dex_slash != std::string::npos) {
- dex_file = dex_file.substr(last_dex_slash + 1);
- }
- size_t last_dex_dot = dex_file.rfind('.');
- if (last_dex_dot != std::string::npos) {
- dex_file = dex_file.substr(0, last_dex_dot);
- }
- if (android::base::StartsWith(dex_file, "core-")) {
- infix = dex_file.substr(strlen("core"));
- }
- }
-
std::string base_symbol_oat;
if (!oat_unstripped_.empty()) {
base_symbol_oat = oat_unstripped_[0];
@@ -1042,11 +1023,11 @@
// Now create the other names. Use a counted loop to skip the first one.
for (size_t i = 1; i < dex_locations_.size(); ++i) {
// TODO: Make everything properly std::string.
- std::string image_name = CreateMultiImageName(dex_locations_[i], prefix, infix, ".art");
+ std::string image_name = CreateMultiImageName(dex_locations_[i], prefix, ".art");
char_backing_storage_.push_front(base_img + image_name);
image_filenames_.push_back(char_backing_storage_.front().c_str());
- std::string oat_name = CreateMultiImageName(dex_locations_[i], prefix, infix, ".oat");
+ std::string oat_name = CreateMultiImageName(dex_locations_[i], prefix, ".oat");
char_backing_storage_.push_front(base_oat + oat_name);
oat_filenames_.push_back(char_backing_storage_.front().c_str());
@@ -1061,11 +1042,9 @@
// 0) Assume input is /a/b/c.d
// 1) Strip the path -> c.d
// 2) Inject prefix p -> pc.d
- // 3) Inject infix i -> pci.d
- // 4) Replace suffix with s if it's "jar" -> d == "jar" -> pci.s
+ // 3) Replace suffix with s if it's "jar" -> d == "jar" -> pc.s
static std::string CreateMultiImageName(std::string in,
const std::string& prefix,
- const std::string& infix,
const char* replace_suffix) {
size_t last_dex_slash = in.rfind('/');
if (last_dex_slash != std::string::npos) {
@@ -1074,13 +1053,6 @@
if (!prefix.empty()) {
in = prefix + in;
}
- if (!infix.empty()) {
- // Inject infix.
- size_t last_dot = in.rfind('.');
- if (last_dot != std::string::npos) {
- in.insert(last_dot, infix);
- }
- }
if (android::base::EndsWith(in, ".jar")) {
in = in.substr(0, in.length() - strlen(".jar")) +
(replace_suffix != nullptr ? replace_suffix : "");
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index 901f478..1e24f46 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -255,7 +255,7 @@
}
// Obtain class count for debugging purposes
- if (kIsDebugBuild && compile_app_image_) {
+ if (VLOG_IS_ON(compiler) && compile_app_image_) {
ScopedObjectAccess soa(self);
size_t app_image_class_count = 0;
@@ -272,7 +272,7 @@
});
}
- LOG(INFO) << "Dex2Oat:AppImage:classCount = " << app_image_class_count;
+ VLOG(compiler) << "Dex2Oat:AppImage:classCount = " << app_image_class_count;
}
if (ClassLinker::kAppImageMayContainStrings && compile_app_image_) {
@@ -316,9 +316,9 @@
CHECK_EQ(image_infos_.back().num_string_references_,
string_reference_offsets_.size());
- LOG(INFO) << "Dex2Oat:AppImage:stringReferences = " << string_reference_offsets_.size();
- LOG(INFO) << "Dex2Oat:AppImage:managedStringReferences = " << managed_string_refs;
- LOG(INFO) << "Dex2Oat:AppImage:nativeStringReferences = " << native_string_refs;
+ VLOG(compiler) << "Dex2Oat:AppImage:stringReferences = " << string_reference_offsets_.size();
+ VLOG(compiler) << "Dex2Oat:AppImage:managedStringReferences = " << managed_string_refs;
+ VLOG(compiler) << "Dex2Oat:AppImage:nativeStringReferences = " << native_string_refs;
}
// This needs to happen after CalculateNewObjectOffsets since it relies on intern_table_bytes_ and
@@ -706,7 +706,7 @@
return false;
}
- if (kIsDebugBuild) {
+ if (VLOG_IS_ON(compiler)) {
size_t separately_written_section_size = bitmap_section.Size() +
image_header->GetImageRelocationsSection().Size() +
sizeof(ImageHeader);
@@ -714,9 +714,9 @@
size_t total_uncompressed_size = raw_image_data.size() + separately_written_section_size,
total_compressed_size = image_data.size() + separately_written_section_size;
- LOG(INFO) << "Dex2Oat:uncompressedImageSize = " << total_uncompressed_size;
+ VLOG(compiler) << "Dex2Oat:uncompressedImageSize = " << total_uncompressed_size;
if (total_uncompressed_size != total_compressed_size) {
- LOG(INFO) << "Dex2Oat:compressedImageSize = " << total_compressed_size;
+ VLOG(compiler) << "Dex2Oat:compressedImageSize = " << total_compressed_size;
}
}
diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc
index f6b764d..832f1d7 100644
--- a/runtime/class_loader_context.cc
+++ b/runtime/class_loader_context.cc
@@ -122,7 +122,7 @@
return false;
}
uint32_t checksum = 0;
- if (!android::base::ParseInt(dex_file_with_checksum[1].c_str(), &checksum)) {
+ if (!android::base::ParseUint(dex_file_with_checksum[1].c_str(), &checksum)) {
return false;
}
class_loader_chain_.back().classpath.push_back(dex_file_with_checksum[0]);
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 19e14b9..fa36835 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -2084,15 +2084,12 @@
size_t total_size =
dchecked_integral_cast<size_t>(oat_end - image_start) + extra_reservation_size;
bool relocate = Runtime::Current()->ShouldRelocate();
- // If relocating, choose a random address for ALSR. Since mmap() does not randomize
- // on its own, over-allocate and select a sub-region at a random offset.
- size_t randomize_size = relocate
- ? RoundUp(ART_BASE_ADDRESS_MAX_DELTA - ART_BASE_ADDRESS_MIN_DELTA, kPageSize) + kPageSize
- : 0u;
+ // If relocating, choose a random address for ALSR.
+ uint32_t addr = relocate ? ART_BASE_ADDRESS + ChooseRelocationOffsetDelta() : image_start;
*image_reservation =
MemMap::MapAnonymous("Boot image reservation",
- relocate ? nullptr : reinterpret_cast32<uint8_t*>(image_start),
- total_size + randomize_size,
+ reinterpret_cast32<uint8_t*>(addr),
+ total_size,
PROT_NONE,
/* low_4gb= */ true,
/* reuse= */ false,
@@ -2101,17 +2098,6 @@
if (!image_reservation->IsValid()) {
return false;
}
- if (relocate) {
- uint32_t offset = RoundDown(GetRandomNumber<uint32_t>(0u, randomize_size), kPageSize);
- if (offset != 0u) {
- MemMap unmapped_head = image_reservation->TakeReservedMemory(offset);
- // Let the destructor of `unmapped_head` unmap the memory before the chunk we shall use.
- }
- DCHECK_LE(total_size, image_reservation->Size());
- MemMap tmp = image_reservation->TakeReservedMemory(total_size);
- tmp.swap(*image_reservation);
- // Let the destructor of `tmp` unmap the memory after the chunk we shall use.
- }
DCHECK(!extra_reservation->IsValid());
if (extra_reservation_size != 0u) {
DCHECK_ALIGNED(extra_reservation_size, kPageSize);
@@ -2392,6 +2378,12 @@
DCHECK_GT(oat_filenames.size(), 1u);
// If the image filename was adapted (e.g., for our tests), we need to change this here,
// too, but need to strip all path components (they will be re-established when loading).
+ // For example, dex location
+ // /system/framework/core-libart.art
+ // with image name
+ // out/target/product/taimen/dex_bootjars/system/framework/arm64/boot-core-libart.art
+ // yields boot class path component
+ // /system/framework/boot-core-libart.art .
std::ostringstream bootcp_oss;
bool first_bootcp = true;
for (size_t i = 0; i < dex_locations.size(); ++i) {
@@ -2411,7 +2403,7 @@
size_t image_last_sep = (image_last_slash == std::string::npos)
? image_last_at
: (image_last_at == std::string::npos)
- ? std::string::npos
+ ? image_last_slash
: std::max(image_last_slash, image_last_at);
// Note: whenever image_last_sep == npos, +1 overflow means using the full string.
diff --git a/runtime/gc/space/region_space.cc b/runtime/gc/space/region_space.cc
index 171af6f..eba6fac 100644
--- a/runtime/gc/space/region_space.cc
+++ b/runtime/gc/space/region_space.cc
@@ -31,8 +31,7 @@
static constexpr uint kEvacuateLivePercentThreshold = 75U;
// Whether we protect the unused and cleared regions.
-// Only protect for target builds to prevent flaky test failures (b/63131961).
-static constexpr bool kProtectClearedRegions = kIsTargetBuild;
+static constexpr bool kProtectClearedRegions = true;
// Wether we poison memory areas occupied by dead objects in unevacuated regions.
static constexpr bool kPoisonDeadObjectsInUnevacuatedRegions = true;
@@ -70,6 +69,7 @@
if (!mem_map.IsValid()) {
LOG(ERROR) << "Failed to allocate pages for alloc space (" << name << ") of size "
<< PrettySize(capacity) << " with message " << error_msg;
+ PrintFileToLog("/proc/self/maps", LogSeverity::ERROR);
MemMap::DumpMaps(LOG_STREAM(ERROR));
return MemMap::Invalid();
}
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index 9467c4c..f696e25 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -1073,7 +1073,8 @@
if (obj->IsClass() && obj->AsClass()->IsRetired()) {
return;
}
- DCHECK(visited_objects_.insert(obj).second) << "Already visited " << obj;
+ DCHECK(visited_objects_.insert(obj).second)
+ << "Already visited " << obj << "(" << obj->PrettyTypeOf() << ")";
++total_objects_;
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 92d4731..6577726 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -584,10 +584,10 @@
for (uint32_t i = 0, e = shadow_frame->NumberOfVRegs(); i < e; ++i) {
if (shadow_frame->GetVRegReference(i) == existing) {
DCHECK_EQ(shadow_frame->GetVRegReference(i),
- reinterpret_cast<mirror::Object*>(shadow_frame->GetVReg(i)));
+ reinterpret_cast<mirror::Object*>(static_cast<uint32_t>(shadow_frame->GetVReg(i))));
shadow_frame->SetVRegReference(i, result.GetL());
DCHECK_EQ(shadow_frame->GetVRegReference(i),
- reinterpret_cast<mirror::Object*>(shadow_frame->GetVReg(i)));
+ reinterpret_cast<mirror::Object*>(static_cast<uint32_t>(shadow_frame->GetVReg(i))));
}
}
}
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 4a3d8cb..0092b97 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -3422,45 +3422,37 @@
return result;
}
-// Note: this visitor may return with a method set, but dex_pc_ being DexFile:kDexNoIndex. This is
-// so we don't abort in a special situation (thinlocked monitor) when dumping the Java stack.
-struct CurrentMethodVisitor final : public StackVisitor {
- CurrentMethodVisitor(Thread* thread, Context* context, bool check_suspended, bool abort_on_error)
- REQUIRES_SHARED(Locks::mutator_lock_)
- : StackVisitor(thread,
- context,
- StackVisitor::StackWalkKind::kIncludeInlinedFrames,
- check_suspended),
- this_object_(nullptr),
- method_(nullptr),
- dex_pc_(0),
- abort_on_error_(abort_on_error) {}
- bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtMethod* m = GetMethod();
- if (m->IsRuntimeMethod()) {
- // Continue if this is a runtime method.
- return true;
- }
- if (context_ != nullptr) {
- this_object_ = GetThisObject();
- }
- method_ = m;
- dex_pc_ = GetDexPc(abort_on_error_);
- return false;
- }
- ObjPtr<mirror::Object> this_object_;
- ArtMethod* method_;
- uint32_t dex_pc_;
- const bool abort_on_error_;
-};
-
ArtMethod* Thread::GetCurrentMethod(uint32_t* dex_pc,
bool check_suspended,
bool abort_on_error) const {
- CurrentMethodVisitor visitor(const_cast<Thread*>(this),
- nullptr,
- check_suspended,
- abort_on_error);
+ // Note: this visitor may return with a method set, but dex_pc_ being DexFile:kDexNoIndex. This is
+ // so we don't abort in a special situation (thinlocked monitor) when dumping the Java
+ // stack.
+ struct CurrentMethodVisitor final : public StackVisitor {
+ CurrentMethodVisitor(Thread* thread, bool check_suspended, bool abort_on_error)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ : StackVisitor(thread,
+ /* context= */nullptr,
+ StackVisitor::StackWalkKind::kIncludeInlinedFrames,
+ check_suspended),
+ method_(nullptr),
+ dex_pc_(0),
+ abort_on_error_(abort_on_error) {}
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
+ ArtMethod* m = GetMethod();
+ if (m->IsRuntimeMethod()) {
+ // Continue if this is a runtime method.
+ return true;
+ }
+ method_ = m;
+ dex_pc_ = GetDexPc(abort_on_error_);
+ return false;
+ }
+ ArtMethod* method_;
+ uint32_t dex_pc_;
+ const bool abort_on_error_;
+ };
+ CurrentMethodVisitor visitor(const_cast<Thread*>(this), check_suspended, abort_on_error);
visitor.WalkStack(false);
if (dex_pc != nullptr) {
*dex_pc = visitor.dex_pc_;
diff --git a/test/530-checker-peel-unroll/smali/PeelUnroll.smali b/test/530-checker-peel-unroll/smali/PeelUnroll.smali
new file mode 100644
index 0000000..6e09e92
--- /dev/null
+++ b/test/530-checker-peel-unroll/smali/PeelUnroll.smali
@@ -0,0 +1,232 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+.class public LPeelUnroll;
+
+.super Ljava/lang/Object;
+
+## CHECK-START: void PeelUnroll.unrollingWhile(int[]) loop_optimization (before)
+## CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+## CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none
+## CHECK-DAG: <<Const128:i\d+>> IntConstant 128 loop:none
+## CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
+## CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
+## CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const128>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<Rem:i\d+>> Rem [<<AddI>>,<<Const2>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<NE:z\d+>> NotEqual [<<Rem>>,<<Const0>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: If [<<NE>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
+## CHECK-DAG: Phi [<<PhiS>>,<<AddS>>] loop:<<Loop>> outer_loop:none
+
+## CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
+## CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+
+## CHECK-START: void PeelUnroll.unrollingWhile(int[]) loop_optimization (after)
+## CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+## CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none
+## CHECK-DAG: <<Const128:i\d+>> IntConstant 128 loop:none
+## CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
+## CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
+## CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const128>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<Rem:i\d+>> Rem [<<AddI>>,<<Const2>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<NE:z\d+>> NotEqual [<<Rem>>,<<Const0>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: If [<<NE>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<PhiS>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<PhiSM:i\d+>> Phi [<<PhiS>>,<<AddS>>] loop:<<Loop>> outer_loop:none
+
+## CHECK-DAG: <<AddIA:i\d+>> Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<AddI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<RemA:i\d+>> Rem [<<AddIA>>,<<Const2>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<NEA:z\d+>> NotEqual [<<RemA>>,<<Const0>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: If [<<NEA>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddSA:i\d+>> Add [<<PhiSM>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<PhiSM>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: Phi [<<AddSA>>,<<PhiSM>>] loop:<<Loop>> outer_loop:none
+
+## CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
+## CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
+.method public static final unrollingWhile([I)V
+ .registers 5
+ .param p0, "a" # [I
+
+ .line 167
+ const/4 v0, 0x0
+
+ .line 168
+ .local v0, "i":I
+ const/16 v1, 0x80
+
+ .line 169
+ .local v1, "s":I
+ :goto_3
+ add-int/lit8 v2, v0, 0x1
+
+ .end local v0 # "i":I
+ .local v2, "i":I
+ const/16 v3, 0xffe
+
+ if-ge v0, v3, :cond_14
+
+ .line 170
+ rem-int/lit8 v0, v2, 0x2
+
+ if-nez v0, :cond_12
+
+ .line 171
+ add-int/lit8 v0, v1, 0x1
+
+ .end local v1 # "s":I
+ .local v0, "s":I
+ aput v1, p0, v2
+
+ .line 169
+ move v1, v0
+
+ .end local v2 # "i":I
+ .local v0, "i":I
+ .restart local v1 # "s":I
+ :cond_12
+ move v0, v2
+
+ goto :goto_3
+
+ .line 174
+ .end local v0 # "i":I
+ .restart local v2 # "i":I
+ :cond_14
+ return-void
+.end method
+
+
+## CHECK-START: int PeelUnroll.unrollingWhileLiveOuts(int[]) loop_optimization (before)
+## CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+## CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none
+## CHECK-DAG: <<Const128:i\d+>> IntConstant 128 loop:none
+## CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
+## CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
+## CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const128>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<Rem:i\d+>> Rem [<<AddI>>,<<Const2>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<NE:z\d+>> NotEqual [<<Rem>>,<<Const0>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: If [<<NE>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
+## CHECK-DAG: Phi [<<PhiS>>,<<AddS>>] loop:<<Loop>> outer_loop:none
+
+## CHECK-NOT: ArrayGet
+## CHECK-NOT: ArraySet
+
+## CHECK-START: int PeelUnroll.unrollingWhileLiveOuts(int[]) loop_optimization (after)
+## CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
+## CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none
+## CHECK-DAG: <<Const128:i\d+>> IntConstant 128 loop:none
+## CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
+## CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
+## CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const128>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<Rem:i\d+>> Rem [<<AddI>>,<<Const2>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<NE:z\d+>> NotEqual [<<Rem>>,<<Const0>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: If [<<NE>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<PhiS>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<PhiSM:i\d+>> Phi [<<PhiS>>,<<AddS>>] loop:<<Loop>> outer_loop:none
+
+## CHECK-DAG: <<AddIA:i\d+>> Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<AddI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<RemA:i\d+>> Rem [<<AddIA>>,<<Const2>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<NEA:z\d+>> NotEqual [<<RemA>>,<<Const0>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: If [<<NEA>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: <<AddSA:i\d+>> Add [<<PhiSM>>,<<Const1>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<PhiSM>>] loop:<<Loop>> outer_loop:none
+## CHECK-DAG: Phi [<<AddSA>>,<<PhiSM>>] loop:<<Loop>> outer_loop:none
+
+## CHECK-DAG: <<RetPhi:i\d+>> Phi [<<PhiS>>,<<PhiSM>>] loop:none
+## CHECK-DAG: Return [<<RetPhi>>] loop:none
+
+## CHECK-NOT: ArrayGet
+## CHECK-NOT: ArraySet
+.method public static final unrollingWhileLiveOuts([I)I
+ .registers 5
+ .param p0, "a" # [I
+
+ .line 598
+ const/4 v0, 0x0
+
+ .line 599
+ .local v0, "i":I
+ const/16 v1, 0x80
+
+ .line 600
+ .local v1, "s":I
+ :goto_3
+ add-int/lit8 v2, v0, 0x1
+
+ .end local v0 # "i":I
+ .local v2, "i":I
+ const/16 v3, 0xffe
+
+ if-ge v0, v3, :cond_14
+
+ .line 601
+ rem-int/lit8 v0, v2, 0x2
+
+ if-nez v0, :cond_12
+
+ .line 602
+ add-int/lit8 v0, v1, 0x1
+
+ .end local v1 # "s":I
+ .local v0, "s":I
+ aput v1, p0, v2
+
+ .line 600
+ move v1, v0
+
+ .end local v2 # "i":I
+ .local v0, "i":I
+ .restart local v1 # "s":I
+ :cond_12
+ move v0, v2
+
+ goto :goto_3
+
+ .line 605
+ .end local v0 # "i":I
+ .restart local v2 # "i":I
+ :cond_14
+ return v1
+.end method
+
diff --git a/test/530-checker-peel-unroll/src/Main.java b/test/530-checker-peel-unroll/src/Main.java
index 4d81440..aee32b7 100644
--- a/test/530-checker-peel-unroll/src/Main.java
+++ b/test/530-checker-peel-unroll/src/Main.java
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+import java.lang.reflect.Method;
+
//
// Test loop optimizations, in particular scalar loop peeling and unrolling.
public class Main {
@@ -110,69 +112,6 @@
}
}
- /// CHECK-START: void Main.unrollingWhile(int[]) loop_optimization (before)
- /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
- /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
- /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none
- /// CHECK-DAG: <<Const128:i\d+>> IntConstant 128 loop:none
- /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
- /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
- /// CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const128>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<Rem:i\d+>> Rem [<<AddI>>,<<Const2>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<Rem>>,<<Const0>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: If [<<NE>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: Phi [<<PhiS>>,<<AddS>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
-
- /// CHECK-START: void Main.unrollingWhile(int[]) loop_optimization (after)
- /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
- /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
- /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none
- /// CHECK-DAG: <<Const128:i\d+>> IntConstant 128 loop:none
- /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
- /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
- /// CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const128>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<Rem:i\d+>> Rem [<<AddI>>,<<Const2>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<Rem>>,<<Const0>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: If [<<NE>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<PhiS>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<PhiSM:i\d+>> Phi [<<PhiS>>,<<AddS>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-DAG: <<AddIA:i\d+>> Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<AddI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<RemA:i\d+>> Rem [<<AddIA>>,<<Const2>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<NEA:z\d+>> NotEqual [<<RemA>>,<<Const0>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: If [<<NEA>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddSA:i\d+>> Add [<<PhiSM>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<PhiSM>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: Phi [<<AddSA>>,<<PhiSM>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none
- /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none
- private static final void unrollingWhile(int[] a) {
- int i = 0;
- int s = 128;
- while (i++ < LENGTH - 2) {
- if (i % 2 == 0) {
- a[i] = s++;
- }
- }
- }
-
// Simple check that loop unrolling has happened.
//
/// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (before)
@@ -538,73 +477,6 @@
return 1 / (s + t);
}
- /// CHECK-START: int Main.unrollingWhileLiveOuts(int[]) loop_optimization (before)
- /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
- /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
- /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none
- /// CHECK-DAG: <<Const128:i\d+>> IntConstant 128 loop:none
- /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
- /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
- /// CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const128>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<Rem:i\d+>> Rem [<<AddI>>,<<Const2>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<Rem>>,<<Const0>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: If [<<NE>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: Phi [<<PhiS>>,<<AddS>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-NOT: ArrayGet
- /// CHECK-NOT: ArraySet
-
- /// CHECK-START: int Main.unrollingWhileLiveOuts(int[]) loop_optimization (after)
- /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
- /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
- /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none
- /// CHECK-DAG: <<Const128:i\d+>> IntConstant 128 loop:none
- /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
- /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none
- /// CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const128>>,{{i\d+}}] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<Rem:i\d+>> Rem [<<AddI>>,<<Const2>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<Rem>>,<<Const0>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: If [<<NE>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<PhiS>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<PhiSM:i\d+>> Phi [<<PhiS>>,<<AddS>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-DAG: <<AddIA:i\d+>> Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<AddI>>,<<Limit>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<RemA:i\d+>> Rem [<<AddIA>>,<<Const2>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<NEA:z\d+>> NotEqual [<<RemA>>,<<Const0>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: If [<<NEA>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: <<AddSA:i\d+>> Add [<<PhiSM>>,<<Const1>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<PhiSM>>] loop:<<Loop>> outer_loop:none
- /// CHECK-DAG: Phi [<<AddSA>>,<<PhiSM>>] loop:<<Loop>> outer_loop:none
- //
- /// CHECK-DAG: <<RetPhi:i\d+>> Phi [<<PhiS>>,<<PhiSM>>] loop:none
- /// CHECK-DAG: Return [<<RetPhi>>] loop:none
- //
- /// CHECK-NOT: ArrayGet
- /// CHECK-NOT: ArraySet
- private static final int unrollingWhileLiveOuts(int[] a) {
- int i = 0;
- int s = 128;
- while (i++ < LENGTH - 2) {
- if (i % 2 == 0) {
- a[i] = s++;
- }
- }
- return s;
- }
-
/// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (before)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
@@ -1113,7 +985,7 @@
}
}
- public void verifyUnrolling() {
+ public void verifyUnrolling() throws Exception {
initIntArray(a);
initIntArray(b);
@@ -1132,7 +1004,12 @@
unrollingTypeConversion(a, doubleArray);
unrollingCheckCast(a, new SubMain());
- unrollingWhile(a);
+ // Call unrollingWhile(a);
+ Class<?> c = Class.forName("PeelUnroll");
+ Method m = c.getMethod("unrollingWhile", Class.forName("[I"));
+ Object[] arguments = { a };
+ m.invoke(null, arguments);
+
unrollingLoadStoreElimination(a);
unrollingSwitch(a);
unrollingSwapElements(a);
@@ -1152,7 +1029,7 @@
expectEquals(expected, found);
}
- public void verifyPeeling() {
+ public void verifyPeeling() throws Exception {
expectEquals(1, peelingHoistOneControl(0)); // anything else loops
expectEquals(1, peelingHoistOneControl(0, 0));
expectEquals(1, peelingHoistOneControl(0, 1));
@@ -1176,7 +1053,13 @@
peelingBreakFromNest(a, true);
unrollingSimpleLiveOuts(a);
- unrollingWhileLiveOuts(a);
+
+ // Call unrollingWhileLiveOuts(a);
+ Class<?> c = Class.forName("PeelUnroll");
+ Method m = c.getMethod("unrollingWhileLiveOuts", Class.forName("[I"));
+ Object[] arguments = { a };
+ m.invoke(null, arguments);
+
unrollingLiveOutsNested(a);
int expected = 51565978;
@@ -1188,7 +1071,7 @@
expectEquals(expected, found);
}
- public static void main(String[] args) {
+ public static void main(String[] args) throws Exception {
Main obj = new Main();
obj.verifyUnrolling();
diff --git a/test/knownfailures.json b/test/knownfailures.json
index a7fb189..002ad07 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -295,7 +295,7 @@
"685-deoptimizeable"],
"description": ["Tests that should fail when the optimizing compiler ",
"compiles them non-debuggable."],
- "variant": "optimizing & ndebuggable | regalloc_gc & ndebuggable | speed-profile & ndebuggable | jit & ndebuggable"
+ "variant": "optimizing & ndebuggable | regalloc_gc & ndebuggable | speed-profile & ndebuggable | jit & ndebuggable | jit-on-first-use & ndebuggable"
},
{
"tests": "596-app-images",
@@ -702,7 +702,7 @@
},
{
"tests": ["661-oat-writer-layout"],
- "variant": "interp-ac | interpreter | jit | no-prebuild | no-image | trace | redefine-stress | jvmti-stress",
+ "variant": "interp-ac | interpreter | jit | jit-on-first-use | no-prebuild | no-image | trace | redefine-stress | jvmti-stress",
"description": ["Test is designed to only check --optimizing"]
},
{
@@ -1017,7 +1017,8 @@
"description": ["Failing on RI. Needs further investigating."]
},
{
- "tests": ["616-cha-unloading",
+ "tests": ["530-checker-peel-unroll",
+ "616-cha-unloading",
"674-hiddenapi",
"677-fsi2",
"678-quickening",
diff --git a/test/testrunner/run_build_test_target.py b/test/testrunner/run_build_test_target.py
index 3160079..14287b0 100755
--- a/test/testrunner/run_build_test_target.py
+++ b/test/testrunner/run_build_test_target.py
@@ -63,11 +63,12 @@
os.environ.update(custom_env)
if 'make' in target:
- build_command = 'make'
+ build_command = 'build/soong/soong_ui.bash --make-mode'
build_command += ' DX='
build_command += ' -j' + str(n_threads)
- build_command += ' -C ' + env.ANDROID_BUILD_TOP
build_command += ' ' + target.get('make')
+ if env.DIST_DIR:
+ build_command += ' dist'
sys.stdout.write(str(build_command) + '\n')
sys.stdout.flush()
if subprocess.call(build_command.split()):
diff --git a/test/testrunner/target_config.py b/test/testrunner/target_config.py
index ad72945..c532705 100644
--- a/test/testrunner/target_config.py
+++ b/test/testrunner/target_config.py
@@ -47,8 +47,7 @@
'run-test' : ['--jit', '--debuggable', '--ndebuggable']
},
'art-jit-on-first-use' : {
- 'run-test' : ['--jit',
- '--runtime-option=-Xjitthreshold:0']
+ 'run-test' : ['--jit-on-first-use']
},
'art-pictest' : {
'run-test' : ['--pictest',
@@ -81,9 +80,8 @@
'--gcverify']
},
'art-jit-on-first-use-gcstress' : {
- 'run-test' : ['--jit',
- '--gcstress',
- '--runtime-option=-Xjitthreshold:0']
+ 'run-test' : ['--jit-on-first-use',
+ '--gcstress']
},
'art-read-barrier-heap-poisoning' : {
'run-test': ['--interpreter',
diff --git a/test/testrunner/testrunner.py b/test/testrunner/testrunner.py
index 2fa7d2a..c5059f6 100755
--- a/test/testrunner/testrunner.py
+++ b/test/testrunner/testrunner.py
@@ -153,8 +153,8 @@
VARIANT_TYPE_DICT['address_sizes'] = {'64', '32'}
VARIANT_TYPE_DICT['jvmti'] = {'no-jvmti', 'jvmti-stress', 'redefine-stress', 'trace-stress',
'field-stress', 'step-stress'}
- VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'optimizing',
- 'regalloc_gc', 'speed-profile'}
+ VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'jit-on-first-use',
+ 'optimizing', 'regalloc_gc', 'speed-profile'}
for v_type in VARIANT_TYPE_DICT:
TOTAL_VARIANTS_SET = TOTAL_VARIANTS_SET.union(VARIANT_TYPE_DICT.get(v_type))
@@ -433,6 +433,8 @@
options_test += ' --interpreter --verify-soft-fail'
elif compiler == 'jit':
options_test += ' --jit'
+ elif compiler == 'jit-on-first-use':
+ options_test += ' --jit --runtime-option -Xjitthreshold:0'
elif compiler == 'speed-profile':
options_test += ' --random-profile'
@@ -1019,10 +1021,8 @@
build_targets += 'test-art-target-run-test-dependencies '
if 'jvm' in _user_input_variants['target']:
build_targets += 'test-art-host-run-test-dependencies '
- build_command = 'make'
+ build_command = 'build/soong/soong_ui.bash --make-mode'
build_command += ' DX='
- build_command += ' -j'
- build_command += ' -C ' + env.ANDROID_BUILD_TOP
build_command += ' ' + build_targets
if subprocess.call(build_command.split()):
# Debugging for b/62653020
diff --git a/test/ti-agent/jni_binder.cc b/test/ti-agent/jni_binder.cc
index 32236de..585b4a4 100644
--- a/test/ti-agent/jni_binder.cc
+++ b/test/ti-agent/jni_binder.cc
@@ -223,7 +223,7 @@
}
// TODO: Implement scanning *all* classloaders.
- LOG(FATAL) << "Unimplemented";
+ LOG(WARNING) << "Scanning all classloaders unimplemented";
return nullptr;
}