summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/Android.common_test.mk4
-rw-r--r--build/Android.gtest.mk60
-rw-r--r--build/Android.oat.mk52
-rw-r--r--compiler/compiled_method.h2
-rw-r--r--compiler/debug/dwarf/headers.h2
-rw-r--r--compiler/debug/elf_debug_writer.cc2
-rw-r--r--compiler/debug/elf_debug_writer.h2
-rw-r--r--compiler/driver/compiled_method_storage.h2
-rw-r--r--compiler/driver/compiler_driver.cc2
-rw-r--r--compiler/driver/compiler_driver.h2
-rw-r--r--compiler/elf_builder.h2
-rw-r--r--compiler/elf_writer.h2
-rw-r--r--compiler/jni/quick/calling_convention.h2
-rw-r--r--compiler/linker/arm64/relative_patcher_arm64.h2
-rw-r--r--compiler/linker/relative_patcher.h2
-rw-r--r--compiler/linker/relative_patcher_test.h2
-rw-r--r--compiler/oat_writer.h2
-rw-r--r--compiler/optimizing/code_generator_arm.h6
-rw-r--r--compiler/optimizing/code_generator_arm64.cc2
-rw-r--r--compiler/optimizing/code_generator_arm64.h6
-rw-r--r--compiler/optimizing/code_generator_mips.h18
-rw-r--r--compiler/optimizing/code_generator_mips64.h16
-rw-r--r--compiler/optimizing/code_generator_x86.h6
-rw-r--r--compiler/optimizing/code_generator_x86_64.h6
-rw-r--r--compiler/optimizing/codegen_test.cc10
-rw-r--r--compiler/optimizing/dead_code_elimination.cc2
-rw-r--r--compiler/optimizing/nodes.h4
-rw-r--r--compiler/optimizing/register_allocation_resolver.h2
-rw-r--r--compiler/utils/arm/assembler_thumb2.cc63
-rw-r--r--compiler/utils/arm/assembler_thumb2.h11
-rw-r--r--compiler/utils/assembler.h2
-rw-r--r--compiler/utils/dedupe_set_test.cc2
-rw-r--r--compiler/utils/jni_macro_assembler.h2
-rw-r--r--compiler/utils/x86/assembler_x86.h2
-rw-r--r--compiler/utils/x86/jni_macro_assembler_x86.h2
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.h2
-rw-r--r--compiler/utils/x86_64/jni_macro_assembler_x86_64.h2
-rw-r--r--dex2oat/dex2oat.cc2
-rw-r--r--dexlist/dexlist_test.cc6
-rw-r--r--runtime/base/array_ref.h (renamed from compiler/utils/array_ref.h)6
-rw-r--r--runtime/base/transform_array_ref.h (renamed from compiler/utils/transform_array_ref.h)10
-rw-r--r--runtime/base/transform_array_ref_test.cc (renamed from compiler/utils/transform_array_ref_test.cc)2
-rw-r--r--runtime/base/transform_iterator.h (renamed from compiler/utils/transform_iterator.h)6
-rw-r--r--runtime/base/transform_iterator_test.cc (renamed from compiler/utils/transform_iterator_test.cc)2
-rw-r--r--runtime/common_runtime_test.cc4
-rw-r--r--test/Android.run-test.mk25
-rwxr-xr-xtest/run-test15
-rw-r--r--tools/art2
-rw-r--r--tools/bisection_search/README.md59
-rwxr-xr-xtools/bisection_search/bisection_search.py64
-rwxr-xr-xtools/bisection_search/common.py143
-rwxr-xr-xtools/javafuzz/run_java_fuzz_test.py481
-rwxr-xr-xtools/run-jdwp-tests.sh2
-rwxr-xr-xtools/run-libcore-tests.sh2
54 files changed, 719 insertions, 422 deletions
diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
index 93e310e0eb..6b7dc0932e 100644
--- a/build/Android.common_test.mk
+++ b/build/Android.common_test.mk
@@ -60,8 +60,8 @@ ART_TEST_OPTIMIZING ?= true
# Do you want to test the optimizing compiler with graph coloring register allocation?
ART_TEST_OPTIMIZING_GRAPH_COLOR ?= $(ART_TEST_FULL)
-# Do we want to test a PIC-compiled core image?
-ART_TEST_PIC_IMAGE ?= $(ART_TEST_FULL)
+# Do we want to test a non-PIC-compiled core image?
+ART_TEST_NPIC_IMAGE ?= $(ART_TEST_FULL)
# Do we want to test PIC-compiled tests ("apps")?
ART_TEST_PIC_TEST ?= $(ART_TEST_FULL)
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 76ee06e453..12b50b8591 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -90,16 +90,16 @@ ART_GTEST_transaction_test_DEX_DEPS := Transaction
ART_GTEST_type_lookup_table_test_DEX_DEPS := Lookup
# The elf writer test has dependencies on core.oat.
-ART_GTEST_elf_writer_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
-ART_GTEST_elf_writer_test_TARGET_DEPS := $(TARGET_CORE_IMAGE_default_no-pic_64) $(TARGET_CORE_IMAGE_default_no-pic_32)
+ART_GTEST_elf_writer_test_HOST_DEPS := $(HOST_CORE_IMAGE_optimizing_no-pic_64) $(HOST_CORE_IMAGE_optimizing_no-pic_32)
+ART_GTEST_elf_writer_test_TARGET_DEPS := $(TARGET_CORE_IMAGE_optimizing_no-pic_64) $(TARGET_CORE_IMAGE_optimizing_no-pic_32)
ART_GTEST_dex2oat_environment_tests_HOST_DEPS := \
- $(HOST_CORE_IMAGE_default_no-pic_64) \
- $(HOST_CORE_IMAGE_default_no-pic_32) \
+ $(HOST_CORE_IMAGE_optimizing_pic_64) \
+ $(HOST_CORE_IMAGE_optimizing_pic_32) \
$(HOST_OUT_EXECUTABLES)/patchoatd
ART_GTEST_dex2oat_environment_tests_TARGET_DEPS := \
- $(TARGET_CORE_IMAGE_default_no-pic_64) \
- $(TARGET_CORE_IMAGE_default_no-pic_32) \
+ $(TARGET_CORE_IMAGE_optimizing_pic_64) \
+ $(TARGET_CORE_IMAGE_optimizing_pic_32) \
$(TARGET_OUT_EXECUTABLES)/patchoatd
ART_GTEST_oat_file_assistant_test_HOST_DEPS := \
@@ -114,62 +114,62 @@ ART_GTEST_dex2oat_test_TARGET_DEPS := \
$(ART_GTEST_dex2oat_environment_tests_TARGET_DEPS)
# TODO: document why this is needed.
-ART_GTEST_proxy_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
+ART_GTEST_proxy_test_HOST_DEPS := $(HOST_CORE_IMAGE_optimizing_no-pic_64) $(HOST_CORE_IMAGE_optimizing_no-pic_32)
# 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_no-pic_64) \
- $(HOST_CORE_IMAGE_default_no-pic_32) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_64) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_32) \
$(HOST_OUT_EXECUTABLES)/dexdump2
ART_GTEST_dexdump_test_TARGET_DEPS := \
- $(TARGET_CORE_IMAGE_default_no-pic_64) \
- $(TARGET_CORE_IMAGE_default_no-pic_32) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_64) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_32) \
dexdump2
# 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_no-pic_64) \
- $(HOST_CORE_IMAGE_default_no-pic_32) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_64) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_32) \
$(HOST_OUT_EXECUTABLES)/dexlayout \
$(HOST_OUT_EXECUTABLES)/dexdump2
ART_GTEST_dexlayout_test_TARGET_DEPS := \
- $(TARGET_CORE_IMAGE_default_no-pic_64) \
- $(TARGET_CORE_IMAGE_default_no-pic_32) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_64) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_32) \
dexlayout \
dexdump2
# The dexlist test requires an image and the dexlist utility.
ART_GTEST_dexlist_test_HOST_DEPS := \
- $(HOST_CORE_IMAGE_default_no-pic_64) \
- $(HOST_CORE_IMAGE_default_no-pic_32) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_64) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_32) \
$(HOST_OUT_EXECUTABLES)/dexlist
ART_GTEST_dexlist_test_TARGET_DEPS := \
- $(TARGET_CORE_IMAGE_default_no-pic_64) \
- $(TARGET_CORE_IMAGE_default_no-pic_32) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_64) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_32) \
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
# target, just the module is fine, the sync will happen late enough.
ART_GTEST_imgdiag_test_HOST_DEPS := \
- $(HOST_CORE_IMAGE_default_no-pic_64) \
- $(HOST_CORE_IMAGE_default_no-pic_32) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_64) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_32) \
$(HOST_OUT_EXECUTABLES)/imgdiagd
ART_GTEST_imgdiag_test_TARGET_DEPS := \
- $(TARGET_CORE_IMAGE_default_no-pic_64) \
- $(TARGET_CORE_IMAGE_default_no-pic_32) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_64) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_32) \
imgdiagd
# Oatdump test requires an image and oatfile to dump.
ART_GTEST_oatdump_test_HOST_DEPS := \
- $(HOST_CORE_IMAGE_default_no-pic_64) \
- $(HOST_CORE_IMAGE_default_no-pic_32) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_64) \
+ $(HOST_CORE_IMAGE_optimizing_no-pic_32) \
$(HOST_OUT_EXECUTABLES)/oatdumpd
ART_GTEST_oatdump_test_TARGET_DEPS := \
- $(TARGET_CORE_IMAGE_default_no-pic_64) \
- $(TARGET_CORE_IMAGE_default_no-pic_32) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_64) \
+ $(TARGET_CORE_IMAGE_optimizing_no-pic_32) \
oatdump
# Profile assistant tests requires profman utility.
@@ -214,6 +214,8 @@ RUNTIME_GTEST_COMMON_SRC_FILES := \
runtime/base/stringprintf_test.cc \
runtime/base/time_utils_test.cc \
runtime/base/timing_logger_test.cc \
+ runtime/base/transform_array_ref_test.cc \
+ runtime/base/transform_iterator_test.cc \
runtime/base/variant_map_test.cc \
runtime/base/unix_file/fd_file_test.cc \
runtime/class_linker_test.cc \
@@ -308,9 +310,7 @@ COMPILER_GTEST_COMMON_SRC_FILES := \
compiler/utils/intrusive_forward_list_test.cc \
compiler/utils/string_reference_test.cc \
compiler/utils/swap_space_test.cc \
- compiler/utils/test_dex_file_builder_test.cc \
- compiler/utils/transform_array_ref_test.cc \
- compiler/utils/transform_iterator_test.cc \
+ compiler/utils/test_dex_file_builder_test.cc
COMPILER_GTEST_COMMON_SRC_FILES_all := \
compiler/jni/jni_cfi_test.cc \
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index 884f698cd9..c4887e61ff 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -37,7 +37,7 @@ else
endif
# Use dex2oat debug version for better error reporting
-# $(1): compiler - default, optimizing, jit, interpreter or interpreter-access-checks.
+# $(1): compiler - optimizing, interpreter or interpreter-access-checks.
# $(2): pic/no-pic
# $(3): 2ND_ or undefined, 2ND_ for 32-bit host builds.
# $(4): wrapper, e.g., valgrind.
@@ -53,13 +53,9 @@ define create-core-oat-host-rules
core_pic_infix :=
core_dex2oat_dependency := $(DEX2OAT_DEPENDENCY)
- ifeq ($(1),default)
- core_compile_options += --compiler-backend=Quick
- endif
ifeq ($(1),optimizing)
core_compile_options += --compiler-backend=Optimizing
core_dex2oat_dependency := $(DEX2OAT)
- core_infix := -optimizing
endif
ifeq ($(1),interpreter)
core_compile_options += --compiler-filter=interpret-only
@@ -69,24 +65,16 @@ define create-core-oat-host-rules
core_compile_options += --compiler-filter=verify-at-runtime --runtime-arg -Xverify:softfail
core_infix := -interp-ac
endif
- ifeq ($(1),jit)
- core_compile_options += --compiler-filter=verify-at-runtime
- core_infix := -jit
- endif
- ifeq ($(1),default)
- # Default has no infix, no compile options.
- endif
- ifneq ($(filter-out default interpreter interp-ac jit optimizing,$(1)),)
+ ifneq ($(filter-out interpreter interp-ac optimizing,$(1)),)
#Technically this test is not precise, but hopefully good enough.
- $$(error found $(1) expected default, interpreter, interpreter-access-checks, jit or optimizing)
+ $$(error found $(1) expected interpreter, interpreter-access-checks, or optimizing)
endif
ifeq ($(2),pic)
core_compile_options += --compile-pic
- core_pic_infix := -pic
endif
ifeq ($(2),no-pic)
- # No change for non-pic
+ core_pic_infix := -npic
endif
ifneq ($(filter-out pic no-pic,$(2)),)
# Technically this test is not precise, but hopefully good enough.
@@ -148,7 +136,7 @@ $$(core_oat_name): $$(core_image_name)
core_pic_infix :=
endef # create-core-oat-host-rules
-# $(1): compiler - default, optimizing, jit, interpreter or interpreter-access-checks.
+# $(1): compiler - optimizing, interpreter or interpreter-access-checks.
# $(2): wrapper.
# $(3): dex2oat suffix.
# $(4): multi-image.
@@ -162,24 +150,18 @@ define create-core-oat-host-rule-combination
endif
endef
-$(eval $(call create-core-oat-host-rule-combination,default,,,false))
$(eval $(call create-core-oat-host-rule-combination,optimizing,,,false))
$(eval $(call create-core-oat-host-rule-combination,interpreter,,,false))
$(eval $(call create-core-oat-host-rule-combination,interp-ac,,,false))
-$(eval $(call create-core-oat-host-rule-combination,jit,,,false))
-$(eval $(call create-core-oat-host-rule-combination,default,,,true))
$(eval $(call create-core-oat-host-rule-combination,optimizing,,,true))
$(eval $(call create-core-oat-host-rule-combination,interpreter,,,true))
$(eval $(call create-core-oat-host-rule-combination,interp-ac,,,true))
-$(eval $(call create-core-oat-host-rule-combination,jit,,,true))
valgrindHOST_CORE_IMG_OUTS :=
valgrindHOST_CORE_OAT_OUTS :=
-$(eval $(call create-core-oat-host-rule-combination,default,valgrind,32,false))
$(eval $(call create-core-oat-host-rule-combination,optimizing,valgrind,32,false))
$(eval $(call create-core-oat-host-rule-combination,interpreter,valgrind,32,false))
$(eval $(call create-core-oat-host-rule-combination,interp-ac,valgrind,32,false))
-$(eval $(call create-core-oat-host-rule-combination,jit,valgrind,32,false))
valgrind-test-art-host-dex2oat-host: $(valgrindHOST_CORE_IMG_OUTS)
@@ -193,15 +175,11 @@ define create-core-oat-target-rules
core_pic_infix :=
core_dex2oat_dependency := $(DEX2OAT_DEPENDENCY)
- ifeq ($(1),default)
- core_compile_options += --compiler-backend=Quick
- endif
ifeq ($(1),optimizing)
core_compile_options += --compiler-backend=Optimizing
# With the optimizing compiler, we want to rerun dex2oat whenever there is
# a dex2oat change to catch regressions early.
core_dex2oat_dependency := $(DEX2OAT)
- core_infix := -optimizing
endif
ifeq ($(1),interpreter)
core_compile_options += --compiler-filter=interpret-only
@@ -211,24 +189,16 @@ define create-core-oat-target-rules
core_compile_options += --compiler-filter=verify-at-runtime --runtime-arg -Xverify:softfail
core_infix := -interp-ac
endif
- ifeq ($(1),jit)
- core_compile_options += --compiler-filter=verify-at-runtime
- core_infix := -jit
- endif
- ifeq ($(1),default)
- # Default has no infix, no compile options.
- endif
- ifneq ($(filter-out default interpreter interp-ac jit optimizing,$(1)),)
+ ifneq ($(filter-out interpreter interp-ac optimizing,$(1)),)
# Technically this test is not precise, but hopefully good enough.
- $$(error found $(1) expected default, interpreter, interpreter-access-checks, jit or optimizing)
+ $$(error found $(1) expected interpreter, interpreter-access-checks, or optimizing)
endif
ifeq ($(2),pic)
core_compile_options += --compile-pic
- core_pic_infix := -pic
endif
ifeq ($(2),no-pic)
- # No change for non-pic
+ core_pic_infix := -npic
endif
ifneq ($(filter-out pic no-pic,$(2)),)
#Technically this test is not precise, but hopefully good enough.
@@ -283,7 +253,7 @@ $$(core_oat_name): $$(core_image_name)
core_pic_infix :=
endef # create-core-oat-target-rules
-# $(1): compiler - default, optimizing, jit, interpreter or interpreter-access-checks.
+# $(1): compiler - optimizing, interpreter or interpreter-access-checks.
# $(2): wrapper.
# $(3): dex2oat suffix.
define create-core-oat-target-rule-combination
@@ -296,19 +266,15 @@ define create-core-oat-target-rule-combination
endif
endef
-$(eval $(call create-core-oat-target-rule-combination,default,,))
$(eval $(call create-core-oat-target-rule-combination,optimizing,,))
$(eval $(call create-core-oat-target-rule-combination,interpreter,,))
$(eval $(call create-core-oat-target-rule-combination,interp-ac,,))
-$(eval $(call create-core-oat-target-rule-combination,jit,,))
valgrindTARGET_CORE_IMG_OUTS :=
valgrindTARGET_CORE_OAT_OUTS :=
-$(eval $(call create-core-oat-target-rule-combination,default,valgrind,32))
$(eval $(call create-core-oat-target-rule-combination,optimizing,valgrind,32))
$(eval $(call create-core-oat-target-rule-combination,interpreter,valgrind,32))
$(eval $(call create-core-oat-target-rule-combination,interp-ac,valgrind,32))
-$(eval $(call create-core-oat-target-rule-combination,jit,valgrind,32))
valgrind-test-art-host-dex2oat-target: $(valgrindTARGET_CORE_IMG_OUTS)
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h
index 2a81804f64..1a87448e80 100644
--- a/compiler/compiled_method.h
+++ b/compiler/compiled_method.h
@@ -23,10 +23,10 @@
#include <vector>
#include "arch/instruction_set.h"
+#include "base/array_ref.h"
#include "base/bit_utils.h"
#include "base/length_prefixed_array.h"
#include "method_reference.h"
-#include "utils/array_ref.h"
namespace art {
diff --git a/compiler/debug/dwarf/headers.h b/compiler/debug/dwarf/headers.h
index 146d9fddf5..28f108423e 100644
--- a/compiler/debug/dwarf/headers.h
+++ b/compiler/debug/dwarf/headers.h
@@ -19,13 +19,13 @@
#include <cstdint>
+#include "base/array_ref.h"
#include "debug/dwarf/debug_frame_opcode_writer.h"
#include "debug/dwarf/debug_info_entry_writer.h"
#include "debug/dwarf/debug_line_opcode_writer.h"
#include "debug/dwarf/dwarf_constants.h"
#include "debug/dwarf/register.h"
#include "debug/dwarf/writer.h"
-#include "utils/array_ref.h"
namespace art {
namespace dwarf {
diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc
index 5bfdd16083..d1c10a9246 100644
--- a/compiler/debug/elf_debug_writer.cc
+++ b/compiler/debug/elf_debug_writer.cc
@@ -18,6 +18,7 @@
#include <vector>
+#include "base/array_ref.h"
#include "debug/dwarf/dwarf_constants.h"
#include "debug/elf_compilation_unit.h"
#include "debug/elf_debug_frame_writer.h"
@@ -29,7 +30,6 @@
#include "debug/method_debug_info.h"
#include "elf_builder.h"
#include "linker/vector_output_stream.h"
-#include "utils/array_ref.h"
namespace art {
namespace debug {
diff --git a/compiler/debug/elf_debug_writer.h b/compiler/debug/elf_debug_writer.h
index b0542c7ac6..07f7229827 100644
--- a/compiler/debug/elf_debug_writer.h
+++ b/compiler/debug/elf_debug_writer.h
@@ -19,11 +19,11 @@
#include <vector>
+#include "base/array_ref.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "debug/dwarf/dwarf_constants.h"
#include "elf_builder.h"
-#include "utils/array_ref.h"
namespace art {
class OatHeader;
diff --git a/compiler/driver/compiled_method_storage.h b/compiler/driver/compiled_method_storage.h
index 8674abf815..124b5a6e25 100644
--- a/compiler/driver/compiled_method_storage.h
+++ b/compiler/driver/compiled_method_storage.h
@@ -20,9 +20,9 @@
#include <iosfwd>
#include <memory>
+#include "base/array_ref.h"
#include "base/length_prefixed_array.h"
#include "base/macros.h"
-#include "utils/array_ref.h"
#include "utils/dedupe_set.h"
#include "utils/swap_space.h"
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index c197ff918e..a149c07beb 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -26,6 +26,7 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
+#include "base/array_ref.h"
#include "base/bit_vector.h"
#include "base/enums.h"
#include "base/stl_util.h"
@@ -67,7 +68,6 @@
#include "thread_pool.h"
#include "trampolines/trampoline_compiler.h"
#include "transaction.h"
-#include "utils/array_ref.h"
#include "utils/dex_cache_arrays_layout-inl.h"
#include "utils/swap_space.h"
#include "verifier/method_verifier.h"
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index fbc1edd0ea..ee21efa854 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -24,6 +24,7 @@
#include "arch/instruction_set.h"
#include "base/arena_allocator.h"
+#include "base/array_ref.h"
#include "base/bit_utils.h"
#include "base/mutex.h"
#include "base/timing_logger.h"
@@ -39,7 +40,6 @@
#include "runtime.h"
#include "safe_map.h"
#include "thread_pool.h"
-#include "utils/array_ref.h"
#include "utils/dex_cache_arrays_layout.h"
namespace art {
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index 7f2e1931d0..02831c9dc7 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -21,13 +21,13 @@
#include "arch/instruction_set.h"
#include "arch/mips/instruction_set_features_mips.h"
+#include "base/array_ref.h"
#include "base/bit_utils.h"
#include "base/casts.h"
#include "base/unix_file/fd_file.h"
#include "elf_utils.h"
#include "leb128.h"
#include "linker/error_delaying_output_stream.h"
-#include "utils/array_ref.h"
namespace art {
diff --git a/compiler/elf_writer.h b/compiler/elf_writer.h
index c9ea0083d5..f8f91029d4 100644
--- a/compiler/elf_writer.h
+++ b/compiler/elf_writer.h
@@ -22,10 +22,10 @@
#include <string>
#include <vector>
+#include "base/array_ref.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "os.h"
-#include "utils/array_ref.h"
namespace art {
diff --git a/compiler/jni/quick/calling_convention.h b/compiler/jni/quick/calling_convention.h
index 3d89146250..f541d8fa19 100644
--- a/compiler/jni/quick/calling_convention.h
+++ b/compiler/jni/quick/calling_convention.h
@@ -18,11 +18,11 @@
#define ART_COMPILER_JNI_QUICK_CALLING_CONVENTION_H_
#include "base/arena_object.h"
+#include "base/array_ref.h"
#include "base/enums.h"
#include "handle_scope.h"
#include "primitive.h"
#include "thread.h"
-#include "utils/array_ref.h"
#include "utils/managed_register.h"
namespace art {
diff --git a/compiler/linker/arm64/relative_patcher_arm64.h b/compiler/linker/arm64/relative_patcher_arm64.h
index 48ad1059b0..a4a80185dc 100644
--- a/compiler/linker/arm64/relative_patcher_arm64.h
+++ b/compiler/linker/arm64/relative_patcher_arm64.h
@@ -17,8 +17,8 @@
#ifndef ART_COMPILER_LINKER_ARM64_RELATIVE_PATCHER_ARM64_H_
#define ART_COMPILER_LINKER_ARM64_RELATIVE_PATCHER_ARM64_H_
+#include "base/array_ref.h"
#include "linker/arm/relative_patcher_arm_base.h"
-#include "utils/array_ref.h"
namespace art {
namespace linker {
diff --git a/compiler/linker/relative_patcher.h b/compiler/linker/relative_patcher.h
index a22b9f2c2d..15e955b2c6 100644
--- a/compiler/linker/relative_patcher.h
+++ b/compiler/linker/relative_patcher.h
@@ -21,9 +21,9 @@
#include "arch/instruction_set.h"
#include "arch/instruction_set_features.h"
+#include "base/array_ref.h"
#include "base/macros.h"
#include "method_reference.h"
-#include "utils/array_ref.h"
namespace art {
diff --git a/compiler/linker/relative_patcher_test.h b/compiler/linker/relative_patcher_test.h
index d21f33e46f..304b31ca84 100644
--- a/compiler/linker/relative_patcher_test.h
+++ b/compiler/linker/relative_patcher_test.h
@@ -19,6 +19,7 @@
#include "arch/instruction_set.h"
#include "arch/instruction_set_features.h"
+#include "base/array_ref.h"
#include "base/macros.h"
#include "compiled_method.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
@@ -31,7 +32,6 @@
#include "method_reference.h"
#include "oat.h"
#include "oat_quick_method_header.h"
-#include "utils/array_ref.h"
#include "vector_output_stream.h"
namespace art {
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index 77525f1a32..dd7d699eee 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -21,6 +21,7 @@
#include <cstddef>
#include <memory>
+#include "base/array_ref.h"
#include "base/dchecked_vector.h"
#include "linker/relative_patcher.h" // For linker::RelativePatcherTargetProvider.
#include "mem_map.h"
@@ -29,7 +30,6 @@
#include "oat.h"
#include "os.h"
#include "safe_map.h"
-#include "utils/array_ref.h"
namespace art {
diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h
index ce9d7e6056..38a2410f9a 100644
--- a/compiler/optimizing/code_generator_arm.h
+++ b/compiler/optimizing/code_generator_arm.h
@@ -556,10 +556,10 @@ class CodeGeneratorARM : public CodeGenerator {
// artReadBarrierForRootSlow.
void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root);
- void GenerateNop();
+ void GenerateNop() OVERRIDE;
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
+ void GenerateImplicitNullCheck(HNullCheck* instruction) OVERRIDE;
+ void GenerateExplicitNullCheck(HNullCheck* instruction) OVERRIDE;
private:
Register GetInvokeStaticOrDirectExtraParameter(HInvokeStaticOrDirect* invoke, Register temp);
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index c00ab56a4c..599185acd3 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -448,7 +448,7 @@ class TypeCheckSlowPathARM64 : public SlowPathCodeARM64 {
}
const char* GetDescription() const OVERRIDE { return "TypeCheckSlowPathARM64"; }
- bool IsFatal() const { return is_fatal_; }
+ bool IsFatal() const OVERRIDE { return is_fatal_; }
private:
const bool is_fatal_;
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index f0d79106dc..f1dc7eecb5 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -644,10 +644,10 @@ class CodeGeneratorARM64 : public CodeGenerator {
// artReadBarrierForRootSlow.
void GenerateReadBarrierForRootSlow(HInstruction* instruction, Location out, Location root);
- void GenerateNop();
+ void GenerateNop() OVERRIDE;
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
+ void GenerateImplicitNullCheck(HNullCheck* instruction) OVERRIDE;
+ void GenerateExplicitNullCheck(HNullCheck* instruction) OVERRIDE;
private:
using Uint64ToLiteralMap = ArenaSafeMap<uint64_t, vixl::aarch64::Literal<uint64_t>*>;
diff --git a/compiler/optimizing/code_generator_mips.h b/compiler/optimizing/code_generator_mips.h
index 956a466f9b..a42374f146 100644
--- a/compiler/optimizing/code_generator_mips.h
+++ b/compiler/optimizing/code_generator_mips.h
@@ -329,10 +329,10 @@ class CodeGeneratorMIPS : public CodeGenerator {
void SetupBlockedRegisters() const OVERRIDE;
- size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id);
- size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id);
- size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id);
- size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id);
+ size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
+ size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
+ size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
+ size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
void ClobberRA() {
clobbered_ra_ = true;
}
@@ -363,7 +363,7 @@ class CodeGeneratorMIPS : public CodeGenerator {
void MoveLocation(Location dst, Location src, Primitive::Type dst_type) OVERRIDE;
- void MoveConstant(Location destination, int32_t value);
+ void MoveConstant(Location destination, int32_t value) OVERRIDE;
void AddLocationAsTemp(Location location, LocationSummary* locations) OVERRIDE;
@@ -375,7 +375,7 @@ class CodeGeneratorMIPS : public CodeGenerator {
ParallelMoveResolver* GetMoveResolver() OVERRIDE { return &move_resolver_; }
- bool NeedsTwoRegisters(Primitive::Type type) const {
+ bool NeedsTwoRegisters(Primitive::Type type) const OVERRIDE {
return type == Primitive::kPrimLong;
}
@@ -403,9 +403,9 @@ class CodeGeneratorMIPS : public CodeGenerator {
UNIMPLEMENTED(FATAL) << "Not implemented on MIPS";
}
- void GenerateNop();
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
+ void GenerateNop() OVERRIDE;
+ void GenerateImplicitNullCheck(HNullCheck* instruction) OVERRIDE;
+ void GenerateExplicitNullCheck(HNullCheck* instruction) OVERRIDE;
// The PcRelativePatchInfo is used for PC-relative addressing of dex cache arrays
// and boot image strings. The only difference is the interpretation of the offset_or_index.
diff --git a/compiler/optimizing/code_generator_mips64.h b/compiler/optimizing/code_generator_mips64.h
index 3910530eb5..2dd409a224 100644
--- a/compiler/optimizing/code_generator_mips64.h
+++ b/compiler/optimizing/code_generator_mips64.h
@@ -285,10 +285,10 @@ class CodeGeneratorMIPS64 : public CodeGenerator {
void SetupBlockedRegisters() const OVERRIDE;
- size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id);
- size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id);
- size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id);
- size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id);
+ size_t SaveCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
+ size_t RestoreCoreRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
+ size_t SaveFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
+ size_t RestoreFloatingPointRegister(size_t stack_index, uint32_t reg_id) OVERRIDE;
void DumpCoreRegister(std::ostream& stream, int reg) const OVERRIDE;
void DumpFloatingPointRegister(std::ostream& stream, int reg) const OVERRIDE;
@@ -327,7 +327,7 @@ class CodeGeneratorMIPS64 : public CodeGenerator {
ParallelMoveResolver* GetMoveResolver() OVERRIDE { return &move_resolver_; }
- bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const { return false; }
+ bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE { return false; }
// Check if the desired_string_load_kind is supported. If it is, return it,
// otherwise return a fall-back kind that should be used instead.
@@ -353,9 +353,9 @@ class CodeGeneratorMIPS64 : public CodeGenerator {
UNIMPLEMENTED(FATAL) << "Not implemented on MIPS64";
}
- void GenerateNop();
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
+ void GenerateNop() OVERRIDE;
+ void GenerateImplicitNullCheck(HNullCheck* instruction) OVERRIDE;
+ void GenerateExplicitNullCheck(HNullCheck* instruction) OVERRIDE;
private:
// Labels for each block that will be compiled.
diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h
index e2250981bb..04a0a3de6a 100644
--- a/compiler/optimizing/code_generator_x86.h
+++ b/compiler/optimizing/code_generator_x86.h
@@ -561,9 +561,9 @@ class CodeGeneratorX86 : public CodeGenerator {
}
}
- void GenerateNop();
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
+ void GenerateNop() OVERRIDE;
+ void GenerateImplicitNullCheck(HNullCheck* instruction) OVERRIDE;
+ void GenerateExplicitNullCheck(HNullCheck* instruction) OVERRIDE;
// When we don't know the proper offset for the value, we use kDummy32BitOffset.
// The correct value will be inserted when processing Assembler fixups.
diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h
index d93908343d..693d0b8d26 100644
--- a/compiler/optimizing/code_generator_x86_64.h
+++ b/compiler/optimizing/code_generator_x86_64.h
@@ -533,9 +533,9 @@ class CodeGeneratorX86_64 : public CodeGenerator {
}
}
- void GenerateNop();
- void GenerateImplicitNullCheck(HNullCheck* instruction);
- void GenerateExplicitNullCheck(HNullCheck* instruction);
+ void GenerateNop() OVERRIDE;
+ void GenerateImplicitNullCheck(HNullCheck* instruction) OVERRIDE;
+ void GenerateExplicitNullCheck(HNullCheck* instruction) OVERRIDE;
// When we don't know the proper offset for the value, we use kDummy32BitOffset.
// We will fix this up in the linker later to have the right value.
diff --git a/compiler/optimizing/codegen_test.cc b/compiler/optimizing/codegen_test.cc
index d9347f604e..070cbb3894 100644
--- a/compiler/optimizing/codegen_test.cc
+++ b/compiler/optimizing/codegen_test.cc
@@ -1007,17 +1007,7 @@ TEST_F(CodegenTest, ComparisonsInt) {
}
TEST_F(CodegenTest, ComparisonsLong) {
- // TODO: make MIPS work for long
- if (kRuntimeISA == kMips || kRuntimeISA == kMips64) {
- return;
- }
-
for (CodegenTargetConfig target_config : GetTargetConfigs()) {
- if ((target_config.GetInstructionSet() == kMips) ||
- (target_config.GetInstructionSet() == kMips64)) {
- continue;
- }
-
for (int64_t i = -1; i <= 1; i++) {
for (int64_t j = -1; j <= 1; j++) {
for (int cond = kCondFirst; cond <= kCondLast; cond++) {
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index e1bde7c737..aa3f26809a 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -16,7 +16,7 @@
#include "dead_code_elimination.h"
-#include "utils/array_ref.h"
+#include "base/array_ref.h"
#include "base/bit_vector-inl.h"
#include "ssa_phi_elimination.h"
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 4c6d28f0c8..7c3ca5cefa 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -24,7 +24,9 @@
#include "base/arena_bit_vector.h"
#include "base/arena_containers.h"
#include "base/arena_object.h"
+#include "base/array_ref.h"
#include "base/stl_util.h"
+#include "base/transform_array_ref.h"
#include "dex_file.h"
#include "entrypoints/quick/quick_entrypoints_enum.h"
#include "handle.h"
@@ -35,9 +37,7 @@
#include "mirror/class.h"
#include "offsets.h"
#include "primitive.h"
-#include "utils/array_ref.h"
#include "utils/intrusive_forward_list.h"
-#include "utils/transform_array_ref.h"
namespace art {
diff --git a/compiler/optimizing/register_allocation_resolver.h b/compiler/optimizing/register_allocation_resolver.h
index a70ceae076..d48b1a0bb9 100644
--- a/compiler/optimizing/register_allocation_resolver.h
+++ b/compiler/optimizing/register_allocation_resolver.h
@@ -18,9 +18,9 @@
#define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATION_RESOLVER_H_
#include "base/arena_containers.h"
+#include "base/array_ref.h"
#include "base/value_object.h"
#include "primitive.h"
-#include "utils/array_ref.h"
namespace art {
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc
index ebdfc98554..f5ccf409fc 100644
--- a/compiler/utils/arm/assembler_thumb2.cc
+++ b/compiler/utils/arm/assembler_thumb2.cc
@@ -2018,6 +2018,45 @@ inline size_t Thumb2Assembler::Fixup::IncreaseSize(Size new_size) {
return adjustment;
}
+bool Thumb2Assembler::Fixup::IsCandidateForEmitEarly() const {
+ DCHECK(size_ == original_size_);
+ if (target_ == kUnresolved) {
+ return false;
+ }
+ // GetOffset() does not depend on current_code_size for branches, only for literals.
+ constexpr uint32_t current_code_size = 0u;
+ switch (GetSize()) {
+ case kBranch16Bit:
+ return IsInt(cond_ != AL ? 9 : 12, GetOffset(current_code_size));
+ case kBranch32Bit:
+ // We don't support conditional branches beyond +-1MiB
+ // or unconditional branches beyond +-16MiB.
+ return true;
+
+ case kCbxz16Bit:
+ return IsUint<7>(GetOffset(current_code_size));
+ case kCbxz32Bit:
+ return IsInt<9>(GetOffset(current_code_size));
+ case kCbxz48Bit:
+ // We don't support conditional branches beyond +-1MiB.
+ return true;
+
+ case kLiteral1KiB:
+ case kLiteral4KiB:
+ case kLiteral64KiB:
+ case kLiteral1MiB:
+ case kLiteralFar:
+ case kLiteralAddr1KiB:
+ case kLiteralAddr4KiB:
+ case kLiteralAddr64KiB:
+ case kLiteralAddrFar:
+ case kLongOrFPLiteral1KiB:
+ case kLongOrFPLiteral64KiB:
+ case kLongOrFPLiteralFar:
+ return false;
+ }
+}
+
uint32_t Thumb2Assembler::Fixup::AdjustSizeIfNeeded(uint32_t current_code_size) {
uint32_t old_code_size = current_code_size;
switch (GetSize()) {
@@ -3343,6 +3382,30 @@ void Thumb2Assembler::Mov(Register rd, Register rm, Condition cond) {
void Thumb2Assembler::Bind(Label* label) {
BindLabel(label, buffer_.Size());
+
+ // Try to emit some Fixups now to reduce the memory needed during the branch fixup later.
+ while (!fixups_.empty() && fixups_.back().IsCandidateForEmitEarly()) {
+ const Fixup& last_fixup = fixups_.back();
+ // Fixups are ordered by location, so the candidate can surely be emitted if it is
+ // a forward branch. If it's a backward branch, it may go over any number of other
+ // fixups. We could check for any number of emit early candidates but we want this
+ // heuristics to be quick, so check just one.
+ uint32_t target = last_fixup.GetTarget();
+ if (target < last_fixup.GetLocation() &&
+ fixups_.size() >= 2u &&
+ fixups_[fixups_.size() - 2u].GetLocation() >= target) {
+ const Fixup& prev_fixup = fixups_[fixups_.size() - 2u];
+ if (!prev_fixup.IsCandidateForEmitEarly()) {
+ break;
+ }
+ uint32_t min_target = std::min(target, prev_fixup.GetTarget());
+ if (fixups_.size() >= 3u && fixups_[fixups_.size() - 3u].GetLocation() >= min_target) {
+ break;
+ }
+ }
+ last_fixup.Emit(&buffer_, buffer_.Size());
+ fixups_.pop_back();
+ }
}
diff --git a/compiler/utils/arm/assembler_thumb2.h b/compiler/utils/arm/assembler_thumb2.h
index 13f3becb6d..917c947aa4 100644
--- a/compiler/utils/arm/assembler_thumb2.h
+++ b/compiler/utils/arm/assembler_thumb2.h
@@ -22,11 +22,11 @@
#include <vector>
#include "base/arena_containers.h"
+#include "base/array_ref.h"
#include "base/logging.h"
#include "constants_arm.h"
#include "utils/arm/managed_register_arm.h"
#include "utils/arm/assembler_arm.h"
-#include "utils/array_ref.h"
#include "offsets.h"
namespace art {
@@ -573,6 +573,10 @@ class Thumb2Assembler FINAL : public ArmAssembler {
return location_;
}
+ uint32_t GetTarget() const {
+ return target_;
+ }
+
uint32_t GetAdjustment() const {
return adjustment_;
}
@@ -592,6 +596,11 @@ class Thumb2Assembler FINAL : public ArmAssembler {
target_ = target;
}
+ // Branches with bound targets that are in range can be emitted early.
+ // However, the caller still needs to check if the branch doesn't go over
+ // another Fixup that's not ready to be emitted.
+ bool IsCandidateForEmitEarly() const;
+
// Check if the current size is OK for current location_, target_ and adjustment_.
// If not, increase the size. Return the size increase, 0 if unchanged.
// If the target if after this Fixup, also add the difference to adjustment_,
diff --git a/compiler/utils/assembler.h b/compiler/utils/assembler.h
index b616057e79..314ff8cf7a 100644
--- a/compiler/utils/assembler.h
+++ b/compiler/utils/assembler.h
@@ -24,6 +24,7 @@
#include "arm/constants_arm.h"
#include "base/arena_allocator.h"
#include "base/arena_object.h"
+#include "base/array_ref.h"
#include "base/enums.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -33,7 +34,6 @@
#include "memory_region.h"
#include "mips/constants_mips.h"
#include "offsets.h"
-#include "utils/array_ref.h"
#include "x86/constants_x86.h"
#include "x86_64/constants_x86_64.h"
diff --git a/compiler/utils/dedupe_set_test.cc b/compiler/utils/dedupe_set_test.cc
index 60a891d6a2..4c0979e0b7 100644
--- a/compiler/utils/dedupe_set_test.cc
+++ b/compiler/utils/dedupe_set_test.cc
@@ -20,10 +20,10 @@
#include <cstdio>
#include <vector>
+#include "base/array_ref.h"
#include "dedupe_set-inl.h"
#include "gtest/gtest.h"
#include "thread-inl.h"
-#include "utils/array_ref.h"
namespace art {
diff --git a/compiler/utils/jni_macro_assembler.h b/compiler/utils/jni_macro_assembler.h
index 6f45bd62db..0119ae9bfb 100644
--- a/compiler/utils/jni_macro_assembler.h
+++ b/compiler/utils/jni_macro_assembler.h
@@ -22,12 +22,12 @@
#include "arch/instruction_set.h"
#include "base/arena_allocator.h"
#include "base/arena_object.h"
+#include "base/array_ref.h"
#include "base/enums.h"
#include "base/logging.h"
#include "base/macros.h"
#include "managed_register.h"
#include "offsets.h"
-#include "utils/array_ref.h"
namespace art {
diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h
index 9738784d45..114986b3e7 100644
--- a/compiler/utils/x86/assembler_x86.h
+++ b/compiler/utils/x86/assembler_x86.h
@@ -20,6 +20,7 @@
#include <vector>
#include "base/arena_containers.h"
+#include "base/array_ref.h"
#include "base/bit_utils.h"
#include "base/enums.h"
#include "base/macros.h"
@@ -27,7 +28,6 @@
#include "globals.h"
#include "managed_register_x86.h"
#include "offsets.h"
-#include "utils/array_ref.h"
#include "utils/assembler.h"
namespace art {
diff --git a/compiler/utils/x86/jni_macro_assembler_x86.h b/compiler/utils/x86/jni_macro_assembler_x86.h
index 3f07ede865..015584cbc1 100644
--- a/compiler/utils/x86/jni_macro_assembler_x86.h
+++ b/compiler/utils/x86/jni_macro_assembler_x86.h
@@ -21,10 +21,10 @@
#include "assembler_x86.h"
#include "base/arena_containers.h"
+#include "base/array_ref.h"
#include "base/enums.h"
#include "base/macros.h"
#include "offsets.h"
-#include "utils/array_ref.h"
#include "utils/jni_macro_assembler.h"
namespace art {
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index fdd3aa9317..acad86d161 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -20,13 +20,13 @@
#include <vector>
#include "base/arena_containers.h"
+#include "base/array_ref.h"
#include "base/bit_utils.h"
#include "base/macros.h"
#include "constants_x86_64.h"
#include "globals.h"
#include "managed_register_x86_64.h"
#include "offsets.h"
-#include "utils/array_ref.h"
#include "utils/assembler.h"
#include "utils/jni_macro_assembler.h"
diff --git a/compiler/utils/x86_64/jni_macro_assembler_x86_64.h b/compiler/utils/x86_64/jni_macro_assembler_x86_64.h
index cc4e57c999..9107f3c422 100644
--- a/compiler/utils/x86_64/jni_macro_assembler_x86_64.h
+++ b/compiler/utils/x86_64/jni_macro_assembler_x86_64.h
@@ -21,10 +21,10 @@
#include "assembler_x86_64.h"
#include "base/arena_containers.h"
+#include "base/array_ref.h"
#include "base/enums.h"
#include "base/macros.h"
#include "offsets.h"
-#include "utils/array_ref.h"
#include "utils/assembler.h"
#include "utils/jni_macro_assembler.h"
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 1dd91321c5..1296bcf525 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -2782,6 +2782,8 @@ static int dex2oat(int argc, char** argv) {
return EXIT_FAILURE;
}
+ VLOG(compiler) << "Running dex2oat (parent PID = " << getppid() << ")";
+
bool result;
if (dex2oat->IsImage()) {
result = CompileImage(*dex2oat);
diff --git a/dexlist/dexlist_test.cc b/dexlist/dexlist_test.cc
index 9a65ba647c..da1dd7fd89 100644
--- a/dexlist/dexlist_test.cc
+++ b/dexlist/dexlist_test.cc
@@ -43,11 +43,7 @@ class DexListTest : public CommonRuntimeTest {
// Runs test with given arguments.
bool Exec(const std::vector<std::string>& args, std::string* error_msg) {
std::string file_path = GetTestAndroidRoot();
- if (IsHost()) {
- file_path += "/bin/dexlist";
- } else {
- file_path += "/xbin/dexlist";
- }
+ file_path += "/bin/dexlist";
EXPECT_TRUE(OS::FileExists(file_path.c_str())) << file_path << " should be a valid file path";
std::vector<std::string> exec_argv = { file_path };
exec_argv.insert(exec_argv.end(), args.begin(), args.end());
diff --git a/compiler/utils/array_ref.h b/runtime/base/array_ref.h
index 8dc9ab4a5e..00b9bad6bf 100644
--- a/compiler/utils/array_ref.h
+++ b/runtime/base/array_ref.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ART_COMPILER_UTILS_ARRAY_REF_H_
-#define ART_COMPILER_UTILS_ARRAY_REF_H_
+#ifndef ART_RUNTIME_BASE_ARRAY_REF_H_
+#define ART_RUNTIME_BASE_ARRAY_REF_H_
#include <type_traits>
#include <vector>
@@ -197,4 +197,4 @@ bool operator!=(const ArrayRef<T>& lhs, const ArrayRef<T>& rhs) {
} // namespace art
-#endif // ART_COMPILER_UTILS_ARRAY_REF_H_
+#endif // ART_RUNTIME_BASE_ARRAY_REF_H_
diff --git a/compiler/utils/transform_array_ref.h b/runtime/base/transform_array_ref.h
index a6da34fb40..a4e0bc27ed 100644
--- a/compiler/utils/transform_array_ref.h
+++ b/runtime/base/transform_array_ref.h
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-#ifndef ART_COMPILER_UTILS_TRANSFORM_ARRAY_REF_H_
-#define ART_COMPILER_UTILS_TRANSFORM_ARRAY_REF_H_
+#ifndef ART_RUNTIME_BASE_TRANSFORM_ARRAY_REF_H_
+#define ART_RUNTIME_BASE_TRANSFORM_ARRAY_REF_H_
#include <type_traits>
-#include "utils/array_ref.h"
-#include "utils/transform_iterator.h"
+#include "base/array_ref.h"
+#include "base/transform_iterator.h"
namespace art {
@@ -193,4 +193,4 @@ TransformArrayRef<const typename Container::value_type, Function> MakeTransformA
} // namespace art
-#endif // ART_COMPILER_UTILS_TRANSFORM_ARRAY_REF_H_
+#endif // ART_RUNTIME_BASE_TRANSFORM_ARRAY_REF_H_
diff --git a/compiler/utils/transform_array_ref_test.cc b/runtime/base/transform_array_ref_test.cc
index 8d71fd7179..494dbb29aa 100644
--- a/compiler/utils/transform_array_ref_test.cc
+++ b/runtime/base/transform_array_ref_test.cc
@@ -19,7 +19,7 @@
#include "gtest/gtest.h"
-#include "utils/transform_array_ref.h"
+#include "base/transform_array_ref.h"
namespace art {
diff --git a/compiler/utils/transform_iterator.h b/runtime/base/transform_iterator.h
index 3bc9046408..9c8f822b71 100644
--- a/compiler/utils/transform_iterator.h
+++ b/runtime/base/transform_iterator.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ART_COMPILER_UTILS_TRANSFORM_ITERATOR_H_
-#define ART_COMPILER_UTILS_TRANSFORM_ITERATOR_H_
+#ifndef ART_RUNTIME_BASE_TRANSFORM_ITERATOR_H_
+#define ART_RUNTIME_BASE_TRANSFORM_ITERATOR_H_
#include <iterator>
#include <type_traits>
@@ -175,4 +175,4 @@ auto MakeTransformRange(BaseRange& range, Function f) {
} // namespace art
-#endif // ART_COMPILER_UTILS_TRANSFORM_ITERATOR_H_
+#endif // ART_RUNTIME_BASE_TRANSFORM_ITERATOR_H_
diff --git a/compiler/utils/transform_iterator_test.cc b/runtime/base/transform_iterator_test.cc
index 57ff0a62ac..a85dda8958 100644
--- a/compiler/utils/transform_iterator_test.cc
+++ b/runtime/base/transform_iterator_test.cc
@@ -22,7 +22,7 @@
#include "gtest/gtest.h"
-#include "utils/transform_iterator.h"
+#include "base/transform_iterator.h"
namespace art {
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index dba0a81125..5bc4e88107 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -591,9 +591,9 @@ std::string CommonRuntimeTestImpl::GetCoreFileLocation(const char* suffix) {
if (IsHost()) {
const char* host_dir = getenv("ANDROID_HOST_OUT");
CHECK(host_dir != nullptr);
- location = StringPrintf("%s/framework/core.%s", host_dir, suffix);
+ location = StringPrintf("%s/framework/core-npic.%s", host_dir, suffix);
} else {
- location = StringPrintf("/data/art-test/core.%s", suffix);
+ location = StringPrintf("/data/art-test/core-npic.%s", suffix);
}
return location;
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index d6957fc39c..e12fd285d4 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -153,17 +153,17 @@ JNI_TYPES := checkjni
ifeq ($(ART_TEST_JNI_FORCECOPY),true)
JNI_TYPES += forcecopy
endif
-IMAGE_TYPES := image
+IMAGE_TYPES := picimage
ifeq ($(ART_TEST_RUN_TEST_NO_IMAGE),true)
IMAGE_TYPES += no-image
endif
ifeq ($(ART_TEST_RUN_TEST_MULTI_IMAGE),true)
- IMAGE_TYPES := multiimage
+ IMAGE_TYPES := multipicimage
endif
-ifeq ($(ART_TEST_PIC_IMAGE),true)
- IMAGE_TYPES += picimage
+ifeq ($(ART_TEST_NPIC_IMAGE),true)
+ IMAGE_TYPES += npicimage
ifeq ($(ART_TEST_RUN_TEST_MULTI_IMAGE),true)
- IMAGE_TYPES := multipicimage
+ IMAGE_TYPES := multinpicimage
endif
endif
PICTEST_TYPES := npictest
@@ -896,6 +896,11 @@ define define-test-art-run-test
ifeq ($(4),regalloc_gc)
# Graph coloring tests share the image_suffix with optimizing tests.
image_suffix := optimizing
+ else
+ ifeq ($(4),jit)
+ # JIT tests share the image_suffix with interpreter tests.
+ image_suffix := interpreter
+ endif
endif
ifeq ($(9),no-image)
test_groups += ART_RUN_TEST_$$(uc_host_or_target)_NO_IMAGE_RULES
@@ -907,8 +912,9 @@ define define-test-art-run-test
prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_no-pic_$(13))
endif
else
- ifeq ($(9),image)
+ ifeq ($(9),npicimage)
test_groups += ART_RUN_TEST_$$(uc_host_or_target)_IMAGE_RULES
+ run_test_options += --npic-image
# Add the core dependency.
ifeq ($(1),host)
prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_no-pic_$(13))
@@ -918,16 +924,15 @@ define define-test-art-run-test
else
ifeq ($(9),picimage)
test_groups += ART_RUN_TEST_$$(uc_host_or_target)_PICIMAGE_RULES
- run_test_options += --pic-image
ifeq ($(1),host)
prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_pic_$(13))
else
prereq_rule += $$(TARGET_CORE_IMAGE_$$(image_suffix)_pic_$(13))
endif
else
- ifeq ($(9),multiimage)
+ ifeq ($(9),multinpicimage)
test_groups += ART_RUN_TEST_$$(uc_host_or_target)_IMAGE_RULES
- run_test_options += --multi-image
+ run_test_options += --npic-image --multi-image
ifeq ($(1),host)
prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_no-pic_multi_$(13))
else
@@ -936,7 +941,7 @@ define define-test-art-run-test
else
ifeq ($(9),multipicimage)
test_groups += ART_RUN_TEST_$$(uc_host_or_target)_PICIMAGE_RULES
- run_test_options += --pic-image --multi-image
+ run_test_options += --multi-image
ifeq ($(1),host)
prereq_rule += $$(HOST_CORE_IMAGE_$$(image_suffix)_pic_multi_$(13))
else
diff --git a/test/run-test b/test/run-test
index 4c294203b3..8fb2adf445 100755
--- a/test/run-test
+++ b/test/run-test
@@ -132,7 +132,7 @@ multi_image_suffix=""
android_root="/system"
# By default we will use optimizing.
image_args=""
-image_suffix="-optimizing"
+image_suffix=""
while true; do
if [ "x$1" = "x--host" ]; then
@@ -180,8 +180,8 @@ while true; do
elif [ "x$1" = "x--no-image" ]; then
have_image="no"
shift
- elif [ "x$1" = "x--pic-image" ]; then
- pic_image_suffix="-pic"
+ elif [ "x$1" = "x--npic-image" ]; then
+ pic_image_suffix="-npic"
shift
elif [ "x$1" = "x--multi-image" ]; then
multi_image_suffix="-multi"
@@ -258,11 +258,10 @@ while true; do
shift
elif [ "x$1" = "x--jit" ]; then
image_args="--jit"
- image_suffix="-jit"
+ image_suffix="-interpreter"
shift
elif [ "x$1" = "x--optimizing" ]; then
image_args="-Xcompiler-option --compiler-backend=Optimizing"
- image_suffix="-optimizing"
shift
elif [ "x$1" = "x--no-verify" ]; then
run_args="${run_args} --no-verify"
@@ -608,8 +607,8 @@ if [ "$usage" = "yes" ]; then
echo " --dex2oat-swap Use a dex2oat swap file."
echo " --instruction-set-features [string]"
echo " Set instruction-set-features for compilation."
- echo " --pic-image Use an image compiled with position independent code for the"
- echo " boot class path."
+ echo " --npic-image Use an image compiled with non-position independent code "
+ echo " for the boot class path."
echo " --multi-image Use a set of images compiled with dex2oat multi-image for"
echo " the boot class path."
echo " --pic-test Compile the test code position independent."
@@ -678,7 +677,7 @@ function arch_supports_read_barrier() {
# Tests named '<number>-checker-*' will also have their CFGs verified with
# Checker when compiled with Optimizing on host.
if [[ "$TEST_NAME" =~ ^[0-9]+-checker- ]]; then
- if [ "$runtime" = "art" -a "$image_suffix" = "-optimizing" -a "$USE_JACK" = "true" ]; then
+ if [ "$runtime" = "art" -a "$image_suffix" = "" -a "$USE_JACK" = "true" ]; then
# Optimizing has read barrier support for certain architectures
# only. On other architectures, compiling is disabled when read
# barriers are enabled, meaning that we do not produce a CFG file
diff --git a/tools/art b/tools/art
index 1a3bba77db..1394a460d1 100644
--- a/tools/art
+++ b/tools/art
@@ -100,7 +100,7 @@ ANDROID_DATA=$ANDROID_DATA \
$invoke_with $ANDROID_ROOT/bin/$DALVIKVM $lib \
-XXlib:$LIBART \
-Xnorelocate \
- -Ximage:$ANDROID_ROOT/framework/core-optimizing-pic.art \
+ -Ximage:$ANDROID_ROOT/framework/core.art \
$DEBUG_OPTION \
"$@"
diff --git a/tools/bisection_search/README.md b/tools/bisection_search/README.md
index a7485c2bb5..64ccb206c4 100644
--- a/tools/bisection_search/README.md
+++ b/tools/bisection_search/README.md
@@ -15,29 +15,54 @@ incorrect output. Prints Mi and Pj.
How to run Bisection Bug Search
===============================
+There are two supported invocation modes:
+
+1. Regular invocation, dalvikvm command is constructed internally:
+
+ ./bisection_search.py -cp classes.dex --expected-output out_int --class Test
+
+2. Raw-cmd invocation, dalvikvm command is accepted as an argument. The command
+ has to start with an executable.
+
+ Extra dalvikvm arguments will be placed on second position in the command
+ by default. {ARGS} tag can be used to specify a custom position.
+
+ ./bisection_search.py --raw-cmd='run.sh -cp classes.dex Test' --expected-retcode SUCCESS
+ ./bisection_search.py --raw-cmd='/bin/sh art {ARGS} -cp classes.dex Test' --expected-retcode SUCCESS
+
+Help:
+
bisection_search.py [-h] [-cp CLASSPATH] [--class CLASSNAME] [--lib LIB]
- [--dalvikvm-option [OPT [OPT ...]]] [--arg [ARG [ARG ...]]]
- [--image IMAGE] [--raw-cmd RAW_CMD]
- [--64] [--device] [--expected-output EXPECTED_OUTPUT]
- [--check-script CHECK_SCRIPT] [--verbose]
+ [--dalvikvm-option [OPT [OPT ...]]] [--arg [ARG [ARG ...]]]
+ [--image IMAGE] [--raw-cmd RAW_CMD]
+ [--64] [--device] [--device-serial DEVICE_SERIAL]
+ [--expected-output EXPECTED_OUTPUT]
+ [--expected-retcode {SUCCESS,TIMEOUT,ERROR}]
+ [--check-script CHECK_SCRIPT] [--logfile LOGFILE] [--cleanup]
+ [--timeout TIMEOUT] [--verbose]
Tool for finding compiler bugs. Either --raw-cmd or both -cp and --class are required.
optional arguments:
- -h, --help show this help message and exit
+ -h, --help show this help message and exit
dalvikvm command options:
- -cp CLASSPATH, --classpath CLASSPATH classpath
- --class CLASSNAME name of main class
- --lib LIB lib to use, default: libart.so
- --dalvikvm-option [OPT [OPT ...]] additional dalvikvm option
- --arg [ARG [ARG ...]] argument passed to test
- --image IMAGE path to image
- --raw-cmd RAW_CMD bisect with this command, ignore other command options
+ -cp CLASSPATH, --classpath CLASSPATH classpath
+ --class CLASSNAME name of main class
+ --lib LIB lib to use, default: libart.so
+ --dalvikvm-option [OPT [OPT ...]] additional dalvikvm option
+ --arg [ARG [ARG ...]] argument passed to test
+ --image IMAGE path to image
+ --raw-cmd RAW_CMD bisect with this command, ignore other command options
bisection options:
- --64 x64 mode
- --device run on device
- --expected-output EXPECTED_OUTPUT file containing expected output
- --check-script CHECK_SCRIPT script comparing output and expected output
- --verbose enable verbose output
+ --64 x64 mode
+ --device run on device
+ --device-serial DEVICE_SERIAL device serial number, implies --device
+ --expected-output EXPECTED_OUTPUT file containing expected output
+ --expected-retcode {SUCCESS,TIMEOUT,ERROR} expected normalized return code
+ --check-script CHECK_SCRIPT script comparing output and expected output
+ --logfile LOGFILE custom logfile location
+ --cleanup clean up after bisecting
+ --timeout TIMEOUT if timeout seconds pass assume test failed
+ --verbose enable verbose output
diff --git a/tools/bisection_search/bisection_search.py b/tools/bisection_search/bisection_search.py
index 110ef82433..0d36aa4622 100755
--- a/tools/bisection_search/bisection_search.py
+++ b/tools/bisection_search/bisection_search.py
@@ -34,6 +34,7 @@ from common import DeviceTestEnv
from common import FatalError
from common import GetEnvVariableOrError
from common import HostTestEnv
+from common import RetCode
# Passes that are never disabled during search process because disabling them
@@ -51,6 +52,10 @@ MANDATORY_PASSES = ['dex_cache_array_fixups_arm',
NON_PASSES = ['builder', 'prepare_for_register_allocation',
'liveness', 'register']
+# If present in raw cmd, this tag will be replaced with runtime arguments
+# controlling the bisection search. Otherwise arguments will be placed on second
+# position in the command.
+RAW_CMD_RUNTIME_ARGS_TAG = '{ARGS}'
class Dex2OatWrapperTestable(object):
"""Class representing a testable compilation.
@@ -58,21 +63,29 @@ class Dex2OatWrapperTestable(object):
Accepts filters on compiled methods and optimization passes.
"""
- def __init__(self, base_cmd, test_env, output_checker=None, verbose=False):
+ def __init__(self, base_cmd, test_env, expected_retcode=None,
+ output_checker=None, verbose=False):
"""Constructor.
Args:
base_cmd: list of strings, base command to run.
test_env: ITestEnv.
+ expected_retcode: RetCode, expected normalized return code.
output_checker: IOutputCheck, output checker.
verbose: bool, enable verbose output.
"""
self._base_cmd = base_cmd
self._test_env = test_env
+ self._expected_retcode = expected_retcode
self._output_checker = output_checker
self._compiled_methods_path = self._test_env.CreateFile('compiled_methods')
self._passes_to_run_path = self._test_env.CreateFile('run_passes')
self._verbose = verbose
+ if RAW_CMD_RUNTIME_ARGS_TAG in self._base_cmd:
+ self._arguments_position = self._base_cmd.index(RAW_CMD_RUNTIME_ARGS_TAG)
+ self._base_cmd.pop(self._arguments_position)
+ else:
+ self._arguments_position = 1
def Test(self, compiled_methods, passes_to_run=None):
"""Tests compilation with compiled_methods and run_passes switches active.
@@ -95,8 +108,11 @@ class Dex2OatWrapperTestable(object):
verbose_compiler=False)
(output, ret_code) = self._test_env.RunCommand(
cmd, {'ANDROID_LOG_TAGS': '*:e'})
- res = ((self._output_checker is None and ret_code == 0)
- or self._output_checker.Check(output))
+ res = True
+ if self._expected_retcode:
+ res = self._expected_retcode == ret_code
+ if self._output_checker:
+ res = res and self._output_checker.Check(output)
if self._verbose:
print('Test passed: {0}.'.format(res))
return res
@@ -142,8 +158,8 @@ class Dex2OatWrapperTestable(object):
def _PrepareCmd(self, compiled_methods=None, passes_to_run=None,
verbose_compiler=False):
"""Prepare command to run."""
- cmd = [self._base_cmd[0]]
- # insert additional arguments
+ cmd = self._base_cmd[0:self._arguments_position]
+ # insert additional arguments before the first argument
if compiled_methods is not None:
self._test_env.WriteLines(self._compiled_methods_path, compiled_methods)
cmd += ['-Xcompiler-option', '--compiled-methods={0}'.format(
@@ -155,7 +171,7 @@ class Dex2OatWrapperTestable(object):
if verbose_compiler:
cmd += ['-Xcompiler-option', '--runtime-arg', '-Xcompiler-option',
'-verbose:compiler', '-Xcompiler-option', '-j1']
- cmd += self._base_cmd[1:]
+ cmd += self._base_cmd[self._arguments_position:]
return cmd
@@ -299,7 +315,7 @@ def PrepareParser():
command_opts.add_argument('-cp', '--classpath', type=str, help='classpath')
command_opts.add_argument('--class', dest='classname', type=str,
help='name of main class')
- command_opts.add_argument('--lib', dest='lib', type=str, default='libart.so',
+ command_opts.add_argument('--lib', type=str, default='libart.so',
help='lib to use, default: libart.so')
command_opts.add_argument('--dalvikvm-option', dest='dalvikvm_opts',
metavar='OPT', nargs='*', default=[],
@@ -307,7 +323,7 @@ def PrepareParser():
command_opts.add_argument('--arg', dest='test_args', nargs='*', default=[],
metavar='ARG', help='argument passed to test')
command_opts.add_argument('--image', type=str, help='path to image')
- command_opts.add_argument('--raw-cmd', dest='raw_cmd', type=str,
+ command_opts.add_argument('--raw-cmd', type=str,
help='bisect with this command, ignore other '
'command options')
bisection_opts = parser.add_argument_group('bisection options')
@@ -315,11 +331,22 @@ def PrepareParser():
default=False, help='x64 mode')
bisection_opts.add_argument(
'--device', action='store_true', default=False, help='run on device')
+ bisection_opts.add_argument(
+ '--device-serial', help='device serial number, implies --device')
bisection_opts.add_argument('--expected-output', type=str,
help='file containing expected output')
bisection_opts.add_argument(
- '--check-script', dest='check_script', type=str,
+ '--expected-retcode', type=str, help='expected normalized return code',
+ choices=[RetCode.SUCCESS.name, RetCode.TIMEOUT.name, RetCode.ERROR.name])
+ bisection_opts.add_argument(
+ '--check-script', type=str,
help='script comparing output and expected output')
+ bisection_opts.add_argument(
+ '--logfile', type=str, help='custom logfile location')
+ bisection_opts.add_argument('--cleanup', action='store_true',
+ default=False, help='clean up after bisecting')
+ bisection_opts.add_argument('--timeout', type=int, default=60,
+ help='if timeout seconds pass assume test failed')
bisection_opts.add_argument('--verbose', action='store_true',
default=False, help='enable verbose output')
return parser
@@ -351,15 +378,24 @@ def main():
args = parser.parse_args()
if not args.raw_cmd and (not args.classpath or not args.classname):
parser.error('Either --raw-cmd or both -cp and --class are required')
+ if args.device_serial:
+ args.device = True
+ if args.expected_retcode:
+ args.expected_retcode = RetCode[args.expected_retcode]
+ if not args.expected_retcode and not args.check_script:
+ args.expected_retcode = RetCode.SUCCESS
# Prepare environment
classpath = args.classpath
if args.device:
- test_env = DeviceTestEnv()
+ test_env = DeviceTestEnv(
+ 'bisection_search_', args.cleanup, args.logfile, args.timeout,
+ args.device_serial)
if classpath:
classpath = test_env.PushClasspath(classpath)
else:
- test_env = HostTestEnv(args.x64)
+ test_env = HostTestEnv(
+ 'bisection_search_', args.cleanup, args.logfile, args.timeout, args.x64)
base_cmd = PrepareBaseCommand(args, classpath)
output_checker = None
if args.expected_output:
@@ -372,11 +408,11 @@ def main():
# Perform the search
try:
- testable = Dex2OatWrapperTestable(base_cmd, test_env, output_checker,
- args.verbose)
+ testable = Dex2OatWrapperTestable(base_cmd, test_env, args.expected_retcode,
+ output_checker, args.verbose)
(method, opt_pass) = BugSearch(testable)
except Exception as e:
- print('Error. Refer to logfile: {0}'.format(test_env.logfile.name))
+ print('Error occurred.\nLogfile: {0}'.format(test_env.logfile.name))
test_env.logfile.write('Exception: {0}\n'.format(e))
raise
diff --git a/tools/bisection_search/common.py b/tools/bisection_search/common.py
index d5029bb970..b69b60668b 100755
--- a/tools/bisection_search/common.py
+++ b/tools/bisection_search/common.py
@@ -18,7 +18,9 @@
import abc
import os
+import signal
import shlex
+import shutil
from subprocess import check_call
from subprocess import PIPE
@@ -29,6 +31,9 @@ from subprocess import TimeoutExpired
from tempfile import mkdtemp
from tempfile import NamedTemporaryFile
+from enum import Enum
+from enum import unique
+
# Temporary directory path on device.
DEVICE_TMP_PATH = '/data/local/tmp'
@@ -36,6 +41,16 @@ DEVICE_TMP_PATH = '/data/local/tmp'
DALVIK_CACHE_ARCHS = ['arm', 'arm64', 'x86', 'x86_64']
+@unique
+class RetCode(Enum):
+ """Enum representing normalized return codes."""
+ SUCCESS = 0
+ TIMEOUT = 1
+ ERROR = 2
+ NOTCOMPILED = 3
+ NOTRUN = 4
+
+
def GetEnvVariableOrError(variable_name):
"""Gets value of an environmental variable.
@@ -70,6 +85,37 @@ def _DexArchCachePaths(android_data_path):
for arch in DALVIK_CACHE_ARCHS)
+def RunCommandForOutput(cmd, env, stdout, stderr, timeout=60):
+ """Runs command piping output to files, stderr or stdout.
+
+ Args:
+ cmd: list of strings, command to run.
+ env: shell environment to run the command with.
+ stdout: file handle or one of Subprocess.PIPE, Subprocess.STDOUT,
+ Subprocess.DEVNULL, see Popen.
+ stderr: file handle or one of Subprocess.PIPE, Subprocess.STDOUT,
+ Subprocess.DEVNULL, see Popen.
+ timeout: int, timeout in seconds.
+
+ Returns:
+ tuple (string, string, RetCode) stdout output, stderr output, normalized
+ return code.
+ """
+ proc = Popen(cmd, stdout=stdout, stderr=stderr, env=env,
+ universal_newlines=True, start_new_session=True)
+ try:
+ (output, stderr_output) = proc.communicate(timeout=timeout)
+ if proc.returncode == 0:
+ retcode = RetCode.SUCCESS
+ else:
+ retcode = RetCode.ERROR
+ except TimeoutExpired:
+ os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
+ (output, stderr_output) = proc.communicate()
+ retcode = RetCode.TIMEOUT
+ return (output, stderr_output, retcode)
+
+
def _RunCommandForOutputAndLog(cmd, env, logfile, timeout=60):
"""Runs command and logs its output. Returns the output.
@@ -77,28 +123,19 @@ def _RunCommandForOutputAndLog(cmd, env, logfile, timeout=60):
cmd: list of strings, command to run.
env: shell environment to run the command with.
logfile: file handle to logfile.
- timeout: int, timeout in seconds
+ timeout: int, timeout in seconds.
Returns:
- tuple (string, string, int) stdout output, stderr output, return code.
+ tuple (string, string, RetCode) stdout output, stderr output, normalized
+ return code.
"""
- proc = Popen(cmd, stderr=STDOUT, stdout=PIPE, env=env,
- universal_newlines=True)
- timeouted = False
- try:
- (output, _) = proc.communicate(timeout=timeout)
- except TimeoutExpired:
- timeouted = True
- proc.kill()
- (output, _) = proc.communicate()
+ (output, _, retcode) = RunCommandForOutput(cmd, env, PIPE, STDOUT, timeout)
logfile.write('Command:\n{0}\n{1}\nReturn code: {2}\n'.format(
- _CommandListToCommandString(cmd), output,
- 'TIMEOUT' if timeouted else proc.returncode))
- ret_code = 1 if timeouted else proc.returncode
- return (output, ret_code)
+ CommandListToCommandString(cmd), output, retcode))
+ return (output, retcode)
-def _CommandListToCommandString(cmd):
+def CommandListToCommandString(cmd):
"""Converts shell command represented as list of strings to a single string.
Each element of the list is wrapped in double quotes.
@@ -109,7 +146,7 @@ def _CommandListToCommandString(cmd):
Returns:
string, shell command.
"""
- return ' '.join(['"{0}"'.format(segment) for segment in cmd])
+ return ' '.join([shlex.quote(segment) for segment in cmd])
class FatalError(Exception):
@@ -175,14 +212,24 @@ class HostTestEnv(ITestEnv):
For methods documentation see base class.
"""
- def __init__(self, x64):
+ def __init__(self, directory_prefix, cleanup=True, logfile_path=None,
+ timeout=60, x64=False):
"""Constructor.
Args:
+ directory_prefix: string, prefix for environment directory name.
+ cleanup: boolean, if True remove test directory in destructor.
+ logfile_path: string, can be used to specify custom logfile location.
+ timeout: int, seconds, time to wait for single test run to finish.
x64: boolean, whether to setup in x64 mode.
"""
- self._env_path = mkdtemp(dir='/tmp/', prefix='bisection_search_')
- self._logfile = open('{0}/log'.format(self._env_path), 'w+')
+ self._cleanup = cleanup
+ self._timeout = timeout
+ self._env_path = mkdtemp(dir='/tmp/', prefix=directory_prefix)
+ if logfile_path is None:
+ self._logfile = open('{0}/log'.format(self._env_path), 'w+')
+ else:
+ self._logfile = open(logfile_path, 'w+')
os.mkdir('{0}/dalvik-cache'.format(self._env_path))
for arch_cache_path in _DexArchCachePaths(self._env_path):
os.mkdir(arch_cache_path)
@@ -199,6 +246,10 @@ class HostTestEnv(ITestEnv):
# Using dlopen requires load bias on the host.
self._shell_env['LD_USE_LOAD_BIAS'] = '1'
+ def __del__(self):
+ if self._cleanup:
+ shutil.rmtree(self._env_path)
+
def CreateFile(self, name=None):
if name is None:
f = NamedTemporaryFile(dir=self._env_path, delete=False)
@@ -217,7 +268,7 @@ class HostTestEnv(ITestEnv):
self._EmptyDexCache()
env = self._shell_env.copy()
env.update(env_updates)
- return _RunCommandForOutputAndLog(cmd, env, self._logfile)
+ return _RunCommandForOutputAndLog(cmd, env, self._logfile, self._timeout)
@property
def logfile(self):
@@ -239,16 +290,28 @@ class HostTestEnv(ITestEnv):
class DeviceTestEnv(ITestEnv):
"""Device test environment. Concrete implementation of ITestEnv.
- Makes use of HostTestEnv to maintain a test directory on host. Creates an
- on device test directory which is kept in sync with the host one.
-
For methods documentation see base class.
"""
- def __init__(self):
- """Constructor."""
- self._host_env_path = mkdtemp(dir='/tmp/', prefix='bisection_search_')
- self._logfile = open('{0}/log'.format(self._host_env_path), 'w+')
+ def __init__(self, directory_prefix, cleanup=True, logfile_path=None,
+ timeout=60, specific_device=None):
+ """Constructor.
+
+ Args:
+ directory_prefix: string, prefix for environment directory name.
+ cleanup: boolean, if True remove test directory in destructor.
+ logfile_path: string, can be used to specify custom logfile location.
+ timeout: int, seconds, time to wait for single test run to finish.
+ specific_device: string, serial number of device to use.
+ """
+ self._cleanup = cleanup
+ self._timeout = timeout
+ self._specific_device = specific_device
+ self._host_env_path = mkdtemp(dir='/tmp/', prefix=directory_prefix)
+ if logfile_path is None:
+ self._logfile = open('{0}/log'.format(self._host_env_path), 'w+')
+ else:
+ self._logfile = open(logfile_path, 'w+')
self._device_env_path = '{0}/{1}'.format(
DEVICE_TMP_PATH, os.path.basename(self._host_env_path))
self._shell_env = os.environ.copy()
@@ -257,6 +320,13 @@ class DeviceTestEnv(ITestEnv):
for arch_cache_path in _DexArchCachePaths(self._device_env_path):
self._AdbMkdir(arch_cache_path)
+ def __del__(self):
+ if self._cleanup:
+ shutil.rmtree(self._host_env_path)
+ check_call(shlex.split(
+ 'adb shell if [ -d "{0}" ]; then rm -rf "{0}"; fi'
+ .format(self._device_env_path)))
+
def CreateFile(self, name=None):
with NamedTemporaryFile(mode='w') as temp_file:
self._AdbPush(temp_file.name, self._device_env_path)
@@ -279,11 +349,18 @@ class DeviceTestEnv(ITestEnv):
env_updates['ANDROID_DATA'] = self._device_env_path
env_updates_cmd = ' '.join(['{0}={1}'.format(var, val) for var, val
in env_updates.items()])
- cmd = _CommandListToCommandString(cmd)
- cmd = ('adb shell "logcat -c && {0} {1} ; logcat -d -s dex2oat:* dex2oatd:*'
- '| grep -v "^---------" 1>&2"').format(env_updates_cmd, cmd)
- return _RunCommandForOutputAndLog(
- shlex.split(cmd), self._shell_env, self._logfile)
+ cmd = CommandListToCommandString(cmd)
+ adb = 'adb'
+ if self._specific_device:
+ adb += ' -s ' + self._specific_device
+ cmd = '{0} shell "logcat -c && {1} {2}"'.format(
+ adb, env_updates_cmd, cmd)
+ (output, retcode) = _RunCommandForOutputAndLog(
+ shlex.split(cmd), self._shell_env, self._logfile, self._timeout)
+ logcat_cmd = 'adb shell "logcat -d -s -b main dex2oat:* dex2oatd:*"'
+ (err_output, _) = _RunCommandForOutputAndLog(
+ shlex.split(logcat_cmd), self._shell_env, self._logfile)
+ return (output + err_output, retcode)
@property
def logfile(self):
diff --git a/tools/javafuzz/run_java_fuzz_test.py b/tools/javafuzz/run_java_fuzz_test.py
index 5f527b804b..085471fc39 100755
--- a/tools/javafuzz/run_java_fuzz_test.py
+++ b/tools/javafuzz/run_java_fuzz_test.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python2
+#!/usr/bin/env python3.4
#
# Copyright (C) 2016 The Android Open Source Project
#
@@ -16,68 +16,71 @@
import abc
import argparse
+import filecmp
+
+from glob import glob
+
+import os
+import shlex
+import shutil
import subprocess
import sys
-import os
from tempfile import mkdtemp
-from threading import Timer
-# Normalized return codes.
-EXIT_SUCCESS = 0
-EXIT_TIMEOUT = 1
-EXIT_NOTCOMPILED = 2
-EXIT_NOTRUN = 3
+
+sys.path.append(os.path.dirname(os.path.dirname(__file__)))
+
+from bisection_search.common import RetCode
+from bisection_search.common import CommandListToCommandString
+from bisection_search.common import FatalError
+from bisection_search.common import GetEnvVariableOrError
+from bisection_search.common import RunCommandForOutput
+from bisection_search.common import DeviceTestEnv
+
+# Return codes supported by bisection bug search.
+BISECTABLE_RET_CODES = (RetCode.SUCCESS, RetCode.ERROR, RetCode.TIMEOUT)
#
# Utility methods.
#
-def RunCommand(cmd, args, out, err, timeout = 5):
+
+def RunCommand(cmd, out, err, timeout=5):
"""Executes a command, and returns its return code.
Args:
- cmd: string, a command to execute
- args: string, arguments to pass to command (or None)
+ cmd: list of strings, a command to execute
out: string, file name to open for stdout (or None)
err: string, file name to open for stderr (or None)
timeout: int, time out in seconds
Returns:
- return code of running command (forced EXIT_TIMEOUT on timeout)
+ RetCode, return code of running command (forced RetCode.TIMEOUT
+ on timeout)
"""
- cmd = 'exec ' + cmd # preserve pid
- if args != None:
- cmd = cmd + ' ' + args
- outf = None
- if out != None:
+ devnull = subprocess.DEVNULL
+ outf = devnull
+ if out is not None:
outf = open(out, mode='w')
- errf = None
- if err != None:
+ errf = devnull
+ if err is not None:
errf = open(err, mode='w')
- proc = subprocess.Popen(cmd, stdout=outf, stderr=errf, shell=True)
- timer = Timer(timeout, proc.kill) # enforces timeout
- timer.start()
- proc.communicate()
- if timer.is_alive():
- timer.cancel()
- returncode = proc.returncode
- else:
- returncode = EXIT_TIMEOUT
- if outf != None:
+ (_, _, retcode) = RunCommandForOutput(cmd, None, outf, errf, timeout)
+ if outf != devnull:
outf.close()
- if errf != None:
+ if errf != devnull:
errf.close()
- return returncode
+ return retcode
+
def GetJackClassPath():
"""Returns Jack's classpath."""
- top = os.environ.get('ANDROID_BUILD_TOP')
- if top == None:
- raise FatalError('Cannot find AOSP build top')
+ top = GetEnvVariableOrError('ANDROID_BUILD_TOP')
libdir = top + '/out/host/common/obj/JAVA_LIBRARIES'
return libdir + '/core-libart-hostdex_intermediates/classes.jack:' \
+ libdir + '/core-oj-hostdex_intermediates/classes.jack'
+
def GetExecutionModeRunner(device, mode):
"""Returns a runner for the given execution mode.
@@ -92,49 +95,44 @@ def GetExecutionModeRunner(device, mode):
if mode == 'ri':
return TestRunnerRIOnHost()
if mode == 'hint':
- return TestRunnerArtOnHost(True)
+ return TestRunnerArtIntOnHost()
if mode == 'hopt':
- return TestRunnerArtOnHost(False)
+ return TestRunnerArtOptOnHost()
if mode == 'tint':
- return TestRunnerArtOnTarget(device, True)
+ return TestRunnerArtIntOnTarget(device)
if mode == 'topt':
- return TestRunnerArtOnTarget(device, False)
+ return TestRunnerArtOptOnTarget(device)
raise FatalError('Unknown execution mode')
-def GetReturnCode(retc):
- """Returns a string representation of the given normalized return code.
- Args:
- retc: int, normalized return code
- Returns:
- string representation of normalized return code
- Raises:
- FatalError: error for unknown normalized return code
- """
- if retc == EXIT_SUCCESS:
- return 'SUCCESS'
- if retc == EXIT_TIMEOUT:
- return 'TIMED-OUT'
- if retc == EXIT_NOTCOMPILED:
- return 'NOT-COMPILED'
- if retc == EXIT_NOTRUN:
- return 'NOT-RUN'
- raise FatalError('Unknown normalized return code')
-
#
# Execution mode classes.
#
+
class TestRunner(object):
"""Abstraction for running a test in a particular execution mode."""
__meta_class__ = abc.ABCMeta
- def GetDescription(self):
+ @abc.abstractproperty
+ def description(self):
"""Returns a description string of the execution mode."""
- return self._description
- def GetId(self):
+ @abc.abstractproperty
+ def id(self):
"""Returns a short string that uniquely identifies the execution mode."""
- return self._id
+
+ @property
+ def output_file(self):
+ return self.id + '_out.txt'
+
+ @abc.abstractmethod
+ def GetBisectionSearchArgs(self):
+ """Get arguments to pass to bisection search tool.
+
+ Returns:
+ list of strings - arguments for bisection search tool, or None if
+ runner is not bisectable
+ """
@abc.abstractmethod
def CompileAndRunTest(self):
@@ -142,8 +140,7 @@ class TestRunner(object):
Ensures that the current Test.java in the temporary directory is compiled
and executed under the current execution mode. On success, transfers the
- generated output to the file GetId()_out.txt in the temporary directory.
- Cleans up after itself.
+ generated output to the file self.output_file in the temporary directory.
Most nonzero return codes are assumed non-divergent, since systems may
exit in different ways. This is enforced by normalizing return codes.
@@ -151,112 +148,196 @@ class TestRunner(object):
Returns:
normalized return code
"""
- pass
+
class TestRunnerRIOnHost(TestRunner):
"""Concrete test runner of the reference implementation on host."""
- def __init__(self):
- """Constructor for the RI tester."""
- self._description = 'RI on host'
- self._id = 'RI'
+ @property
+ def description(self):
+ return 'RI on host'
+
+ @property
+ def id(self):
+ return 'RI'
def CompileAndRunTest(self):
- if RunCommand('javac', 'Test.java',
- out=None, err=None, timeout=30) == EXIT_SUCCESS:
- retc = RunCommand('java', 'Test', 'RI_run_out.txt', err=None)
- if retc != EXIT_SUCCESS and retc != EXIT_TIMEOUT:
- retc = EXIT_NOTRUN
+ if RunCommand(['javac', 'Test.java'],
+ out=None, err=None, timeout=30) == RetCode.SUCCESS:
+ retc = RunCommand(['java', 'Test'], self.output_file, err=None)
else:
- retc = EXIT_NOTCOMPILED
- # Cleanup and return.
- RunCommand('rm', '-f Test.class', out=None, err=None)
+ retc = RetCode.NOTCOMPILED
return retc
+ def GetBisectionSearchArgs(self):
+ return None
+
+
class TestRunnerArtOnHost(TestRunner):
- """Concrete test runner of Art on host (interpreter or optimizing)."""
+ """Abstract test runner of Art on host."""
- def __init__(self, interpreter):
+ def __init__(self, extra_args=None):
"""Constructor for the Art on host tester.
Args:
- interpreter: boolean, selects between interpreter or optimizing
+ extra_args: list of strings, extra arguments for dalvikvm
"""
- self._art_args = '-cp classes.dex Test'
- if interpreter:
- self._description = 'Art interpreter on host'
- self._id = 'HInt'
- self._art_args = '-Xint ' + self._art_args
- else:
- self._description = 'Art optimizing on host'
- self._id = 'HOpt'
- self._jack_args = '-cp ' + GetJackClassPath() + ' --output-dex . Test.java'
+ self._art_cmd = ['/bin/bash', 'art', '-cp', 'classes.dex']
+ if extra_args is not None:
+ self._art_cmd += extra_args
+ self._art_cmd.append('Test')
+ self._jack_args = ['-cp', GetJackClassPath(), '--output-dex', '.',
+ 'Test.java']
def CompileAndRunTest(self):
- if RunCommand('jack', self._jack_args,
- out=None, err='jackerr.txt', timeout=30) == EXIT_SUCCESS:
- out = self.GetId() + '_run_out.txt'
- retc = RunCommand('art', self._art_args, out, 'arterr.txt')
- if retc != EXIT_SUCCESS and retc != EXIT_TIMEOUT:
- retc = EXIT_NOTRUN
+ if RunCommand(['jack'] + self._jack_args, out=None, err='jackerr.txt',
+ timeout=30) == RetCode.SUCCESS:
+ retc = RunCommand(self._art_cmd, self.output_file, 'arterr.txt')
else:
- retc = EXIT_NOTCOMPILED
- # Cleanup and return.
- RunCommand('rm', '-rf classes.dex jackerr.txt arterr.txt android-data*',
- out=None, err=None)
+ retc = RetCode.NOTCOMPILED
return retc
-# TODO: very rough first version without proper cache,
-# reuse staszkiewicz' module for properly setting up dalvikvm on target.
+
+class TestRunnerArtIntOnHost(TestRunnerArtOnHost):
+ """Concrete test runner of interpreter mode Art on host."""
+
+ def __init__(self):
+ """Constructor."""
+ super().__init__(['-Xint'])
+
+ @property
+ def description(self):
+ return 'Art interpreter on host'
+
+ @property
+ def id(self):
+ return 'HInt'
+
+ def GetBisectionSearchArgs(self):
+ return None
+
+
+class TestRunnerArtOptOnHost(TestRunnerArtOnHost):
+ """Concrete test runner of optimizing compiler mode Art on host."""
+
+ def __init__(self):
+ """Constructor."""
+ super().__init__(None)
+
+ @property
+ def description(self):
+ return 'Art optimizing on host'
+
+ @property
+ def id(self):
+ return 'HOpt'
+
+ def GetBisectionSearchArgs(self):
+ cmd_str = CommandListToCommandString(
+ self._art_cmd[0:2] + ['{ARGS}'] + self._art_cmd[2:])
+ return ['--raw-cmd={0}'.format(cmd_str), '--timeout', str(30)]
+
+
class TestRunnerArtOnTarget(TestRunner):
- """Concrete test runner of Art on target (interpreter or optimizing)."""
+ """Abstract test runner of Art on target."""
- def __init__(self, device, interpreter):
+ def __init__(self, device, extra_args=None):
"""Constructor for the Art on target tester.
Args:
device: string, target device serial number (or None)
- interpreter: boolean, selects between interpreter or optimizing
+ extra_args: list of strings, extra arguments for dalvikvm
"""
- self._dalvik_args = 'shell dalvikvm -cp /data/local/tmp/classes.dex Test'
- if interpreter:
- self._description = 'Art interpreter on target'
- self._id = 'TInt'
- self._dalvik_args = '-Xint ' + self._dalvik_args
- else:
- self._description = 'Art optimizing on target'
- self._id = 'TOpt'
- self._adb = 'adb'
- if device != None:
- self._adb = self._adb + ' -s ' + device
- self._jack_args = '-cp ' + GetJackClassPath() + ' --output-dex . Test.java'
+ self._test_env = DeviceTestEnv('javafuzz_', specific_device=device)
+ self._dalvik_cmd = ['dalvikvm']
+ if extra_args is not None:
+ self._dalvik_cmd += extra_args
+ self._device = device
+ self._jack_args = ['-cp', GetJackClassPath(), '--output-dex', '.',
+ 'Test.java']
+ self._device_classpath = None
def CompileAndRunTest(self):
- if RunCommand('jack', self._jack_args,
- out=None, err='jackerr.txt', timeout=30) == EXIT_SUCCESS:
- if RunCommand(self._adb, 'push classes.dex /data/local/tmp/',
- 'adb.txt', err=None) != EXIT_SUCCESS:
- raise FatalError('Cannot push to target device')
- out = self.GetId() + '_run_out.txt'
- retc = RunCommand(self._adb, self._dalvik_args, out, err=None)
- if retc != EXIT_SUCCESS and retc != EXIT_TIMEOUT:
- retc = EXIT_NOTRUN
+ if RunCommand(['jack'] + self._jack_args, out=None, err='jackerr.txt',
+ timeout=30) == RetCode.SUCCESS:
+ self._device_classpath = self._test_env.PushClasspath('classes.dex')
+ cmd = self._dalvik_cmd + ['-cp', self._device_classpath, 'Test']
+ (output, retc) = self._test_env.RunCommand(
+ cmd, {'ANDROID_LOG_TAGS': '*:s'})
+ with open(self.output_file, 'w') as run_out:
+ run_out.write(output)
else:
- retc = EXIT_NOTCOMPILED
- # Cleanup and return.
- RunCommand('rm', '-f classes.dex jackerr.txt adb.txt',
- out=None, err=None)
- RunCommand(self._adb, 'shell rm -f /data/local/tmp/classes.dex',
- out=None, err=None)
+ retc = RetCode.NOTCOMPILED
return retc
+ def GetBisectionSearchArgs(self):
+ cmd_str = CommandListToCommandString(
+ self._dalvik_cmd + ['-cp',self._device_classpath, 'Test'])
+ cmd = ['--raw-cmd={0}'.format(cmd_str), '--timeout', str(30)]
+ if self._device:
+ cmd += ['--device-serial', self._device]
+ else:
+ cmd.append('--device')
+ return cmd
+
+
+class TestRunnerArtIntOnTarget(TestRunnerArtOnTarget):
+ """Concrete test runner of interpreter mode Art on target."""
+
+ def __init__(self, device):
+ """Constructor.
+
+ Args:
+ device: string, target device serial number (or None)
+ """
+ super().__init__(device, ['-Xint'])
+
+ @property
+ def description(self):
+ return 'Art interpreter on target'
+
+ @property
+ def id(self):
+ return 'TInt'
+
+ def GetBisectionSearchArgs(self):
+ return None
+
+
+class TestRunnerArtOptOnTarget(TestRunnerArtOnTarget):
+ """Concrete test runner of optimizing compiler mode Art on target."""
+
+ def __init__(self, device):
+ """Constructor.
+
+ Args:
+ device: string, target device serial number (or None)
+ """
+ super().__init__(device, None)
+
+ @property
+ def description(self):
+ return 'Art optimizing on target'
+
+ @property
+ def id(self):
+ return 'TOpt'
+
+ def GetBisectionSearchArgs(self):
+ cmd_str = CommandListToCommandString(
+ self._dalvik_cmd + ['-cp', self._device_classpath, 'Test'])
+ cmd = ['--raw-cmd={0}'.format(cmd_str), '--timeout', str(30)]
+ if self._device:
+ cmd += ['--device-serial', self._device]
+ else:
+ cmd.append('--device')
+ return cmd
+
+
#
# Tester classes.
#
-class FatalError(Exception):
- """Fatal error in the tester."""
- pass
class JavaFuzzTester(object):
"""Tester that runs JavaFuzz many times and report divergences."""
@@ -265,10 +346,10 @@ class JavaFuzzTester(object):
"""Constructor for the tester.
Args:
- num_tests: int, number of tests to run
- device: string, target device serial number (or None)
- mode1: string, execution mode for first runner
- mode2: string, execution mode for second runner
+ num_tests: int, number of tests to run
+ device: string, target device serial number (or None)
+ mode1: string, execution mode for first runner
+ mode2: string, execution mode for second runner
"""
self._num_tests = num_tests
self._device = device
@@ -291,8 +372,9 @@ class JavaFuzzTester(object):
FatalError: error when temp directory cannot be constructed
"""
self._save_dir = os.getcwd()
- self._tmp_dir = mkdtemp(dir="/tmp/")
- if self._tmp_dir == None:
+ self._results_dir = mkdtemp(dir='/tmp/')
+ self._tmp_dir = mkdtemp(dir=self._results_dir)
+ if self._tmp_dir is None or self._results_dir is None:
raise FatalError('Cannot obtain temp directory')
os.chdir(self._tmp_dir)
return self
@@ -300,37 +382,38 @@ class JavaFuzzTester(object):
def __exit__(self, etype, evalue, etraceback):
"""On exit, re-enters previously saved current directory and cleans up."""
os.chdir(self._save_dir)
+ shutil.rmtree(self._tmp_dir)
if self._num_divergences == 0:
- RunCommand('rm', '-rf ' + self._tmp_dir, out=None, err=None)
+ shutil.rmtree(self._results_dir)
def Run(self):
"""Runs JavaFuzz many times and report divergences."""
- print
- print '**\n**** JavaFuzz Testing\n**'
- print
- print '#Tests :', self._num_tests
- print 'Device :', self._device
- print 'Directory :', self._tmp_dir
- print 'Exec-mode1:', self._runner1.GetDescription()
- print 'Exec-mode2:', self._runner2.GetDescription()
+ print()
+ print('**\n**** JavaFuzz Testing\n**')
+ print()
+ print('#Tests :', self._num_tests)
+ print('Device :', self._device)
+ print('Directory :', self._results_dir)
+ print('Exec-mode1:', self._runner1.description)
+ print('Exec-mode2:', self._runner2.description)
print
self.ShowStats()
for self._test in range(1, self._num_tests + 1):
self.RunJavaFuzzTest()
self.ShowStats()
if self._num_divergences == 0:
- print '\n\nsuccess (no divergences)\n'
+ print('\n\nsuccess (no divergences)\n')
else:
- print '\n\nfailure (divergences)\n'
+ print('\n\nfailure (divergences)\n')
def ShowStats(self):
"""Shows current statistics (on same line) while tester is running."""
- print '\rTests:', self._test, \
- 'Success:', self._num_success, \
- 'Not-compiled:', self._num_not_compiled, \
- 'Not-run:', self._num_not_run, \
- 'Timed-out:', self._num_timed_out, \
- 'Divergences:', self._num_divergences,
+ print('\rTests:', self._test, \
+ 'Success:', self._num_success, \
+ 'Not-compiled:', self._num_not_compiled, \
+ 'Not-run:', self._num_not_run, \
+ 'Timed-out:', self._num_timed_out, \
+ 'Divergences:', self._num_divergences, end='')
sys.stdout.flush()
def RunJavaFuzzTest(self):
@@ -347,8 +430,7 @@ class JavaFuzzTester(object):
Raises:
FatalError: error when javafuzz fails
"""
- if RunCommand('javafuzz', args=None,
- out='Test.java', err=None) != EXIT_SUCCESS:
+ if RunCommand(['javafuzz'], out='Test.java', err=None) != RetCode.SUCCESS:
raise FatalError('Unexpected error while running JavaFuzz')
def CheckForDivergence(self, retc1, retc2):
@@ -360,38 +442,85 @@ class JavaFuzzTester(object):
"""
if retc1 == retc2:
# Non-divergent in return code.
- if retc1 == EXIT_SUCCESS:
+ if retc1 == RetCode.SUCCESS:
# Both compilations and runs were successful, inspect generated output.
- args = self._runner1.GetId() + '_run_out.txt ' \
- + self._runner2.GetId() + '_run_out.txt'
- if RunCommand('diff', args, out=None, err=None) != EXIT_SUCCESS:
- self.ReportDivergence('divergence in output')
+ runner1_out = self._runner1.output_file
+ runner2_out = self._runner2.output_file
+ if not filecmp.cmp(runner1_out, runner2_out, shallow=False):
+ self.ReportDivergence(retc1, retc2, is_output_divergence=True)
else:
self._num_success += 1
- elif retc1 == EXIT_TIMEOUT:
+ elif retc1 == RetCode.TIMEOUT:
self._num_timed_out += 1
- elif retc1 == EXIT_NOTCOMPILED:
+ elif retc1 == RetCode.NOTCOMPILED:
self._num_not_compiled += 1
else:
self._num_not_run += 1
else:
# Divergent in return code.
- self.ReportDivergence('divergence in return code: ' +
- GetReturnCode(retc1) + ' vs. ' +
- GetReturnCode(retc2))
+ self.ReportDivergence(retc1, retc2, is_output_divergence=False)
+
+ def GetCurrentDivergenceDir(self):
+ return self._results_dir + '/divergence' + str(self._num_divergences)
- def ReportDivergence(self, reason):
+ def ReportDivergence(self, retc1, retc2, is_output_divergence):
"""Reports and saves a divergence."""
self._num_divergences += 1
- print '\n', self._test, reason
+ print('\n' + str(self._num_divergences), end='')
+ if is_output_divergence:
+ print(' divergence in output')
+ else:
+ print(' divergence in return code: ' + retc1.name + ' vs. ' +
+ retc2.name)
# Save.
- ddir = 'divergence' + str(self._test)
- RunCommand('mkdir', ddir, out=None, err=None)
- RunCommand('mv', 'Test.java *.txt ' + ddir, out=None, err=None)
+ ddir = self.GetCurrentDivergenceDir()
+ os.mkdir(ddir)
+ for f in glob('*.txt') + ['Test.java']:
+ shutil.copy(f, ddir)
+ # Maybe run bisection bug search.
+ if retc1 in BISECTABLE_RET_CODES and retc2 in BISECTABLE_RET_CODES:
+ self.MaybeBisectDivergence(retc1, retc2, is_output_divergence)
+
+ def RunBisectionSearch(self, args, expected_retcode, expected_output,
+ runner_id):
+ ddir = self.GetCurrentDivergenceDir()
+ outfile_path = ddir + '/' + runner_id + '_bisection_out.txt'
+ logfile_path = ddir + '/' + runner_id + '_bisection_log.txt'
+ errfile_path = ddir + '/' + runner_id + '_bisection_err.txt'
+ args = list(args) + ['--logfile', logfile_path, '--cleanup']
+ args += ['--expected-retcode', expected_retcode.name]
+ if expected_output:
+ args += ['--expected-output', expected_output]
+ bisection_search_path = os.path.join(
+ GetEnvVariableOrError('ANDROID_BUILD_TOP'),
+ 'art/tools/bisection_search/bisection_search.py')
+ if RunCommand([bisection_search_path] + args, out=outfile_path,
+ err=errfile_path, timeout=300) == RetCode.TIMEOUT:
+ print('Bisection search TIMEOUT')
+
+ def MaybeBisectDivergence(self, retc1, retc2, is_output_divergence):
+ bisection_args1 = self._runner1.GetBisectionSearchArgs()
+ bisection_args2 = self._runner2.GetBisectionSearchArgs()
+ if is_output_divergence:
+ maybe_output1 = self._runner1.output_file
+ maybe_output2 = self._runner2.output_file
+ else:
+ maybe_output1 = maybe_output2 = None
+ if bisection_args1 is not None:
+ self.RunBisectionSearch(bisection_args1, retc2, maybe_output2,
+ self._runner1.id)
+ if bisection_args2 is not None:
+ self.RunBisectionSearch(bisection_args2, retc1, maybe_output1,
+ self._runner2.id)
def CleanupTest(self):
"""Cleans up after a single test run."""
- RunCommand('rm', '-f Test.java *.txt', out=None, err=None)
+ for file_name in os.listdir(self._tmp_dir):
+ file_path = os.path.join(self._tmp_dir, file_name)
+ if os.path.isfile(file_path):
+ os.unlink(file_path)
+ elif os.path.isdir(file_path):
+ shutil.rmtree(file_path)
def main():
@@ -406,11 +535,11 @@ def main():
help='execution mode 2 (default: hopt)')
args = parser.parse_args()
if args.mode1 == args.mode2:
- raise FatalError("Identical execution modes given")
+ raise FatalError('Identical execution modes given')
# Run the JavaFuzz tester.
with JavaFuzzTester(args.num_tests, args.device,
args.mode1, args.mode2) as fuzzer:
fuzzer.Run()
-if __name__ == "__main__":
+if __name__ == '__main__':
main()
diff --git a/tools/run-jdwp-tests.sh b/tools/run-jdwp-tests.sh
index 01dae432e6..74b0f16466 100755
--- a/tools/run-jdwp-tests.sh
+++ b/tools/run-jdwp-tests.sh
@@ -43,7 +43,7 @@ vm_command="--vm-command=$art"
image_compiler_option=""
debug="no"
verbose="no"
-image="-Ximage:/data/art-test/core-optimizing-pic.art"
+image="-Ximage:/data/art-test/core.art"
vm_args=""
# By default, we run the whole JDWP test suite.
test="org.apache.harmony.jpda.tests.share.AllTests"
diff --git a/tools/run-libcore-tests.sh b/tools/run-libcore-tests.sh
index 2a6e172c69..01c7f203f9 100755
--- a/tools/run-libcore-tests.sh
+++ b/tools/run-libcore-tests.sh
@@ -95,7 +95,7 @@ while true; do
if [[ "$1" == "--mode=device" ]]; then
vogar_args="$vogar_args --device-dir=/data/local/tmp"
vogar_args="$vogar_args --vm-command=/data/local/tmp/system/bin/art"
- vogar_args="$vogar_args --vm-arg -Ximage:/data/art-test/core-optimizing.art"
+ vogar_args="$vogar_args --vm-arg -Ximage:/data/art-test/core.art"
shift
elif [[ "$1" == "--mode=host" ]]; then
# We explicitly give a wrong path for the image, to ensure vogar