summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk18
-rw-r--r--build/Android.common_build.mk4
-rw-r--r--build/Android.gtest.mk24
-rw-r--r--cmdline/cmdline_parser.h1
-rw-r--r--cmdline/cmdline_types.h1
-rw-r--r--cmdline/memory_representation.h25
-rw-r--r--compiler/compiled_method.h2
-rw-r--r--compiler/compiler.cc1
-rw-r--r--compiler/dex/compiler_ir.cc1
-rw-r--r--compiler/dex/compiler_ir.h2
-rw-r--r--compiler/dex/local_value_numbering.cc2
-rw-r--r--compiler/dex/local_value_numbering.h3
-rw-r--r--compiler/dex/mir_analysis.cc1
-rw-r--r--compiler/dex/mir_graph.cc1
-rw-r--r--compiler/dex/mir_graph.h1
-rw-r--r--compiler/dex/mir_optimization.cc1
-rw-r--r--compiler/dex/quick/arm/call_arm.cc2
-rw-r--r--compiler/dex/quick/arm/int_arm.cc2
-rw-r--r--compiler/dex/quick/arm64/fp_arm64.cc1
-rw-r--r--compiler/dex/quick/arm64/int_arm64.cc2
-rw-r--r--compiler/dex/quick/codegen_util.cc4
-rw-r--r--compiler/dex/quick/gen_common.cc2
-rw-r--r--compiler/dex/quick/mir_to_lir-inl.h1
-rw-r--r--compiler/dex/quick/mir_to_lir.h1
-rw-r--r--compiler/dex/quick/quick_cfi_test.cc3
-rw-r--r--compiler/dex/quick/resource_mask.cc2
-rw-r--r--compiler/dex/quick/x86/assemble_x86.cc2
-rwxr-xr-xcompiler/dex/quick/x86/int_x86.cc2
-rw-r--r--compiler/dex/quick/x86/quick_assemble_x86_test.cc3
-rw-r--r--compiler/dex/type_inference.cc1
-rw-r--r--compiler/dex/type_inference.h1
-rw-r--r--compiler/driver/compiler_driver.cc1
-rw-r--r--compiler/driver/compiler_driver.h2
-rw-r--r--compiler/driver/compiler_options.cc9
-rw-r--r--compiler/driver/compiler_options.h17
-rw-r--r--compiler/dwarf/debug_frame_opcode_writer.h2
-rw-r--r--compiler/dwarf/dwarf_test.h1
-rw-r--r--compiler/dwarf/writer.h4
-rw-r--r--compiler/elf_builder.h35
-rw-r--r--compiler/elf_writer_debug.cc1
-rw-r--r--compiler/elf_writer_quick.cc174
-rw-r--r--compiler/elf_writer_quick.h2
-rw-r--r--compiler/elf_writer_test.cc98
-rw-r--r--compiler/gc_map_builder.h2
-rw-r--r--compiler/image_writer.cc14
-rw-r--r--compiler/image_writer.h4
-rw-r--r--compiler/jit/jit_compiler.cc4
-rw-r--r--compiler/jni/quick/arm64/calling_convention_arm64.cc3
-rw-r--r--compiler/jni/quick/calling_convention.cc1
-rw-r--r--compiler/jni/quick/jni_compiler.cc2
-rw-r--r--compiler/jni/quick/x86/calling_convention_x86.cc1
-rw-r--r--compiler/jni/quick/x86_64/calling_convention_x86_64.cc2
-rw-r--r--compiler/oat_writer.cc11
-rw-r--r--compiler/oat_writer.h19
-rw-r--r--compiler/optimizing/builder.cc21
-rw-r--r--compiler/optimizing/code_generator_arm.cc81
-rw-r--r--compiler/optimizing/code_generator_arm64.cc44
-rw-r--r--compiler/optimizing/code_generator_x86.cc62
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc68
-rw-r--r--compiler/optimizing/inliner.cc4
-rw-r--r--compiler/optimizing/intrinsics.cc1
-rw-r--r--compiler/optimizing/nodes.cc16
-rw-r--r--compiler/optimizing/nodes.h39
-rw-r--r--compiler/optimizing/optimizing_compiler.cc6
-rw-r--r--compiler/optimizing/parallel_move_resolver.h1
-rw-r--r--compiler/optimizing/register_allocator.cc18
-rw-r--r--compiler/optimizing/register_allocator.h1
-rw-r--r--compiler/utils/arm/assembler_arm.cc2
-rw-r--r--compiler/utils/arm/assembler_arm.h2
-rw-r--r--compiler/utils/arm/assembler_arm32.cc2
-rw-r--r--compiler/utils/arm/assembler_arm32.h1
-rw-r--r--compiler/utils/arm/assembler_thumb2.cc2
-rw-r--r--compiler/utils/arm/assembler_thumb2.h1
-rw-r--r--compiler/utils/arm64/assembler_arm64.cc1
-rw-r--r--compiler/utils/arm64/assembler_arm64.h1
-rw-r--r--compiler/utils/arm64/managed_register_arm64.h3
-rw-r--r--compiler/utils/assembler_test_base.h5
-rw-r--r--compiler/utils/dedupe_set.h1
-rw-r--r--compiler/utils/dex_cache_arrays_layout-inl.h2
-rw-r--r--compiler/utils/mips/assembler_mips.cc1
-rw-r--r--compiler/utils/mips/assembler_mips.h1
-rw-r--r--compiler/utils/mips64/assembler_mips64.cc3
-rw-r--r--compiler/utils/mips64/assembler_mips64.h1
-rw-r--r--compiler/utils/swap_space.h1
-rw-r--r--compiler/utils/test_dex_file_builder.h3
-rw-r--r--compiler/utils/test_dex_file_builder_test.cc1
-rw-r--r--compiler/utils/x86/assembler_x86.h2
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.h3
-rw-r--r--compiler/utils/x86_64/assembler_x86_64_test.cc2
-rw-r--r--dex2oat/dex2oat.cc40
-rw-r--r--oatdump/oatdump.cc4
-rw-r--r--oatdump/oatdump_test.cc132
-rw-r--r--patchoat/patchoat.cc10
-rw-r--r--patchoat/patchoat.h1
-rw-r--r--runtime/Android.mk1
-rw-r--r--runtime/arch/arm/context_arm.cc46
-rw-r--r--runtime/arch/arm/quick_entrypoints_arm.S5
-rw-r--r--runtime/arch/arm/quick_method_frame_info_arm.h2
-rw-r--r--runtime/arch/arm64/context_arm64.cc45
-rw-r--r--runtime/arch/arm64/quick_entrypoints_arm64.S5
-rw-r--r--runtime/arch/arm64/quick_method_frame_info_arm64.h2
-rw-r--r--runtime/arch/memcmp16_test.cc4
-rw-r--r--runtime/arch/mips/asm_support_mips.h2
-rw-r--r--runtime/arch/mips/context_mips.cc46
-rw-r--r--runtime/arch/mips/quick_entrypoints_mips.S64
-rw-r--r--runtime/arch/mips/quick_method_frame_info_mips.h12
-rw-r--r--runtime/arch/mips64/context_mips64.cc44
-rw-r--r--runtime/arch/mips64/quick_entrypoints_mips64.S6
-rw-r--r--runtime/arch/mips64/quick_method_frame_info_mips64.h1
-rw-r--r--runtime/arch/x86/context_x86.cc62
-rw-r--r--runtime/arch/x86/quick_entrypoints_x86.S9
-rw-r--r--runtime/arch/x86/quick_method_frame_info_x86.h1
-rw-r--r--runtime/arch/x86_64/context_x86_64.cc51
-rw-r--r--runtime/arch/x86_64/quick_entrypoints_x86_64.S4
-rw-r--r--runtime/arch/x86_64/quick_method_frame_info_x86_64.h1
-rw-r--r--runtime/barrier.cc1
-rw-r--r--runtime/base/arena_allocator.h2
-rw-r--r--runtime/base/bit_utils.h337
-rw-r--r--runtime/base/bit_utils_test.cc400
-rw-r--r--runtime/base/bit_vector-inl.h2
-rw-r--r--runtime/base/bit_vector.h2
-rw-r--r--runtime/base/bounded_fifo.h15
-rw-r--r--runtime/base/histogram-inl.h9
-rw-r--r--runtime/base/histogram.h1
-rw-r--r--runtime/base/iteration_range.h47
-rw-r--r--runtime/base/mutex-inl.h1
-rw-r--r--runtime/base/mutex.cc2
-rw-r--r--runtime/base/time_utils.cc209
-rw-r--r--runtime/base/time_utils.h89
-rw-r--r--runtime/base/time_utils_test.cc58
-rw-r--r--runtime/base/timing_logger.cc3
-rw-r--r--runtime/base/unix_file/random_access_file_test.h2
-rw-r--r--runtime/class_linker.cc133
-rw-r--r--runtime/class_linker.h6
-rw-r--r--runtime/debugger.cc5
-rw-r--r--runtime/dex_file-inl.h2
-rw-r--r--runtime/elf_file.cc83
-rw-r--r--runtime/elf_file_impl.h9
-rw-r--r--runtime/entrypoints/quick/callee_save_frame.h15
-rw-r--r--runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc4
-rw-r--r--runtime/entrypoints/quick/quick_trampoline_entrypoints.cc38
-rw-r--r--runtime/gc/accounting/atomic_stack.h2
-rw-r--r--runtime/gc/accounting/bitmap-inl.h2
-rw-r--r--runtime/gc/accounting/bitmap.cc1
-rw-r--r--runtime/gc/accounting/card_table-inl.h2
-rw-r--r--runtime/gc/accounting/read_barrier_table.h1
-rw-r--r--runtime/gc/accounting/space_bitmap-inl.h2
-rw-r--r--runtime/gc/allocator/dlmalloc.cc1
-rw-r--r--runtime/gc/allocator/rosalloc.h2
-rw-r--r--runtime/gc/collector/garbage_collector.cc2
-rw-r--r--runtime/gc/collector/mark_sweep.cc10
-rw-r--r--runtime/gc/heap-inl.h2
-rw-r--r--runtime/gc/heap.cc1
-rw-r--r--runtime/gc/heap.h1
-rw-r--r--runtime/gc/reference_processor.cc2
-rw-r--r--runtime/gc/space/bump_pointer_space-inl.h1
-rw-r--r--runtime/gc/space/dlmalloc_space.cc1
-rw-r--r--runtime/gc/space/image_space.cc3
-rw-r--r--runtime/gc/space/large_object_space.cc1
-rw-r--r--runtime/gc/space/large_object_space_test.cc1
-rw-r--r--runtime/gc/space/rosalloc_space.cc1
-rw-r--r--runtime/gc/task_processor.cc1
-rw-r--r--runtime/gc/task_processor_test.cc2
-rw-r--r--runtime/handle_scope.h1
-rw-r--r--runtime/hprof/hprof.cc1
-rw-r--r--runtime/image.cc2
-rw-r--r--runtime/image.h1
-rw-r--r--runtime/java_vm_ext.cc10
-rw-r--r--runtime/java_vm_ext.h8
-rw-r--r--runtime/jdwp/jdwp_handler.cc1
-rw-r--r--runtime/jdwp/jdwp_main.cc1
-rw-r--r--runtime/jit/jit.h4
-rw-r--r--runtime/jit/jit_code_cache_test.cc1
-rw-r--r--runtime/leb128.h5
-rw-r--r--runtime/leb128_test.cc1
-rw-r--r--runtime/lock_word.h2
-rw-r--r--runtime/memory_region.h8
-rw-r--r--runtime/mirror/array-inl.h8
-rw-r--r--runtime/mirror/array.h4
-rw-r--r--runtime/mirror/art_method-inl.h1
-rw-r--r--runtime/mirror/class-inl.h1
-rw-r--r--runtime/mirror/class.h1
-rw-r--r--runtime/mirror/field.cc1
-rw-r--r--runtime/mirror/object-inl.h12
-rw-r--r--runtime/mirror/object.h2
-rw-r--r--runtime/mirror/object_array-inl.h4
-rw-r--r--runtime/mirror/string-inl.h1
-rw-r--r--runtime/monitor.cc1
-rw-r--r--runtime/monitor_test.cc2
-rw-r--r--runtime/native/dalvik_system_VMDebug.cc1
-rw-r--r--runtime/native/dalvik_system_VMRuntime.cc9
-rw-r--r--runtime/native/dalvik_system_ZygoteHooks.cc10
-rw-r--r--runtime/native/java_lang_reflect_Field.cc1
-rw-r--r--runtime/oat.cc2
-rw-r--r--runtime/profiler.cc2
-rw-r--r--runtime/read_barrier-inl.h1
-rw-r--r--runtime/reflection.cc25
-rw-r--r--runtime/reflection.h3
-rw-r--r--runtime/runtime_linux.cc3
-rw-r--r--runtime/signal_catcher.cc1
-rw-r--r--runtime/stack.h2
-rw-r--r--runtime/stack_map.cc127
-rw-r--r--runtime/stack_map.h14
-rw-r--r--runtime/thread.cc1
-rw-r--r--runtime/thread.h1
-rw-r--r--runtime/thread_linux.cc5
-rw-r--r--runtime/thread_list.cc2
-rw-r--r--runtime/thread_pool.cc1
-rw-r--r--runtime/trace.cc2
-rw-r--r--runtime/utils.cc179
-rw-r--r--runtime/utils.h288
-rw-r--r--runtime/utils_test.cc142
-rw-r--r--runtime/verifier/method_verifier.cc2
-rw-r--r--test/004-JniTest/jni_test.cc16
-rw-r--r--test/441-checker-inliner/src/Main.java154
-rw-r--r--test/442-checker-constant-folding/src/Main.java590
-rw-r--r--test/444-checker-nce/src/Main.java154
-rw-r--r--test/445-checker-licm/src/Main.java58
-rw-r--r--test/446-checker-inliner2/src/Main.java32
-rw-r--r--test/447-checker-inliner3/src/Main.java26
-rw-r--r--test/449-checker-bce/src/Main.java866
-rw-r--r--test/450-checker-types/src/Main.java160
-rw-r--r--test/455-checker-gvn/src/Main.java16
-rw-r--r--test/458-checker-instruction-simplification/src/Main.java1114
-rw-r--r--test/462-checker-inlining-across-dex-files/src/Main.java134
-rw-r--r--test/463-checker-boolean-simplifier/src/Main.java214
-rw-r--r--test/464-checker-inline-sharpen-calls/src/Main.java26
-rw-r--r--test/465-checker-clinit-gvn/src/Main.java36
-rw-r--r--test/468-checker-bool-simplifier-regression/smali/TestCase.smali22
-rw-r--r--test/473-checker-inliner-constants/src/Main.java36
-rw-r--r--test/474-checker-boolean-input/src/Main.java24
-rw-r--r--test/476-checker-ctor-memory-barrier/src/Main.java136
-rw-r--r--test/477-checker-bound-type/src/Main.java16
-rw-r--r--test/478-checker-clinit-check-pruning/src/Main.java158
-rw-r--r--test/478-checker-inliner-nested-loop/src/Main.java10
-rw-r--r--test/480-checker-dead-blocks/src/Main.java152
-rw-r--r--test/482-checker-loop-back-edge-use/src/Main.java72
-rw-r--r--test/484-checker-register-hints/src/Main.java72
-rw-r--r--test/485-checker-dce-loop-update/smali/TestCase.smali226
-rw-r--r--test/486-checker-must-do-null-check/src/Main.java16
-rw-r--r--test/Android.run-test.mk5
-rw-r--r--tools/art2
-rwxr-xr-xtools/buildbot-build.sh77
-rw-r--r--tools/checker/file_format/checker/parser.py18
-rw-r--r--tools/checker/file_format/checker/test.py113
-rw-r--r--tools/checker/match/test.py128
-rw-r--r--tools/libcore_failures.txt17
247 files changed, 4916 insertions, 3934 deletions
diff --git a/Android.mk b/Android.mk
index 3467f1d062..54a33b2305 100644
--- a/Android.mk
+++ b/Android.mk
@@ -119,6 +119,10 @@ include $(art_path)/test/Android.run-test.mk
# Sync test files to the target, depends upon all things that must be pushed to the target.
.PHONY: test-art-target-sync
+# Check if we need to sync. In case ART_TEST_ANDROID_ROOT is not empty,
+# the code below uses 'adb push' instead of 'adb sync', which does not
+# check if the files on the device have changed.
+ifneq ($(ART_TEST_NO_SYNC),true)
ifeq ($(ART_TEST_ANDROID_ROOT),)
test-art-target-sync: $(TEST_ART_TARGET_SYNC_DEPS)
adb root
@@ -130,9 +134,7 @@ test-art-target-sync: $(TEST_ART_TARGET_SYNC_DEPS)
adb wait-for-device push $(ANDROID_PRODUCT_OUT)/system $(ART_TEST_ANDROID_ROOT)
adb push $(ANDROID_PRODUCT_OUT)/data /data
endif
-
-# Undefine variable now its served its purpose.
-TEST_ART_TARGET_SYNC_DEPS :=
+endif
# "mm test-art" to build and run all tests on host and device
.PHONY: test-art
@@ -377,6 +379,15 @@ build-art-host: $(HOST_OUT_EXECUTABLES)/art $(ART_HOST_DEPENDENCIES) $(HOST_CO
build-art-target: $(TARGET_OUT_EXECUTABLES)/art $(ART_TARGET_DEPENDENCIES) $(TARGET_CORE_IMG_OUTS)
########################################################################
+# Rules for building all dependencies for tests.
+
+.PHONY: build-art-host-tests
+build-art-host-tests: build-art-host $(TEST_ART_RUN_TEST_DEPENDENCIES) $(ART_TEST_HOST_RUN_TEST_DEPENDENCIES) $(ART_TEST_HOST_GTEST_DEPENDENCIES)
+
+.PHONY: build-art-target-tests
+build-art-target-tests: build-art-target $(TEST_ART_RUN_TEST_DEPENDENCIES) $(TEST_ART_TARGET_SYNC_DEPS)
+
+########################################################################
# targets to switch back and forth from libdvm to libart
.PHONY: use-art
@@ -467,3 +478,4 @@ endif # !art_dont_bother
# Clear locally used variables.
art_dont_bother :=
art_test_bother :=
+TEST_ART_TARGET_SYNC_DEPS :=
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
index 3e427a33ee..b84154b307 100644
--- a/build/Android.common_build.mk
+++ b/build/Android.common_build.mk
@@ -177,8 +177,8 @@ ART_CPP_EXTENSION := .cc
ART_C_INCLUDES := \
external/gtest/include \
external/icu/icu4c/source/common \
- external/valgrind/main/include \
- external/valgrind/main \
+ external/valgrind/include \
+ external/valgrind \
external/vixl/src \
external/zlib \
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index bfc8956358..5052187794 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -105,12 +105,23 @@ ART_GTEST_imgdiag_test_TARGET_DEPS := \
$(TARGET_CORE_IMAGE_default_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_OUT_EXECUTABLES)/oatdumpd
+ART_GTEST_oatdump_test_TARGET_DEPS := \
+ $(TARGET_CORE_IMAGE_default_no-pic_64) \
+ $(TARGET_CORE_IMAGE_default_no-pic_32) \
+ oatdump
+
# The path for which all the source files are relative, not actually the current directory.
LOCAL_PATH := art
RUNTIME_GTEST_COMMON_SRC_FILES := \
cmdline/cmdline_parser_test.cc \
imgdiag/imgdiag_test.cc \
+ oatdump/oatdump_test.cc \
runtime/arch/arch_test.cc \
runtime/arch/instruction_set_test.cc \
runtime/arch/instruction_set_features_test.cc \
@@ -124,6 +135,7 @@ RUNTIME_GTEST_COMMON_SRC_FILES := \
runtime/arch/x86_64/instruction_set_features_x86_64_test.cc \
runtime/barrier_test.cc \
runtime/base/bit_field_test.cc \
+ runtime/base/bit_utils_test.cc \
runtime/base/bit_vector_test.cc \
runtime/base/hash_set_test.cc \
runtime/base/hex_dump_test.cc \
@@ -131,6 +143,7 @@ RUNTIME_GTEST_COMMON_SRC_FILES := \
runtime/base/mutex_test.cc \
runtime/base/scoped_flock_test.cc \
runtime/base/stringprintf_test.cc \
+ runtime/base/time_utils_test.cc \
runtime/base/timing_logger_test.cc \
runtime/base/variant_map_test.cc \
runtime/base/unix_file/fd_file_test.cc \
@@ -300,6 +313,7 @@ ART_TEST_HOST_VALGRIND_GTEST_RULES :=
ART_TEST_TARGET_GTEST$(ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
ART_TEST_TARGET_GTEST$(2ND_ART_PHONY_TEST_TARGET_SUFFIX)_RULES :=
ART_TEST_TARGET_GTEST_RULES :=
+ART_TEST_HOST_GTEST_DEPENDENCIES :=
ART_GTEST_TARGET_ANDROID_ROOT := '/system'
ifneq ($(ART_TEST_ANDROID_ROOT),)
@@ -361,11 +375,15 @@ define define-art-gtest-rule-host
gtest_exe := $$(HOST_OUT_EXECUTABLES)/$(1)$$($(2)ART_PHONY_TEST_HOST_SUFFIX)
# Dependencies for all host gtests.
gtest_deps := $$(HOST_CORE_DEX_LOCATIONS) \
- $$($(2)ART_HOST_OUT_SHARED_LIBRARIES)/libjavacore$$(ART_HOST_SHLIB_EXTENSION)
+ $$($(2)ART_HOST_OUT_SHARED_LIBRARIES)/libjavacore$$(ART_HOST_SHLIB_EXTENSION) \
+ $$(gtest_exe) \
+ $$(ART_GTEST_$(1)_HOST_DEPS) \
+ $(foreach file,$(ART_GTEST_$(1)_DEX_DEPS),$(ART_TEST_HOST_GTEST_$(file)_DEX))
+ ART_TEST_HOST_GTEST_DEPENDENCIES += $$(gtest_deps)
.PHONY: $$(gtest_rule)
-$$(gtest_rule): $$(gtest_exe) $$(ART_GTEST_$(1)_HOST_DEPS) $(foreach file,$(ART_GTEST_$(1)_DEX_DEPS),$(ART_TEST_HOST_GTEST_$(file)_DEX)) $$(gtest_deps)
+$$(gtest_rule): $$(gtest_exe) $$(gtest_deps)
$(hide) ($$(call ART_TEST_SKIP,$$@) && $$< && $$(call ART_TEST_PASSED,$$@)) \
|| $$(call ART_TEST_FAILED,$$@)
@@ -375,7 +393,7 @@ $$(gtest_rule): $$(gtest_exe) $$(ART_GTEST_$(1)_HOST_DEPS) $(foreach file,$(ART_
.PHONY: valgrind-$$(gtest_rule)
-valgrind-$$(gtest_rule): $$(gtest_exe) $$(ART_GTEST_$(1)_HOST_DEPS) $(foreach file,$(ART_GTEST_$(1)_DEX_DEPS),$(ART_TEST_HOST_GTEST_$(file)_DEX)) $$(gtest_deps) $(ART_VALGRIND_DEPENDENCIES)
+valgrind-$$(gtest_rule): $$(gtest_exe) $$(gtest_deps) $(ART_VALGRIND_DEPENDENCIES)
$(hide) $$(call ART_TEST_SKIP,$$@) && \
VALGRIND_LIB=$(HOST_OUT)/lib64/valgrind \
$(HOST_OUT_EXECUTABLES)/valgrind --leak-check=full --error-exitcode=1 $$< && \
diff --git a/cmdline/cmdline_parser.h b/cmdline/cmdline_parser.h
index e4af4f98e8..cebba65aca 100644
--- a/cmdline/cmdline_parser.h
+++ b/cmdline/cmdline_parser.h
@@ -30,7 +30,6 @@
#include "cmdline_parse_result.h"
#include "runtime/base/variant_map.h"
-#include "utils.h"
#include <vector>
#include <memory>
diff --git a/cmdline/cmdline_types.h b/cmdline/cmdline_types.h
index e02fe4b6a0..28bd754108 100644
--- a/cmdline/cmdline_types.h
+++ b/cmdline/cmdline_types.h
@@ -27,6 +27,7 @@
#include "unit.h"
#include "jdwp/jdwp.h"
#include "runtime/base/logging.h"
+#include "runtime/base/time_utils.h"
#include "gc/collector_type.h"
#include "gc/space/large_object_space.h"
#include "profiler_options.h"
diff --git a/cmdline/memory_representation.h b/cmdline/memory_representation.h
index 93387de83c..2619c317e3 100644
--- a/cmdline/memory_representation.h
+++ b/cmdline/memory_representation.h
@@ -20,24 +20,25 @@
#include <string>
#include <assert.h>
#include <ostream>
-#include "utils.h"
+
+#include "base/bit_utils.h"
namespace art {
// An integral representation of bytes of memory.
// The underlying runtime size_t value is guaranteed to be a multiple of Divisor.
-template <size_t Divisor = 1024>
+template <size_t kDivisor = 1024>
struct Memory {
- static_assert(IsPowerOfTwo(Divisor), "Divisor must be a power of 2");
+ static_assert(IsPowerOfTwo(kDivisor), "Divisor must be a power of 2");
- static Memory<Divisor> FromBytes(size_t bytes) {
- assert(bytes % Divisor == 0);
- return Memory<Divisor>(bytes);
+ static Memory<kDivisor> FromBytes(size_t bytes) {
+ assert(bytes % kDivisor == 0);
+ return Memory<kDivisor>(bytes);
}
Memory() : Value(0u) {}
Memory(size_t value) : Value(value) { // NOLINT [runtime/explicit] [5]
- assert(value % Divisor == 0);
+ assert(value % kDivisor == 0);
}
operator size_t() const { return Value; }
@@ -45,12 +46,10 @@ struct Memory {
return Value;
}
- static constexpr size_t kDivisor = Divisor;
-
static const char* Name() {
static std::string str;
if (str.empty()) {
- str = "Memory<" + std::to_string(Divisor) + '>';
+ str = "Memory<" + std::to_string(kDivisor) + '>';
}
return str.c_str();
@@ -59,9 +58,9 @@ struct Memory {
size_t Value;
};
-template <size_t Divisor>
-std::ostream& operator<<(std::ostream& stream, Memory<Divisor> memory) {
- return stream << memory.Value << '*' << Divisor;
+template <size_t kDivisor>
+std::ostream& operator<<(std::ostream& stream, Memory<kDivisor> memory) {
+ return stream << memory.Value << '*' << kDivisor;
}
using MemoryKiB = Memory<1024>;
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h
index 480d021db0..45a62bc6c7 100644
--- a/compiler/compiled_method.h
+++ b/compiler/compiled_method.h
@@ -22,8 +22,8 @@
#include <vector>
#include "arch/instruction_set.h"
+#include "base/bit_utils.h"
#include "method_reference.h"
-#include "utils.h"
#include "utils/array_ref.h"
#include "utils/swap_space.h"
diff --git a/compiler/compiler.cc b/compiler/compiler.cc
index 5e8ec1e01b..223affad82 100644
--- a/compiler/compiler.cc
+++ b/compiler/compiler.cc
@@ -20,6 +20,7 @@
#include "dex/quick/quick_compiler_factory.h"
#include "driver/compiler_driver.h"
#include "optimizing/optimizing_compiler.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/dex/compiler_ir.cc b/compiler/dex/compiler_ir.cc
index 7fc1b03035..6e1853bbd7 100644
--- a/compiler/dex/compiler_ir.cc
+++ b/compiler/dex/compiler_ir.cc
@@ -22,6 +22,7 @@
#include "dex/quick/mir_to_lir.h"
#include "driver/compiler_driver.h"
#include "mir_graph.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/dex/compiler_ir.h b/compiler/dex/compiler_ir.h
index dceea240fa..d28df1dcce 100644
--- a/compiler/dex/compiler_ir.h
+++ b/compiler/dex/compiler_ir.h
@@ -21,6 +21,7 @@
#include <string>
#include <vector>
+#include "arch/instruction_set.h"
#include "base/arena_allocator.h"
#include "base/scoped_arena_allocator.h"
#include "base/timing_logger.h"
@@ -31,6 +32,7 @@ namespace art {
class ClassLinker;
class CompilerDriver;
+class DexFile;
class Mir2Lir;
class MIRGraph;
diff --git a/compiler/dex/local_value_numbering.cc b/compiler/dex/local_value_numbering.cc
index cc9dbe4adb..38f7d1e712 100644
--- a/compiler/dex/local_value_numbering.cc
+++ b/compiler/dex/local_value_numbering.cc
@@ -16,9 +16,11 @@
#include "local_value_numbering.h"
+#include "base/bit_utils.h"
#include "global_value_numbering.h"
#include "mir_field_info.h"
#include "mir_graph.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/dex/local_value_numbering.h b/compiler/dex/local_value_numbering.h
index 67fb647eba..dff5e27521 100644
--- a/compiler/dex/local_value_numbering.h
+++ b/compiler/dex/local_value_numbering.h
@@ -106,8 +106,7 @@ class LocalValueNumbering : public DeletableArenaObject<kArenaAllocMisc> {
}
void SetOperandValueImpl(uint16_t s_reg, uint16_t value, SregValueMap* map) {
- DCHECK_EQ(map->count(s_reg), 0u) << PrettyMethod(gvn_->cu_->method_idx, *gvn_->cu_->dex_file)
- << " LVN id: " << id_ << ", s_reg: " << s_reg;
+ DCHECK_EQ(map->count(s_reg), 0u);
map->Put(s_reg, value);
}
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc
index 9099e8a54d..1cff8dc50c 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -30,6 +30,7 @@
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
#include "driver/dex_compilation_unit.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index 1871f07106..9fa5148ced 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -35,6 +35,7 @@
#include "leb128.h"
#include "pass_driver_me_post_opt.h"
#include "stack.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index 7385a8bd53..f038397e1e 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include "base/arena_containers.h"
+#include "base/bit_utils.h"
#include "base/scoped_arena_containers.h"
#include "dex_file.h"
#include "dex_instruction.h"
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 217dbeeb44..7679db8bac 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -31,6 +31,7 @@
#include "quick/dex_file_to_method_inliner_map.h"
#include "stack.h"
#include "type_inference.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/dex/quick/arm/call_arm.cc b/compiler/dex/quick/arm/call_arm.cc
index 2b2d6af326..822ea2106f 100644
--- a/compiler/dex/quick/arm/call_arm.cc
+++ b/compiler/dex/quick/arm/call_arm.cc
@@ -19,6 +19,7 @@
#include "codegen_arm.h"
#include "arm_lir.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "dex/mir_graph.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
@@ -29,7 +30,6 @@
#include "mirror/art_method.h"
#include "mirror/object_array-inl.h"
#include "entrypoints/quick/quick_entrypoints.h"
-#include "utils.h"
#include "utils/dex_cache_arrays_layout-inl.h"
namespace art {
diff --git a/compiler/dex/quick/arm/int_arm.cc b/compiler/dex/quick/arm/int_arm.cc
index 7598e50977..7de8e55e56 100644
--- a/compiler/dex/quick/arm/int_arm.cc
+++ b/compiler/dex/quick/arm/int_arm.cc
@@ -20,6 +20,7 @@
#include "arch/instruction_set_features.h"
#include "arm_lir.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "dex/compiler_ir.h"
#include "dex/mir_graph.h"
@@ -28,7 +29,6 @@
#include "driver/compiler_driver.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "mirror/array-inl.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/dex/quick/arm64/fp_arm64.cc b/compiler/dex/quick/arm64/fp_arm64.cc
index 49b15fef58..3b88021361 100644
--- a/compiler/dex/quick/arm64/fp_arm64.cc
+++ b/compiler/dex/quick/arm64/fp_arm64.cc
@@ -20,7 +20,6 @@
#include "base/logging.h"
#include "dex/mir_graph.h"
#include "dex/quick/mir_to_lir-inl.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/dex/quick/arm64/int_arm64.cc b/compiler/dex/quick/arm64/int_arm64.cc
index 9340d01640..08aa5d20d0 100644
--- a/compiler/dex/quick/arm64/int_arm64.cc
+++ b/compiler/dex/quick/arm64/int_arm64.cc
@@ -20,6 +20,7 @@
#include "arch/instruction_set_features.h"
#include "arm64_lir.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "dex/compiler_ir.h"
#include "dex/mir_graph.h"
@@ -28,7 +29,6 @@
#include "driver/compiler_driver.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "mirror/array-inl.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 86bb69d01e..dc8bf1a0cf 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -670,7 +670,7 @@ bool Mir2Lir::VerifyCatchEntries() {
void Mir2Lir::CreateMappingTables() {
- bool generate_src_map = cu_->compiler_driver->GetCompilerOptions().GetIncludeDebugSymbols();
+ bool generate_src_map = cu_->compiler_driver->GetCompilerOptions().GetGenerateDebugInfo();
uint32_t pc2dex_data_size = 0u;
uint32_t pc2dex_entries = 0u;
@@ -1071,7 +1071,7 @@ Mir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena
pc_rel_temp_(nullptr),
dex_cache_arrays_min_offset_(std::numeric_limits<uint32_t>::max()),
cfi_(&last_lir_insn_,
- cu->compiler_driver->GetCompilerOptions().GetIncludeCFI(),
+ cu->compiler_driver->GetCompilerOptions().GetGenerateDebugInfo(),
arena),
in_to_reg_storage_mapping_(arena) {
switch_tables_.reserve(4);
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc
index 0592c74181..63f83f94cf 100644
--- a/compiler/dex/quick/gen_common.cc
+++ b/compiler/dex/quick/gen_common.cc
@@ -19,6 +19,7 @@
#include <functional>
#include "arch/arm/instruction_set_features_arm.h"
+#include "base/bit_utils.h"
#include "base/macros.h"
#include "dex/compiler_ir.h"
#include "dex/mir_graph.h"
@@ -30,7 +31,6 @@
#include "mirror/object_array-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_reference.h"
-#include "utils.h"
#include "utils/dex_cache_arrays_layout-inl.h"
#include "verifier/method_verifier.h"
diff --git a/compiler/dex/quick/mir_to_lir-inl.h b/compiler/dex/quick/mir_to_lir-inl.h
index 280dbbe106..767fe250d8 100644
--- a/compiler/dex/quick/mir_to_lir-inl.h
+++ b/compiler/dex/quick/mir_to_lir-inl.h
@@ -21,6 +21,7 @@
#include "base/logging.h"
#include "dex/compiler_ir.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 4fdc7289bf..d54616f47c 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -31,6 +31,7 @@
#include "invoke_type.h"
#include "lazy_debug_frame_opcode_writer.h"
#include "leb128.h"
+#include "primitive.h"
#include "safe_map.h"
#include "utils/array_ref.h"
#include "utils/dex_cache_arrays_layout.h"
diff --git a/compiler/dex/quick/quick_cfi_test.cc b/compiler/dex/quick/quick_cfi_test.cc
index b3c73557a7..87bbe14040 100644
--- a/compiler/dex/quick/quick_cfi_test.cc
+++ b/compiler/dex/quick/quick_cfi_test.cc
@@ -59,8 +59,7 @@ class QuickCFITest : public CFITest {
false,
CompilerOptions::kDefaultTopKProfileThreshold,
false,
- true, // include_debug_symbols.
- true, // include_cfi
+ true, // generate_debug_info.
false,
false,
false,
diff --git a/compiler/dex/quick/resource_mask.cc b/compiler/dex/quick/resource_mask.cc
index 57e8af32a2..817a69aa3b 100644
--- a/compiler/dex/quick/resource_mask.cc
+++ b/compiler/dex/quick/resource_mask.cc
@@ -18,9 +18,9 @@
#include "resource_mask.h"
+#include "base/bit_utils.h"
#include "base/arena_allocator.h"
#include "base/logging.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc
index 8467b718a1..12523aca76 100644
--- a/compiler/dex/quick/x86/assemble_x86.cc
+++ b/compiler/dex/quick/x86/assemble_x86.cc
@@ -16,10 +16,12 @@
#include "codegen_x86.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "dex/compiler_ir.h"
#include "dex/quick/mir_to_lir.h"
#include "oat.h"
+#include "utils.h"
#include "x86_lir.h"
namespace art {
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 943bfc0300..9bbb5f84be 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -18,12 +18,12 @@
#include "codegen_x86.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "dex/quick/mir_to_lir-inl.h"
#include "dex/reg_storage_eq.h"
#include "mirror/art_method.h"
#include "mirror/array-inl.h"
-#include "utils.h"
#include "x86_lir.h"
namespace art {
diff --git a/compiler/dex/quick/x86/quick_assemble_x86_test.cc b/compiler/dex/quick/x86/quick_assemble_x86_test.cc
index f58f206af5..798e23fbac 100644
--- a/compiler/dex/quick/x86/quick_assemble_x86_test.cc
+++ b/compiler/dex/quick/x86/quick_assemble_x86_test.cc
@@ -42,8 +42,7 @@ class QuickAssembleX86TestBase : public testing::Test {
false,
CompilerOptions::kDefaultTopKProfileThreshold,
false,
- false,
- false,
+ CompilerOptions::kDefaultGenerateDebugInfo,
false,
false,
false,
diff --git a/compiler/dex/type_inference.cc b/compiler/dex/type_inference.cc
index 19d591ba41..cd6467f4e5 100644
--- a/compiler/dex/type_inference.cc
+++ b/compiler/dex/type_inference.cc
@@ -25,6 +25,7 @@
#include "mir_field_info.h"
#include "mir_graph.h"
#include "mir_method_info.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/dex/type_inference.h b/compiler/dex/type_inference.h
index c9b29bf7aa..85f79af36e 100644
--- a/compiler/dex/type_inference.h
+++ b/compiler/dex/type_inference.h
@@ -17,6 +17,7 @@
#ifndef ART_COMPILER_DEX_TYPE_INFERENCE_H_
#define ART_COMPILER_DEX_TYPE_INFERENCE_H_
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "base/arena_object.h"
#include "base/scoped_arena_containers.h"
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index d352f39fbc..f988812d73 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -29,6 +29,7 @@
#include "art_field-inl.h"
#include "base/stl_util.h"
+#include "base/time_utils.h"
#include "base/timing_logger.h"
#include "class_linker-inl.h"
#include "compiled_class.h"
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 2b0985a77e..2cc2409a34 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/bit_utils.h"
#include "base/mutex.h"
#include "base/timing_logger.h"
#include "class_reference.h"
@@ -41,7 +42,6 @@
#include "utils/dedupe_set.h"
#include "utils/dex_cache_arrays_layout.h"
#include "utils/swap_space.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc
index c5fc98a957..226e6b7952 100644
--- a/compiler/driver/compiler_options.cc
+++ b/compiler/driver/compiler_options.cc
@@ -30,8 +30,7 @@ CompilerOptions::CompilerOptions()
include_patch_information_(kDefaultIncludePatchInformation),
top_k_profile_threshold_(kDefaultTopKProfileThreshold),
debuggable_(false),
- include_debug_symbols_(kDefaultIncludeDebugSymbols),
- include_cfi_(false),
+ generate_debug_info_(kDefaultGenerateDebugInfo),
implicit_null_checks_(true),
implicit_so_checks_(true),
implicit_suspend_checks_(false),
@@ -56,8 +55,7 @@ CompilerOptions::CompilerOptions(CompilerFilter compiler_filter,
bool include_patch_information,
double top_k_profile_threshold,
bool debuggable,
- bool include_debug_symbols,
- bool include_cfi,
+ bool generate_debug_info,
bool implicit_null_checks,
bool implicit_so_checks,
bool implicit_suspend_checks,
@@ -76,8 +74,7 @@ CompilerOptions::CompilerOptions(CompilerFilter compiler_filter,
include_patch_information_(include_patch_information),
top_k_profile_threshold_(top_k_profile_threshold),
debuggable_(debuggable),
- include_debug_symbols_(include_debug_symbols),
- include_cfi_(include_cfi),
+ generate_debug_info_(generate_debug_info),
implicit_null_checks_(implicit_null_checks),
implicit_so_checks_(implicit_so_checks),
implicit_suspend_checks_(implicit_suspend_checks),
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index bf3f8ec08a..356663bd8a 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -49,7 +49,7 @@ class CompilerOptions FINAL {
static const size_t kDefaultTinyMethodThreshold = 20;
static const size_t kDefaultNumDexMethodsThreshold = 900;
static constexpr double kDefaultTopKProfileThreshold = 90.0;
- static const bool kDefaultIncludeDebugSymbols = kIsDebugBuild;
+ static const bool kDefaultGenerateDebugInfo = kIsDebugBuild;
static const bool kDefaultIncludePatchInformation = false;
CompilerOptions();
@@ -64,8 +64,7 @@ class CompilerOptions FINAL {
bool include_patch_information,
double top_k_profile_threshold,
bool debuggable,
- bool include_debug_symbols,
- bool include_cfi,
+ bool generate_debug_info,
bool implicit_null_checks,
bool implicit_so_checks,
bool implicit_suspend_checks,
@@ -146,13 +145,8 @@ class CompilerOptions FINAL {
return debuggable_;
}
- bool GetIncludeDebugSymbols() const {
- return include_debug_symbols_;
- }
-
- bool GetIncludeCFI() const {
- // include-debug-symbols implies include-cfi.
- return include_cfi_ || include_debug_symbols_;
+ bool GetGenerateDebugInfo() const {
+ return generate_debug_info_;
}
bool GetImplicitNullChecks() const {
@@ -212,8 +206,7 @@ class CompilerOptions FINAL {
// When using a profile file only the top K% of the profiled samples will be compiled.
const double top_k_profile_threshold_;
const bool debuggable_;
- const bool include_debug_symbols_;
- const bool include_cfi_;
+ const bool generate_debug_info_;
const bool implicit_null_checks_;
const bool implicit_so_checks_;
const bool implicit_suspend_checks_;
diff --git a/compiler/dwarf/debug_frame_opcode_writer.h b/compiler/dwarf/debug_frame_opcode_writer.h
index 4112c84027..d8077d5da9 100644
--- a/compiler/dwarf/debug_frame_opcode_writer.h
+++ b/compiler/dwarf/debug_frame_opcode_writer.h
@@ -17,10 +17,10 @@
#ifndef ART_COMPILER_DWARF_DEBUG_FRAME_OPCODE_WRITER_H_
#define ART_COMPILER_DWARF_DEBUG_FRAME_OPCODE_WRITER_H_
+#include "base/bit_utils.h"
#include "dwarf/dwarf_constants.h"
#include "dwarf/register.h"
#include "dwarf/writer.h"
-#include "utils.h"
namespace art {
namespace dwarf {
diff --git a/compiler/dwarf/dwarf_test.h b/compiler/dwarf/dwarf_test.h
index 3afb5eae56..f819c49cee 100644
--- a/compiler/dwarf/dwarf_test.h
+++ b/compiler/dwarf/dwarf_test.h
@@ -25,7 +25,6 @@
#include <string>
#include <sys/types.h>
-#include "utils.h"
#include "base/unix_file/fd_file.h"
#include "common_runtime_test.h"
#include "elf_builder.h"
diff --git a/compiler/dwarf/writer.h b/compiler/dwarf/writer.h
index 3b9c55866a..e703aeea2d 100644
--- a/compiler/dwarf/writer.h
+++ b/compiler/dwarf/writer.h
@@ -18,9 +18,9 @@
#define ART_COMPILER_DWARF_WRITER_H_
#include <vector>
-#include "leb128.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
-#include "utils.h"
+#include "leb128.h"
namespace art {
namespace dwarf {
diff --git a/compiler/elf_builder.h b/compiler/elf_builder.h
index 972bd08270..5b74c94767 100644
--- a/compiler/elf_builder.h
+++ b/compiler/elf_builder.h
@@ -20,6 +20,7 @@
#include <vector>
#include "arch/instruction_set.h"
+#include "base/bit_utils.h"
#include "base/unix_file/fd_file.h"
#include "buffered_output_stream.h"
#include "elf_utils.h"
@@ -56,12 +57,12 @@ class ElfBuilder FINAL {
public:
Section(const std::string& name, Elf_Word type, Elf_Word flags,
const Section* link, Elf_Word info, Elf_Word align, Elf_Word entsize)
- : header_(new Elf_Shdr()), section_index_(0), name_(name), link_(link) {
- header_->sh_type = type;
- header_->sh_flags = flags;
- header_->sh_info = info;
- header_->sh_addralign = align;
- header_->sh_entsize = entsize;
+ : header_(), section_index_(0), name_(name), link_(link) {
+ header_.sh_type = type;
+ header_.sh_flags = flags;
+ header_.sh_info = info;
+ header_.sh_addralign = align;
+ header_.sh_entsize = entsize;
}
virtual ~Section() {}
@@ -79,11 +80,11 @@ class ElfBuilder FINAL {
}
const Elf_Shdr* GetHeader() const {
- return header_.get();
+ return &header_;
}
Elf_Shdr* GetHeader() {
- return header_.get();
+ return &header_;
}
Elf_Word GetSectionIndex() const {
@@ -100,9 +101,7 @@ class ElfBuilder FINAL {
}
private:
- // Elf_Shdr is somewhat large so allocate it on the heap.
- // Otherwise we get in trouble with stack frame sizes.
- std::unique_ptr<Elf_Shdr> header_;
+ Elf_Shdr header_;
Elf_Word section_index_;
const std::string name_;
const Section* const link_;
@@ -167,6 +166,10 @@ class ElfBuilder FINAL {
patched_(false), patch_(patch), patch_base_section_(patch_base_section) {
}
+ RawSection(const std::string& name, Elf_Word type)
+ : RawSection(name, type, 0, nullptr, 0, 1, 0, nullptr, nullptr) {
+ }
+
Elf_Word GetSize() const OVERRIDE {
return buffer_.size();
}
@@ -778,10 +781,12 @@ class ElfBuilder FINAL {
template<typename T>
static bool WriteArray(File* elf_file, const T* data, size_t count) {
- DCHECK(data != nullptr);
- if (!elf_file->WriteFully(data, count * sizeof(T))) {
- PLOG(ERROR) << "Failed to write to file " << elf_file->GetPath();
- return false;
+ if (count != 0) {
+ DCHECK(data != nullptr);
+ if (!elf_file->WriteFully(data, count * sizeof(T))) {
+ PLOG(ERROR) << "Failed to write to file " << elf_file->GetPath();
+ return false;
+ }
}
return true;
}
diff --git a/compiler/elf_writer_debug.cc b/compiler/elf_writer_debug.cc
index f4df6c18d0..c68bbc0655 100644
--- a/compiler/elf_writer_debug.cc
+++ b/compiler/elf_writer_debug.cc
@@ -25,6 +25,7 @@
#include "dwarf/headers.h"
#include "dwarf/register.h"
#include "oat_writer.h"
+#include "utils.h"
namespace art {
namespace dwarf {
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 96dd7ca62d..dce1e861b4 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -19,6 +19,7 @@
#include <unordered_map>
#include <unordered_set>
+#include "base/casts.h"
#include "base/logging.h"
#include "base/unix_file/fd_file.h"
#include "compiled_method.h"
@@ -43,7 +44,17 @@ namespace art {
// it is used by C++ exception handling (which we do not use so we
// can choose either). C++ compilers generally tend to use .eh_frame
// because if they need it sometimes, they might as well always use it.
-constexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_EH_FRAME_FORMAT;
+// Let's use .debug_frame because it is easier to strip or compress.
+constexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_DEBUG_FRAME_FORMAT;
+
+// The ARM specification defines three special mapping symbols
+// $a, $t and $d which mark ARM, Thumb and data ranges respectively.
+// These symbols can be used by tools, for example, to pretty
+// print instructions correctly. Objdump will use them if they
+// exist, but it will still work well without them.
+// However, these extra symbols take space, so let's just generate
+// one symbol which marks the whole .text section as code.
+constexpr bool kGenerateSingleArmMappingSymbol = true;
template <typename ElfTypes>
bool ElfWriterQuick<ElfTypes>::Create(File* elf_file,
@@ -59,36 +70,17 @@ bool ElfWriterQuick<ElfTypes>::Create(File* elf_file,
template <typename ElfTypes>
static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writer);
-// Encode patch locations in .oat_patches format.
+// Encode patch locations as LEB128 list of deltas between consecutive addresses.
template <typename ElfTypes>
-void ElfWriterQuick<ElfTypes>::EncodeOatPatches(
- const OatWriter::PatchLocationsMap& sections,
- std::vector<uint8_t>* buffer) {
- for (const auto& section : sections) {
- const std::string& name = section.first;
- std::vector<uintptr_t>* locations = section.second.get();
- DCHECK(!name.empty());
- std::sort(locations->begin(), locations->end());
- // Reserve buffer space - guess 2 bytes per ULEB128.
- buffer->reserve(buffer->size() + name.size() + locations->size() * 2);
- // Write null-terminated section name.
- const uint8_t* name_data = reinterpret_cast<const uint8_t*>(name.c_str());
- buffer->insert(buffer->end(), name_data, name_data + name.size() + 1);
- // Write placeholder for data length.
- size_t length_pos = buffer->size();
- EncodeUnsignedLeb128(buffer, UINT32_MAX);
- // Write LEB128 encoded list of advances (deltas between consequtive addresses).
- size_t data_pos = buffer->size();
- uintptr_t address = 0; // relative to start of section.
- for (uintptr_t location : *locations) {
- DCHECK_LT(location - address, UINT32_MAX) << "Large gap between patch locations";
- EncodeUnsignedLeb128(buffer, location - address);
- address = location;
- }
- // Update length.
- UpdateUnsignedLeb128(buffer->data() + length_pos, buffer->size() - data_pos);
+void ElfWriterQuick<ElfTypes>::EncodeOatPatches(const std::vector<uintptr_t>& locations,
+ std::vector<uint8_t>* buffer) {
+ buffer->reserve(buffer->size() + locations.size() * 2); // guess 2 bytes per ULEB128.
+ uintptr_t address = 0; // relative to start of section.
+ for (uintptr_t location : locations) {
+ DCHECK_GE(location, address) << "Patch locations are not in sorted order";
+ EncodeUnsignedLeb128(buffer, dchecked_integral_cast<uint32_t>(location - address));
+ address = location;
}
- buffer->push_back(0); // End of sections.
}
class RodataWriter FINAL : public CodeOutput {
@@ -164,79 +156,95 @@ bool ElfWriterQuick<ElfTypes>::Write(
isa, rodata_size, &rodata_writer, text_size, &text_writer, bss_size));
// Add debug sections.
- // They are stack allocated here (in the same scope as the builder),
- // but they are registred with the builder only if they are used.
+ // They are allocated here (in the same scope as the builder),
+ // but they are registered with the builder only if they are used.
using RawSection = typename ElfBuilder<ElfTypes>::RawSection;
const auto* text = builder->GetText();
const bool is64bit = Is64BitInstructionSet(isa);
const int pointer_size = GetInstructionSetPointerSize(isa);
- RawSection eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kPageSize, 0,
- is64bit ? Patch<Elf_Addr, uint64_t, kPointerRelativeAddress> :
- Patch<Elf_Addr, uint32_t, kPointerRelativeAddress>,
- text);
- RawSection eh_frame_hdr(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0,
- Patch<Elf_Addr, uint32_t, kSectionRelativeAddress>, text);
- RawSection debug_frame(".debug_frame", SHT_PROGBITS, 0, nullptr, 0, pointer_size, 0,
- is64bit ? Patch<Elf_Addr, uint64_t, kAbsoluteAddress> :
- Patch<Elf_Addr, uint32_t, kAbsoluteAddress>,
- text);
- RawSection debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0,
- Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, text);
- RawSection debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
- RawSection debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
- RawSection debug_line(".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0,
- Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, text);
+ std::unique_ptr<RawSection> eh_frame(new RawSection(
+ ".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kPageSize, 0,
+ is64bit ? Patch<Elf_Addr, uint64_t, kPointerRelativeAddress> :
+ Patch<Elf_Addr, uint32_t, kPointerRelativeAddress>,
+ text));
+ std::unique_ptr<RawSection> eh_frame_hdr(new RawSection(
+ ".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0,
+ Patch<Elf_Addr, uint32_t, kSectionRelativeAddress>, text));
+ std::unique_ptr<RawSection> debug_frame(new RawSection(
+ ".debug_frame", SHT_PROGBITS, 0, nullptr, 0, pointer_size, 0,
+ is64bit ? Patch<Elf_Addr, uint64_t, kAbsoluteAddress> :
+ Patch<Elf_Addr, uint32_t, kAbsoluteAddress>,
+ text));
+ std::unique_ptr<RawSection> debug_frame_oat_patches(new RawSection(
+ ".debug_frame.oat_patches", SHT_OAT_PATCH));
+ std::unique_ptr<RawSection> debug_info(new RawSection(
+ ".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0,
+ Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, text));
+ std::unique_ptr<RawSection> debug_info_oat_patches(new RawSection(
+ ".debug_info.oat_patches", SHT_OAT_PATCH));
+ std::unique_ptr<RawSection> debug_abbrev(new RawSection(
+ ".debug_abbrev", SHT_PROGBITS));
+ std::unique_ptr<RawSection> debug_str(new RawSection(
+ ".debug_str", SHT_PROGBITS));
+ std::unique_ptr<RawSection> debug_line(new RawSection(
+ ".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0,
+ Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, text));
+ std::unique_ptr<RawSection> debug_line_oat_patches(new RawSection(
+ ".debug_line.oat_patches", SHT_OAT_PATCH));
if (!oat_writer->GetMethodDebugInfo().empty()) {
- if (compiler_driver_->GetCompilerOptions().GetIncludeCFI()) {
+ if (compiler_driver_->GetCompilerOptions().GetGenerateDebugInfo()) {
+ // Generate CFI (stack unwinding information).
if (kCFIFormat == dwarf::DW_EH_FRAME_FORMAT) {
dwarf::WriteCFISection(
compiler_driver_, oat_writer,
dwarf::DW_EH_PE_pcrel, kCFIFormat,
- eh_frame.GetBuffer(), eh_frame.GetPatchLocations(),
- eh_frame_hdr.GetBuffer(), eh_frame_hdr.GetPatchLocations());
- builder->RegisterSection(&eh_frame);
- builder->RegisterSection(&eh_frame_hdr);
+ eh_frame->GetBuffer(), eh_frame->GetPatchLocations(),
+ eh_frame_hdr->GetBuffer(), eh_frame_hdr->GetPatchLocations());
+ builder->RegisterSection(eh_frame.get());
+ builder->RegisterSection(eh_frame_hdr.get());
} else {
DCHECK(kCFIFormat == dwarf::DW_DEBUG_FRAME_FORMAT);
dwarf::WriteCFISection(
compiler_driver_, oat_writer,
dwarf::DW_EH_PE_absptr, kCFIFormat,
- debug_frame.GetBuffer(), debug_frame.GetPatchLocations(),
+ debug_frame->GetBuffer(), debug_frame->GetPatchLocations(),
nullptr, nullptr);
- builder->RegisterSection(&debug_frame);
- *oat_writer->GetAbsolutePatchLocationsFor(".debug_frame") =
- *debug_frame.GetPatchLocations();
+ builder->RegisterSection(debug_frame.get());
+ EncodeOatPatches(*debug_frame->GetPatchLocations(),
+ debug_frame_oat_patches->GetBuffer());
+ builder->RegisterSection(debug_frame_oat_patches.get());
}
- }
- if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
// Add methods to .symtab.
WriteDebugSymbols(builder.get(), oat_writer);
// Generate DWARF .debug_* sections.
dwarf::WriteDebugSections(
compiler_driver_, oat_writer,
- debug_info.GetBuffer(), debug_info.GetPatchLocations(),
- debug_abbrev.GetBuffer(),
- debug_str.GetBuffer(),
- debug_line.GetBuffer(), debug_line.GetPatchLocations());
- builder->RegisterSection(&debug_info);
- builder->RegisterSection(&debug_abbrev);
- builder->RegisterSection(&debug_str);
- builder->RegisterSection(&debug_line);
- *oat_writer->GetAbsolutePatchLocationsFor(".debug_info") =
- *debug_info.GetPatchLocations();
- *oat_writer->GetAbsolutePatchLocationsFor(".debug_line") =
- *debug_line.GetPatchLocations();
+ debug_info->GetBuffer(), debug_info->GetPatchLocations(),
+ debug_abbrev->GetBuffer(),
+ debug_str->GetBuffer(),
+ debug_line->GetBuffer(), debug_line->GetPatchLocations());
+ builder->RegisterSection(debug_info.get());
+ EncodeOatPatches(*debug_info->GetPatchLocations(),
+ debug_info_oat_patches->GetBuffer());
+ builder->RegisterSection(debug_info_oat_patches.get());
+ builder->RegisterSection(debug_abbrev.get());
+ builder->RegisterSection(debug_str.get());
+ builder->RegisterSection(debug_line.get());
+ EncodeOatPatches(*debug_line->GetPatchLocations(),
+ debug_line_oat_patches->GetBuffer());
+ builder->RegisterSection(debug_line_oat_patches.get());
}
}
- // Add relocation section.
- RawSection oat_patches(".oat_patches", SHT_OAT_PATCH, 0, nullptr, 0, 1, 0);
- if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation() ||
- // ElfWriter::Fixup will be called regardless and it needs to be able
- // to patch debug sections so we have to include patches for them.
- compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
- EncodeOatPatches(oat_writer->GetAbsolutePatchLocations(), oat_patches.GetBuffer());
- builder->RegisterSection(&oat_patches);
+ // Add relocation section for .text.
+ std::unique_ptr<RawSection> text_oat_patches(new RawSection(
+ ".text.oat_patches", SHT_OAT_PATCH));
+ if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
+ // Note that ElfWriter::Fixup will be called regardless and therefore
+ // we need to include oat_patches for debug sections unconditionally.
+ EncodeOatPatches(oat_writer->GetAbsolutePatchLocations(),
+ text_oat_patches->GetBuffer());
+ builder->RegisterSection(text_oat_patches.get());
}
return builder->Write(elf_file_);
@@ -245,6 +253,7 @@ bool ElfWriterQuick<ElfTypes>::Write(
template <typename ElfTypes>
static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writer) {
const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetMethodDebugInfo();
+ bool generated_mapping_symbol = false;
// Find all addresses (low_pc) which contain deduped methods.
// The first instance of method is not marked deduped_, but the rest is.
@@ -273,9 +282,14 @@ static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writ
// Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
// instructions, so that disassembler tools can correctly disassemble.
+ // Note that even if we generate just a single mapping symbol, ARM's Streamline
+ // requires it to match function symbol. Just address 0 does not work.
if (it->compiled_method_->GetInstructionSet() == kThumb2) {
- symtab->AddSymbol("$t", builder->GetText(), it->low_pc_ & ~1, true,
- 0, STB_LOCAL, STT_NOTYPE);
+ if (!generated_mapping_symbol || !kGenerateSingleArmMappingSymbol) {
+ symtab->AddSymbol("$t", builder->GetText(), it->low_pc_ & ~1, true,
+ 0, STB_LOCAL, STT_NOTYPE);
+ generated_mapping_symbol = true;
+ }
}
}
}
diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h
index 955b5684e7..fd202eeb5f 100644
--- a/compiler/elf_writer_quick.h
+++ b/compiler/elf_writer_quick.h
@@ -35,7 +35,7 @@ class ElfWriterQuick FINAL : public ElfWriter {
const CompilerDriver& driver)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void EncodeOatPatches(const OatWriter::PatchLocationsMap& sections,
+ static void EncodeOatPatches(const std::vector<uintptr_t>& locations,
std::vector<uint8_t>* buffer);
protected:
diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc
index 08523d8587..ccf34b816b 100644
--- a/compiler/elf_writer_test.cc
+++ b/compiler/elf_writer_test.cc
@@ -88,73 +88,41 @@ TEST_F(ElfWriterTest, dlsym) {
}
}
-// Run only on host since we do unaligned memory accesses.
-#ifndef HAVE_ANDROID_OS
-
-static void PatchSection(const std::vector<uintptr_t>& patch_locations,
- std::vector<uint8_t>* section, int32_t delta) {
- for (uintptr_t location : patch_locations) {
- *reinterpret_cast<int32_t*>(section->data() + location) += delta;
- }
-}
-
TEST_F(ElfWriterTest, EncodeDecodeOatPatches) {
- std::vector<uint8_t> oat_patches; // Encoded patches.
-
- // Encode patch locations for a few sections.
- OatWriter::PatchLocationsMap sections;
- std::vector<uintptr_t> patches0 { 0, 4, 8, 15, 128, 200 }; // NOLINT
- sections.emplace(".section0", std::unique_ptr<std::vector<uintptr_t>>(
- new std::vector<uintptr_t> { patches0 }));
- std::vector<uintptr_t> patches1 { 8, 127 }; // NOLINT
- sections.emplace(".section1", std::unique_ptr<std::vector<uintptr_t>>(
- new std::vector<uintptr_t> { patches1 }));
- std::vector<uintptr_t> patches2 { }; // NOLINT
- sections.emplace(".section2", std::unique_ptr<std::vector<uintptr_t>>(
- new std::vector<uintptr_t> { patches2 }));
- ElfWriterQuick32::EncodeOatPatches(sections, &oat_patches);
-
- // Create buffers to be patched.
- std::vector<uint8_t> initial_data(256);
- for (size_t i = 0; i < initial_data.size(); i++) {
- initial_data[i] = i;
+ const std::vector<std::vector<uintptr_t>> test_data {
+ { 0, 4, 8, 15, 128, 200 },
+ { 8, 8 + 127 },
+ { 8, 8 + 128 },
+ { },
+ };
+ for (const auto& patch_locations : test_data) {
+ constexpr int32_t delta = 0x11235813;
+
+ // Encode patch locations.
+ std::vector<uint8_t> oat_patches;
+ ElfWriterQuick32::EncodeOatPatches(patch_locations, &oat_patches);
+
+ // Create buffer to be patched.
+ std::vector<uint8_t> initial_data(256);
+ for (size_t i = 0; i < initial_data.size(); i++) {
+ initial_data[i] = i;
+ }
+
+ // Patch manually.
+ std::vector<uint8_t> expected = initial_data;
+ for (uintptr_t location : patch_locations) {
+ typedef __attribute__((__aligned__(1))) uint32_t UnalignedAddress;
+ *reinterpret_cast<UnalignedAddress*>(expected.data() + location) += delta;
+ }
+
+ // Decode and apply patch locations.
+ std::vector<uint8_t> actual = initial_data;
+ ElfFileImpl32::ApplyOatPatches(
+ oat_patches.data(), oat_patches.data() + oat_patches.size(), delta,
+ actual.data(), actual.data() + actual.size());
+
+ EXPECT_EQ(expected, actual);
}
- std::vector<uint8_t> section0_expected = initial_data;
- std::vector<uint8_t> section1_expected = initial_data;
- std::vector<uint8_t> section2_expected = initial_data;
- std::vector<uint8_t> section0_actual = initial_data;
- std::vector<uint8_t> section1_actual = initial_data;
- std::vector<uint8_t> section2_actual = initial_data;
-
- // Patch manually.
- constexpr int32_t delta = 0x11235813;
- PatchSection(patches0, &section0_expected, delta);
- PatchSection(patches1, &section1_expected, delta);
- PatchSection(patches2, &section2_expected, delta);
-
- // Decode and apply patch locations.
- bool section0_successful = ElfFileImpl32::ApplyOatPatches(
- oat_patches.data(), oat_patches.data() + oat_patches.size(),
- ".section0", delta,
- section0_actual.data(), section0_actual.data() + section0_actual.size());
- EXPECT_TRUE(section0_successful);
- EXPECT_EQ(section0_expected, section0_actual);
-
- bool section1_successful = ElfFileImpl32::ApplyOatPatches(
- oat_patches.data(), oat_patches.data() + oat_patches.size(),
- ".section1", delta,
- section1_actual.data(), section1_actual.data() + section1_actual.size());
- EXPECT_TRUE(section1_successful);
- EXPECT_EQ(section1_expected, section1_actual);
-
- bool section2_successful = ElfFileImpl32::ApplyOatPatches(
- oat_patches.data(), oat_patches.data() + oat_patches.size(),
- ".section2", delta,
- section2_actual.data(), section2_actual.data() + section2_actual.size());
- EXPECT_TRUE(section2_successful);
- EXPECT_EQ(section2_expected, section2_actual);
}
-#endif
-
} // namespace art
diff --git a/compiler/gc_map_builder.h b/compiler/gc_map_builder.h
index 4c36ef733c..45e3fc5589 100644
--- a/compiler/gc_map_builder.h
+++ b/compiler/gc_map_builder.h
@@ -19,8 +19,8 @@
#include <vector>
+#include "base/bit_utils.h"
#include "gc_map.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index bf32febabe..02a2588180 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -972,8 +972,8 @@ void ImageWriter::CopyAndFixupObjects() {
// Fix up the object previously had hash codes.
for (const std::pair<mirror::Object*, uint32_t>& hash_pair : saved_hashes_) {
Object* obj = hash_pair.first;
- DCHECK_EQ(obj->GetLockWord(false).ReadBarrierState(), 0U);
- obj->SetLockWord(LockWord::FromHashCode(hash_pair.second, 0U), false);
+ DCHECK_EQ(obj->GetLockWord<kVerifyNone>(false).ReadBarrierState(), 0U);
+ obj->SetLockWord<kVerifyNone>(LockWord::FromHashCode(hash_pair.second, 0U), false);
}
saved_hashes_.clear();
}
@@ -1008,11 +1008,11 @@ bool ImageWriter::CopyAndFixupIfDexCacheFieldArray(mirror::Object* dst, mirror::
const size_t num_elements = arr->GetLength();
if (target_ptr_size_ == 4u) {
// Will get fixed up by fixup object.
- dst->SetClass(down_cast<mirror::Class*>(
+ dst->SetClass<kVerifyNone>(down_cast<mirror::Class*>(
GetImageAddress(mirror::IntArray::GetArrayClass())));
} else {
DCHECK_EQ(target_ptr_size_, 8u);
- dst->SetClass(down_cast<mirror::Class*>(
+ dst->SetClass<kVerifyNone>(down_cast<mirror::Class*>(
GetImageAddress(mirror::LongArray::GetArrayClass())));
}
mirror::Array* dest_array = down_cast<mirror::Array*>(dst);
@@ -1027,15 +1027,15 @@ bool ImageWriter::CopyAndFixupIfDexCacheFieldArray(mirror::Object* dst, mirror::
fixup_location = image_begin_ + it2->second;
}
if (target_ptr_size_ == 4u) {
- down_cast<mirror::IntArray*>(dest_array)->SetWithoutChecks<kVerifyNone>(
+ down_cast<mirror::IntArray*>(dest_array)->SetWithoutChecks<false, false, kVerifyNone>(
i, static_cast<uint32_t>(reinterpret_cast<uint64_t>(fixup_location)));
} else {
DCHECK_EQ(target_ptr_size_, 8u);
- down_cast<mirror::LongArray*>(dest_array)->SetWithoutChecks<kVerifyNone>(
+ down_cast<mirror::LongArray*>(dest_array)->SetWithoutChecks<false, false, kVerifyNone>(
i, reinterpret_cast<uint64_t>(fixup_location));
}
}
- dst->SetLockWord(LockWord::Default(), false);
+ dst->SetLockWord<kVerifyNone>(LockWord::Default(), false);
return true;
}
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index c0cffa5b2e..5921732399 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -26,6 +26,7 @@
#include <string>
#include <ostream>
+#include "base/bit_utils.h"
#include "base/macros.h"
#include "driver/compiler_driver.h"
#include "gc/space/space.h"
@@ -35,7 +36,6 @@
#include "os.h"
#include "safe_map.h"
#include "gc/space/space.h"
-#include "utils.h"
namespace art {
@@ -136,7 +136,7 @@ class ImageWriter FINAL {
friend std::ostream& operator<<(std::ostream& stream, const Bin& bin);
- static constexpr size_t kBinBits = MinimumBitsToStore(kBinMirrorCount - 1);
+ static constexpr size_t kBinBits = MinimumBitsToStore<uint32_t>(kBinMirrorCount - 1);
// uint32 = typeof(lockword_)
static constexpr size_t kBinShift = BitSizeOf<uint32_t>() - kBinBits;
// 111000.....0
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index 7c400ee82c..e28f8f0418 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -18,6 +18,7 @@
#include "arch/instruction_set.h"
#include "arch/instruction_set_features.h"
+#include "base/time_utils.h"
#include "base/timing_logger.h"
#include "compiler_callbacks.h"
#include "dex/pass_manager.h"
@@ -73,8 +74,7 @@ JitCompiler::JitCompiler() : total_time_(0) {
false,
CompilerOptions::kDefaultTopKProfileThreshold,
false, // TODO: Think about debuggability of JIT-compiled code.
- false,
- false,
+ CompilerOptions::kDefaultGenerateDebugInfo,
false,
false,
false,
diff --git a/compiler/jni/quick/arm64/calling_convention_arm64.cc b/compiler/jni/quick/arm64/calling_convention_arm64.cc
index 03dccb93b9..8e7fd2b95f 100644
--- a/compiler/jni/quick/arm64/calling_convention_arm64.cc
+++ b/compiler/jni/quick/arm64/calling_convention_arm64.cc
@@ -158,7 +158,8 @@ Arm64JniCallingConvention::Arm64JniCallingConvention(bool is_static, bool is_syn
const char* shorty)
: JniCallingConvention(is_static, is_synchronized, shorty, kFramePointerSize) {
uint32_t core_spill_mask = CoreSpillMask();
- for (int x_reg = 0; x_reg < kNumberOfXRegisters; ++x_reg) {
+ DCHECK_EQ(XZR, kNumberOfXRegisters - 1); // Exclude XZR from the loop (avoid 1 << 32).
+ for (int x_reg = 0; x_reg < kNumberOfXRegisters - 1; ++x_reg) {
if (((1 << x_reg) & core_spill_mask) != 0) {
callee_save_regs_.push_back(
Arm64ManagedRegister::FromXRegister(static_cast<XRegister>(x_reg)));
diff --git a/compiler/jni/quick/calling_convention.cc b/compiler/jni/quick/calling_convention.cc
index 436fc0cfd0..2e146c4527 100644
--- a/compiler/jni/quick/calling_convention.cc
+++ b/compiler/jni/quick/calling_convention.cc
@@ -23,7 +23,6 @@
#include "jni/quick/mips64/calling_convention_mips64.h"
#include "jni/quick/x86/calling_convention_x86.h"
#include "jni/quick/x86_64/calling_convention_x86_64.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc
index a06303d23e..573c088aba 100644
--- a/compiler/jni/quick/jni_compiler.cc
+++ b/compiler/jni/quick/jni_compiler.cc
@@ -94,7 +94,7 @@ CompiledMethod* ArtJniCompileMethodInternal(CompilerDriver* driver,
// Assembler that holds generated instructions
std::unique_ptr<Assembler> jni_asm(Assembler::Create(instruction_set));
- jni_asm->cfi().SetEnabled(driver->GetCompilerOptions().GetIncludeCFI());
+ jni_asm->cfi().SetEnabled(driver->GetCompilerOptions().GetGenerateDebugInfo());
// Offsets into data structures
// TODO: if cross compiling these offsets are for the host not the target
diff --git a/compiler/jni/quick/x86/calling_convention_x86.cc b/compiler/jni/quick/x86/calling_convention_x86.cc
index 8a45f0c855..499dd7cf58 100644
--- a/compiler/jni/quick/x86/calling_convention_x86.cc
+++ b/compiler/jni/quick/x86/calling_convention_x86.cc
@@ -19,7 +19,6 @@
#include "base/logging.h"
#include "handle_scope-inl.h"
#include "utils/x86/managed_register_x86.h"
-#include "utils.h"
namespace art {
namespace x86 {
diff --git a/compiler/jni/quick/x86_64/calling_convention_x86_64.cc b/compiler/jni/quick/x86_64/calling_convention_x86_64.cc
index bbdf1fe7bb..7e92d12ce8 100644
--- a/compiler/jni/quick/x86_64/calling_convention_x86_64.cc
+++ b/compiler/jni/quick/x86_64/calling_convention_x86_64.cc
@@ -16,10 +16,10 @@
#include "calling_convention_x86_64.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "handle_scope-inl.h"
#include "utils/x86_64/managed_register_x86_64.h"
-#include "utils.h"
namespace art {
namespace x86_64 {
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 15b4017816..8f153b1905 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -351,9 +351,8 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor {
public:
InitCodeMethodVisitor(OatWriter* writer, size_t offset)
: OatDexMethodVisitor(writer, offset),
- text_absolute_patch_locations_(writer->GetAbsolutePatchLocationsFor(".text")),
debuggable_(writer->GetCompilerDriver()->GetCompilerOptions().GetDebuggable()) {
- text_absolute_patch_locations_->reserve(
+ writer_->absolute_patch_locations_.reserve(
writer_->compiler_driver_->GetNonRelativeLinkerPatchCount());
}
@@ -444,14 +443,13 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor {
uintptr_t base_loc = offset_ - code_size - writer_->oat_header_->GetExecutableOffset();
for (const LinkerPatch& patch : compiled_method->GetPatches()) {
if (!patch.IsPcRelative()) {
- text_absolute_patch_locations_->push_back(base_loc + patch.LiteralOffset());
+ writer_->absolute_patch_locations_.push_back(base_loc + patch.LiteralOffset());
}
}
}
}
- if (writer_->compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols() ||
- writer_->compiler_driver_->GetCompilerOptions().GetIncludeCFI()) {
+ if (writer_->compiler_driver_->GetCompilerOptions().GetGenerateDebugInfo()) {
// Record debug information for this function if we are doing that.
const uint32_t quick_code_start = quick_code_offset -
writer_->oat_header_->GetExecutableOffset() - thumb_offset;
@@ -547,9 +545,6 @@ class OatWriter::InitCodeMethodVisitor : public OatDexMethodVisitor {
// so we can simply compare the pointers to find out if things are duplicated.
SafeMap<const CompiledMethod*, uint32_t, CodeOffsetsKeyComparator> dedupe_map_;
- // Patch locations for the .text section.
- std::vector<uintptr_t>* const text_absolute_patch_locations_;
-
// Cache of compiler's --debuggable option.
const bool debuggable_;
};
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index 6f1b4ec15a..82b9377c07 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -19,7 +19,6 @@
#include <stdint.h>
#include <cstddef>
-#include <map>
#include <memory>
#include "linker/relative_patcher.h" // For linker::RelativePatcherTargetProvider.
@@ -82,8 +81,6 @@ class TimingLogger;
//
class OatWriter {
public:
- typedef std::map<std::string, std::unique_ptr<std::vector<uintptr_t>>> PatchLocationsMap;
-
OatWriter(const std::vector<const DexFile*>& dex_files,
uint32_t image_file_location_oat_checksum,
uintptr_t image_file_location_oat_begin,
@@ -105,19 +102,10 @@ class OatWriter {
return bss_size_;
}
- const PatchLocationsMap& GetAbsolutePatchLocations() const {
+ const std::vector<uintptr_t>& GetAbsolutePatchLocations() const {
return absolute_patch_locations_;
}
- std::vector<uintptr_t>* GetAbsolutePatchLocationsFor(const char* section_name) {
- auto it = absolute_patch_locations_.emplace(
- std::string(section_name), std::unique_ptr<std::vector<uintptr_t>>());
- if (it.second) { // Inserted new item.
- it.first->second.reset(new std::vector<uintptr_t>());
- }
- return it.first->second.get();
- }
-
bool WriteRodata(OutputStream* out);
bool WriteCode(OutputStream* out);
@@ -339,9 +327,8 @@ class OatWriter {
std::unique_ptr<linker::RelativePatcher> relative_patcher_;
- // The locations of absolute patches relative to the start of section.
- // The map's key is the ELF's section name (including the dot).
- PatchLocationsMap absolute_patch_locations_;
+ // The locations of absolute patches relative to the start of the executable section.
+ std::vector<uintptr_t> absolute_patch_locations_;
// Map method reference to assigned offset.
// Wrap the map in a class implementing linker::RelativePatcherTargetProvider.
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index edce9487f8..a17b578e4c 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -712,7 +712,11 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction,
} else {
clinit_check_requirement = HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit;
HLoadClass* load_class = new (arena_) HLoadClass(
- storage_index, *dex_compilation_unit_->GetDexFile(), is_referrer_class, dex_pc);
+ graph_->GetCurrentMethod(),
+ storage_index,
+ *dex_compilation_unit_->GetDexFile(),
+ is_referrer_class,
+ dex_pc);
current_block_->AddInstruction(load_class);
clinit_check = new (arena_) HClinitCheck(load_class, dex_pc);
current_block_->AddInstruction(clinit_check);
@@ -919,8 +923,11 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
*outer_compilation_unit_->GetDexFile(), storage_index);
bool is_initialized = resolved_field->GetDeclaringClass()->IsInitialized() && is_in_dex_cache;
- HLoadClass* constant = new (arena_) HLoadClass(
- storage_index, *dex_compilation_unit_->GetDexFile(), is_referrer_class, dex_pc);
+ HLoadClass* constant = new (arena_) HLoadClass(graph_->GetCurrentMethod(),
+ storage_index,
+ *dex_compilation_unit_->GetDexFile(),
+ is_referrer_class,
+ dex_pc);
current_block_->AddInstruction(constant);
HInstruction* cls = constant;
@@ -1167,6 +1174,7 @@ bool HGraphBuilder::BuildTypeCheck(const Instruction& instruction,
}
HInstruction* object = LoadLocal(reference, Primitive::kPrimNot);
HLoadClass* cls = new (arena_) HLoadClass(
+ graph_->GetCurrentMethod(),
type_index,
*dex_compilation_unit_->GetDexFile(),
IsOutermostCompilingClass(type_index),
@@ -2154,13 +2162,15 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
}
case Instruction::CONST_STRING: {
- current_block_->AddInstruction(new (arena_) HLoadString(instruction.VRegB_21c(), dex_pc));
+ current_block_->AddInstruction(
+ new (arena_) HLoadString(graph_->GetCurrentMethod(), instruction.VRegB_21c(), dex_pc));
UpdateLocal(instruction.VRegA_21c(), current_block_->GetLastInstruction());
break;
}
case Instruction::CONST_STRING_JUMBO: {
- current_block_->AddInstruction(new (arena_) HLoadString(instruction.VRegB_31c(), dex_pc));
+ current_block_->AddInstruction(
+ new (arena_) HLoadString(graph_->GetCurrentMethod(), instruction.VRegB_31c(), dex_pc));
UpdateLocal(instruction.VRegA_31c(), current_block_->GetLastInstruction());
break;
}
@@ -2182,6 +2192,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, uint32
return false;
}
current_block_->AddInstruction(new (arena_) HLoadClass(
+ graph_->GetCurrentMethod(),
type_index,
*dex_compilation_unit_->GetDexFile(),
IsOutermostCompilingClass(type_index),
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index 09ed9c700e..bd1f134c32 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -41,6 +41,7 @@ static bool ExpectedPairLayout(Location location) {
}
static constexpr int kCurrentMethodStackOffset = 0;
+static constexpr Register kMethodRegisterArgument = R0;
// We unconditionally allocate R5 to ensure we can do long operations
// with baseline.
@@ -494,11 +495,6 @@ InstructionCodeGeneratorARM::InstructionCodeGeneratorARM(HGraph* graph, CodeGene
assembler_(codegen->GetAssembler()),
codegen_(codegen) {}
-static uint32_t LeastSignificantBit(uint32_t mask) {
- // ffs starts at 1.
- return ffs(mask) - 1;
-}
-
void CodeGeneratorARM::ComputeSpillMask() {
core_spill_mask_ = allocated_registers_.GetCoreRegisters() & core_callee_save_mask_;
// Save one extra register for baseline. Note that on thumb2, there is no easy
@@ -549,7 +545,7 @@ void CodeGeneratorARM::GenerateFrameEntry() {
uint32_t push_mask = (core_spill_mask_ & (~(1 << PC))) | 1 << LR;
__ PushList(push_mask);
__ cfi().AdjustCFAOffset(kArmWordSize * POPCOUNT(push_mask));
- __ cfi().RelOffsetForMany(DWARFReg(R0), 0, push_mask, kArmWordSize);
+ __ cfi().RelOffsetForMany(DWARFReg(kMethodRegisterArgument), 0, push_mask, kArmWordSize);
if (fpu_spill_mask_ != 0) {
SRegister start_register = SRegister(LeastSignificantBit(fpu_spill_mask_));
__ vpushs(start_register, POPCOUNT(fpu_spill_mask_));
@@ -559,7 +555,7 @@ void CodeGeneratorARM::GenerateFrameEntry() {
int adjust = GetFrameSize() - FrameEntrySpillSize();
__ AddConstant(SP, -adjust);
__ cfi().AdjustCFAOffset(adjust);
- __ StoreToOffset(kStoreWord, R0, SP, 0);
+ __ StoreToOffset(kStoreWord, kMethodRegisterArgument, SP, 0);
}
void CodeGeneratorARM::GenerateFrameExit() {
@@ -808,11 +804,11 @@ void CodeGeneratorARM::Move64(Location destination, Location source) {
void CodeGeneratorARM::Move(HInstruction* instruction, Location location, HInstruction* move_for) {
LocationSummary* locations = instruction->GetLocations();
- if (locations != nullptr && locations->Out().Equals(location)) {
+ if (instruction->IsCurrentMethod()) {
+ Move32(location, Location::StackSlot(kCurrentMethodStackOffset));
+ } else if (locations != nullptr && locations->Out().Equals(location)) {
return;
- }
-
- if (locations != nullptr && locations->Out().IsConstant()) {
+ } else if (locations != nullptr && locations->Out().IsConstant()) {
HConstant* const_to_move = locations->Out().GetConstant();
if (const_to_move->IsIntConstant() || const_to_move->IsNullConstant()) {
int32_t value = GetInt32ValueOf(const_to_move);
@@ -1033,19 +1029,19 @@ void InstructionCodeGeneratorARM::VisitDeoptimize(HDeoptimize* deoptimize) {
GenerateTestAndBranch(deoptimize, slow_path_entry, nullptr, slow_path_entry);
}
-void LocationsBuilderARM::VisitCondition(HCondition* comp) {
+void LocationsBuilderARM::VisitCondition(HCondition* cond) {
LocationSummary* locations =
- new (GetGraph()->GetArena()) LocationSummary(comp, LocationSummary::kNoCall);
+ new (GetGraph()->GetArena()) LocationSummary(cond, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
- locations->SetInAt(1, Location::RegisterOrConstant(comp->InputAt(1)));
- if (comp->NeedsMaterialization()) {
+ locations->SetInAt(1, Location::RegisterOrConstant(cond->InputAt(1)));
+ if (cond->NeedsMaterialization()) {
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
}
}
-void InstructionCodeGeneratorARM::VisitCondition(HCondition* comp) {
- if (!comp->NeedsMaterialization()) return;
- LocationSummary* locations = comp->GetLocations();
+void InstructionCodeGeneratorARM::VisitCondition(HCondition* cond) {
+ if (!cond->NeedsMaterialization()) return;
+ LocationSummary* locations = cond->GetLocations();
Register left = locations->InAt(0).AsRegister<Register>();
if (locations->InAt(1).IsRegister()) {
@@ -1062,11 +1058,11 @@ void InstructionCodeGeneratorARM::VisitCondition(HCondition* comp) {
__ cmp(left, ShifterOperand(temp));
}
}
- __ it(ARMCondition(comp->GetCondition()), kItElse);
+ __ it(ARMCondition(cond->GetCondition()), kItElse);
__ mov(locations->Out().AsRegister<Register>(), ShifterOperand(1),
- ARMCondition(comp->GetCondition()));
+ ARMCondition(cond->GetCondition()));
__ mov(locations->Out().AsRegister<Register>(), ShifterOperand(0),
- ARMOppositeCondition(comp->GetCondition()));
+ ARMOppositeCondition(cond->GetCondition()));
}
void LocationsBuilderARM::VisitEqual(HEqual* comp) {
@@ -1291,7 +1287,7 @@ void InstructionCodeGeneratorARM::VisitInvokeStaticOrDirect(HInvokeStaticOrDirec
void LocationsBuilderARM::HandleInvoke(HInvoke* invoke) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
- locations->AddTemp(Location::RegisterLocation(R0));
+ locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
InvokeDexCallingConventionVisitorARM calling_convention_visitor;
for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
@@ -2222,7 +2218,7 @@ void InstructionCodeGeneratorARM::DivRemByPowerOfTwo(HBinaryOperation* instructi
Register dividend = locations->InAt(0).AsRegister<Register>();
Register temp = locations->GetTemp(0).AsRegister<Register>();
int32_t imm = second.GetConstant()->AsIntConstant()->GetValue();
- int32_t abs_imm = std::abs(imm);
+ uint32_t abs_imm = static_cast<uint32_t>(std::abs(imm));
DCHECK(IsPowerOfTwo(abs_imm));
int ctz_imm = CTZ(abs_imm);
@@ -2807,9 +2803,19 @@ void LocationsBuilderARM::VisitParameterValue(HParameterValue* instruction) {
locations->SetOut(location);
}
-void InstructionCodeGeneratorARM::VisitParameterValue(HParameterValue* instruction) {
+void InstructionCodeGeneratorARM::VisitParameterValue(
+ HParameterValue* instruction ATTRIBUTE_UNUSED) {
// Nothing to do, the parameter is already at its location.
- UNUSED(instruction);
+}
+
+void LocationsBuilderARM::VisitCurrentMethod(HCurrentMethod* instruction) {
+ LocationSummary* locations =
+ new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
+ locations->SetOut(Location::RegisterLocation(kMethodRegisterArgument));
+}
+
+void InstructionCodeGeneratorARM::VisitCurrentMethod(HCurrentMethod* instruction ATTRIBUTE_UNUSED) {
+ // Nothing to do, the method is already at its location.
}
void LocationsBuilderARM::VisitNot(HNot* not_) {
@@ -3959,21 +3965,25 @@ void LocationsBuilderARM::VisitLoadClass(HLoadClass* cls) {
: LocationSummary::kNoCall;
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(cls, call_kind);
+ locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister());
}
void InstructionCodeGeneratorARM::VisitLoadClass(HLoadClass* cls) {
- Register out = cls->GetLocations()->Out().AsRegister<Register>();
+ LocationSummary* locations = cls->GetLocations();
+ Register out = locations->Out().AsRegister<Register>();
+ Register current_method = locations->InAt(0).AsRegister<Register>();
if (cls->IsReferrersClass()) {
DCHECK(!cls->CanCallRuntime());
DCHECK(!cls->MustGenerateClinitCheck());
- codegen_->LoadCurrentMethod(out);
- __ LoadFromOffset(kLoadWord, out, out, mirror::ArtMethod::DeclaringClassOffset().Int32Value());
+ __ LoadFromOffset(
+ kLoadWord, out, current_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value());
} else {
DCHECK(cls->CanCallRuntime());
- codegen_->LoadCurrentMethod(out);
- __ LoadFromOffset(
- kLoadWord, out, out, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value());
+ __ LoadFromOffset(kLoadWord,
+ out,
+ current_method,
+ mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value());
__ LoadFromOffset(kLoadWord, out, out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex()));
SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM(
@@ -4021,6 +4031,7 @@ void InstructionCodeGeneratorARM::GenerateClassInitializationCheck(
void LocationsBuilderARM::VisitLoadString(HLoadString* load) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(load, LocationSummary::kCallOnSlowPath);
+ locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister());
}
@@ -4028,9 +4039,11 @@ void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) {
SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathARM(load);
codegen_->AddSlowPath(slow_path);
- Register out = load->GetLocations()->Out().AsRegister<Register>();
- codegen_->LoadCurrentMethod(out);
- __ LoadFromOffset(kLoadWord, out, out, mirror::ArtMethod::DeclaringClassOffset().Int32Value());
+ LocationSummary* locations = load->GetLocations();
+ Register out = locations->Out().AsRegister<Register>();
+ Register current_method = locations->InAt(0).AsRegister<Register>();
+ __ LoadFromOffset(
+ kLoadWord, out, current_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value());
__ LoadFromOffset(kLoadWord, out, out, mirror::Class::DexCacheStringsOffset().Int32Value());
__ LoadFromOffset(kLoadWord, out, out, CodeGenerator::GetCacheOffset(load->GetStringIndex()));
__ cmp(out, ShifterOperand(0));
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index b6d99abca0..cf5a8fb605 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -634,16 +634,16 @@ void CodeGeneratorARM64::Move(HInstruction* instruction,
Location location,
HInstruction* move_for) {
LocationSummary* locations = instruction->GetLocations();
- if (locations != nullptr && locations->Out().Equals(location)) {
- return;
- }
-
Primitive::Type type = instruction->GetType();
DCHECK_NE(type, Primitive::kPrimVoid);
- if (instruction->IsIntConstant()
- || instruction->IsLongConstant()
- || instruction->IsNullConstant()) {
+ if (instruction->IsCurrentMethod()) {
+ MoveLocation(location, Location::StackSlot(kCurrentMethodStackOffset));
+ } else if (locations != nullptr && locations->Out().Equals(location)) {
+ return;
+ } else if (instruction->IsIntConstant()
+ || instruction->IsLongConstant()
+ || instruction->IsNullConstant()) {
int64_t value = GetInt64ValueOf(instruction->AsConstant());
if (location.IsRegister()) {
Register dst = RegisterFrom(location, type);
@@ -1738,7 +1738,7 @@ void InstructionCodeGeneratorARM64::DivRemByPowerOfTwo(HBinaryOperation* instruc
Register out = OutputRegister(instruction);
Register dividend = InputRegisterAt(instruction, 0);
int64_t imm = Int64FromConstant(second.GetConstant());
- int64_t abs_imm = std::abs(imm);
+ uint64_t abs_imm = static_cast<uint64_t>(std::abs(imm));
DCHECK(IsPowerOfTwo(abs_imm));
int ctz_imm = CTZ(abs_imm);
@@ -2345,20 +2345,20 @@ void LocationsBuilderARM64::VisitLoadClass(HLoadClass* cls) {
LocationSummary::CallKind call_kind = cls->CanCallRuntime() ? LocationSummary::kCallOnSlowPath
: LocationSummary::kNoCall;
LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(cls, call_kind);
+ locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister());
}
void InstructionCodeGeneratorARM64::VisitLoadClass(HLoadClass* cls) {
Register out = OutputRegister(cls);
+ Register current_method = InputRegisterAt(cls, 0);
if (cls->IsReferrersClass()) {
DCHECK(!cls->CanCallRuntime());
DCHECK(!cls->MustGenerateClinitCheck());
- codegen_->LoadCurrentMethod(out);
- __ Ldr(out, HeapOperand(out, mirror::ArtMethod::DeclaringClassOffset()));
+ __ Ldr(out, HeapOperand(current_method, mirror::ArtMethod::DeclaringClassOffset()));
} else {
DCHECK(cls->CanCallRuntime());
- codegen_->LoadCurrentMethod(out);
- __ Ldr(out, HeapOperand(out, mirror::ArtMethod::DexCacheResolvedTypesOffset()));
+ __ Ldr(out, HeapOperand(current_method, mirror::ArtMethod::DexCacheResolvedTypesOffset()));
__ Ldr(out, HeapOperand(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())));
SlowPathCodeARM64* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathARM64(
@@ -2397,6 +2397,7 @@ void InstructionCodeGeneratorARM64::VisitLoadLocal(HLoadLocal* load) {
void LocationsBuilderARM64::VisitLoadString(HLoadString* load) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(load, LocationSummary::kCallOnSlowPath);
+ locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister());
}
@@ -2405,8 +2406,8 @@ void InstructionCodeGeneratorARM64::VisitLoadString(HLoadString* load) {
codegen_->AddSlowPath(slow_path);
Register out = OutputRegister(load);
- codegen_->LoadCurrentMethod(out);
- __ Ldr(out, HeapOperand(out, mirror::ArtMethod::DeclaringClassOffset()));
+ Register current_method = InputRegisterAt(load, 0);
+ __ Ldr(out, HeapOperand(current_method, mirror::ArtMethod::DeclaringClassOffset()));
__ Ldr(out, HeapOperand(out, mirror::Class::DexCacheStringsOffset()));
__ Ldr(out, HeapOperand(out, CodeGenerator::GetCacheOffset(load->GetStringIndex())));
__ Cbz(out, slow_path->GetEntryLabel());
@@ -2674,9 +2675,20 @@ void LocationsBuilderARM64::VisitParameterValue(HParameterValue* instruction) {
locations->SetOut(location);
}
-void InstructionCodeGeneratorARM64::VisitParameterValue(HParameterValue* instruction) {
+void InstructionCodeGeneratorARM64::VisitParameterValue(
+ HParameterValue* instruction ATTRIBUTE_UNUSED) {
// Nothing to do, the parameter is already at its location.
- UNUSED(instruction);
+}
+
+void LocationsBuilderARM64::VisitCurrentMethod(HCurrentMethod* instruction) {
+ LocationSummary* locations =
+ new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
+ locations->SetOut(LocationFrom(x0));
+}
+
+void InstructionCodeGeneratorARM64::VisitCurrentMethod(
+ HCurrentMethod* instruction ATTRIBUTE_UNUSED) {
+ // Nothing to do, the method is already at its location.
}
void LocationsBuilderARM64::VisitPhi(HPhi* instruction) {
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index a6f01dad38..81c3526b35 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -36,6 +36,7 @@ namespace art {
namespace x86 {
static constexpr int kCurrentMethodStackOffset = 0;
+static constexpr Register kMethodRegisterArgument = EAX;
static constexpr Register kCoreCalleeSaves[] = { EBP, ESI, EDI };
@@ -498,7 +499,7 @@ void CodeGeneratorX86::GenerateFrameEntry() {
int adjust = GetFrameSize() - FrameEntrySpillSize();
__ subl(ESP, Immediate(adjust));
__ cfi().AdjustCFAOffset(adjust);
- __ movl(Address(ESP, kCurrentMethodStackOffset), EAX);
+ __ movl(Address(ESP, kCurrentMethodStackOffset), kMethodRegisterArgument);
}
void CodeGeneratorX86::GenerateFrameExit() {
@@ -717,11 +718,11 @@ void CodeGeneratorX86::Move64(Location destination, Location source) {
void CodeGeneratorX86::Move(HInstruction* instruction, Location location, HInstruction* move_for) {
LocationSummary* locations = instruction->GetLocations();
- if (locations != nullptr && locations->Out().Equals(location)) {
+ if (instruction->IsCurrentMethod()) {
+ Move32(location, Location::StackSlot(kCurrentMethodStackOffset));
+ } else if (locations != nullptr && locations->Out().Equals(location)) {
return;
- }
-
- if (locations != nullptr && locations->Out().IsConstant()) {
+ } else if (locations != nullptr && locations->Out().IsConstant()) {
HConstant* const_to_move = locations->Out().GetConstant();
if (const_to_move->IsIntConstant() || const_to_move->IsNullConstant()) {
Immediate imm(GetInt32ValueOf(const_to_move));
@@ -983,20 +984,20 @@ void InstructionCodeGeneratorX86::VisitStoreLocal(HStoreLocal* store) {
UNUSED(store);
}
-void LocationsBuilderX86::VisitCondition(HCondition* comp) {
+void LocationsBuilderX86::VisitCondition(HCondition* cond) {
LocationSummary* locations =
- new (GetGraph()->GetArena()) LocationSummary(comp, LocationSummary::kNoCall);
+ new (GetGraph()->GetArena()) LocationSummary(cond, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::Any());
- if (comp->NeedsMaterialization()) {
+ if (cond->NeedsMaterialization()) {
// We need a byte register.
locations->SetOut(Location::RegisterLocation(ECX));
}
}
-void InstructionCodeGeneratorX86::VisitCondition(HCondition* comp) {
- if (comp->NeedsMaterialization()) {
- LocationSummary* locations = comp->GetLocations();
+void InstructionCodeGeneratorX86::VisitCondition(HCondition* cond) {
+ if (cond->NeedsMaterialization()) {
+ LocationSummary* locations = cond->GetLocations();
Register reg = locations->Out().AsRegister<Register>();
// Clear register: setcc only sets the low byte.
__ xorl(reg, reg);
@@ -1014,7 +1015,7 @@ void InstructionCodeGeneratorX86::VisitCondition(HCondition* comp) {
} else {
__ cmpl(lhs.AsRegister<Register>(), Address(ESP, rhs.GetStackIndex()));
}
- __ setb(X86Condition(comp->GetCondition()), reg);
+ __ setb(X86Condition(cond->GetCondition()), reg);
}
}
@@ -1239,7 +1240,7 @@ void LocationsBuilderX86::VisitInvokeVirtual(HInvokeVirtual* invoke) {
void LocationsBuilderX86::HandleInvoke(HInvoke* invoke) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
- locations->AddTemp(Location::RegisterLocation(EAX));
+ locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
InvokeDexCallingConventionVisitorX86 calling_convention_visitor;
for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
@@ -1959,6 +1960,8 @@ void InstructionCodeGeneratorX86::VisitAdd(HAdd* add) {
if (second.IsRegister()) {
if (out.AsRegister<Register>() == first.AsRegister<Register>()) {
__ addl(out.AsRegister<Register>(), second.AsRegister<Register>());
+ } else if (out.AsRegister<Register>() == second.AsRegister<Register>()) {
+ __ addl(out.AsRegister<Register>(), first.AsRegister<Register>());
} else {
__ leal(out.AsRegister<Register>(), Address(
first.AsRegister<Register>(), second.AsRegister<Register>(), TIMES_1, 0));
@@ -3010,8 +3013,17 @@ void LocationsBuilderX86::VisitParameterValue(HParameterValue* instruction) {
locations->SetOut(location);
}
-void InstructionCodeGeneratorX86::VisitParameterValue(HParameterValue* instruction) {
- UNUSED(instruction);
+void InstructionCodeGeneratorX86::VisitParameterValue(
+ HParameterValue* instruction ATTRIBUTE_UNUSED) {
+}
+
+void LocationsBuilderX86::VisitCurrentMethod(HCurrentMethod* instruction) {
+ LocationSummary* locations =
+ new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
+ locations->SetOut(Location::RegisterLocation(kMethodRegisterArgument));
+}
+
+void InstructionCodeGeneratorX86::VisitCurrentMethod(HCurrentMethod* instruction ATTRIBUTE_UNUSED) {
}
void LocationsBuilderX86::VisitNot(HNot* not_) {
@@ -4279,20 +4291,22 @@ void LocationsBuilderX86::VisitLoadClass(HLoadClass* cls) {
: LocationSummary::kNoCall;
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(cls, call_kind);
+ locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister());
}
void InstructionCodeGeneratorX86::VisitLoadClass(HLoadClass* cls) {
- Register out = cls->GetLocations()->Out().AsRegister<Register>();
+ LocationSummary* locations = cls->GetLocations();
+ Register out = locations->Out().AsRegister<Register>();
+ Register current_method = locations->InAt(0).AsRegister<Register>();
if (cls->IsReferrersClass()) {
DCHECK(!cls->CanCallRuntime());
DCHECK(!cls->MustGenerateClinitCheck());
- codegen_->LoadCurrentMethod(out);
- __ movl(out, Address(out, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
+ __ movl(out, Address(current_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
} else {
DCHECK(cls->CanCallRuntime());
- codegen_->LoadCurrentMethod(out);
- __ movl(out, Address(out, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value()));
+ __ movl(out, Address(
+ current_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value()));
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())));
SlowPathCodeX86* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathX86(
@@ -4338,6 +4352,7 @@ void InstructionCodeGeneratorX86::GenerateClassInitializationCheck(
void LocationsBuilderX86::VisitLoadString(HLoadString* load) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(load, LocationSummary::kCallOnSlowPath);
+ locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister());
}
@@ -4345,9 +4360,10 @@ void InstructionCodeGeneratorX86::VisitLoadString(HLoadString* load) {
SlowPathCodeX86* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathX86(load);
codegen_->AddSlowPath(slow_path);
- Register out = load->GetLocations()->Out().AsRegister<Register>();
- codegen_->LoadCurrentMethod(out);
- __ movl(out, Address(out, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
+ LocationSummary* locations = load->GetLocations();
+ Register out = locations->Out().AsRegister<Register>();
+ Register current_method = locations->InAt(0).AsRegister<Register>();
+ __ movl(out, Address(current_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
__ movl(out, Address(out, mirror::Class::DexCacheStringsOffset().Int32Value()));
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(load->GetStringIndex())));
__ testl(out, out);
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index f49c26db2b..f8125c64e1 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -39,13 +39,13 @@ namespace x86_64 {
static constexpr Register TMP = R11;
static constexpr int kCurrentMethodStackOffset = 0;
+static constexpr Register kMethodRegisterArgument = RDI;
static constexpr Register kCoreCalleeSaves[] = { RBX, RBP, R12, R13, R14, R15 };
static constexpr FloatRegister kFpuCalleeSaves[] = { XMM12, XMM13, XMM14, XMM15 };
static constexpr int kC2ConditionMask = 0x400;
-
#define __ reinterpret_cast<X86_64Assembler*>(codegen->GetAssembler())->
class NullCheckSlowPathX86_64 : public SlowPathCodeX86_64 {
@@ -545,7 +545,8 @@ void CodeGeneratorX86_64::GenerateFrameEntry() {
}
}
- __ movl(Address(CpuRegister(RSP), kCurrentMethodStackOffset), CpuRegister(RDI));
+ __ movl(Address(CpuRegister(RSP), kCurrentMethodStackOffset),
+ CpuRegister(kMethodRegisterArgument));
}
void CodeGeneratorX86_64::GenerateFrameExit() {
@@ -689,11 +690,11 @@ void CodeGeneratorX86_64::Move(HInstruction* instruction,
Location location,
HInstruction* move_for) {
LocationSummary* locations = instruction->GetLocations();
- if (locations != nullptr && locations->Out().Equals(location)) {
+ if (instruction->IsCurrentMethod()) {
+ Move(location, Location::StackSlot(kCurrentMethodStackOffset));
+ } else if (locations != nullptr && locations->Out().Equals(location)) {
return;
- }
-
- if (locations != nullptr && locations->Out().IsConstant()) {
+ } else if (locations != nullptr && locations->Out().IsConstant()) {
HConstant* const_to_move = locations->Out().GetConstant();
if (const_to_move->IsIntConstant() || const_to_move->IsNullConstant()) {
Immediate imm(GetInt32ValueOf(const_to_move));
@@ -944,19 +945,19 @@ void InstructionCodeGeneratorX86_64::VisitStoreLocal(HStoreLocal* store) {
UNUSED(store);
}
-void LocationsBuilderX86_64::VisitCondition(HCondition* comp) {
+void LocationsBuilderX86_64::VisitCondition(HCondition* cond) {
LocationSummary* locations =
- new (GetGraph()->GetArena()) LocationSummary(comp, LocationSummary::kNoCall);
+ new (GetGraph()->GetArena()) LocationSummary(cond, LocationSummary::kNoCall);
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::Any());
- if (comp->NeedsMaterialization()) {
+ if (cond->NeedsMaterialization()) {
locations->SetOut(Location::RequiresRegister());
}
}
-void InstructionCodeGeneratorX86_64::VisitCondition(HCondition* comp) {
- if (comp->NeedsMaterialization()) {
- LocationSummary* locations = comp->GetLocations();
+void InstructionCodeGeneratorX86_64::VisitCondition(HCondition* cond) {
+ if (cond->NeedsMaterialization()) {
+ LocationSummary* locations = cond->GetLocations();
CpuRegister reg = locations->Out().AsRegister<CpuRegister>();
// Clear register: setcc only sets the low byte.
__ xorl(reg, reg);
@@ -974,7 +975,7 @@ void InstructionCodeGeneratorX86_64::VisitCondition(HCondition* comp) {
} else {
__ cmpl(lhs.AsRegister<CpuRegister>(), Address(CpuRegister(RSP), rhs.GetStackIndex()));
}
- __ setcc(X86_64Condition(comp->GetCondition()), reg);
+ __ setcc(X86_64Condition(cond->GetCondition()), reg);
}
}
@@ -1339,7 +1340,7 @@ void InstructionCodeGeneratorX86_64::VisitInvokeStaticOrDirect(HInvokeStaticOrDi
void LocationsBuilderX86_64::HandleInvoke(HInvoke* invoke) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(invoke, LocationSummary::kCall);
- locations->AddTemp(Location::RegisterLocation(RDI));
+ locations->AddTemp(Location::RegisterLocation(kMethodRegisterArgument));
InvokeDexCallingConventionVisitorX86_64 calling_convention_visitor;
for (size_t i = 0; i < invoke->GetNumberOfArguments(); i++) {
@@ -2117,6 +2118,8 @@ void InstructionCodeGeneratorX86_64::VisitAdd(HAdd* add) {
if (second.IsRegister()) {
if (out.AsRegister<Register>() == first.AsRegister<Register>()) {
__ addl(out.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>());
+ } else if (out.AsRegister<Register>() == second.AsRegister<Register>()) {
+ __ addl(out.AsRegister<CpuRegister>(), first.AsRegister<CpuRegister>());
} else {
__ leal(out.AsRegister<CpuRegister>(), Address(
first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>(), TIMES_1, 0));
@@ -2140,6 +2143,8 @@ void InstructionCodeGeneratorX86_64::VisitAdd(HAdd* add) {
if (second.IsRegister()) {
if (out.AsRegister<Register>() == first.AsRegister<Register>()) {
__ addq(out.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>());
+ } else if (out.AsRegister<Register>() == second.AsRegister<Register>()) {
+ __ addq(out.AsRegister<CpuRegister>(), first.AsRegister<CpuRegister>());
} else {
__ leaq(out.AsRegister<CpuRegister>(), Address(
first.AsRegister<CpuRegister>(), second.AsRegister<CpuRegister>(), TIMES_1, 0));
@@ -3066,9 +3071,20 @@ void LocationsBuilderX86_64::VisitParameterValue(HParameterValue* instruction) {
locations->SetOut(location);
}
-void InstructionCodeGeneratorX86_64::VisitParameterValue(HParameterValue* instruction) {
+void InstructionCodeGeneratorX86_64::VisitParameterValue(
+ HParameterValue* instruction ATTRIBUTE_UNUSED) {
// Nothing to do, the parameter is already at its location.
- UNUSED(instruction);
+}
+
+void LocationsBuilderX86_64::VisitCurrentMethod(HCurrentMethod* instruction) {
+ LocationSummary* locations =
+ new (GetGraph()->GetArena()) LocationSummary(instruction, LocationSummary::kNoCall);
+ locations->SetOut(Location::RegisterLocation(kMethodRegisterArgument));
+}
+
+void InstructionCodeGeneratorX86_64::VisitCurrentMethod(
+ HCurrentMethod* instruction ATTRIBUTE_UNUSED) {
+ // Nothing to do, the method is already at its location.
}
void LocationsBuilderX86_64::VisitNot(HNot* not_) {
@@ -4123,20 +4139,22 @@ void LocationsBuilderX86_64::VisitLoadClass(HLoadClass* cls) {
: LocationSummary::kNoCall;
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(cls, call_kind);
+ locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister());
}
void InstructionCodeGeneratorX86_64::VisitLoadClass(HLoadClass* cls) {
- CpuRegister out = cls->GetLocations()->Out().AsRegister<CpuRegister>();
+ LocationSummary* locations = cls->GetLocations();
+ CpuRegister out = locations->Out().AsRegister<CpuRegister>();
+ CpuRegister current_method = locations->InAt(0).AsRegister<CpuRegister>();
if (cls->IsReferrersClass()) {
DCHECK(!cls->CanCallRuntime());
DCHECK(!cls->MustGenerateClinitCheck());
- codegen_->LoadCurrentMethod(out);
- __ movl(out, Address(out, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
+ __ movl(out, Address(current_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
} else {
DCHECK(cls->CanCallRuntime());
- codegen_->LoadCurrentMethod(out);
- __ movl(out, Address(out, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value()));
+ __ movl(out, Address(
+ current_method, mirror::ArtMethod::DexCacheResolvedTypesOffset().Int32Value()));
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(cls->GetTypeIndex())));
SlowPathCodeX86_64* slow_path = new (GetGraph()->GetArena()) LoadClassSlowPathX86_64(
cls, cls, cls->GetDexPc(), cls->MustGenerateClinitCheck());
@@ -4172,6 +4190,7 @@ void InstructionCodeGeneratorX86_64::VisitClinitCheck(HClinitCheck* check) {
void LocationsBuilderX86_64::VisitLoadString(HLoadString* load) {
LocationSummary* locations =
new (GetGraph()->GetArena()) LocationSummary(load, LocationSummary::kCallOnSlowPath);
+ locations->SetInAt(0, Location::RequiresRegister());
locations->SetOut(Location::RequiresRegister());
}
@@ -4179,9 +4198,10 @@ void InstructionCodeGeneratorX86_64::VisitLoadString(HLoadString* load) {
SlowPathCodeX86_64* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathX86_64(load);
codegen_->AddSlowPath(slow_path);
- CpuRegister out = load->GetLocations()->Out().AsRegister<CpuRegister>();
- codegen_->LoadCurrentMethod(CpuRegister(out));
- __ movl(out, Address(out, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
+ LocationSummary* locations = load->GetLocations();
+ CpuRegister out = locations->Out().AsRegister<CpuRegister>();
+ CpuRegister current_method = locations->InAt(0).AsRegister<CpuRegister>();
+ __ movl(out, Address(current_method, mirror::ArtMethod::DeclaringClassOffset().Int32Value()));
__ movl(out, Address(out, mirror::Class::DexCacheStringsOffset().Int32Value()));
__ movl(out, Address(out, CodeGenerator::GetCacheOffset(load->GetStringIndex())));
__ testl(out, out);
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index a72817fade..997f980f45 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -207,7 +207,9 @@ bool HInliner::TryBuildAndInline(Handle<mirror::ArtMethod> resolved_method,
if (!builder.BuildGraph(*code_item)) {
VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file)
<< " could not be built, so cannot be inlined";
- resolved_method->SetShouldNotInline();
+ // There could be multiple reasons why the graph could not be built, including
+ // unaccessible methods/fields due to using a different dex cache. We do not mark
+ // the method as non-inlineable so that other callers can still try to inline it.
return false;
}
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index 4e3436e32b..8ef13e125e 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -22,6 +22,7 @@
#include "invoke_type.h"
#include "nodes.h"
#include "quick/inline_method_analyser.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 2ece5a559c..80d4b4a863 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -19,6 +19,7 @@
#include "code_generator.h"
#include "ssa_builder.h"
#include "base/bit_vector-inl.h"
+#include "base/bit_utils.h"
#include "utils/growable_array.h"
#include "scoped_thread_state_change.h"
@@ -294,6 +295,19 @@ HNullConstant* HGraph::GetNullConstant() {
return cached_null_constant_;
}
+HCurrentMethod* HGraph::GetCurrentMethod() {
+ if (cached_current_method_ == nullptr) {
+ cached_current_method_ = new (arena_) HCurrentMethod();
+ if (entry_block_->GetFirstInstruction() == nullptr) {
+ entry_block_->AddInstruction(cached_current_method_);
+ } else {
+ entry_block_->InsertInstructionBefore(
+ cached_current_method_, entry_block_->GetFirstInstruction());
+ }
+ }
+ return cached_current_method_;
+}
+
HConstant* HGraph::GetConstant(Primitive::Type type, int64_t value) {
switch (type) {
case Primitive::Type::kPrimBoolean:
@@ -1460,6 +1474,8 @@ void HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {
DCHECK(parameter_index != last_input_index);
}
current->ReplaceWith(invoke->InputAt(parameter_index++));
+ } else if (current->IsCurrentMethod()) {
+ current->ReplaceWith(outer_graph->GetCurrentMethod());
} else {
DCHECK(current->IsGoto() || current->IsSuspendCheck());
entry_block_->RemoveInstruction(current);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index d9d09aafa2..944568dfc2 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -35,6 +35,7 @@ namespace art {
class GraphChecker;
class HBasicBlock;
+class HCurrentMethod;
class HDoubleConstant;
class HEnvironment;
class HFloatConstant;
@@ -149,7 +150,8 @@ class HGraph : public ArenaObject<kArenaAllocMisc> {
cached_int_constants_(std::less<int32_t>(), arena->Adapter()),
cached_float_constants_(std::less<int32_t>(), arena->Adapter()),
cached_long_constants_(std::less<int64_t>(), arena->Adapter()),
- cached_double_constants_(std::less<int64_t>(), arena->Adapter()) {}
+ cached_double_constants_(std::less<int64_t>(), arena->Adapter()),
+ cached_current_method_(nullptr) {}
ArenaAllocator* GetArena() const { return arena_; }
const GrowableArray<HBasicBlock*>& GetBlocks() const { return blocks_; }
@@ -280,6 +282,8 @@ class HGraph : public ArenaObject<kArenaAllocMisc> {
return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_);
}
+ HCurrentMethod* GetCurrentMethod();
+
HBasicBlock* FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const;
const DexFile& GetDexFile() const {
@@ -388,6 +392,8 @@ class HGraph : public ArenaObject<kArenaAllocMisc> {
ArenaSafeMap<int64_t, HLongConstant*> cached_long_constants_;
ArenaSafeMap<int64_t, HDoubleConstant*> cached_double_constants_;
+ HCurrentMethod* cached_current_method_;
+
friend class SsaBuilder; // For caching constants.
friend class SsaLivenessAnalysis; // For the linear order.
ART_FRIEND_TEST(GraphTest, IfSuccessorSimpleJoinBlock1);
@@ -813,6 +819,7 @@ class HLoopInformationOutwardIterator : public ValueObject {
M(ClinitCheck, Instruction) \
M(Compare, BinaryOperation) \
M(Condition, BinaryOperation) \
+ M(CurrentMethod, Instruction) \
M(Deoptimize, Instruction) \
M(Div, BinaryOperation) \
M(DivZeroCheck, Instruction) \
@@ -1826,6 +1833,19 @@ class HDeoptimize : public HTemplateInstruction<1> {
DISALLOW_COPY_AND_ASSIGN(HDeoptimize);
};
+// Represents the ArtMethod that was passed as a first argument to
+// the method. It is used by instructions that depend on it, like
+// instructions that work with the dex cache.
+class HCurrentMethod : public HExpression<0> {
+ public:
+ HCurrentMethod() : HExpression(Primitive::kPrimNot, SideEffects::None()) {}
+
+ DECLARE_INSTRUCTION(CurrentMethod);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HCurrentMethod);
+};
+
class HUnaryOperation : public HExpression<1> {
public:
HUnaryOperation(Primitive::Type result_type, HInstruction* input)
@@ -3455,9 +3475,10 @@ class HSuspendCheck : public HTemplateInstruction<0> {
/**
* Instruction to load a Class object.
*/
-class HLoadClass : public HExpression<0> {
+class HLoadClass : public HExpression<1> {
public:
- HLoadClass(uint16_t type_index,
+ HLoadClass(HCurrentMethod* current_method,
+ uint16_t type_index,
const DexFile& dex_file,
bool is_referrers_class,
uint32_t dex_pc)
@@ -3467,7 +3488,9 @@ class HLoadClass : public HExpression<0> {
is_referrers_class_(is_referrers_class),
dex_pc_(dex_pc),
generate_clinit_check_(false),
- loaded_class_rti_(ReferenceTypeInfo::CreateTop(/* is_exact */ false)) {}
+ loaded_class_rti_(ReferenceTypeInfo::CreateTop(/* is_exact */ false)) {
+ SetRawInputAt(0, current_method);
+ }
bool CanBeMoved() const OVERRIDE { return true; }
@@ -3539,12 +3562,14 @@ class HLoadClass : public HExpression<0> {
DISALLOW_COPY_AND_ASSIGN(HLoadClass);
};
-class HLoadString : public HExpression<0> {
+class HLoadString : public HExpression<1> {
public:
- HLoadString(uint32_t string_index, uint32_t dex_pc)
+ HLoadString(HCurrentMethod* current_method, uint32_t string_index, uint32_t dex_pc)
: HExpression(Primitive::kPrimNot, SideEffects::None()),
string_index_(string_index),
- dex_pc_(dex_pc) {}
+ dex_pc_(dex_pc) {
+ SetRawInputAt(0, current_method);
+ }
bool CanBeMoved() const OVERRIDE { return true; }
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index fa3c310811..3123843b7f 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -401,7 +401,7 @@ CompiledMethod* OptimizingCompiler::CompileOptimized(HGraph* graph,
codegen->CompileOptimized(&allocator);
DefaultSrcMap src_mapping_table;
- if (compiler_driver->GetCompilerOptions().GetIncludeDebugSymbols()) {
+ if (compiler_driver->GetCompilerOptions().GetGenerateDebugInfo()) {
codegen->BuildSourceMap(&src_mapping_table);
}
@@ -438,7 +438,7 @@ CompiledMethod* OptimizingCompiler::CompileBaseline(
std::vector<uint8_t> mapping_table;
codegen->BuildMappingTable(&mapping_table);
DefaultSrcMap src_mapping_table;
- if (compiler_driver->GetCompilerOptions().GetIncludeDebugSymbols()) {
+ if (compiler_driver->GetCompilerOptions().GetGenerateDebugInfo()) {
codegen->BuildSourceMap(&src_mapping_table);
}
std::vector<uint8_t> vmap_table;
@@ -534,7 +534,7 @@ CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_ite
return nullptr;
}
codegen->GetAssembler()->cfi().SetEnabled(
- compiler_driver->GetCompilerOptions().GetIncludeCFI());
+ compiler_driver->GetCompilerOptions().GetGenerateDebugInfo());
PassInfoPrinter pass_info_printer(graph,
method_name.c_str(),
diff --git a/compiler/optimizing/parallel_move_resolver.h b/compiler/optimizing/parallel_move_resolver.h
index e89417df7d..9ede91013e 100644
--- a/compiler/optimizing/parallel_move_resolver.h
+++ b/compiler/optimizing/parallel_move_resolver.h
@@ -20,6 +20,7 @@
#include "base/value_object.h"
#include "utils/growable_array.h"
#include "locations.h"
+#include "primitive.h"
namespace art {
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc
index 925099ade6..d4ff4d8dee 100644
--- a/compiler/optimizing/register_allocator.cc
+++ b/compiler/optimizing/register_allocator.cc
@@ -482,8 +482,9 @@ bool RegisterAllocator::ValidateIntervals(const GrowableArray<LiveInterval*>& in
LiveInterval* current = it.CurrentInterval();
HInstruction* defined_by = current->GetParent()->GetDefinedBy();
if (current->GetParent()->HasSpillSlot()
- // Parameters have their own stack slot.
- && !(defined_by != nullptr && defined_by->IsParameterValue())) {
+ // Parameters and current method have their own stack slot.
+ && !(defined_by != nullptr && (defined_by->IsParameterValue()
+ || defined_by->IsCurrentMethod()))) {
BitVector* liveness_of_spill_slot = liveness_of_values.Get(number_of_registers
+ current->GetParent()->GetSpillSlot() / kVRegSize
- number_of_out_slots);
@@ -1246,6 +1247,11 @@ void RegisterAllocator::AllocateSpillSlotFor(LiveInterval* interval) {
return;
}
+ if (defined_by->IsCurrentMethod()) {
+ parent->SetSpillSlot(0);
+ return;
+ }
+
if (defined_by->IsConstant()) {
// Constants don't need a spill slot.
return;
@@ -1519,7 +1525,10 @@ void RegisterAllocator::InsertMoveAfter(HInstruction* instruction,
void RegisterAllocator::ConnectSiblings(LiveInterval* interval) {
LiveInterval* current = interval;
- if (current->HasSpillSlot() && current->HasRegister()) {
+ if (current->HasSpillSlot()
+ && current->HasRegister()
+ // Currently, we spill unconditionnally the current method in the code generators.
+ && !interval->GetDefinedBy()->IsCurrentMethod()) {
// We spill eagerly, so move must be at definition.
InsertMoveAfter(interval->GetDefinedBy(),
interval->ToLocation(),
@@ -1715,6 +1724,9 @@ void RegisterAllocator::Resolve() {
} else if (current->HasSpillSlot()) {
current->SetSpillSlot(current->GetSpillSlot() + codegen_->GetFrameSize());
}
+ } else if (instruction->IsCurrentMethod()) {
+ // The current method is always at offset 0.
+ DCHECK(!current->HasSpillSlot() || (current->GetSpillSlot() == 0));
} else if (current->HasSpillSlot()) {
// Adjust the stack slot, now that we know the number of them for each type.
// The way this implementation lays out the stack is the following:
diff --git a/compiler/optimizing/register_allocator.h b/compiler/optimizing/register_allocator.h
index 6d5bfc3f0d..c29fe75921 100644
--- a/compiler/optimizing/register_allocator.h
+++ b/compiler/optimizing/register_allocator.h
@@ -17,6 +17,7 @@
#ifndef ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_
#define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_
+#include "arch/instruction_set.h"
#include "base/macros.h"
#include "primitive.h"
#include "utils/growable_array.h"
diff --git a/compiler/utils/arm/assembler_arm.cc b/compiler/utils/arm/assembler_arm.cc
index eca6f5a30c..0cd5c8b24b 100644
--- a/compiler/utils/arm/assembler_arm.cc
+++ b/compiler/utils/arm/assembler_arm.cc
@@ -16,11 +16,11 @@
#include "assembler_arm.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "offsets.h"
#include "thread.h"
-#include "utils.h"
namespace art {
namespace arm {
diff --git a/compiler/utils/arm/assembler_arm.h b/compiler/utils/arm/assembler_arm.h
index 52a69ca487..9179965a9d 100644
--- a/compiler/utils/arm/assembler_arm.h
+++ b/compiler/utils/arm/assembler_arm.h
@@ -19,13 +19,13 @@
#include <vector>
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "base/value_object.h"
#include "constants_arm.h"
#include "utils/arm/managed_register_arm.h"
#include "utils/assembler.h"
#include "offsets.h"
-#include "utils.h"
namespace art {
namespace arm {
diff --git a/compiler/utils/arm/assembler_arm32.cc b/compiler/utils/arm/assembler_arm32.cc
index 6e165fc151..cdf62bf885 100644
--- a/compiler/utils/arm/assembler_arm32.cc
+++ b/compiler/utils/arm/assembler_arm32.cc
@@ -16,11 +16,11 @@
#include "assembler_arm32.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "offsets.h"
#include "thread.h"
-#include "utils.h"
namespace art {
namespace arm {
diff --git a/compiler/utils/arm/assembler_arm32.h b/compiler/utils/arm/assembler_arm32.h
index 45647675e8..3164623fd9 100644
--- a/compiler/utils/arm/assembler_arm32.h
+++ b/compiler/utils/arm/assembler_arm32.h
@@ -24,7 +24,6 @@
#include "utils/arm/managed_register_arm.h"
#include "utils/arm/assembler_arm.h"
#include "offsets.h"
-#include "utils.h"
namespace art {
namespace arm {
diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc
index 4ff3aeb45b..26cb6c3739 100644
--- a/compiler/utils/arm/assembler_thumb2.cc
+++ b/compiler/utils/arm/assembler_thumb2.cc
@@ -16,11 +16,11 @@
#include "assembler_thumb2.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "offsets.h"
#include "thread.h"
-#include "utils.h"
namespace art {
namespace arm {
diff --git a/compiler/utils/arm/assembler_thumb2.h b/compiler/utils/arm/assembler_thumb2.h
index 9f02e56a74..2382b74c30 100644
--- a/compiler/utils/arm/assembler_thumb2.h
+++ b/compiler/utils/arm/assembler_thumb2.h
@@ -24,7 +24,6 @@
#include "utils/arm/managed_register_arm.h"
#include "utils/arm/assembler_arm.h"
#include "offsets.h"
-#include "utils.h"
namespace art {
namespace arm {
diff --git a/compiler/utils/arm64/assembler_arm64.cc b/compiler/utils/arm64/assembler_arm64.cc
index f924c71dc1..9cc0c914a0 100644
--- a/compiler/utils/arm64/assembler_arm64.cc
+++ b/compiler/utils/arm64/assembler_arm64.cc
@@ -19,7 +19,6 @@
#include "entrypoints/quick/quick_entrypoints.h"
#include "offsets.h"
#include "thread.h"
-#include "utils.h"
using namespace vixl; // NOLINT(build/namespaces)
diff --git a/compiler/utils/arm64/assembler_arm64.h b/compiler/utils/arm64/assembler_arm64.h
index e47b5314fd..b1b66ed49a 100644
--- a/compiler/utils/arm64/assembler_arm64.h
+++ b/compiler/utils/arm64/assembler_arm64.h
@@ -26,7 +26,6 @@
#include "utils/arm64/managed_register_arm64.h"
#include "utils/assembler.h"
#include "offsets.h"
-#include "utils.h"
// TODO: make vixl clean wrt -Wshadow.
#pragma GCC diagnostic push
diff --git a/compiler/utils/arm64/managed_register_arm64.h b/compiler/utils/arm64/managed_register_arm64.h
index 62c1d4dbee..dbcd8c56f7 100644
--- a/compiler/utils/arm64/managed_register_arm64.h
+++ b/compiler/utils/arm64/managed_register_arm64.h
@@ -117,8 +117,7 @@ class Arm64ManagedRegister : public ManagedRegister {
bool IsSRegister() const {
CHECK(IsValidManagedRegister());
- const int test = id_ - (kNumberOfXRegIds + kNumberOfWRegIds +
- kNumberOfDRegIds);
+ const int test = id_ - (kNumberOfXRegIds + kNumberOfWRegIds + kNumberOfDRegIds);
return (0 <= test) && (test < kNumberOfSRegIds);
}
diff --git a/compiler/utils/assembler_test_base.h b/compiler/utils/assembler_test_base.h
index 40eb15bbdc..c8b3fe58a8 100644
--- a/compiler/utils/assembler_test_base.h
+++ b/compiler/utils/assembler_test_base.h
@@ -17,14 +17,15 @@
#ifndef ART_COMPILER_UTILS_ASSEMBLER_TEST_BASE_H_
#define ART_COMPILER_UTILS_ASSEMBLER_TEST_BASE_H_
-#include "common_runtime_test.h" // For ScratchFile
-
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iterator>
#include <sys/stat.h>
+#include "common_runtime_test.h" // For ScratchFile
+#include "utils.h"
+
namespace art {
// If you want to take a look at the differences between the ART assembler and GCC, set this flag
diff --git a/compiler/utils/dedupe_set.h b/compiler/utils/dedupe_set.h
index a9a5781093..8cdb180740 100644
--- a/compiler/utils/dedupe_set.h
+++ b/compiler/utils/dedupe_set.h
@@ -26,6 +26,7 @@
#include "base/mutex.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
+#include "base/time_utils.h"
#include "utils/swap_space.h"
namespace art {
diff --git a/compiler/utils/dex_cache_arrays_layout-inl.h b/compiler/utils/dex_cache_arrays_layout-inl.h
index 2c50c96305..a71eeceafb 100644
--- a/compiler/utils/dex_cache_arrays_layout-inl.h
+++ b/compiler/utils/dex_cache_arrays_layout-inl.h
@@ -19,11 +19,11 @@
#include "dex_cache_arrays_layout.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "globals.h"
#include "mirror/array-inl.h"
#include "primitive.h"
-#include "utils.h"
namespace mirror {
class ArtMethod;
diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc
index 709a911f6a..e769489479 100644
--- a/compiler/utils/mips/assembler_mips.cc
+++ b/compiler/utils/mips/assembler_mips.cc
@@ -16,6 +16,7 @@
#include "assembler_mips.h"
+#include "base/bit_utils.h"
#include "base/casts.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "memory_region.h"
diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h
index d4acf03dc9..34713e1305 100644
--- a/compiler/utils/mips/assembler_mips.h
+++ b/compiler/utils/mips/assembler_mips.h
@@ -25,7 +25,6 @@
#include "managed_register_mips.h"
#include "utils/assembler.h"
#include "offsets.h"
-#include "utils.h"
namespace art {
namespace mips {
diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc
index 5e9653df33..b95e436897 100644
--- a/compiler/utils/mips64/assembler_mips64.cc
+++ b/compiler/utils/mips64/assembler_mips64.cc
@@ -16,6 +16,7 @@
#include "assembler_mips64.h"
+#include "base/bit_utils.h"
#include "base/casts.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "memory_region.h"
@@ -116,7 +117,7 @@ void Mips64Assembler::EmitJump(Label* label, bool link) {
int32_t Mips64Assembler::EncodeBranchOffset(int offset, int32_t inst, bool is_jump) {
CHECK_ALIGNED(offset, 4);
- CHECK(IsInt(POPCOUNT(kBranchOffsetMask), offset)) << offset;
+ CHECK(IsInt<POPCOUNT(kBranchOffsetMask)>(offset)) << offset;
// Properly preserve only the bits supported in the instruction.
offset >>= 2;
diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h
index 2d7c661eac..95ba967646 100644
--- a/compiler/utils/mips64/assembler_mips64.h
+++ b/compiler/utils/mips64/assembler_mips64.h
@@ -25,7 +25,6 @@
#include "managed_register_mips64.h"
#include "utils/assembler.h"
#include "offsets.h"
-#include "utils.h"
namespace art {
namespace mips64 {
diff --git a/compiler/utils/swap_space.h b/compiler/utils/swap_space.h
index 1f8f5da6cd..691df4a945 100644
--- a/compiler/utils/swap_space.h
+++ b/compiler/utils/swap_space.h
@@ -28,7 +28,6 @@
#include "base/macros.h"
#include "base/mutex.h"
#include "mem_map.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/utils/test_dex_file_builder.h b/compiler/utils/test_dex_file_builder.h
index ab039aa215..b1d7b4ccf3 100644
--- a/compiler/utils/test_dex_file_builder.h
+++ b/compiler/utils/test_dex_file_builder.h
@@ -22,8 +22,9 @@
#include <map>
#include <vector>
+#include "base/bit_utils.h"
+#include "base/logging.h"
#include "dex_file.h"
-#include "utils.h"
namespace art {
diff --git a/compiler/utils/test_dex_file_builder_test.cc b/compiler/utils/test_dex_file_builder_test.cc
index ee6e35dcce..7a424a23f5 100644
--- a/compiler/utils/test_dex_file_builder_test.cc
+++ b/compiler/utils/test_dex_file_builder_test.cc
@@ -18,6 +18,7 @@
#include "dex_file-inl.h"
#include "gtest/gtest.h"
+#include "utils.h"
namespace art {
diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h
index 136b0cbfdb..5319dacab7 100644
--- a/compiler/utils/x86/assembler_x86.h
+++ b/compiler/utils/x86/assembler_x86.h
@@ -18,13 +18,13 @@
#define ART_COMPILER_UTILS_X86_ASSEMBLER_X86_H_
#include <vector>
+#include "base/bit_utils.h"
#include "base/macros.h"
#include "constants_x86.h"
#include "globals.h"
#include "managed_register_x86.h"
#include "offsets.h"
#include "utils/assembler.h"
-#include "utils.h"
namespace art {
namespace x86 {
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index 162714af68..7daf994900 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -18,13 +18,14 @@
#define ART_COMPILER_UTILS_X86_64_ASSEMBLER_X86_64_H_
#include <vector>
+
+#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/assembler.h"
-#include "utils.h"
namespace art {
namespace x86_64 {
diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc
index 0be4d632fb..dcffe35113 100644
--- a/compiler/utils/x86_64/assembler_x86_64_test.cc
+++ b/compiler/utils/x86_64/assembler_x86_64_test.cc
@@ -20,9 +20,9 @@
#include <map>
#include <random>
+#include "base/bit_utils.h"
#include "base/stl_util.h"
#include "utils/assembler_test.h"
-#include "utils.h"
namespace art {
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 43bec37dda..cf4ef3ed3f 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -41,6 +41,7 @@
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/stringpiece.h"
+#include "base/time_utils.h"
#include "base/timing_logger.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
@@ -229,14 +230,14 @@ NO_RETURN static void Usage(const char* fmt, ...) {
UsageError("");
UsageError(" --no-include-patch-information: Do not include patching information.");
UsageError("");
- UsageError(" --include-debug-symbols: Include ELF symbols in this oat file");
+ UsageError(" -g");
+ UsageError(" --generate-debug-info: Generate debug information for native debugging,");
+ UsageError(" such as stack unwinding information, ELF symbols and DWARF sections.");
+ UsageError(" This generates all the available information. Unneeded parts can be");
+ UsageError(" stripped using standard command line tools such as strip or objcopy.");
+ UsageError(" (enabled by default in debug builds, disabled by default otherwise)");
UsageError("");
- UsageError(" --no-include-debug-symbols: Do not include ELF symbols in this oat file");
- UsageError("");
- UsageError(" --include-cfi: Include call frame information in the .eh_frame section.");
- UsageError(" The --include-debug-symbols option implies --include-cfi.");
- UsageError("");
- UsageError(" --no-include-cfi: Do not include call frame information in the .eh_frame section.");
+ UsageError(" --no-generate-debug-info: Do not generate debug information for native debugging.");
UsageError("");
UsageError(" --runtime-arg <argument>: used to specify various arguments for the runtime,");
UsageError(" such as initial heap size, maximum heap size, and verbose output.");
@@ -498,8 +499,7 @@ class Dex2Oat FINAL {
bool debuggable = false;
bool include_patch_information = CompilerOptions::kDefaultIncludePatchInformation;
- bool include_debug_symbols = kIsDebugBuild;
- bool include_cfi = kIsDebugBuild;
+ bool generate_debug_info = kIsDebugBuild;
bool watch_dog_enabled = true;
bool abort_on_hard_verifier_error = false;
bool requested_specific_compiler = false;
@@ -681,18 +681,13 @@ class Dex2Oat FINAL {
dump_cfg_file_name_ = option.substr(strlen("--dump-cfg=")).data();
} else if (option == "--dump-stats") {
dump_stats_ = true;
- } else if (option == "--include-debug-symbols" || option == "--no-strip-symbols") {
- include_debug_symbols = true;
- } else if (option == "--no-include-debug-symbols" || option == "--strip-symbols") {
- include_debug_symbols = false;
- } else if (option == "--include-cfi") {
- include_cfi = true;
- } else if (option == "--no-include-cfi") {
- include_cfi = false;
+ } else if (option == "--generate-debug-info" || option == "-g") {
+ generate_debug_info = true;
+ } else if (option == "--no-generate-debug-info") {
+ generate_debug_info = false;
} else if (option == "--debuggable") {
debuggable = true;
- include_debug_symbols = true;
- include_cfi = true;
+ generate_debug_info = true;
} else if (option.starts_with("--profile-file=")) {
profile_file_ = option.substr(strlen("--profile-file=")).data();
VLOG(compiler) << "dex2oat: profile file is " << profile_file_;
@@ -932,10 +927,6 @@ class Dex2Oat FINAL {
break;
}
- if (debuggable) {
- // TODO: Consider adding CFI info and symbols here.
- }
-
compiler_options_.reset(new CompilerOptions(compiler_filter,
huge_method_threshold,
large_method_threshold,
@@ -945,8 +936,7 @@ class Dex2Oat FINAL {
include_patch_information,
top_k_profile_threshold,
debuggable,
- include_debug_symbols,
- include_cfi,
+ generate_debug_info,
implicit_null_checks,
implicit_so_checks,
implicit_suspend_checks,
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 949c2cbcc8..04f5a6add8 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -1035,7 +1035,7 @@ class OatDumper {
void DumpCodeInfo(std::ostream& os,
const CodeInfo& code_info,
const DexFile::CodeItem& code_item) {
- code_info.Dump(os, code_item.registers_size_);
+ code_info.Dump(os, code_item.registers_size_, true);
}
// Display a vmap table.
@@ -2302,7 +2302,7 @@ struct OatdumpArgs : public CmdlineArgs {
" --dump:raw_mapping_table enables dumping of the mapping table.\n"
" Example: --dump:raw_mapping_table\n"
"\n"
- " --dump:raw_mapping_table enables dumping of the GC map.\n"
+ " --dump:raw_gc_map enables dumping of the GC map.\n"
" Example: --dump:raw_gc_map\n"
"\n"
" --no-dump:vmap may be used to disable vmap dumping.\n"
diff --git a/oatdump/oatdump_test.cc b/oatdump/oatdump_test.cc
new file mode 100644
index 0000000000..b34bc84eca
--- /dev/null
+++ b/oatdump/oatdump_test.cc
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#include <string>
+#include <vector>
+#include <sstream>
+
+#include "common_runtime_test.h"
+
+#include "base/stringprintf.h"
+#include "runtime/arch/instruction_set.h"
+#include "runtime/gc/heap.h"
+#include "runtime/gc/space/image_space.h"
+#include "runtime/os.h"
+#include "runtime/utils.h"
+#include "utils.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace art {
+
+class OatDumpTest : public CommonRuntimeTest {
+ protected:
+ virtual void SetUp() {
+ CommonRuntimeTest::SetUp();
+ core_art_location_ = GetCoreArtLocation();
+ core_oat_location_ = GetSystemImageFilename(GetCoreOatLocation().c_str(), kRuntimeISA);
+ }
+
+ // Returns path to the oatdump binary.
+ std::string GetOatDumpFilePath() {
+ std::string root = GetTestAndroidRoot();
+ root += "/bin/oatdump";
+ if (kIsDebugBuild) {
+ root += "d";
+ }
+ return root;
+ }
+
+ enum Mode {
+ kModeOat,
+ kModeArt,
+ kModeSymbolize,
+ };
+
+ // Run the test with custom arguments.
+ bool Exec(Mode mode, const std::vector<std::string>& args, std::string* error_msg) {
+ std::string file_path = GetOatDumpFilePath();
+
+ EXPECT_TRUE(OS::FileExists(file_path.c_str())) << file_path << " should be a valid file path";
+
+ std::vector<std::string> exec_argv = { file_path };
+ if (mode == kModeSymbolize) {
+ exec_argv.push_back("--symbolize=" + core_oat_location_);
+ exec_argv.push_back("--output=" + core_oat_location_ + ".symbolize");
+ } else if (mode == kModeArt) {
+ exec_argv.push_back("--image=" + core_art_location_);
+ exec_argv.push_back("--output=/dev/null");
+ } else {
+ CHECK_EQ(static_cast<size_t>(mode), static_cast<size_t>(kModeOat));
+ exec_argv.push_back("--oat-file=" + core_oat_location_);
+ exec_argv.push_back("--output=/dev/null");
+ }
+ exec_argv.insert(exec_argv.end(), args.begin(), args.end());
+ return ::art::Exec(exec_argv, error_msg);
+ }
+
+ private:
+ std::string core_art_location_;
+ std::string core_oat_location_;
+};
+
+TEST_F(OatDumpTest, TestImage) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeArt, {}, &error_msg)) << error_msg;
+}
+
+TEST_F(OatDumpTest, TestOatImage) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeOat, {}, &error_msg)) << error_msg;
+}
+
+TEST_F(OatDumpTest, TestDumpRawMappingTable) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeArt, {"--dump:raw_mapping_table"}, &error_msg)) << error_msg;
+}
+
+TEST_F(OatDumpTest, TestDumpRawGcMap) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeArt, {"--dump:raw_gc_map"}, &error_msg)) << error_msg;
+}
+
+TEST_F(OatDumpTest, TestNoDumpVmap) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeArt, {"--no-dump:vmap"}, &error_msg)) << error_msg;
+}
+
+TEST_F(OatDumpTest, TestNoDisassemble) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeArt, {"--no-disassemble"}, &error_msg)) << error_msg;
+}
+
+TEST_F(OatDumpTest, TestListClasses) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeArt, {"--list-classes"}, &error_msg)) << error_msg;
+}
+
+TEST_F(OatDumpTest, TestListMethods) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeArt, {"--list-methods"}, &error_msg)) << error_msg;
+}
+
+TEST_F(OatDumpTest, TestSymbolize) {
+ std::string error_msg;
+ ASSERT_TRUE(Exec(kModeSymbolize, {}, &error_msg)) << error_msg;
+}
+
+} // namespace art
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index ef84a1717c..8db1d2398f 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -563,21 +563,21 @@ void PatchOat::FixupMethod(mirror::ArtMethod* object, mirror::ArtMethod* copy) {
uintptr_t quick= reinterpret_cast<uintptr_t>(
object->GetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(pointer_size));
if (quick != 0) {
- copy->SetEntryPointFromQuickCompiledCodePtrSize(reinterpret_cast<void*>(quick + delta_),
- pointer_size);
+ copy->SetEntryPointFromQuickCompiledCodePtrSize<kVerifyNone>(
+ reinterpret_cast<void*>(quick + delta_), pointer_size);
}
uintptr_t interpreter = reinterpret_cast<uintptr_t>(
object->GetEntryPointFromInterpreterPtrSize<kVerifyNone>(pointer_size));
if (interpreter != 0) {
- copy->SetEntryPointFromInterpreterPtrSize(
+ copy->SetEntryPointFromInterpreterPtrSize<kVerifyNone>(
reinterpret_cast<mirror::EntryPointFromInterpreter*>(interpreter + delta_), pointer_size);
}
uintptr_t native_method = reinterpret_cast<uintptr_t>(
object->GetEntryPointFromJniPtrSize(pointer_size));
if (native_method != 0) {
- copy->SetEntryPointFromJniPtrSize(reinterpret_cast<void*>(native_method + delta_),
- pointer_size);
+ copy->SetEntryPointFromJniPtrSize<kVerifyNone>(
+ reinterpret_cast<void*>(native_method + delta_), pointer_size);
}
}
diff --git a/patchoat/patchoat.h b/patchoat/patchoat.h
index 86f9118e2e..8f16f6b283 100644
--- a/patchoat/patchoat.h
+++ b/patchoat/patchoat.h
@@ -25,7 +25,6 @@
#include "gc/accounting/space_bitmap.h"
#include "gc/heap.h"
#include "os.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/Android.mk b/runtime/Android.mk
index ece9d4b87a..a4fa24d43c 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -32,6 +32,7 @@ LIBART_COMMON_SRC_FILES := \
base/scoped_flock.cc \
base/stringpiece.cc \
base/stringprintf.cc \
+ base/time_utils.cc \
base/timing_logger.cc \
base/unix_file/fd_file.cc \
base/unix_file/random_access_file_utils.cc \
diff --git a/runtime/arch/arm/context_arm.cc b/runtime/arch/arm/context_arm.cc
index 5bd23d0def..c0e658ca47 100644
--- a/runtime/arch/arm/context_arm.cc
+++ b/runtime/arch/arm/context_arm.cc
@@ -16,9 +16,9 @@
#include "context_arm.h"
+#include "base/bit_utils.h"
#include "mirror/art_method-inl.h"
#include "quick/quick_method_frame_info.h"
-#include "utils.h"
namespace art {
namespace arm {
@@ -26,12 +26,8 @@ namespace arm {
static constexpr uint32_t gZero = 0;
void ArmContext::Reset() {
- for (size_t i = 0; i < kNumberOfCoreRegisters; i++) {
- gprs_[i] = nullptr;
- }
- for (size_t i = 0; i < kNumberOfSRegisters; i++) {
- fprs_[i] = nullptr;
- }
+ std::fill_n(gprs_, arraysize(gprs_), nullptr);
+ std::fill_n(fprs_, arraysize(fprs_), nullptr);
gprs_[SP] = &sp_;
gprs_[PC] = &pc_;
// Initialize registers with easy to spot debug values.
@@ -42,29 +38,23 @@ void ArmContext::Reset() {
void ArmContext::FillCalleeSaves(const StackVisitor& fr) {
mirror::ArtMethod* method = fr.GetMethod();
const QuickMethodFrameInfo frame_info = method->GetQuickFrameInfo();
- size_t spill_count = POPCOUNT(frame_info.CoreSpillMask());
- size_t fp_spill_count = POPCOUNT(frame_info.FpSpillMask());
- if (spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context
- int j = 1;
- for (size_t i = 0; i < kNumberOfCoreRegisters; i++) {
- if (((frame_info.CoreSpillMask() >> i) & 1) != 0) {
- gprs_[i] = fr.CalleeSaveAddress(spill_count - j, frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ int spill_pos = 0;
+
+ // Core registers come first, from the highest down to the lowest.
+ uint32_t core_regs = frame_info.CoreSpillMask();
+ DCHECK_EQ(0u, core_regs & (static_cast<uint32_t>(-1) << kNumberOfCoreRegisters));
+ for (uint32_t core_reg : HighToLowBits(core_regs)) {
+ gprs_[core_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
- if (fp_spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context
- int j = 1;
- for (size_t i = 0; i < kNumberOfSRegisters; i++) {
- if (((frame_info.FpSpillMask() >> i) & 1) != 0) {
- fprs_[i] = fr.CalleeSaveAddress(spill_count + fp_spill_count - j,
- frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()));
+
+ // FP registers come second, from the highest down to the lowest.
+ for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) {
+ fprs_[fp_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask()));
}
void ArmContext::SetGPR(uint32_t reg, uintptr_t value) {
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 3c145d77ad..6e53ba489f 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -890,10 +890,7 @@ END art_quick_proxy_invoke_handler
* dex method index.
*/
ENTRY art_quick_imt_conflict_trampoline
- ldr r0, [sp, #0] @ load caller Method*
- ldr r0, [r0, #MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET] @ load dex_cache_resolved_methods
- add r0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET @ get starting address of data
- ldr r0, [r0, r12, lsl 2] @ load the target method
+ mov r0, r12
b art_quick_invoke_interface_trampoline
END art_quick_imt_conflict_trampoline
diff --git a/runtime/arch/arm/quick_method_frame_info_arm.h b/runtime/arch/arm/quick_method_frame_info_arm.h
index c1f3fc256d..5580ee4f17 100644
--- a/runtime/arch/arm/quick_method_frame_info_arm.h
+++ b/runtime/arch/arm/quick_method_frame_info_arm.h
@@ -17,10 +17,10 @@
#ifndef ART_RUNTIME_ARCH_ARM_QUICK_METHOD_FRAME_INFO_ARM_H_
#define ART_RUNTIME_ARCH_ARM_QUICK_METHOD_FRAME_INFO_ARM_H_
+#include "base/bit_utils.h"
#include "quick/quick_method_frame_info.h"
#include "registers_arm.h"
#include "runtime.h" // for Runtime::CalleeSaveType.
-#include "utils.h"
namespace art {
namespace arm {
diff --git a/runtime/arch/arm64/context_arm64.cc b/runtime/arch/arm64/context_arm64.cc
index 2e93c1d2a9..5488f9d602 100644
--- a/runtime/arch/arm64/context_arm64.cc
+++ b/runtime/arch/arm64/context_arm64.cc
@@ -18,9 +18,9 @@
#include "context_arm64.h"
+#include "base/bit_utils.h"
#include "mirror/art_method-inl.h"
#include "quick/quick_method_frame_info.h"
-#include "utils.h"
namespace art {
namespace arm64 {
@@ -28,12 +28,8 @@ namespace arm64 {
static constexpr uint64_t gZero = 0;
void Arm64Context::Reset() {
- for (size_t i = 0; i < kNumberOfXRegisters; i++) {
- gprs_[i] = nullptr;
- }
- for (size_t i = 0; i < kNumberOfDRegisters; i++) {
- fprs_[i] = nullptr;
- }
+ std::fill_n(gprs_, arraysize(gprs_), nullptr);
+ std::fill_n(fprs_, arraysize(fprs_), nullptr);
gprs_[SP] = &sp_;
gprs_[LR] = &pc_;
// Initialize registers with easy to spot debug values.
@@ -44,30 +40,21 @@ void Arm64Context::Reset() {
void Arm64Context::FillCalleeSaves(const StackVisitor& fr) {
mirror::ArtMethod* method = fr.GetMethod();
const QuickMethodFrameInfo frame_info = method->GetQuickFrameInfo();
- size_t spill_count = POPCOUNT(frame_info.CoreSpillMask());
- size_t fp_spill_count = POPCOUNT(frame_info.FpSpillMask());
- if (spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- int j = 1;
- for (size_t i = 0; i < kNumberOfXRegisters; i++) {
- if (((frame_info.CoreSpillMask() >> i) & 1) != 0) {
- gprs_[i] = fr.CalleeSaveAddress(spill_count - j, frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ int spill_pos = 0;
+
+ // Core registers come first, from the highest down to the lowest.
+ for (uint32_t core_reg : HighToLowBits(frame_info.CoreSpillMask())) {
+ gprs_[core_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()));
- if (fp_spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- int j = 1;
- for (size_t i = 0; i < kNumberOfDRegisters; i++) {
- if (((frame_info.FpSpillMask() >> i) & 1) != 0) {
- fprs_[i] = fr.CalleeSaveAddress(spill_count + fp_spill_count - j,
- frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ // FP registers come second, from the highest down to the lowest.
+ for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) {
+ fprs_[fp_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask()));
}
void Arm64Context::SetGPR(uint32_t reg, uintptr_t value) {
@@ -147,7 +134,7 @@ void Arm64Context::DoLongJump() {
gprs[i] = gprs_[i] != nullptr ? *gprs_[i] : Arm64Context::kBadGprBase + i;
}
for (size_t i = 0; i < kNumberOfDRegisters; ++i) {
- fprs[i] = fprs_[i] != nullptr ? *fprs_[i] : Arm64Context::kBadGprBase + i;
+ fprs[i] = fprs_[i] != nullptr ? *fprs_[i] : Arm64Context::kBadFprBase + i;
}
DCHECK_EQ(reinterpret_cast<uintptr_t>(Thread::Current()), gprs[TR]);
art_quick_do_long_jump(gprs, fprs);
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 991d29f384..7eb6c16117 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1426,10 +1426,7 @@ END art_quick_proxy_invoke_handler
* dex method index.
*/
ENTRY art_quick_imt_conflict_trampoline
- ldr w0, [sp, #0] // load caller Method*
- ldr w0, [x0, #MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET] // load dex_cache_resolved_methods
- add x0, x0, #MIRROR_OBJECT_ARRAY_DATA_OFFSET // get starting address of data
- ldr w0, [x0, xIP1, lsl 2] // load the target method
+ mov x0, xIP1
b art_quick_invoke_interface_trampoline
END art_quick_imt_conflict_trampoline
diff --git a/runtime/arch/arm64/quick_method_frame_info_arm64.h b/runtime/arch/arm64/quick_method_frame_info_arm64.h
index bf1a92d9d7..b525309e96 100644
--- a/runtime/arch/arm64/quick_method_frame_info_arm64.h
+++ b/runtime/arch/arm64/quick_method_frame_info_arm64.h
@@ -17,10 +17,10 @@
#ifndef ART_RUNTIME_ARCH_ARM64_QUICK_METHOD_FRAME_INFO_ARM64_H_
#define ART_RUNTIME_ARCH_ARM64_QUICK_METHOD_FRAME_INFO_ARM64_H_
+#include "base/bit_utils.h"
#include "quick/quick_method_frame_info.h"
#include "registers_arm64.h"
#include "runtime.h" // for Runtime::CalleeSaveType.
-#include "utils.h" // for POPCOUNT
namespace art {
namespace arm64 {
diff --git a/runtime/arch/memcmp16_test.cc b/runtime/arch/memcmp16_test.cc
index 5ba06f82a2..9ba7de1df5 100644
--- a/runtime/arch/memcmp16_test.cc
+++ b/runtime/arch/memcmp16_test.cc
@@ -144,10 +144,10 @@ static void CheckSeparate(size_t max_length, size_t min_length) {
ASSERT_EQ(expected, computed) << "Run " << round << ", c1=" << count1 << " c2=" << count2;
if (count1 > 0U) {
- delete s1;
+ delete[] s1;
}
if (count2 > 0U) {
- delete s2;
+ delete[] s2;
}
}
}
diff --git a/runtime/arch/mips/asm_support_mips.h b/runtime/arch/mips/asm_support_mips.h
index 02c098216b..390c606374 100644
--- a/runtime/arch/mips/asm_support_mips.h
+++ b/runtime/arch/mips/asm_support_mips.h
@@ -19,7 +19,7 @@
#include "asm_support.h"
-#define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 48
+#define FRAME_SIZE_SAVE_ALL_CALLEE_SAVE 96
#define FRAME_SIZE_REFS_ONLY_CALLEE_SAVE 48
#define FRAME_SIZE_REFS_AND_ARGS_CALLEE_SAVE 64
diff --git a/runtime/arch/mips/context_mips.cc b/runtime/arch/mips/context_mips.cc
index 3b525be122..24892e95bb 100644
--- a/runtime/arch/mips/context_mips.cc
+++ b/runtime/arch/mips/context_mips.cc
@@ -16,9 +16,9 @@
#include "context_mips.h"
+#include "base/bit_utils.h"
#include "mirror/art_method-inl.h"
#include "quick/quick_method_frame_info.h"
-#include "utils.h"
namespace art {
namespace mips {
@@ -26,12 +26,8 @@ namespace mips {
static constexpr uint32_t gZero = 0;
void MipsContext::Reset() {
- for (size_t i = 0; i < kNumberOfCoreRegisters; i++) {
- gprs_[i] = nullptr;
- }
- for (size_t i = 0; i < kNumberOfFRegisters; i++) {
- fprs_[i] = nullptr;
- }
+ std::fill_n(gprs_, arraysize(gprs_), nullptr);
+ std::fill_n(fprs_, arraysize(fprs_), nullptr);
gprs_[SP] = &sp_;
gprs_[RA] = &ra_;
// Initialize registers with easy to spot debug values.
@@ -42,29 +38,21 @@ void MipsContext::Reset() {
void MipsContext::FillCalleeSaves(const StackVisitor& fr) {
mirror::ArtMethod* method = fr.GetMethod();
const QuickMethodFrameInfo frame_info = method->GetQuickFrameInfo();
- size_t spill_count = POPCOUNT(frame_info.CoreSpillMask());
- size_t fp_spill_count = POPCOUNT(frame_info.FpSpillMask());
- if (spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- int j = 1;
- for (size_t i = 0; i < kNumberOfCoreRegisters; i++) {
- if (((frame_info.CoreSpillMask() >> i) & 1) != 0) {
- gprs_[i] = fr.CalleeSaveAddress(spill_count - j, frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ int spill_pos = 0;
+
+ // Core registers come first, from the highest down to the lowest.
+ for (uint32_t core_reg : HighToLowBits(frame_info.CoreSpillMask())) {
+ gprs_[core_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
- if (fp_spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- int j = 1;
- for (size_t i = 0; i < kNumberOfFRegisters; i++) {
- if (((frame_info.FpSpillMask() >> i) & 1) != 0) {
- fprs_[i] = fr.CalleeSaveAddress(spill_count + fp_spill_count - j,
- frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()));
+
+ // FP registers come second, from the highest down to the lowest.
+ for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) {
+ fprs_[fp_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask()));
}
void MipsContext::SetGPR(uint32_t reg, uintptr_t value) {
@@ -99,7 +87,7 @@ void MipsContext::DoLongJump() {
gprs[i] = gprs_[i] != nullptr ? *gprs_[i] : MipsContext::kBadGprBase + i;
}
for (size_t i = 0; i < kNumberOfFRegisters; ++i) {
- fprs[i] = fprs_[i] != nullptr ? *fprs_[i] : MipsContext::kBadGprBase + i;
+ fprs[i] = fprs_[i] != nullptr ? *fprs_[i] : MipsContext::kBadFprBase + i;
}
art_quick_do_long_jump(gprs, fprs);
}
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index 92b180e605..c00d6cbe1d 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -37,36 +37,44 @@
* Reserves FRAME_SIZE_SAVE_ALL_CALLEE_SAVE + ARG_SLOT_SIZE bytes on the stack
*/
.macro SETUP_SAVE_ALL_CALLEE_SAVE_FRAME
- addiu $sp, $sp, -48
- .cfi_adjust_cfa_offset 48
+ addiu $sp, $sp, -96
+ .cfi_adjust_cfa_offset 96
// Ugly compile-time check, but we only have the preprocessor.
-#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 48)
+#if (FRAME_SIZE_SAVE_ALL_CALLEE_SAVE != 96)
#error "SAVE_ALL_CALLEE_SAVE_FRAME(MIPS) size not as expected."
#endif
- sw $ra, 44($sp)
- .cfi_rel_offset 31, 44
- sw $s8, 40($sp)
- .cfi_rel_offset 30, 40
- sw $gp, 36($sp)
- .cfi_rel_offset 28, 36
- sw $s7, 32($sp)
- .cfi_rel_offset 23, 32
- sw $s6, 28($sp)
- .cfi_rel_offset 22, 28
- sw $s5, 24($sp)
- .cfi_rel_offset 21, 24
- sw $s4, 20($sp)
- .cfi_rel_offset 20, 20
- sw $s3, 16($sp)
- .cfi_rel_offset 19, 16
- sw $s2, 12($sp)
- .cfi_rel_offset 18, 12
- sw $s1, 8($sp)
- .cfi_rel_offset 17, 8
- sw $s0, 4($sp)
- .cfi_rel_offset 16, 4
+ sw $ra, 92($sp)
+ .cfi_rel_offset 31, 92
+ sw $s8, 88($sp)
+ .cfi_rel_offset 30, 88
+ sw $gp, 84($sp)
+ .cfi_rel_offset 28, 84
+ sw $s7, 80($sp)
+ .cfi_rel_offset 23, 80
+ sw $s6, 76($sp)
+ .cfi_rel_offset 22, 76
+ sw $s5, 72($sp)
+ .cfi_rel_offset 21, 72
+ sw $s4, 68($sp)
+ .cfi_rel_offset 20, 68
+ sw $s3, 64($sp)
+ .cfi_rel_offset 19, 64
+ sw $s2, 60($sp)
+ .cfi_rel_offset 18, 60
+ sw $s1, 56($sp)
+ .cfi_rel_offset 17, 56
+ sw $s0, 52($sp)
+ .cfi_rel_offset 16, 52
+
+ SDu $f30, $f31, 44, $sp, $t1
+ SDu $f28, $f29, 36, $sp, $t1
+ SDu $f26, $f27, 28, $sp, $t1
+ SDu $f24, $f25, 20, $sp, $t1
+ SDu $f22, $f23, 12, $sp, $t1
+ SDu $f20, $f21, 4, $sp, $t1
+
# 1 word for holding Method*
lw $t0, %got(_ZN3art7Runtime9instance_E)($gp)
@@ -1091,13 +1099,9 @@ END art_quick_proxy_invoke_handler
* dex method index.
*/
ENTRY art_quick_imt_conflict_trampoline
- lw $a0, 0($sp) # load caller Method*
- lw $a0, MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET($a0) # load dex_cache_resolved_methods
- sll $t0, 2 # convert target method offset to bytes
- add $a0, $t0 # get address of target method
- lw $a0, MIRROR_OBJECT_ARRAY_DATA_OFFSET($a0) # load the target method
la $t9, art_quick_invoke_interface_trampoline
jalr $zero, $t9
+ move $a0, $t0
END art_quick_imt_conflict_trampoline
.extern artQuickResolutionTrampoline
diff --git a/runtime/arch/mips/quick_method_frame_info_mips.h b/runtime/arch/mips/quick_method_frame_info_mips.h
index 5fbffbcaca..dd5ac800e2 100644
--- a/runtime/arch/mips/quick_method_frame_info_mips.h
+++ b/runtime/arch/mips/quick_method_frame_info_mips.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_ARCH_MIPS_QUICK_METHOD_FRAME_INFO_MIPS_H_
#define ART_RUNTIME_ARCH_MIPS_QUICK_METHOD_FRAME_INFO_MIPS_H_
+#include "base/bit_utils.h"
#include "quick/quick_method_frame_info.h"
#include "registers_mips.h"
#include "runtime.h" // for Runtime::CalleeSaveType.
@@ -31,6 +32,10 @@ static constexpr uint32_t kMipsCalleeSaveArgSpills =
(1 << art::mips::A1) | (1 << art::mips::A2) | (1 << art::mips::A3);
static constexpr uint32_t kMipsCalleeSaveAllSpills =
(1 << art::mips::S0) | (1 << art::mips::S1);
+static constexpr uint32_t kMipsCalleeSaveAllFPSpills =
+ (1 << art::mips::F20) | (1 << art::mips::F21) | (1 << art::mips::F22) | (1 << art::mips::F23) |
+ (1 << art::mips::F24) | (1 << art::mips::F25) | (1 << art::mips::F26) | (1 << art::mips::F27) |
+ (1 << art::mips::F28) | (1 << art::mips::F29) | (1 << art::mips::F30) | (1 << art::mips::F31);
constexpr uint32_t MipsCalleeSaveCoreSpills(Runtime::CalleeSaveType type) {
return kMipsCalleeSaveRefSpills |
@@ -38,15 +43,20 @@ constexpr uint32_t MipsCalleeSaveCoreSpills(Runtime::CalleeSaveType type) {
(type == Runtime::kSaveAll ? kMipsCalleeSaveAllSpills : 0) | (1 << art::mips::RA);
}
+constexpr uint32_t MipsCalleeSaveFPSpills(Runtime::CalleeSaveType type) {
+ return type == Runtime::kSaveAll ? kMipsCalleeSaveAllFPSpills : 0;
+}
+
constexpr uint32_t MipsCalleeSaveFrameSize(Runtime::CalleeSaveType type) {
return RoundUp((POPCOUNT(MipsCalleeSaveCoreSpills(type)) /* gprs */ +
+ POPCOUNT(MipsCalleeSaveFPSpills(type)) /* fprs */ +
1 /* Method* */) * kMipsPointerSize, kStackAlignment);
}
constexpr QuickMethodFrameInfo MipsCalleeSaveMethodFrameInfo(Runtime::CalleeSaveType type) {
return QuickMethodFrameInfo(MipsCalleeSaveFrameSize(type),
MipsCalleeSaveCoreSpills(type),
- 0u);
+ MipsCalleeSaveFPSpills(type));
}
} // namespace mips
diff --git a/runtime/arch/mips64/context_mips64.cc b/runtime/arch/mips64/context_mips64.cc
index 6b3f4c9d43..8ce6cf0993 100644
--- a/runtime/arch/mips64/context_mips64.cc
+++ b/runtime/arch/mips64/context_mips64.cc
@@ -16,9 +16,9 @@
#include "context_mips64.h"
+#include "base/bit_utils.h"
#include "mirror/art_method-inl.h"
#include "quick/quick_method_frame_info.h"
-#include "utils.h"
namespace art {
namespace mips64 {
@@ -26,12 +26,8 @@ namespace mips64 {
static constexpr uintptr_t gZero = 0;
void Mips64Context::Reset() {
- for (size_t i = 0; i < kNumberOfGpuRegisters; i++) {
- gprs_[i] = nullptr;
- }
- for (size_t i = 0; i < kNumberOfFpuRegisters; i++) {
- fprs_[i] = nullptr;
- }
+ std::fill_n(gprs_, arraysize(gprs_), nullptr);
+ std::fill_n(fprs_, arraysize(fprs_), nullptr);
gprs_[SP] = &sp_;
gprs_[RA] = &ra_;
// Initialize registers with easy to spot debug values.
@@ -42,29 +38,21 @@ void Mips64Context::Reset() {
void Mips64Context::FillCalleeSaves(const StackVisitor& fr) {
mirror::ArtMethod* method = fr.GetMethod();
const QuickMethodFrameInfo frame_info = method->GetQuickFrameInfo();
- size_t spill_count = POPCOUNT(frame_info.CoreSpillMask());
- size_t fp_spill_count = POPCOUNT(frame_info.FpSpillMask());
- if (spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- int j = 1;
- for (size_t i = 0; i < kNumberOfGpuRegisters; i++) {
- if (((frame_info.CoreSpillMask() >> i) & 1) != 0) {
- gprs_[i] = fr.CalleeSaveAddress(spill_count - j, frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ int spill_pos = 0;
+
+ // Core registers come first, from the highest down to the lowest.
+ for (uint32_t core_reg : HighToLowBits(frame_info.CoreSpillMask())) {
+ gprs_[core_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
- if (fp_spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- int j = 1;
- for (size_t i = 0; i < kNumberOfFpuRegisters; i++) {
- if (((frame_info.FpSpillMask() >> i) & 1) != 0) {
- fprs_[i] = fr.CalleeSaveAddress(spill_count + fp_spill_count - j,
- frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()));
+
+ // FP registers come second, from the highest down to the lowest.
+ for (uint32_t fp_reg : HighToLowBits(frame_info.FpSpillMask())) {
+ fprs_[fp_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) + POPCOUNT(frame_info.FpSpillMask()));
}
void Mips64Context::SetGPR(uint32_t reg, uintptr_t value) {
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index b7320a61ff..031f85f32f 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -1365,14 +1365,10 @@ END art_quick_proxy_invoke_handler
* dex method index.
*/
ENTRY art_quick_imt_conflict_trampoline
- lwu $a0, 0($sp) # load caller Method*
- lwu $a0, MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET($a0) # load dex_cache_resolved_methods
- dsll $t0, 2 # convert target method offset to bytes
- daddu $a0, $t0 # get address of target method
dla $t9, art_quick_invoke_interface_trampoline
.cpreturn
jalr $zero, $t9
- lwu $a0, MIRROR_OBJECT_ARRAY_DATA_OFFSET($a0) # load the target method
+ move $a0, $t0
END art_quick_imt_conflict_trampoline
.extern artQuickResolutionTrampoline
diff --git a/runtime/arch/mips64/quick_method_frame_info_mips64.h b/runtime/arch/mips64/quick_method_frame_info_mips64.h
index de55e81654..f967be0e4c 100644
--- a/runtime/arch/mips64/quick_method_frame_info_mips64.h
+++ b/runtime/arch/mips64/quick_method_frame_info_mips64.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_ARCH_MIPS64_QUICK_METHOD_FRAME_INFO_MIPS64_H_
#define ART_RUNTIME_ARCH_MIPS64_QUICK_METHOD_FRAME_INFO_MIPS64_H_
+#include "base/bit_utils.h"
#include "quick/quick_method_frame_info.h"
#include "registers_mips64.h"
#include "runtime.h" // for Runtime::CalleeSaveType.
diff --git a/runtime/arch/x86/context_x86.cc b/runtime/arch/x86/context_x86.cc
index 52a35dde92..06bae75585 100644
--- a/runtime/arch/x86/context_x86.cc
+++ b/runtime/arch/x86/context_x86.cc
@@ -16,10 +16,9 @@
#include "context_x86.h"
+#include "base/bit_utils.h"
#include "mirror/art_method-inl.h"
#include "quick/quick_method_frame_info.h"
-#include "utils.h"
-
namespace art {
namespace x86 {
@@ -27,12 +26,8 @@ namespace x86 {
static constexpr uintptr_t gZero = 0;
void X86Context::Reset() {
- for (size_t i = 0; i < kNumberOfCpuRegisters; i++) {
- gprs_[i] = nullptr;
- }
- for (size_t i = 0; i < kNumberOfFloatRegisters; ++i) {
- fprs_[i] = nullptr;
- }
+ std::fill_n(gprs_, arraysize(gprs_), nullptr);
+ std::fill_n(fprs_, arraysize(fprs_), nullptr);
gprs_[ESP] = &esp_;
// Initialize registers with easy to spot debug values.
esp_ = X86Context::kBadGprBase + ESP;
@@ -42,36 +37,31 @@ void X86Context::Reset() {
void X86Context::FillCalleeSaves(const StackVisitor& fr) {
mirror::ArtMethod* method = fr.GetMethod();
const QuickMethodFrameInfo frame_info = method->GetQuickFrameInfo();
- size_t spill_count = POPCOUNT(frame_info.CoreSpillMask());
- size_t fp_spill_count = POPCOUNT(frame_info.FpSpillMask());
- if (spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- int j = 2; // Offset j to skip return address spill.
- for (int i = 0; i < kNumberOfCpuRegisters; i++) {
- if (((frame_info.CoreSpillMask() >> i) & 1) != 0) {
- gprs_[i] = fr.CalleeSaveAddress(spill_count - j, frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ int spill_pos = 0;
+
+ // Core registers come first, from the highest down to the lowest.
+ uint32_t core_regs =
+ frame_info.CoreSpillMask() & ~(static_cast<uint32_t>(-1) << kNumberOfCpuRegisters);
+ DCHECK_EQ(1, POPCOUNT(frame_info.CoreSpillMask() & ~core_regs)); // Return address spill.
+ for (uint32_t core_reg : HighToLowBits(core_regs)) {
+ gprs_[core_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
- if (fp_spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- size_t j = 2; // Offset j to skip return address spill.
- size_t fp_spill_size_in_words = fp_spill_count * 2;
- for (size_t i = 0; i < kNumberOfFloatRegisters; ++i) {
- if (((frame_info.FpSpillMask() >> i) & 1) != 0) {
- // There are 2 pieces to each XMM register, to match VR size.
- fprs_[2*i] = reinterpret_cast<uint32_t*>(
- fr.CalleeSaveAddress(spill_count + fp_spill_size_in_words - j,
- frame_info.FrameSizeInBytes()));
- fprs_[2*i+1] = reinterpret_cast<uint32_t*>(
- fr.CalleeSaveAddress(spill_count + fp_spill_size_in_words - j - 1,
- frame_info.FrameSizeInBytes()));
- // Two void* per XMM register.
- j += 2;
- }
- }
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) - 1);
+
+ // FP registers come second, from the highest down to the lowest.
+ uint32_t fp_regs = frame_info.FpSpillMask();
+ DCHECK_EQ(0u, fp_regs & (static_cast<uint32_t>(-1) << kNumberOfFloatRegisters));
+ for (uint32_t fp_reg : HighToLowBits(fp_regs)) {
+ // Two void* per XMM register.
+ fprs_[2 * fp_reg] = reinterpret_cast<uint32_t*>(
+ fr.CalleeSaveAddress(spill_pos + 1, frame_info.FrameSizeInBytes()));
+ fprs_[2 * fp_reg + 1] = reinterpret_cast<uint32_t*>(
+ fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes()));
+ spill_pos += 2;
}
+ DCHECK_EQ(spill_pos,
+ POPCOUNT(frame_info.CoreSpillMask()) - 1 + 2 * POPCOUNT(frame_info.FpSpillMask()));
}
void X86Context::SmashCallerSaves() {
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index d62c1bcebe..8207360abd 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -1385,16 +1385,11 @@ DEFINE_FUNCTION art_quick_proxy_invoke_handler
END_FUNCTION art_quick_proxy_invoke_handler
/*
- * Called to resolve an imt conflict. xmm0 is a hidden argument that holds the target method's
+ * Called to resolve an imt conflict. xmm7 is a hidden argument that holds the target method's
* dex method index.
*/
DEFINE_FUNCTION art_quick_imt_conflict_trampoline
- PUSH ecx
- movl 8(%esp), %eax // load caller Method*
- movl MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET(%eax), %eax // load dex_cache_resolved_methods
- movd %xmm7, %ecx // get target method index stored in xmm0
- movl MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4), %eax // load the target method
- POP ecx
+ movd %xmm7, %eax // get target method index stored in xmm7
jmp SYMBOL(art_quick_invoke_interface_trampoline)
END_FUNCTION art_quick_imt_conflict_trampoline
diff --git a/runtime/arch/x86/quick_method_frame_info_x86.h b/runtime/arch/x86/quick_method_frame_info_x86.h
index 9bba531638..ed1d860850 100644
--- a/runtime/arch/x86/quick_method_frame_info_x86.h
+++ b/runtime/arch/x86/quick_method_frame_info_x86.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_ARCH_X86_QUICK_METHOD_FRAME_INFO_X86_H_
#define ART_RUNTIME_ARCH_X86_QUICK_METHOD_FRAME_INFO_X86_H_
+#include "base/bit_utils.h"
#include "quick/quick_method_frame_info.h"
#include "registers_x86.h"
#include "runtime.h" // for Runtime::CalleeSaveType.
diff --git a/runtime/arch/x86_64/context_x86_64.cc b/runtime/arch/x86_64/context_x86_64.cc
index 63365411e8..2c4532c42b 100644
--- a/runtime/arch/x86_64/context_x86_64.cc
+++ b/runtime/arch/x86_64/context_x86_64.cc
@@ -16,9 +16,9 @@
#include "context_x86_64.h"
+#include "base/bit_utils.h"
#include "mirror/art_method-inl.h"
#include "quick/quick_method_frame_info.h"
-#include "utils.h"
namespace art {
namespace x86_64 {
@@ -26,12 +26,8 @@ namespace x86_64 {
static constexpr uintptr_t gZero = 0;
void X86_64Context::Reset() {
- for (size_t i = 0; i < kNumberOfCpuRegisters; ++i) {
- gprs_[i] = nullptr;
- }
- for (size_t i = 0; i < kNumberOfFloatRegisters; ++i) {
- fprs_[i] = nullptr;
- }
+ std::fill_n(gprs_, arraysize(gprs_), nullptr);
+ std::fill_n(fprs_, arraysize(fprs_), nullptr);
gprs_[RSP] = &rsp_;
// Initialize registers with easy to spot debug values.
rsp_ = X86_64Context::kBadGprBase + RSP;
@@ -41,29 +37,28 @@ void X86_64Context::Reset() {
void X86_64Context::FillCalleeSaves(const StackVisitor& fr) {
mirror::ArtMethod* method = fr.GetMethod();
const QuickMethodFrameInfo frame_info = method->GetQuickFrameInfo();
- size_t spill_count = POPCOUNT(frame_info.CoreSpillMask());
- size_t fp_spill_count = POPCOUNT(frame_info.FpSpillMask());
- if (spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- size_t j = 2; // Offset j to skip return address spill.
- for (size_t i = 0; i < kNumberOfCpuRegisters; ++i) {
- if (((frame_info.CoreSpillMask() >> i) & 1) != 0) {
- gprs_[i] = fr.CalleeSaveAddress(spill_count - j, frame_info.FrameSizeInBytes());
- j++;
- }
- }
+ int spill_pos = 0;
+
+ // Core registers come first, from the highest down to the lowest.
+ uint32_t core_regs =
+ frame_info.CoreSpillMask() & ~(static_cast<uint32_t>(-1) << kNumberOfCpuRegisters);
+ DCHECK_EQ(1, POPCOUNT(frame_info.CoreSpillMask() & ~core_regs)); // Return address spill.
+ for (uint32_t core_reg : HighToLowBits(core_regs)) {
+ gprs_[core_reg] = fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes());
+ ++spill_pos;
}
- if (fp_spill_count > 0) {
- // Lowest number spill is farthest away, walk registers and fill into context.
- size_t j = 2; // Offset j to skip return address spill.
- for (size_t i = 0; i < kNumberOfFloatRegisters; ++i) {
- if (((frame_info.FpSpillMask() >> i) & 1) != 0) {
- fprs_[i] = reinterpret_cast<uint64_t*>(
- fr.CalleeSaveAddress(spill_count + fp_spill_count - j, frame_info.FrameSizeInBytes()));
- j++;
- }
- }
+ DCHECK_EQ(spill_pos, POPCOUNT(frame_info.CoreSpillMask()) - 1);
+
+ // FP registers come second, from the highest down to the lowest.
+ uint32_t fp_regs = frame_info.FpSpillMask();
+ DCHECK_EQ(0u, fp_regs & (static_cast<uint32_t>(-1) << kNumberOfFloatRegisters));
+ for (uint32_t fp_reg : HighToLowBits(fp_regs)) {
+ fprs_[fp_reg] = reinterpret_cast<uint64_t*>(
+ fr.CalleeSaveAddress(spill_pos, frame_info.FrameSizeInBytes()));
+ ++spill_pos;
}
+ DCHECK_EQ(spill_pos,
+ POPCOUNT(frame_info.CoreSpillMask()) - 1 + POPCOUNT(frame_info.FpSpillMask()));
}
void X86_64Context::SmashCallerSaves() {
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index ddeb5b8e56..7bb18a4403 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -1338,9 +1338,7 @@ DEFINE_FUNCTION art_quick_imt_conflict_trampoline
int3
int3
#else
- movl 8(%rsp), %edi // load caller Method*
- movl MIRROR_ART_METHOD_DEX_CACHE_METHODS_OFFSET(%rdi), %edi // load dex_cache_resolved_methods
- movl MIRROR_OBJECT_ARRAY_DATA_OFFSET(%rdi, %rax, 4), %edi // load the target method
+ movq %rax, %rdi
jmp art_quick_invoke_interface_trampoline
#endif // __APPLE__
END_FUNCTION art_quick_imt_conflict_trampoline
diff --git a/runtime/arch/x86_64/quick_method_frame_info_x86_64.h b/runtime/arch/x86_64/quick_method_frame_info_x86_64.h
index 53aa212a88..72d7e9913b 100644
--- a/runtime/arch/x86_64/quick_method_frame_info_x86_64.h
+++ b/runtime/arch/x86_64/quick_method_frame_info_x86_64.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_ARCH_X86_64_QUICK_METHOD_FRAME_INFO_X86_64_H_
#define ART_RUNTIME_ARCH_X86_64_QUICK_METHOD_FRAME_INFO_X86_64_H_
+#include "base/bit_utils.h"
#include "quick/quick_method_frame_info.h"
#include "registers_x86_64.h"
#include "runtime.h" // for Runtime::CalleeSaveType.
diff --git a/runtime/barrier.cc b/runtime/barrier.cc
index f80a65f0ba..d21f551209 100644
--- a/runtime/barrier.cc
+++ b/runtime/barrier.cc
@@ -17,6 +17,7 @@
#include "barrier.h"
#include "base/mutex.h"
+#include "base/time_utils.h"
#include "thread.h"
namespace art {
diff --git a/runtime/base/arena_allocator.h b/runtime/base/arena_allocator.h
index ab5968cfb5..2e617b500a 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -20,10 +20,10 @@
#include <stdint.h>
#include <stddef.h>
+#include "base/bit_utils.h"
#include "debug_stack.h"
#include "macros.h"
#include "mutex.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/base/bit_utils.h b/runtime/base/bit_utils.h
new file mode 100644
index 0000000000..797215822c
--- /dev/null
+++ b/runtime/base/bit_utils.h
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_RUNTIME_BASE_BIT_UTILS_H_
+#define ART_RUNTIME_BASE_BIT_UTILS_H_
+
+#include <iterator>
+#include <limits>
+#include <type_traits>
+
+#include "base/logging.h"
+#include "base/iteration_range.h"
+
+namespace art {
+
+template<typename T>
+static constexpr int CLZ(T x) {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ // TODO: assert unsigned. There is currently many uses with signed values.
+ static_assert(sizeof(T) <= sizeof(long long), // NOLINT [runtime/int] [4]
+ "T too large, must be smaller than long long");
+ return (sizeof(T) == sizeof(uint32_t))
+ ? __builtin_clz(x) // TODO: __builtin_clz[ll] has undefined behavior for x=0
+ : __builtin_clzll(x);
+}
+
+template<typename T>
+static constexpr int CTZ(T x) {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ // TODO: assert unsigned. There is currently many uses with signed values.
+ return (sizeof(T) == sizeof(uint32_t))
+ ? __builtin_ctz(x)
+ : __builtin_ctzll(x);
+}
+
+template<typename T>
+static constexpr int POPCOUNT(T x) {
+ return (sizeof(T) == sizeof(uint32_t))
+ ? __builtin_popcount(x)
+ : __builtin_popcountll(x);
+}
+
+// Find the bit position of the most significant bit (0-based), or -1 if there were no bits set.
+template <typename T>
+static constexpr ssize_t MostSignificantBit(T value) {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+ static_assert(std::numeric_limits<T>::radix == 2, "Unexpected radix!");
+ return (value == 0) ? -1 : std::numeric_limits<T>::digits - 1 - CLZ(value);
+}
+
+// Find the bit position of the least significant bit (0-based), or -1 if there were no bits set.
+template <typename T>
+static constexpr ssize_t LeastSignificantBit(T value) {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+ return (value == 0) ? -1 : CTZ(value);
+}
+
+// How many bits (minimally) does it take to store the constant 'value'? i.e. 1 for 1, 3 for 5, etc.
+template <typename T>
+static constexpr size_t MinimumBitsToStore(T value) {
+ return static_cast<size_t>(MostSignificantBit(value) + 1);
+}
+
+template <typename T>
+static constexpr inline T RoundUpToPowerOfTwo(T x) {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+ // NOTE: Undefined if x > (1 << (std::numeric_limits<T>::digits - 1)).
+ return (x < 2u) ? x : static_cast<T>(1u) << (std::numeric_limits<T>::digits - CLZ(x - 1u));
+}
+
+template<typename T>
+static constexpr bool IsPowerOfTwo(T x) {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ // TODO: assert unsigned. There is currently many uses with signed values.
+ return (x & (x - 1)) == 0;
+}
+
+template<typename T>
+static inline int WhichPowerOf2(T x) {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ // TODO: assert unsigned. There is currently many uses with signed values.
+ DCHECK((x != 0) && IsPowerOfTwo(x));
+ return CTZ(x);
+}
+
+// For rounding integers.
+// NOTE: In the absence of std::omit_from_type_deduction<T> or std::identity<T>, use std::decay<T>.
+template<typename T>
+static constexpr T RoundDown(T x, typename std::decay<T>::type n) WARN_UNUSED;
+
+template<typename T>
+static constexpr T RoundDown(T x, typename std::decay<T>::type n) {
+ return
+ DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))
+ (x & -n);
+}
+
+template<typename T>
+static constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) WARN_UNUSED;
+
+template<typename T>
+static constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) {
+ return RoundDown(x + n - 1, n);
+}
+
+// For aligning pointers.
+template<typename T>
+static inline T* AlignDown(T* x, uintptr_t n) WARN_UNUSED;
+
+template<typename T>
+static inline T* AlignDown(T* x, uintptr_t n) {
+ return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uintptr_t>(x), n));
+}
+
+template<typename T>
+static inline T* AlignUp(T* x, uintptr_t n) WARN_UNUSED;
+
+template<typename T>
+static inline T* AlignUp(T* x, uintptr_t n) {
+ return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uintptr_t>(x), n));
+}
+
+template<int n, typename T>
+static inline bool IsAligned(T x) {
+ static_assert((n & (n - 1)) == 0, "n is not a power of two");
+ return (x & (n - 1)) == 0;
+}
+
+template<int n, typename T>
+static inline bool IsAligned(T* x) {
+ return IsAligned<n>(reinterpret_cast<const uintptr_t>(x));
+}
+
+template<typename T>
+static inline bool IsAlignedParam(T x, int n) {
+ return (x & (n - 1)) == 0;
+}
+
+#define CHECK_ALIGNED(value, alignment) \
+ CHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value)
+
+#define DCHECK_ALIGNED(value, alignment) \
+ DCHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value)
+
+#define DCHECK_ALIGNED_PARAM(value, alignment) \
+ DCHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value)
+
+// Like sizeof, but count how many bits a type takes. Pass type explicitly.
+template <typename T>
+static constexpr size_t BitSizeOf() {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ typedef typename std::make_unsigned<T>::type unsigned_type;
+ static_assert(sizeof(T) == sizeof(unsigned_type), "Unexpected type size mismatch!");
+ static_assert(std::numeric_limits<unsigned_type>::radix == 2, "Unexpected radix!");
+ return std::numeric_limits<unsigned_type>::digits;
+}
+
+// Like sizeof, but count how many bits a type takes. Infers type from parameter.
+template <typename T>
+static constexpr size_t BitSizeOf(T /*x*/) {
+ return BitSizeOf<T>();
+}
+
+static inline uint16_t Low16Bits(uint32_t value) {
+ return static_cast<uint16_t>(value);
+}
+
+static inline uint16_t High16Bits(uint32_t value) {
+ return static_cast<uint16_t>(value >> 16);
+}
+
+static inline uint32_t Low32Bits(uint64_t value) {
+ return static_cast<uint32_t>(value);
+}
+
+static inline uint32_t High32Bits(uint64_t value) {
+ return static_cast<uint32_t>(value >> 32);
+}
+
+// Check whether an N-bit two's-complement representation can hold value.
+template <typename T>
+static inline bool IsInt(size_t N, T value) {
+ if (N == BitSizeOf<T>()) {
+ return true;
+ } else {
+ CHECK_LT(0u, N);
+ CHECK_LT(N, BitSizeOf<T>());
+ T limit = static_cast<T>(1) << (N - 1u);
+ return (-limit <= value) && (value < limit);
+ }
+}
+
+template <typename T>
+static constexpr T GetIntLimit(size_t bits) {
+ return
+ DCHECK_CONSTEXPR(bits > 0, "bits cannot be zero", 0)
+ DCHECK_CONSTEXPR(bits < BitSizeOf<T>(), "kBits must be < max.", 0)
+ static_cast<T>(1) << (bits - 1);
+}
+
+template <size_t kBits, typename T>
+static constexpr bool IsInt(T value) {
+ static_assert(kBits > 0, "kBits cannot be zero.");
+ static_assert(kBits <= BitSizeOf<T>(), "kBits must be <= max.");
+ static_assert(std::is_signed<T>::value, "Needs a signed type.");
+ // Corner case for "use all bits." Can't use the limits, as they would overflow, but it is
+ // trivially true.
+ return (kBits == BitSizeOf<T>()) ?
+ true :
+ (-GetIntLimit<T>(kBits) <= value) && (value < GetIntLimit<T>(kBits));
+}
+
+template <size_t kBits, typename T>
+static constexpr bool IsUint(T value) {
+ static_assert(kBits > 0, "kBits cannot be zero.");
+ static_assert(kBits <= BitSizeOf<T>(), "kBits must be <= max.");
+ static_assert(std::is_integral<T>::value, "Needs an integral type.");
+ // Corner case for "use all bits." Can't use the limits, as they would overflow, but it is
+ // trivially true.
+ // NOTE: To avoid triggering assertion in GetIntLimit(kBits+1) if kBits+1==BitSizeOf<T>(),
+ // use GetIntLimit(kBits)*2u. The unsigned arithmetic works well for us if it overflows.
+ return (0 <= value) &&
+ (kBits == BitSizeOf<T>() ||
+ (static_cast<typename std::make_unsigned<T>::type>(value) <=
+ GetIntLimit<typename std::make_unsigned<T>::type>(kBits) * 2u - 1u));
+}
+
+template <size_t kBits, typename T>
+static constexpr bool IsAbsoluteUint(T value) {
+ static_assert(kBits <= BitSizeOf<T>(), "kBits must be <= max.");
+ static_assert(std::is_integral<T>::value, "Needs an integral type.");
+ typedef typename std::make_unsigned<T>::type unsigned_type;
+ return (kBits == BitSizeOf<T>())
+ ? true
+ : IsUint<kBits>(value < 0
+ ? static_cast<unsigned_type>(-1 - value) + 1u // Avoid overflow.
+ : static_cast<unsigned_type>(value));
+}
+
+// Using the Curiously Recurring Template Pattern to implement everything shared
+// by LowToHighBitIterator and HighToLowBitIterator, i.e. everything but operator*().
+template <typename T, typename Iter>
+class BitIteratorBase
+ : public std::iterator<std::forward_iterator_tag, uint32_t, ptrdiff_t, void, void> {
+ static_assert(std::is_integral<T>::value, "T must be integral");
+ static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+
+ static_assert(sizeof(T) == sizeof(uint32_t) || sizeof(T) == sizeof(uint64_t), "Unsupported size");
+
+ public:
+ BitIteratorBase() : bits_(0u) { }
+ explicit BitIteratorBase(T bits) : bits_(bits) { }
+
+ Iter& operator++() {
+ DCHECK_NE(bits_, 0u);
+ uint32_t bit = *static_cast<Iter&>(*this);
+ bits_ &= ~(static_cast<T>(1u) << bit);
+ return static_cast<Iter&>(*this);
+ }
+
+ Iter& operator++(int) {
+ Iter tmp(static_cast<Iter&>(*this));
+ ++*this;
+ return tmp;
+ }
+
+ protected:
+ T bits_;
+
+ template <typename U, typename I>
+ friend bool operator==(const BitIteratorBase<U, I>& lhs, const BitIteratorBase<U, I>& rhs);
+};
+
+template <typename T, typename Iter>
+bool operator==(const BitIteratorBase<T, Iter>& lhs, const BitIteratorBase<T, Iter>& rhs) {
+ return lhs.bits_ == rhs.bits_;
+}
+
+template <typename T, typename Iter>
+bool operator!=(const BitIteratorBase<T, Iter>& lhs, const BitIteratorBase<T, Iter>& rhs) {
+ return !(lhs == rhs);
+}
+
+template <typename T>
+class LowToHighBitIterator : public BitIteratorBase<T, LowToHighBitIterator<T>> {
+ public:
+ using BitIteratorBase<T, LowToHighBitIterator<T>>::BitIteratorBase;
+
+ uint32_t operator*() const {
+ DCHECK_NE(this->bits_, 0u);
+ return CTZ(this->bits_);
+ }
+};
+
+template <typename T>
+class HighToLowBitIterator : public BitIteratorBase<T, HighToLowBitIterator<T>> {
+ public:
+ using BitIteratorBase<T, HighToLowBitIterator<T>>::BitIteratorBase;
+
+ uint32_t operator*() const {
+ DCHECK_NE(this->bits_, 0u);
+ static_assert(std::numeric_limits<T>::radix == 2, "Unexpected radix!");
+ return std::numeric_limits<T>::digits - 1u - CLZ(this->bits_);
+ }
+};
+
+template <typename T>
+IterationRange<LowToHighBitIterator<T>> LowToHighBits(T bits) {
+ return IterationRange<LowToHighBitIterator<T>>(
+ LowToHighBitIterator<T>(bits), LowToHighBitIterator<T>());
+}
+
+template <typename T>
+IterationRange<HighToLowBitIterator<T>> HighToLowBits(T bits) {
+ return IterationRange<HighToLowBitIterator<T>>(
+ HighToLowBitIterator<T>(bits), HighToLowBitIterator<T>());
+}
+
+} // namespace art
+
+#endif // ART_RUNTIME_BASE_BIT_UTILS_H_
diff --git a/runtime/base/bit_utils_test.cc b/runtime/base/bit_utils_test.cc
new file mode 100644
index 0000000000..77bd0b815e
--- /dev/null
+++ b/runtime/base/bit_utils_test.cc
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#include <vector>
+
+#include "bit_utils.h"
+
+#include "gtest/gtest.h"
+
+namespace art {
+
+// NOTE: CLZ(0u) is undefined.
+static_assert(31 == CLZ<uint32_t>(1u), "TestCLZ32#1");
+static_assert(30 == CLZ<uint32_t>(2u), "TestCLZ32#2");
+static_assert(16 == CLZ<uint32_t>(0x00008765u), "TestCLZ32#3");
+static_assert(15 == CLZ<uint32_t>(0x00012345u), "TestCLZ32#4");
+static_assert(1 == CLZ<uint32_t>(0x43214321u), "TestCLZ32#5");
+static_assert(0 == CLZ<uint32_t>(0x87654321u), "TestCLZ32#6");
+
+// NOTE: CLZ(0ull) is undefined.
+static_assert(63 == CLZ<uint64_t>(UINT64_C(1)), "TestCLZ64#1");
+static_assert(62 == CLZ<uint64_t>(UINT64_C(3)), "TestCLZ64#2");
+static_assert(48 == CLZ<uint64_t>(UINT64_C(0x00008765)), "TestCLZ64#3");
+static_assert(32 == CLZ<uint64_t>(UINT64_C(0x87654321)), "TestCLZ64#4");
+static_assert(31 == CLZ<uint64_t>(UINT64_C(0x123456789)), "TestCLZ64#5");
+static_assert(16 == CLZ<uint64_t>(UINT64_C(0x876543211234)), "TestCLZ64#6");
+static_assert(1 == CLZ<uint64_t>(UINT64_C(0x4321432187654321)), "TestCLZ64#7");
+static_assert(0 == CLZ<uint64_t>(UINT64_C(0x8765432187654321)), "TestCLZ64#8");
+
+// NOTE: CTZ(0u) is undefined.
+static_assert(0 == CTZ<uint32_t>(1u), "TestCTZ32#1");
+static_assert(1 == CTZ<uint32_t>(2u), "TestCTZ32#2");
+static_assert(15 == CTZ<uint32_t>(0x45678000u), "TestCTZ32#3");
+static_assert(16 == CTZ<uint32_t>(0x43210000u), "TestCTZ32#4");
+static_assert(30 == CTZ<uint32_t>(0xc0000000u), "TestCTZ32#5");
+static_assert(31 == CTZ<uint32_t>(0x80000000u), "TestCTZ32#6");
+
+// NOTE: CTZ(0ull) is undefined.
+static_assert(0 == CTZ<uint64_t>(UINT64_C(1)), "TestCTZ64#1");
+static_assert(1 == CTZ<uint64_t>(UINT64_C(2)), "TestCTZ64#2");
+static_assert(16 == CTZ<uint64_t>(UINT64_C(0x43210000)), "TestCTZ64#3");
+static_assert(31 == CTZ<uint64_t>(UINT64_C(0x80000000)), "TestCTZ64#4");
+static_assert(32 == CTZ<uint64_t>(UINT64_C(0x8765432100000000)), "TestCTZ64#5");
+static_assert(48 == CTZ<uint64_t>(UINT64_C(0x4321000000000000)), "TestCTZ64#6");
+static_assert(62 == CTZ<uint64_t>(UINT64_C(0x4000000000000000)), "TestCTZ64#7");
+static_assert(63 == CTZ<uint64_t>(UINT64_C(0x8000000000000000)), "TestCTZ64#8");
+
+static_assert(0 == POPCOUNT<uint32_t>(0u), "TestPOPCOUNT32#1");
+static_assert(1 == POPCOUNT<uint32_t>(8u), "TestPOPCOUNT32#2");
+static_assert(15 == POPCOUNT<uint32_t>(0x55555554u), "TestPOPCOUNT32#3");
+static_assert(16 == POPCOUNT<uint32_t>(0xaaaaaaaau), "TestPOPCOUNT32#4");
+static_assert(31 == POPCOUNT<uint32_t>(0xfffffffeu), "TestPOPCOUNT32#5");
+static_assert(32 == POPCOUNT<uint32_t>(0xffffffffu), "TestPOPCOUNT32#6");
+
+static_assert(0 == POPCOUNT<uint64_t>(UINT64_C(0)), "TestPOPCOUNT64#1");
+static_assert(1 == POPCOUNT<uint64_t>(UINT64_C(0x40000)), "TestPOPCOUNT64#2");
+static_assert(16 == POPCOUNT<uint64_t>(UINT64_C(0x1414141482828282)), "TestPOPCOUNT64#3");
+static_assert(31 == POPCOUNT<uint64_t>(UINT64_C(0x0000ffff00007fff)), "TestPOPCOUNT64#4");
+static_assert(32 == POPCOUNT<uint64_t>(UINT64_C(0x5555555555555555)), "TestPOPCOUNT64#5");
+static_assert(48 == POPCOUNT<uint64_t>(UINT64_C(0x7777bbbbddddeeee)), "TestPOPCOUNT64#6");
+static_assert(63 == POPCOUNT<uint64_t>(UINT64_C(0x7fffffffffffffff)), "TestPOPCOUNT64#7");
+static_assert(64 == POPCOUNT<uint64_t>(UINT64_C(0xffffffffffffffff)), "TestPOPCOUNT64#8");
+
+static_assert(-1 == MostSignificantBit<uint32_t>(0u), "TestMSB32#1");
+static_assert(0 == MostSignificantBit<uint32_t>(1u), "TestMSB32#2");
+static_assert(31 == MostSignificantBit<uint32_t>(~static_cast<uint32_t>(0u)), "TestMSB32#3");
+static_assert(2 == MostSignificantBit<uint32_t>(0b110), "TestMSB32#4");
+static_assert(2 == MostSignificantBit<uint32_t>(0b100), "TestMSB32#5");
+
+static_assert(-1 == MostSignificantBit<uint64_t>(UINT64_C(0)), "TestMSB64#1");
+static_assert(0 == MostSignificantBit<uint64_t>(UINT64_C(1)), "TestMSB64#2");
+static_assert(63 == MostSignificantBit<uint64_t>(~UINT64_C(0)), "TestMSB64#3");
+static_assert(34 == MostSignificantBit<uint64_t>(UINT64_C(0x700000000)), "TestMSB64#4");
+static_assert(34 == MostSignificantBit<uint64_t>(UINT64_C(0x777777777)), "TestMSB64#5");
+
+static_assert(-1 == LeastSignificantBit<uint32_t>(0u), "TestLSB32#1");
+static_assert(0 == LeastSignificantBit<uint32_t>(1u), "TestLSB32#1");
+static_assert(0 == LeastSignificantBit<uint32_t>(~static_cast<uint32_t>(0u)), "TestLSB32#1");
+static_assert(1 == LeastSignificantBit<uint32_t>(0b110), "TestLSB32#1");
+static_assert(2 == LeastSignificantBit<uint32_t>(0b100), "TestLSB32#1");
+
+static_assert(-1 == LeastSignificantBit<uint64_t>(UINT64_C(0)), "TestLSB64#1");
+static_assert(0 == LeastSignificantBit<uint64_t>(UINT64_C(1)), "TestLSB64#2");
+static_assert(0 == LeastSignificantBit<uint64_t>(~UINT64_C(0)), "TestLSB64#3");
+static_assert(12 == LeastSignificantBit<uint64_t>(UINT64_C(0x5000)), "TestLSB64#4");
+static_assert(48 == LeastSignificantBit<uint64_t>(UINT64_C(0x5555000000000000)), "TestLSB64#5");
+
+static_assert(0u == MinimumBitsToStore<uint32_t>(0u), "TestMinBits2Store32#1");
+static_assert(1u == MinimumBitsToStore<uint32_t>(1u), "TestMinBits2Store32#2");
+static_assert(2u == MinimumBitsToStore<uint32_t>(0b10u), "TestMinBits2Store32#3");
+static_assert(2u == MinimumBitsToStore<uint32_t>(0b11u), "TestMinBits2Store32#4");
+static_assert(3u == MinimumBitsToStore<uint32_t>(0b100u), "TestMinBits2Store32#5");
+static_assert(3u == MinimumBitsToStore<uint32_t>(0b110u), "TestMinBits2Store32#6");
+static_assert(3u == MinimumBitsToStore<uint32_t>(0b101u), "TestMinBits2Store32#7");
+static_assert(8u == MinimumBitsToStore<uint32_t>(0xFFu), "TestMinBits2Store32#8");
+static_assert(32u == MinimumBitsToStore<uint32_t>(~static_cast<uint32_t>(0u)),
+ "TestMinBits2Store32#9");
+
+static_assert(0u == MinimumBitsToStore<uint64_t>(UINT64_C(0)), "TestMinBits2Store64#1");
+static_assert(1u == MinimumBitsToStore<uint64_t>(UINT64_C(1)), "TestMinBits2Store64#2");
+static_assert(2u == MinimumBitsToStore<uint64_t>(UINT64_C(0b10)), "TestMinBits2Store64#3");
+static_assert(2u == MinimumBitsToStore<uint64_t>(UINT64_C(0b11)), "TestMinBits2Store64#4");
+static_assert(3u == MinimumBitsToStore<uint64_t>(UINT64_C(0b100)), "TestMinBits2Store64#5");
+static_assert(3u == MinimumBitsToStore<uint64_t>(UINT64_C(0b110)), "TestMinBits2Store64#6");
+static_assert(3u == MinimumBitsToStore<uint64_t>(UINT64_C(0b101)), "TestMinBits2Store64#7");
+static_assert(8u == MinimumBitsToStore<uint64_t>(UINT64_C(0xFF)), "TestMinBits2Store64#8");
+static_assert(32u == MinimumBitsToStore<uint64_t>(UINT64_C(0xFFFFFFFF)), "TestMinBits2Store64#9");
+static_assert(33u == MinimumBitsToStore<uint64_t>(UINT64_C(0x1FFFFFFFF)), "TestMinBits2Store64#10");
+static_assert(64u == MinimumBitsToStore<uint64_t>(~UINT64_C(0)), "TestMinBits2Store64#11");
+
+static_assert(0 == RoundUpToPowerOfTwo<uint32_t>(0u), "TestRoundUpPowerOfTwo32#1");
+static_assert(1 == RoundUpToPowerOfTwo<uint32_t>(1u), "TestRoundUpPowerOfTwo32#2");
+static_assert(2 == RoundUpToPowerOfTwo<uint32_t>(2u), "TestRoundUpPowerOfTwo32#3");
+static_assert(4 == RoundUpToPowerOfTwo<uint32_t>(3u), "TestRoundUpPowerOfTwo32#4");
+static_assert(8 == RoundUpToPowerOfTwo<uint32_t>(7u), "TestRoundUpPowerOfTwo32#5");
+static_assert(0x40000u == RoundUpToPowerOfTwo<uint32_t>(0x2aaaau),
+ "TestRoundUpPowerOfTwo32#6");
+static_assert(0x80000000u == RoundUpToPowerOfTwo<uint32_t>(0x40000001u),
+ "TestRoundUpPowerOfTwo32#7");
+static_assert(0x80000000u == RoundUpToPowerOfTwo<uint32_t>(0x80000000u),
+ "TestRoundUpPowerOfTwo32#8");
+
+static_assert(0 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(0)), "TestRoundUpPowerOfTwo64#1");
+static_assert(1 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(1)), "TestRoundUpPowerOfTwo64#2");
+static_assert(2 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(2)), "TestRoundUpPowerOfTwo64#3");
+static_assert(4 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(3)), "TestRoundUpPowerOfTwo64#4");
+static_assert(8 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(7)), "TestRoundUpPowerOfTwo64#5");
+static_assert(UINT64_C(0x40000) == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(0x2aaaa)),
+ "TestRoundUpPowerOfTwo64#6");
+static_assert(
+ UINT64_C(0x8000000000000000) == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(0x4000000000000001)),
+ "TestRoundUpPowerOfTwo64#7");
+static_assert(
+ UINT64_C(0x8000000000000000) == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(0x8000000000000000)),
+ "TestRoundUpPowerOfTwo64#8");
+
+static constexpr int64_t kInt32MinMinus1 =
+ static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1;
+static constexpr int64_t kInt32MaxPlus1 =
+ static_cast<int64_t>(std::numeric_limits<int32_t>::max()) + 1;
+static constexpr int64_t kUint32MaxPlus1 =
+ static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) + 1;
+
+TEST(BitUtilsTest, TestIsInt32) {
+ EXPECT_FALSE(IsInt<int32_t>(1, -2));
+ EXPECT_TRUE(IsInt<int32_t>(1, -1));
+ EXPECT_TRUE(IsInt<int32_t>(1, 0));
+ EXPECT_FALSE(IsInt<int32_t>(1, 1));
+ EXPECT_FALSE(IsInt<int32_t>(4, -9));
+ EXPECT_TRUE(IsInt<int32_t>(4, -8));
+ EXPECT_TRUE(IsInt<int32_t>(4, 7));
+ EXPECT_FALSE(IsInt<int32_t>(4, 8));
+ EXPECT_FALSE(IsInt<int32_t>(31, std::numeric_limits<int32_t>::min()));
+ EXPECT_FALSE(IsInt<int32_t>(31, std::numeric_limits<int32_t>::max()));
+ EXPECT_TRUE(IsInt<int32_t>(32, std::numeric_limits<int32_t>::min()));
+ EXPECT_TRUE(IsInt<int32_t>(32, std::numeric_limits<int32_t>::max()));
+}
+
+TEST(BitUtilsTest, TestIsInt64) {
+ EXPECT_FALSE(IsInt<int64_t>(1, -2));
+ EXPECT_TRUE(IsInt<int64_t>(1, -1));
+ EXPECT_TRUE(IsInt<int64_t>(1, 0));
+ EXPECT_FALSE(IsInt<int64_t>(1, 1));
+ EXPECT_FALSE(IsInt<int64_t>(4, -9));
+ EXPECT_TRUE(IsInt<int64_t>(4, -8));
+ EXPECT_TRUE(IsInt<int64_t>(4, 7));
+ EXPECT_FALSE(IsInt<int64_t>(4, 8));
+ EXPECT_FALSE(IsInt<int64_t>(31, std::numeric_limits<int32_t>::min()));
+ EXPECT_FALSE(IsInt<int64_t>(31, std::numeric_limits<int32_t>::max()));
+ EXPECT_TRUE(IsInt<int64_t>(32, std::numeric_limits<int32_t>::min()));
+ EXPECT_TRUE(IsInt<int64_t>(32, std::numeric_limits<int32_t>::max()));
+ EXPECT_FALSE(IsInt<int64_t>(32, kInt32MinMinus1));
+ EXPECT_FALSE(IsInt<int64_t>(32, kInt32MaxPlus1));
+ EXPECT_FALSE(IsInt<int64_t>(63, std::numeric_limits<int64_t>::min()));
+ EXPECT_FALSE(IsInt<int64_t>(63, std::numeric_limits<int64_t>::max()));
+ EXPECT_TRUE(IsInt<int64_t>(64, std::numeric_limits<int64_t>::min()));
+ EXPECT_TRUE(IsInt<int64_t>(64, std::numeric_limits<int64_t>::max()));
+}
+
+static_assert(!IsInt<1, int32_t>(-2), "TestIsInt32#1");
+static_assert(IsInt<1, int32_t>(-1), "TestIsInt32#2");
+static_assert(IsInt<1, int32_t>(0), "TestIsInt32#3");
+static_assert(!IsInt<1, int32_t>(1), "TestIsInt32#4");
+static_assert(!IsInt<4, int32_t>(-9), "TestIsInt32#5");
+static_assert(IsInt<4, int32_t>(-8), "TestIsInt32#6");
+static_assert(IsInt<4, int32_t>(7), "TestIsInt32#7");
+static_assert(!IsInt<4, int32_t>(8), "TestIsInt32#8");
+static_assert(!IsInt<31, int32_t>(std::numeric_limits<int32_t>::min()), "TestIsInt32#9");
+static_assert(!IsInt<31, int32_t>(std::numeric_limits<int32_t>::max()), "TestIsInt32#10");
+static_assert(IsInt<32, int32_t>(std::numeric_limits<int32_t>::min()), "TestIsInt32#11");
+static_assert(IsInt<32, int32_t>(std::numeric_limits<int32_t>::max()), "TestIsInt32#12");
+
+static_assert(!IsInt<1, int64_t>(-2), "TestIsInt64#1");
+static_assert(IsInt<1, int64_t>(-1), "TestIsInt64#2");
+static_assert(IsInt<1, int64_t>(0), "TestIsInt64#3");
+static_assert(!IsInt<1, int64_t>(1), "TestIsInt64#4");
+static_assert(!IsInt<4, int64_t>(-9), "TestIsInt64#5");
+static_assert(IsInt<4, int64_t>(-8), "TestIsInt64#6");
+static_assert(IsInt<4, int64_t>(7), "TestIsInt64#7");
+static_assert(!IsInt<4, int64_t>(8), "TestIsInt64#8");
+static_assert(!IsInt<31, int64_t>(std::numeric_limits<int32_t>::min()), "TestIsInt64#9");
+static_assert(!IsInt<31, int64_t>(std::numeric_limits<int32_t>::max()), "TestIsInt64#10");
+static_assert(IsInt<32, int64_t>(std::numeric_limits<int32_t>::min()), "TestIsInt64#11");
+static_assert(IsInt<32, int64_t>(std::numeric_limits<int32_t>::max()), "TestIsInt64#12");
+static_assert(!IsInt<32, int64_t>(kInt32MinMinus1), "TestIsInt64#13");
+static_assert(!IsInt<32, int64_t>(kInt32MaxPlus1), "TestIsInt64#14");
+static_assert(!IsInt<63, int64_t>(std::numeric_limits<int64_t>::min()), "TestIsInt64#15");
+static_assert(!IsInt<63, int64_t>(std::numeric_limits<int64_t>::max()), "TestIsInt64#16");
+static_assert(IsInt<64, int64_t>(std::numeric_limits<int64_t>::min()), "TestIsInt64#17");
+static_assert(IsInt<64, int64_t>(std::numeric_limits<int64_t>::max()), "TestIsInt64#18");
+
+static_assert(!IsUint<1, int32_t>(-1), "TestIsUint32#1");
+static_assert(IsUint<1, int32_t>(0), "TestIsUint32#2");
+static_assert(IsUint<1, int32_t>(1), "TestIsUint32#3");
+static_assert(!IsUint<1, int32_t>(2), "TestIsUint32#4");
+static_assert(!IsUint<4, int32_t>(-1), "TestIsUint32#5");
+static_assert(IsUint<4, int32_t>(0), "TestIsUint32#6");
+static_assert(IsUint<4, int32_t>(15), "TestIsUint32#7");
+static_assert(!IsUint<4, int32_t>(16), "TestIsUint32#8");
+static_assert(!IsUint<30, int32_t>(std::numeric_limits<int32_t>::max()), "TestIsUint32#9");
+static_assert(IsUint<31, int32_t>(std::numeric_limits<int32_t>::max()), "TestIsUint32#10");
+static_assert(!IsUint<32, int32_t>(-1), "TestIsUint32#11");
+static_assert(IsUint<32, int32_t>(0), "TestIsUint32#11");
+static_assert(IsUint<32, uint32_t>(static_cast<uint32_t>(-1)), "TestIsUint32#12");
+
+static_assert(!IsUint<1, int64_t>(-1), "TestIsUint64#1");
+static_assert(IsUint<1, int64_t>(0), "TestIsUint64#2");
+static_assert(IsUint<1, int64_t>(1), "TestIsUint64#3");
+static_assert(!IsUint<1, int64_t>(2), "TestIsUint64#4");
+static_assert(!IsUint<4, int64_t>(-1), "TestIsUint64#5");
+static_assert(IsUint<4, int64_t>(0), "TestIsUint64#6");
+static_assert(IsUint<4, int64_t>(15), "TestIsUint64#7");
+static_assert(!IsUint<4, int64_t>(16), "TestIsUint64#8");
+static_assert(!IsUint<30, int64_t>(std::numeric_limits<int32_t>::max()), "TestIsUint64#9");
+static_assert(IsUint<31, int64_t>(std::numeric_limits<int32_t>::max()), "TestIsUint64#10");
+static_assert(!IsUint<62, int64_t>(std::numeric_limits<int64_t>::max()), "TestIsUint64#11");
+static_assert(IsUint<63, int64_t>(std::numeric_limits<int64_t>::max()), "TestIsUint64#12");
+static_assert(!IsUint<64, int64_t>(-1), "TestIsUint64#13");
+static_assert(IsUint<64, int64_t>(0), "TestIsUint64#14");
+static_assert(IsUint<64, uint64_t>(static_cast<uint32_t>(-1)), "TestIsUint64#15");
+
+static_assert(!IsAbsoluteUint<1, int32_t>(-2), "TestIsAbsoluteUint32#1");
+static_assert(IsAbsoluteUint<1, int32_t>(-1), "TestIsAbsoluteUint32#2");
+static_assert(IsAbsoluteUint<1, int32_t>(0), "TestIsAbsoluteUint32#3");
+static_assert(IsAbsoluteUint<1, int32_t>(1), "TestIsAbsoluteUint32#4");
+static_assert(!IsAbsoluteUint<1, int32_t>(2), "TestIsAbsoluteUint32#5");
+static_assert(!IsAbsoluteUint<4, int32_t>(-16), "TestIsAbsoluteUint32#6");
+static_assert(IsAbsoluteUint<4, int32_t>(-15), "TestIsAbsoluteUint32#7");
+static_assert(IsAbsoluteUint<4, int32_t>(0), "TestIsAbsoluteUint32#8");
+static_assert(IsAbsoluteUint<4, int32_t>(15), "TestIsAbsoluteUint32#9");
+static_assert(!IsAbsoluteUint<4, int32_t>(16), "TestIsAbsoluteUint32#10");
+static_assert(!IsAbsoluteUint<30, int32_t>(std::numeric_limits<int32_t>::max()),
+ "TestIsAbsoluteUint32#11");
+static_assert(IsAbsoluteUint<31, int32_t>(std::numeric_limits<int32_t>::max()),
+ "TestIsAbsoluteUint32#12");
+static_assert(!IsAbsoluteUint<31, int32_t>(std::numeric_limits<int32_t>::min()),
+ "TestIsAbsoluteUint32#13");
+static_assert(IsAbsoluteUint<31, int32_t>(std::numeric_limits<int32_t>::min() + 1),
+ "TestIsAbsoluteUint32#14");
+static_assert(IsAbsoluteUint<32, int32_t>(std::numeric_limits<int32_t>::max()),
+ "TestIsAbsoluteUint32#15");
+static_assert(IsAbsoluteUint<32, int32_t>(std::numeric_limits<int32_t>::min()),
+ "TestIsAbsoluteUint32#16");
+static_assert(IsAbsoluteUint<32, int32_t>(0), "TestIsAbsoluteUint32#17");
+
+static_assert(!IsAbsoluteUint<1, int64_t>(-2), "TestIsAbsoluteUint64#1");
+static_assert(IsAbsoluteUint<1, int64_t>(-1), "TestIsAbsoluteUint64#2");
+static_assert(IsAbsoluteUint<1, int64_t>(0), "TestIsAbsoluteUint64#3");
+static_assert(IsAbsoluteUint<1, int64_t>(1), "TestIsAbsoluteUint64#4");
+static_assert(!IsAbsoluteUint<1, int64_t>(2), "TestIsAbsoluteUint64#5");
+static_assert(!IsAbsoluteUint<4, int64_t>(-16), "TestIsAbsoluteUint64#6");
+static_assert(IsAbsoluteUint<4, int64_t>(-15), "TestIsAbsoluteUint64#7");
+static_assert(IsAbsoluteUint<4, int64_t>(0), "TestIsAbsoluteUint64#8");
+static_assert(IsAbsoluteUint<4, int64_t>(15), "TestIsAbsoluteUint64#9");
+static_assert(!IsAbsoluteUint<4, int64_t>(16), "TestIsAbsoluteUint64#10");
+static_assert(!IsAbsoluteUint<30, int64_t>(std::numeric_limits<int32_t>::max()),
+ "TestIsAbsoluteUint64#11");
+static_assert(IsAbsoluteUint<31, int64_t>(std::numeric_limits<int32_t>::max()),
+ "TestIsAbsoluteUint64#12");
+static_assert(!IsAbsoluteUint<31, int64_t>(std::numeric_limits<int32_t>::min()),
+ "TestIsAbsoluteUint64#13");
+static_assert(IsAbsoluteUint<31, int64_t>(std::numeric_limits<int32_t>::min() + 1),
+ "TestIsAbsoluteUint64#14");
+static_assert(IsAbsoluteUint<32, int64_t>(std::numeric_limits<int32_t>::max()),
+ "TestIsAbsoluteUint64#15");
+static_assert(IsAbsoluteUint<32, int64_t>(std::numeric_limits<int32_t>::min()),
+ "TestIsAbsoluteUint64#16");
+static_assert(!IsAbsoluteUint<62, int64_t>(std::numeric_limits<int64_t>::max()),
+ "TestIsAbsoluteUint64#17");
+static_assert(IsAbsoluteUint<63, int64_t>(std::numeric_limits<int64_t>::max()),
+ "TestIsAbsoluteUint64#18");
+static_assert(!IsAbsoluteUint<63, int64_t>(std::numeric_limits<int64_t>::min()),
+ "TestIsAbsoluteUint64#19");
+static_assert(IsAbsoluteUint<63, int64_t>(std::numeric_limits<int64_t>::min() + 1),
+ "TestIsAbsoluteUint64#20");
+static_assert(IsAbsoluteUint<64, int64_t>(std::numeric_limits<int64_t>::max()),
+ "TestIsAbsoluteUint64#21");
+static_assert(IsAbsoluteUint<64, int64_t>(std::numeric_limits<int64_t>::min()),
+ "TestIsAbsoluteUint64#22");
+static_assert(!IsAbsoluteUint<32, int64_t>(-kUint32MaxPlus1), "TestIsAbsoluteUint64#23");
+static_assert(IsAbsoluteUint<32, int64_t>(-kUint32MaxPlus1 + 1), "TestIsAbsoluteUint64#24");
+static_assert(IsAbsoluteUint<32, int64_t>(0), "TestIsAbsoluteUint64#25");
+static_assert(IsAbsoluteUint<64, int64_t>(0), "TestIsAbsoluteUint64#26");
+static_assert(IsAbsoluteUint<32, int64_t>(std::numeric_limits<uint32_t>::max()),
+ "TestIsAbsoluteUint64#27");
+static_assert(!IsAbsoluteUint<32, int64_t>(kUint32MaxPlus1), "TestIsAbsoluteUint64#28");
+
+template <typename Container>
+void CheckElements(const std::initializer_list<uint32_t>& expected, const Container& elements) {
+ auto expected_it = expected.begin();
+ auto element_it = elements.begin();
+ size_t idx = 0u;
+ while (expected_it != expected.end() && element_it != elements.end()) {
+ EXPECT_EQ(*expected_it, *element_it) << idx;
+ ++idx;
+ ++expected_it;
+ ++element_it;
+ }
+ ASSERT_TRUE(expected_it == expected.end() && element_it == elements.end())
+ << std::boolalpha << (expected_it == expected.end()) << " " << (element_it == elements.end());
+}
+
+TEST(BitUtilsTest, TestLowToHighBits32) {
+ CheckElements({}, LowToHighBits<uint32_t>(0u));
+ CheckElements({0}, LowToHighBits<uint32_t>(1u));
+ CheckElements({15}, LowToHighBits<uint32_t>(0x8000u));
+ CheckElements({31}, LowToHighBits<uint32_t>(0x80000000u));
+ CheckElements({0, 31}, LowToHighBits<uint32_t>(0x80000001u));
+ CheckElements({0, 1, 2, 3, 4, 5, 6, 7, 31}, LowToHighBits<uint32_t>(0x800000ffu));
+ CheckElements({0, 8, 16, 24, 31}, LowToHighBits<uint32_t>(0x81010101u));
+ CheckElements({16, 17, 30, 31}, LowToHighBits<uint32_t>(0xc0030000u));
+ CheckElements({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
+ LowToHighBits<uint32_t>(0xffffffffu));
+}
+
+TEST(BitUtilsTest, TestLowToHighBits64) {
+ CheckElements({}, LowToHighBits<uint64_t>(UINT64_C(0)));
+ CheckElements({0}, LowToHighBits<uint64_t>(UINT64_C(1)));
+ CheckElements({32}, LowToHighBits<uint64_t>(UINT64_C(0x100000000)));
+ CheckElements({63}, LowToHighBits<uint64_t>(UINT64_C(0x8000000000000000)));
+ CheckElements({0, 63}, LowToHighBits<uint64_t>(UINT64_C(0x8000000000000001)));
+ CheckElements({0, 1, 2, 3, 4, 5, 6, 7, 63},
+ LowToHighBits<uint64_t>(UINT64_C(0x80000000000000ff)));
+ CheckElements({0, 8, 16, 24, 32, 40, 48, 56, 63},
+ LowToHighBits<uint64_t>(UINT64_C(0x8101010101010101)));
+ CheckElements({16, 17, 62, 63}, LowToHighBits<uint64_t>(UINT64_C(0xc000000000030000)));
+ CheckElements({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63},
+ LowToHighBits<uint64_t>(UINT64_C(0xffffffffffffffff)));
+}
+
+TEST(BitUtilsTest, TestHighToLowBits32) {
+ CheckElements({}, HighToLowBits<uint32_t>(0u));
+ CheckElements({0}, HighToLowBits<uint32_t>(1u));
+ CheckElements({15}, HighToLowBits<uint32_t>(0x8000u));
+ CheckElements({31}, HighToLowBits<uint32_t>(0x80000000u));
+ CheckElements({31, 0}, HighToLowBits<uint32_t>(0x80000001u));
+ CheckElements({31, 7, 6, 5, 4, 3, 2, 1, 0}, HighToLowBits<uint32_t>(0x800000ffu));
+ CheckElements({31, 24, 16, 8, 0}, HighToLowBits<uint32_t>(0x81010101u));
+ CheckElements({31, 30, 17, 16}, HighToLowBits<uint32_t>(0xc0030000u));
+ CheckElements({31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
+ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
+ HighToLowBits<uint32_t>(0xffffffffu));
+}
+
+TEST(BitUtilsTest, TestHighToLowBits64) {
+ CheckElements({}, HighToLowBits<uint64_t>(UINT64_C(0)));
+ CheckElements({0}, HighToLowBits<uint64_t>(UINT64_C(1)));
+ CheckElements({32}, HighToLowBits<uint64_t>(UINT64_C(0x100000000)));
+ CheckElements({63}, HighToLowBits<uint64_t>(UINT64_C(0x8000000000000000)));
+ CheckElements({63, 0}, HighToLowBits<uint64_t>(UINT64_C(0x8000000000000001)));
+ CheckElements({63, 7, 6, 5, 4, 3, 2, 1, 0},
+ HighToLowBits<uint64_t>(UINT64_C(0x80000000000000ff)));
+ CheckElements({63, 56, 48, 40, 32, 24, 16, 8, 0},
+ HighToLowBits<uint64_t>(UINT64_C(0x8101010101010101)));
+ CheckElements({63, 62, 17, 16}, HighToLowBits<uint64_t>(UINT64_C(0xc000000000030000)));
+ CheckElements({63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48,
+ 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32,
+ 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
+ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
+ HighToLowBits<uint64_t>(UINT64_C(0xffffffffffffffff)));
+}
+
+} // namespace art
diff --git a/runtime/base/bit_vector-inl.h b/runtime/base/bit_vector-inl.h
index 39b19e5481..08877987b1 100644
--- a/runtime/base/bit_vector-inl.h
+++ b/runtime/base/bit_vector-inl.h
@@ -17,9 +17,9 @@
#ifndef ART_RUNTIME_BASE_BIT_VECTOR_INL_H_
#define ART_RUNTIME_BASE_BIT_VECTOR_INL_H_
+#include "base/bit_utils.h"
#include "bit_vector.h"
#include "logging.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/base/bit_vector.h b/runtime/base/bit_vector.h
index 6e4367ac9d..17835f5610 100644
--- a/runtime/base/bit_vector.h
+++ b/runtime/base/bit_vector.h
@@ -20,7 +20,7 @@
#include <stdint.h>
#include <iterator>
-#include "utils.h"
+#include "base/bit_utils.h"
namespace art {
diff --git a/runtime/base/bounded_fifo.h b/runtime/base/bounded_fifo.h
index d04840aa23..7bcd382022 100644
--- a/runtime/base/bounded_fifo.h
+++ b/runtime/base/bounded_fifo.h
@@ -17,16 +17,19 @@
#ifndef ART_RUNTIME_BASE_BOUNDED_FIFO_H_
#define ART_RUNTIME_BASE_BOUNDED_FIFO_H_
+#include "base/bit_utils.h"
+#include "base/logging.h"
+
namespace art {
// A bounded fifo is a fifo which has a bounded size. The power of two version uses a bit mask to
// avoid needing to deal with wrapping integers around or using a modulo operation.
-template <typename T, const size_t MaxSize>
+template <typename T, const size_t kMaxSize>
class BoundedFifoPowerOfTwo {
+ static_assert(IsPowerOfTwo(kMaxSize), "kMaxSize must be a power of 2.");
+
public:
BoundedFifoPowerOfTwo() {
- // TODO: Do this with a compile time check.
- CHECK(IsPowerOfTwo(MaxSize));
clear();
}
@@ -45,7 +48,7 @@ class BoundedFifoPowerOfTwo {
void push_back(const T& value) {
++size_;
- DCHECK_LE(size_, MaxSize);
+ DCHECK_LE(size_, kMaxSize);
// Relies on integer overflow behavior.
data_[back_index_++ & mask_] = value;
}
@@ -61,9 +64,9 @@ class BoundedFifoPowerOfTwo {
}
private:
- static const size_t mask_ = MaxSize - 1;
+ static const size_t mask_ = kMaxSize - 1;
size_t back_index_, size_;
- T data_[MaxSize];
+ T data_[kMaxSize];
};
} // namespace art
diff --git a/runtime/base/histogram-inl.h b/runtime/base/histogram-inl.h
index 0f969b9626..aba376287e 100644
--- a/runtime/base/histogram-inl.h
+++ b/runtime/base/histogram-inl.h
@@ -17,15 +17,16 @@
#ifndef ART_RUNTIME_BASE_HISTOGRAM_INL_H_
#define ART_RUNTIME_BASE_HISTOGRAM_INL_H_
-#include "histogram.h"
-
-#include "utils.h"
-
#include <algorithm>
#include <cmath>
#include <limits>
#include <ostream>
+#include "histogram.h"
+
+#include "base/bit_utils.h"
+#include "base/time_utils.h"
+
namespace art {
template <class Value> inline void Histogram<Value>::AddValue(Value value) {
diff --git a/runtime/base/histogram.h b/runtime/base/histogram.h
index c312fb252c..ef3a5d78ca 100644
--- a/runtime/base/histogram.h
+++ b/runtime/base/histogram.h
@@ -20,7 +20,6 @@
#include <string>
#include "base/logging.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/base/iteration_range.h b/runtime/base/iteration_range.h
new file mode 100644
index 0000000000..5a46376237
--- /dev/null
+++ b/runtime/base/iteration_range.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_RUNTIME_BASE_ITERATION_RANGE_H_
+#define ART_RUNTIME_BASE_ITERATION_RANGE_H_
+
+namespace art {
+
+// Helper class that acts as a container for range-based loops, given an iteration
+// range [first, last) defined by two iterators.
+template <typename Iter>
+class IterationRange {
+ public:
+ typedef Iter iterator;
+ typedef typename std::iterator_traits<Iter>::difference_type difference_type;
+ typedef typename std::iterator_traits<Iter>::value_type value_type;
+ typedef typename std::iterator_traits<Iter>::pointer pointer;
+ typedef typename std::iterator_traits<Iter>::reference reference;
+
+ IterationRange(iterator first, iterator last) : first_(first), last_(last) { }
+
+ iterator begin() const { return first_; }
+ iterator end() const { return last_; }
+ iterator cbegin() const { return first_; }
+ iterator cend() const { return last_; }
+
+ private:
+ iterator first_;
+ iterator last_;
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_BASE_ITERATION_RANGE_H_
diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h
index a727992687..87840e7a08 100644
--- a/runtime/base/mutex-inl.h
+++ b/runtime/base/mutex-inl.h
@@ -25,6 +25,7 @@
#include "base/value_object.h"
#include "runtime.h"
#include "thread.h"
+#include "utils.h"
#if ART_USE_FUTEXES
#include "linux/futex.h"
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index 99c7246d61..5c6065dcb3 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -24,12 +24,12 @@
#include "atomic.h"
#include "base/logging.h"
+#include "base/time_utils.h"
#include "base/value_object.h"
#include "mutex-inl.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
#include "thread-inl.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/base/time_utils.cc b/runtime/base/time_utils.cc
new file mode 100644
index 0000000000..48b0a090ce
--- /dev/null
+++ b/runtime/base/time_utils.cc
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#include <inttypes.h>
+#include <sstream>
+
+#include "time_utils.h"
+
+#include "base/logging.h"
+#include "base/stringprintf.h"
+
+#if defined(__APPLE__)
+#include <sys/time.h>
+#endif
+
+namespace art {
+
+std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits) {
+ if (nano_duration == 0) {
+ return "0";
+ } else {
+ return FormatDuration(nano_duration, GetAppropriateTimeUnit(nano_duration),
+ max_fraction_digits);
+ }
+}
+
+TimeUnit GetAppropriateTimeUnit(uint64_t nano_duration) {
+ const uint64_t one_sec = 1000 * 1000 * 1000;
+ const uint64_t one_ms = 1000 * 1000;
+ const uint64_t one_us = 1000;
+ if (nano_duration >= one_sec) {
+ return kTimeUnitSecond;
+ } else if (nano_duration >= one_ms) {
+ return kTimeUnitMillisecond;
+ } else if (nano_duration >= one_us) {
+ return kTimeUnitMicrosecond;
+ } else {
+ return kTimeUnitNanosecond;
+ }
+}
+
+uint64_t GetNsToTimeUnitDivisor(TimeUnit time_unit) {
+ const uint64_t one_sec = 1000 * 1000 * 1000;
+ const uint64_t one_ms = 1000 * 1000;
+ const uint64_t one_us = 1000;
+
+ switch (time_unit) {
+ case kTimeUnitSecond:
+ return one_sec;
+ case kTimeUnitMillisecond:
+ return one_ms;
+ case kTimeUnitMicrosecond:
+ return one_us;
+ case kTimeUnitNanosecond:
+ return 1;
+ }
+ return 0;
+}
+
+std::string FormatDuration(uint64_t nano_duration, TimeUnit time_unit,
+ size_t max_fraction_digits) {
+ const char* unit = nullptr;
+ uint64_t divisor = GetNsToTimeUnitDivisor(time_unit);
+ switch (time_unit) {
+ case kTimeUnitSecond:
+ unit = "s";
+ break;
+ case kTimeUnitMillisecond:
+ unit = "ms";
+ break;
+ case kTimeUnitMicrosecond:
+ unit = "us";
+ break;
+ case kTimeUnitNanosecond:
+ unit = "ns";
+ break;
+ }
+ const uint64_t whole_part = nano_duration / divisor;
+ uint64_t fractional_part = nano_duration % divisor;
+ if (fractional_part == 0) {
+ return StringPrintf("%" PRIu64 "%s", whole_part, unit);
+ } else {
+ static constexpr size_t kMaxDigits = 30;
+ size_t avail_digits = kMaxDigits;
+ char fraction_buffer[kMaxDigits];
+ char* ptr = fraction_buffer;
+ uint64_t multiplier = 10;
+ // This infinite loops if fractional part is 0.
+ while (avail_digits > 1 && fractional_part * multiplier < divisor) {
+ multiplier *= 10;
+ *ptr++ = '0';
+ avail_digits--;
+ }
+ snprintf(ptr, avail_digits, "%" PRIu64, fractional_part);
+ fraction_buffer[std::min(kMaxDigits - 1, max_fraction_digits)] = '\0';
+ return StringPrintf("%" PRIu64 ".%s%s", whole_part, fraction_buffer, unit);
+ }
+}
+
+std::string GetIsoDate() {
+ time_t now = time(nullptr);
+ tm tmbuf;
+ tm* ptm = localtime_r(&now, &tmbuf);
+ return StringPrintf("%04d-%02d-%02d %02d:%02d:%02d",
+ ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday,
+ ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
+}
+
+uint64_t MilliTime() {
+#if defined(__linux__)
+ timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_nsec / UINT64_C(1000000);
+#else // __APPLE__
+ timeval now;
+ gettimeofday(&now, nullptr);
+ return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_usec / UINT64_C(1000);
+#endif
+}
+
+uint64_t MicroTime() {
+#if defined(__linux__)
+ timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_nsec / UINT64_C(1000);
+#else // __APPLE__
+ timeval now;
+ gettimeofday(&now, nullptr);
+ return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_usec;
+#endif
+}
+
+uint64_t NanoTime() {
+#if defined(__linux__)
+ timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
+#else // __APPLE__
+ timeval now;
+ gettimeofday(&now, nullptr);
+ return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_usec * UINT64_C(1000);
+#endif
+}
+
+uint64_t ThreadCpuNanoTime() {
+#if defined(__linux__)
+ timespec now;
+ clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
+ return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
+#else // __APPLE__
+ UNIMPLEMENTED(WARNING);
+ return -1;
+#endif
+}
+
+void NanoSleep(uint64_t ns) {
+ timespec tm;
+ tm.tv_sec = ns / MsToNs(1000);
+ tm.tv_nsec = ns - static_cast<uint64_t>(tm.tv_sec) * MsToNs(1000);
+ nanosleep(&tm, nullptr);
+}
+
+void InitTimeSpec(bool absolute, int clock, int64_t ms, int32_t ns, timespec* ts) {
+ int64_t endSec;
+
+ if (absolute) {
+#if !defined(__APPLE__)
+ clock_gettime(clock, ts);
+#else
+ UNUSED(clock);
+ timeval tv;
+ gettimeofday(&tv, nullptr);
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = tv.tv_usec * 1000;
+#endif
+ } else {
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+ }
+ endSec = ts->tv_sec + ms / 1000;
+ if (UNLIKELY(endSec >= 0x7fffffff)) {
+ std::ostringstream ss;
+ LOG(INFO) << "Note: end time exceeds epoch: " << ss.str();
+ endSec = 0x7ffffffe;
+ }
+ ts->tv_sec = endSec;
+ ts->tv_nsec = (ts->tv_nsec + (ms % 1000) * 1000000) + ns;
+
+ // Catch rollover.
+ if (ts->tv_nsec >= 1000000000L) {
+ ts->tv_sec++;
+ ts->tv_nsec -= 1000000000L;
+ }
+}
+
+} // namespace art
diff --git a/runtime/base/time_utils.h b/runtime/base/time_utils.h
new file mode 100644
index 0000000000..f58c22a7cc
--- /dev/null
+++ b/runtime/base/time_utils.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ART_RUNTIME_BASE_TIME_UTILS_H_
+#define ART_RUNTIME_BASE_TIME_UTILS_H_
+
+#include <stdint.h>
+#include <string>
+#include <time.h>
+
+#include "base/macros.h"
+
+namespace art {
+
+enum TimeUnit {
+ kTimeUnitNanosecond,
+ kTimeUnitMicrosecond,
+ kTimeUnitMillisecond,
+ kTimeUnitSecond,
+};
+
+// Returns a human-readable time string which prints every nanosecond while trying to limit the
+// number of trailing zeros. Prints using the largest human readable unit up to a second.
+// e.g. "1ms", "1.000000001s", "1.001us"
+std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits = 3);
+
+// Format a nanosecond time to specified units.
+std::string FormatDuration(uint64_t nano_duration, TimeUnit time_unit,
+ size_t max_fraction_digits);
+
+// Get the appropriate unit for a nanosecond duration.
+TimeUnit GetAppropriateTimeUnit(uint64_t nano_duration);
+
+// Get the divisor to convert from a nanoseconds to a time unit.
+uint64_t GetNsToTimeUnitDivisor(TimeUnit time_unit);
+
+// Returns the current date in ISO yyyy-mm-dd hh:mm:ss format.
+std::string GetIsoDate();
+
+// Returns the monotonic time since some unspecified starting point in milliseconds.
+uint64_t MilliTime();
+
+// Returns the monotonic time since some unspecified starting point in microseconds.
+uint64_t MicroTime();
+
+// Returns the monotonic time since some unspecified starting point in nanoseconds.
+uint64_t NanoTime();
+
+// Returns the thread-specific CPU-time clock in nanoseconds or -1 if unavailable.
+uint64_t ThreadCpuNanoTime();
+
+// Converts the given number of nanoseconds to milliseconds.
+static constexpr inline uint64_t NsToMs(uint64_t ns) {
+ return ns / 1000 / 1000;
+}
+
+// Converts the given number of milliseconds to nanoseconds
+static constexpr inline uint64_t MsToNs(uint64_t ns) {
+ return ns * 1000 * 1000;
+}
+
+#if defined(__APPLE__)
+// No clocks to specify on OS/X, fake value to pass to routines that require a clock.
+#define CLOCK_REALTIME 0xebadf00d
+#endif
+
+// Sleep for the given number of nanoseconds, a bad way to handle contention.
+void NanoSleep(uint64_t ns);
+
+// Initialize a timespec to either a relative time (ms,ns), or to the absolute
+// time corresponding to the indicated clock value plus the supplied offset.
+void InitTimeSpec(bool absolute, int clock, int64_t ms, int32_t ns, timespec* ts);
+
+} // namespace art
+
+#endif // ART_RUNTIME_BASE_TIME_UTILS_H_
diff --git a/runtime/base/time_utils_test.cc b/runtime/base/time_utils_test.cc
new file mode 100644
index 0000000000..c553f4ed03
--- /dev/null
+++ b/runtime/base/time_utils_test.cc
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#include "time_utils.h"
+
+#include "gtest/gtest.h"
+
+namespace art {
+
+TEST(TimeUtilsTest, PrettyDuration) {
+ const uint64_t one_sec = 1000000000;
+ const uint64_t one_ms = 1000000;
+ const uint64_t one_us = 1000;
+
+ EXPECT_EQ("1s", PrettyDuration(1 * one_sec));
+ EXPECT_EQ("10s", PrettyDuration(10 * one_sec));
+ EXPECT_EQ("100s", PrettyDuration(100 * one_sec));
+ EXPECT_EQ("1.001s", PrettyDuration(1 * one_sec + one_ms));
+ EXPECT_EQ("1.000001s", PrettyDuration(1 * one_sec + one_us, 6));
+ EXPECT_EQ("1.000000001s", PrettyDuration(1 * one_sec + 1, 9));
+ EXPECT_EQ("1.000s", PrettyDuration(1 * one_sec + one_us, 3));
+
+ EXPECT_EQ("1ms", PrettyDuration(1 * one_ms));
+ EXPECT_EQ("10ms", PrettyDuration(10 * one_ms));
+ EXPECT_EQ("100ms", PrettyDuration(100 * one_ms));
+ EXPECT_EQ("1.001ms", PrettyDuration(1 * one_ms + one_us));
+ EXPECT_EQ("1.000001ms", PrettyDuration(1 * one_ms + 1, 6));
+
+ EXPECT_EQ("1us", PrettyDuration(1 * one_us));
+ EXPECT_EQ("10us", PrettyDuration(10 * one_us));
+ EXPECT_EQ("100us", PrettyDuration(100 * one_us));
+ EXPECT_EQ("1.001us", PrettyDuration(1 * one_us + 1));
+
+ EXPECT_EQ("1ns", PrettyDuration(1));
+ EXPECT_EQ("10ns", PrettyDuration(10));
+ EXPECT_EQ("100ns", PrettyDuration(100));
+}
+
+TEST(TimeUtilsTest, TestSleep) {
+ auto start = NanoTime();
+ NanoSleep(MsToNs(1500));
+ EXPECT_GT(NanoTime() - start, MsToNs(1000));
+}
+
+} // namespace art
diff --git a/runtime/base/timing_logger.cc b/runtime/base/timing_logger.cc
index b6a2aaf33b..f1f6f9b1c1 100644
--- a/runtime/base/timing_logger.cc
+++ b/runtime/base/timing_logger.cc
@@ -22,9 +22,10 @@
#include "timing_logger.h"
#include "base/logging.h"
-#include "thread-inl.h"
#include "base/stl_util.h"
#include "base/histogram-inl.h"
+#include "base/time_utils.h"
+#include "thread-inl.h"
#include <cmath>
#include <iomanip>
diff --git a/runtime/base/unix_file/random_access_file_test.h b/runtime/base/unix_file/random_access_file_test.h
index e7ace4caaa..91858c21de 100644
--- a/runtime/base/unix_file/random_access_file_test.h
+++ b/runtime/base/unix_file/random_access_file_test.h
@@ -82,7 +82,7 @@ class RandomAccessFileTest : public testing::Test {
void TestReadContent(const std::string& content, RandomAccessFile* file) {
const int buf_size = content.size() + 10;
- std::unique_ptr<char> buf(new char[buf_size]);
+ std::unique_ptr<char[]> buf(new char[buf_size]);
// Can't read from a negative offset.
ASSERT_EQ(-EINVAL, file->Read(buf.get(), 0, -123));
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 7912629f35..9ad987a449 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -30,6 +30,7 @@
#include "base/logging.h"
#include "base/scoped_flock.h"
#include "base/stl_util.h"
+#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "base/value_object.h"
#include "class_linker-inl.h"
@@ -1816,8 +1817,8 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor, si
// TODO: Use fast jobjects?
auto interfaces = hs.NewHandle<mirror::ObjectArray<mirror::Class>>(nullptr);
- mirror::Class* new_class = nullptr;
- if (!LinkClass(self, descriptor, klass, interfaces, &new_class)) {
+ MutableHandle<mirror::Class> h_new_class = hs.NewHandle<mirror::Class>(nullptr);
+ if (!LinkClass(self, descriptor, klass, interfaces, &h_new_class)) {
// Linking failed.
if (!klass->IsErroneous()) {
mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
@@ -1825,10 +1826,8 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor, si
return nullptr;
}
self->AssertNoPendingException();
- CHECK(new_class != nullptr) << descriptor;
- CHECK(new_class->IsResolved()) << descriptor;
-
- Handle<mirror::Class> new_class_h(hs.NewHandle(new_class));
+ CHECK(h_new_class.Get() != nullptr) << descriptor;
+ CHECK(h_new_class->IsResolved()) << descriptor;
// Instrumentation may have updated entrypoints for all methods of all
// classes. However it could not update methods of this class while we
@@ -1839,7 +1838,7 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor, si
// suspending all threads to update entrypoints while we are doing it
// for this class.
DCHECK_EQ(self->GetState(), kRunnable);
- Runtime::Current()->GetInstrumentation()->InstallStubsForClass(new_class_h.Get());
+ Runtime::Current()->GetInstrumentation()->InstallStubsForClass(h_new_class.Get());
}
/*
@@ -1853,9 +1852,9 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor, si
* The class has been prepared and resolved but possibly not yet verified
* at this point.
*/
- Dbg::PostClassPrepare(new_class_h.Get());
+ Dbg::PostClassPrepare(h_new_class.Get());
- return new_class_h.Get();
+ return h_new_class.Get();
}
uint32_t ClassLinker::SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file,
@@ -2739,11 +2738,7 @@ mirror::Class* ClassLinker::UpdateClass(const char* descriptor, mirror::Class* k
WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
auto existing_it = class_table_.FindWithHash(std::make_pair(descriptor, klass->GetClassLoader()),
hash);
- if (existing_it == class_table_.end()) {
- CHECK(klass->IsProxyClass());
- return nullptr;
- }
-
+ CHECK(existing_it != class_table_.end());
mirror::Class* existing = existing_it->Read();
CHECK_NE(existing, klass) << descriptor;
CHECK(!existing->IsResolved()) << descriptor;
@@ -3215,7 +3210,7 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
jobjectArray interfaces, jobject loader,
jobjectArray methods, jobjectArray throws) {
Thread* self = soa.Self();
- StackHandleScope<9> hs(self);
+ StackHandleScope<10> hs(self);
MutableHandle<mirror::Class> klass(hs.NewHandle(
AllocClass(self, GetClassRoot(kJavaLangClass), sizeof(mirror::Class))));
if (klass.Get() == nullptr) {
@@ -3229,9 +3224,17 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
klass->SetClassLoader(soa.Decode<mirror::ClassLoader*>(loader));
DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
klass->SetName(soa.Decode<mirror::String*>(name));
- mirror::Class* proxy_class = GetClassRoot(kJavaLangReflectProxy);
- klass->SetDexCache(proxy_class->GetDexCache());
+ klass->SetDexCache(GetClassRoot(kJavaLangReflectProxy)->GetDexCache());
mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, self);
+ std::string descriptor(GetDescriptorForProxy(klass.Get()));
+ size_t hash = ComputeModifiedUtf8Hash(descriptor.c_str());
+
+ // Insert the class before loading the fields as the field roots
+ // (ArtField::declaring_class_) are only visited from the class
+ // table. There can't be any suspend points between inserting the
+ // class and setting the field arrays below.
+ mirror::Class* existing = InsertClass(descriptor.c_str(), klass.Get(), hash);
+ CHECK(existing == nullptr);
// Instance fields are inherited, but we add a couple of static fields...
const size_t num_fields = 2;
@@ -3254,18 +3257,21 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
// Proxies have 1 direct method, the constructor
{
- mirror::ObjectArray<mirror::ArtMethod>* directs = AllocArtMethodArray(self, 1);
- if (UNLIKELY(directs == nullptr)) {
+ StackHandleScope<2> hs2(self);
+ Handle<mirror::ObjectArray<mirror::ArtMethod>> directs =
+ hs2.NewHandle(AllocArtMethodArray(self, 1));
+ if (UNLIKELY(directs.Get() == nullptr)) {
CHECK(self->IsExceptionPending()); // OOME.
return nullptr;
}
- klass->SetDirectMethods(directs);
- mirror::ArtMethod* constructor = CreateProxyConstructor(self, klass, proxy_class);
- if (UNLIKELY(constructor == nullptr)) {
+ klass->SetDirectMethods(directs.Get());
+ Handle<mirror::ArtMethod> constructor =
+ hs2.NewHandle(CreateProxyConstructor(self, klass));
+ if (UNLIKELY(constructor.Get() == nullptr)) {
CHECK(self->IsExceptionPending()); // OOME.
return nullptr;
}
- klass->SetDirectMethod(0, constructor);
+ klass->SetDirectMethod(0, constructor.Get());
}
// Create virtual method using specified prototypes.
@@ -3274,35 +3280,38 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
<< PrettyClass(h_methods->GetClass());
const size_t num_virtual_methods = h_methods->GetLength();
{
- mirror::ObjectArray<mirror::ArtMethod>* virtuals = AllocArtMethodArray(self,
- num_virtual_methods);
- if (UNLIKELY(virtuals == nullptr)) {
+ StackHandleScope<1> hs2(self);
+ Handle<mirror::ObjectArray<mirror::ArtMethod>> virtuals =
+ hs2.NewHandle(AllocArtMethodArray(self, num_virtual_methods));
+ if (UNLIKELY(virtuals.Get() == nullptr)) {
CHECK(self->IsExceptionPending()); // OOME.
return nullptr;
}
- klass->SetVirtualMethods(virtuals);
+ klass->SetVirtualMethods(virtuals.Get());
}
for (size_t i = 0; i < num_virtual_methods; ++i) {
- StackHandleScope<1> hs2(self);
+ StackHandleScope<2> hs2(self);
Handle<mirror::ArtMethod> prototype(hs2.NewHandle(h_methods->Get(i)->GetArtMethod()));
- mirror::ArtMethod* clone = CreateProxyMethod(self, klass, prototype);
- if (UNLIKELY(clone == nullptr)) {
+ Handle<mirror::ArtMethod> clone(hs2.NewHandle(CreateProxyMethod(self, klass, prototype)));
+ if (UNLIKELY(clone.Get() == nullptr)) {
CHECK(self->IsExceptionPending()); // OOME.
return nullptr;
}
- klass->SetVirtualMethod(i, clone);
+ klass->SetVirtualMethod(i, clone.Get());
}
- klass->SetSuperClass(proxy_class); // The super class is java.lang.reflect.Proxy
- mirror::Class::SetStatus(klass, mirror::Class::kStatusLoaded, self); // Now effectively in the loaded state.
+ // The super class is java.lang.reflect.Proxy
+ klass->SetSuperClass(GetClassRoot(kJavaLangReflectProxy));
+ // Now effectively in the loaded state.
+ mirror::Class::SetStatus(klass, mirror::Class::kStatusLoaded, self);
self->AssertNoPendingException();
- std::string descriptor(GetDescriptorForProxy(klass.Get()));
- mirror::Class* new_class = nullptr;
+ MutableHandle<mirror::Class> new_class = hs.NewHandle<mirror::Class>(nullptr);
{
// Must hold lock on object when resolved.
ObjectLock<mirror::Class> resolution_lock(self, klass);
- // Link the fields and virtual methods, creating vtable and iftables
+ // Link the fields and virtual methods, creating vtable and iftables.
+ // The new class will replace the old one in the class table.
Handle<mirror::ObjectArray<mirror::Class> > h_interfaces(
hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces)));
if (!LinkClass(self, descriptor.c_str(), klass, h_interfaces, &new_class)) {
@@ -3310,15 +3319,14 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
return nullptr;
}
}
-
CHECK(klass->IsRetired());
- CHECK_NE(klass.Get(), new_class);
- klass.Assign(new_class);
+ CHECK_NE(klass.Get(), new_class.Get());
+ klass.Assign(new_class.Get());
- CHECK_EQ(interfaces_sfield->GetDeclaringClass(), new_class);
+ CHECK_EQ(interfaces_sfield->GetDeclaringClass(), klass.Get());
interfaces_sfield->SetObject<false>(klass.Get(),
soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces));
- CHECK_EQ(throws_sfield->GetDeclaringClass(), new_class);
+ CHECK_EQ(throws_sfield->GetDeclaringClass(), klass.Get());
throws_sfield->SetObject<false>(klass.Get(),
soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >*>(throws));
@@ -3339,7 +3347,8 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
CheckProxyMethod(virtual_method, prototype);
}
- mirror::String* decoded_name = soa.Decode<mirror::String*>(name);
+ StackHandleScope<1> hs2(self);
+ Handle<mirror::String> decoded_name = hs2.NewHandle(soa.Decode<mirror::String*>(name));
std::string interfaces_field_name(StringPrintf("java.lang.Class[] %s.interfaces",
decoded_name->ToModifiedUtf8().c_str()));
CHECK_EQ(PrettyField(klass->GetStaticField(0)), interfaces_field_name);
@@ -3353,9 +3362,6 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
CHECK_EQ(klass.Get()->GetThrows(),
soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class>>*>(throws));
}
- mirror::Class* existing = InsertClass(descriptor.c_str(), klass.Get(),
- ComputeModifiedUtf8Hash(descriptor.c_str()));
- CHECK(existing == nullptr);
return klass.Get();
}
@@ -3390,17 +3396,16 @@ mirror::ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class,
mirror::ArtMethod* ClassLinker::CreateProxyConstructor(Thread* self,
- Handle<mirror::Class> klass,
- mirror::Class* proxy_class) {
+ Handle<mirror::Class> klass) {
// Create constructor for Proxy that must initialize h
mirror::ObjectArray<mirror::ArtMethod>* proxy_direct_methods =
- proxy_class->GetDirectMethods();
+ GetClassRoot(kJavaLangReflectProxy)->GetDirectMethods();
CHECK_EQ(proxy_direct_methods->GetLength(), 16);
mirror::ArtMethod* proxy_constructor = proxy_direct_methods->Get(2);
// Ensure constructor is in dex cache so that we can use the dex cache to look up the overridden
// constructor method.
- proxy_class->GetDexCache()->SetResolvedMethod(proxy_constructor->GetDexMethodIndex(),
- proxy_constructor);
+ GetClassRoot(kJavaLangReflectProxy)->GetDexCache()->SetResolvedMethod(
+ proxy_constructor->GetDexMethodIndex(), proxy_constructor);
// Clone the existing constructor of Proxy (our constructor would just invoke it so steal its
// code_ too)
mirror::ArtMethod* constructor = down_cast<mirror::ArtMethod*>(proxy_constructor->Clone(self));
@@ -3924,7 +3929,7 @@ void ClassLinker::FixupTemporaryDeclaringClass(mirror::Class* temp_class, mirror
bool ClassLinker::LinkClass(Thread* self, const char* descriptor, Handle<mirror::Class> klass,
Handle<mirror::ObjectArray<mirror::Class>> interfaces,
- mirror::Class** new_class) {
+ MutableHandle<mirror::Class>* h_new_class_out) {
CHECK_EQ(mirror::Class::kStatusLoaded, klass->GetStatus());
if (!LinkSuperClass(klass)) {
@@ -3957,25 +3962,23 @@ bool ClassLinker::LinkClass(Thread* self, const char* descriptor, Handle<mirror:
// This will notify waiters on klass that saw the not yet resolved
// class in the class_table_ during EnsureResolved.
mirror::Class::SetStatus(klass, mirror::Class::kStatusResolved, self);
- *new_class = klass.Get();
+ h_new_class_out->Assign(klass.Get());
} else {
CHECK(!klass->IsResolved());
// Retire the temporary class and create the correctly sized resolved class.
- *new_class = klass->CopyOf(self, class_size, &imt_handle_scope);
- if (UNLIKELY(*new_class == nullptr)) {
+ StackHandleScope<1> hs(self);
+ auto h_new_class = hs.NewHandle<mirror::Class>(
+ klass->CopyOf(self, class_size, &imt_handle_scope));
+ if (UNLIKELY(h_new_class.Get() == nullptr)) {
CHECK(self->IsExceptionPending()); // Expect an OOME.
mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
return false;
}
- CHECK_EQ((*new_class)->GetClassSize(), class_size);
- StackHandleScope<1> hs(self);
- auto new_class_h = hs.NewHandleWrapper<mirror::Class>(new_class);
- ObjectLock<mirror::Class> lock(self, new_class_h);
-
- FixupTemporaryDeclaringClass(klass.Get(), new_class_h.Get());
-
- mirror::Class* existing = UpdateClass(descriptor, new_class_h.Get(),
+ CHECK_EQ(h_new_class->GetClassSize(), class_size);
+ ObjectLock<mirror::Class> lock(self, h_new_class);
+ FixupTemporaryDeclaringClass(klass.Get(), h_new_class.Get());
+ mirror::Class* existing = UpdateClass(descriptor, h_new_class.Get(),
ComputeModifiedUtf8Hash(descriptor));
CHECK(existing == nullptr || existing == klass.Get());
@@ -3983,10 +3986,12 @@ bool ClassLinker::LinkClass(Thread* self, const char* descriptor, Handle<mirror:
// class_table_ during EnsureResolved.
mirror::Class::SetStatus(klass, mirror::Class::kStatusRetired, self);
- CHECK_EQ(new_class_h->GetStatus(), mirror::Class::kStatusResolving);
+ CHECK_EQ(h_new_class->GetStatus(), mirror::Class::kStatusResolving);
// This will notify waiters on new_class that saw the not yet resolved
// class in the class_table_ during EnsureResolved.
- mirror::Class::SetStatus(new_class_h, mirror::Class::kStatusResolved, self);
+ mirror::Class::SetStatus(h_new_class, mirror::Class::kStatusResolved, self);
+ // Return the new class.
+ h_new_class_out->Assign(h_new_class.Get());
}
return true;
}
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 95c8aa0244..947e15210b 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -49,6 +49,7 @@ namespace mirror {
} // namespace mirror
template<class T> class Handle;
+template<class T> class MutableHandle;
class InternTable;
template<class T> class ObjectLock;
class Runtime;
@@ -572,7 +573,7 @@ class ClassLinker {
bool LinkClass(Thread* self, const char* descriptor, Handle<mirror::Class> klass,
Handle<mirror::ObjectArray<mirror::Class>> interfaces,
- mirror::Class** new_class)
+ MutableHandle<mirror::Class>* h_new_class_out)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool LinkSuperClass(Handle<mirror::Class> klass)
@@ -622,8 +623,7 @@ class ClassLinker {
// Returns the boot image oat file.
const OatFile* GetBootOatFile() SHARED_LOCKS_REQUIRED(dex_lock_);
- mirror::ArtMethod* CreateProxyConstructor(Thread* self, Handle<mirror::Class> klass,
- mirror::Class* proxy_class)
+ mirror::ArtMethod* CreateProxyConstructor(Thread* self, Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ArtMethod* CreateProxyMethod(Thread* self, Handle<mirror::Class> klass,
Handle<mirror::ArtMethod> prototype)
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index ef1aa6a98c..728e8e3ccb 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -22,6 +22,7 @@
#include "arch/context.h"
#include "art_field-inl.h"
+#include "base/time_utils.h"
#include "class_linker.h"
#include "class_linker-inl.h"
#include "dex_file-inl.h"
@@ -3702,7 +3703,9 @@ JDWP::JdwpError Dbg::ConfigureStep(JDWP::ObjectId thread_id, JDWP::JdwpStepSize
mirror::ArtMethod* m = single_step_control->GetMethod();
const int32_t line_number = visitor.line_number;
- if (!m->IsNative()) {
+ // Note: if the thread is not running Java code (pure native thread), there is no "current"
+ // method on the stack (and no line number either).
+ if (m != nullptr && !m->IsNative()) {
const DexFile::CodeItem* const code_item = m->GetCodeItem();
DebugCallbackContext context(single_step_control, line_number, code_item);
m->GetDexFile()->DecodeDebugInfo(code_item, m->IsStatic(), m->GetDexMethodIndex(),
diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h
index 760006a480..4e6c3ca279 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -17,11 +17,11 @@
#ifndef ART_RUNTIME_DEX_FILE_INL_H_
#define ART_RUNTIME_DEX_FILE_INL_H_
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "base/stringpiece.h"
#include "dex_file.h"
#include "leb128.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc
index b1d933df62..9fd8c87435 100644
--- a/runtime/elf_file.cc
+++ b/runtime/elf_file.cc
@@ -1401,86 +1401,53 @@ typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByName(
}
template <typename ElfTypes>
-bool ElfFileImpl<ElfTypes>::FixupDebugSections(typename std::make_signed<Elf_Off>::type base_address_delta) {
+bool ElfFileImpl<ElfTypes>::FixupDebugSections(Elf_Addr base_address_delta) {
if (base_address_delta == 0) {
return true;
}
- if (FindSectionByName(".debug_frame") != nullptr) {
- if (!ApplyOatPatchesTo(".debug_frame", base_address_delta)) {
- return false;
- }
- }
- if (FindSectionByName(".debug_info") != nullptr) {
- if (!ApplyOatPatchesTo(".debug_info", base_address_delta)) {
- return false;
- }
- }
- if (FindSectionByName(".debug_line") != nullptr) {
- if (!ApplyOatPatchesTo(".debug_line", base_address_delta)) {
- return false;
- }
- }
- return true;
+ return ApplyOatPatchesTo(".debug_frame", base_address_delta) &&
+ ApplyOatPatchesTo(".debug_info", base_address_delta) &&
+ ApplyOatPatchesTo(".debug_line", base_address_delta);
}
template <typename ElfTypes>
bool ElfFileImpl<ElfTypes>::ApplyOatPatchesTo(
- const char* target_section_name,
- typename std::make_signed<Elf_Off>::type delta) {
- auto patches_section = FindSectionByName(".oat_patches");
+ const char* target_section_name, Elf_Addr delta) {
+ auto target_section = FindSectionByName(target_section_name);
+ if (target_section == nullptr) {
+ return true;
+ }
+ std::string patches_name = target_section_name + std::string(".oat_patches");
+ auto patches_section = FindSectionByName(patches_name.c_str());
if (patches_section == nullptr) {
- LOG(ERROR) << ".oat_patches section not found.";
+ LOG(ERROR) << patches_name << " section not found.";
return false;
}
if (patches_section->sh_type != SHT_OAT_PATCH) {
- LOG(ERROR) << "Unexpected type of .oat_patches.";
- return false;
- }
- auto target_section = FindSectionByName(target_section_name);
- if (target_section == nullptr) {
- LOG(ERROR) << target_section_name << " section not found.";
+ LOG(ERROR) << "Unexpected type of " << patches_name;
return false;
}
- if (!ApplyOatPatches(
+ ApplyOatPatches(
Begin() + patches_section->sh_offset,
Begin() + patches_section->sh_offset + patches_section->sh_size,
- target_section_name, delta,
+ delta,
Begin() + target_section->sh_offset,
- Begin() + target_section->sh_offset + target_section->sh_size)) {
- LOG(ERROR) << target_section_name << " section not found in .oat_patches.";
- }
+ Begin() + target_section->sh_offset + target_section->sh_size);
return true;
}
-// Apply .oat_patches to given section.
+// Apply LEB128 encoded patches to given section.
template <typename ElfTypes>
-bool ElfFileImpl<ElfTypes>::ApplyOatPatches(
- const uint8_t* patches, const uint8_t* patches_end,
- const char* target_section_name,
- typename std::make_signed<Elf_Off>::type delta,
+void ElfFileImpl<ElfTypes>::ApplyOatPatches(
+ const uint8_t* patches, const uint8_t* patches_end, Elf_Addr delta,
uint8_t* to_patch, const uint8_t* to_patch_end) {
- // Read null-terminated section name.
- const char* section_name;
- while ((section_name = reinterpret_cast<const char*>(patches))[0] != '\0') {
- patches += strlen(section_name) + 1;
- uint32_t length = DecodeUnsignedLeb128(&patches);
- const uint8_t* next_section = patches + length;
- // Is it the section we want to patch?
- if (strcmp(section_name, target_section_name) == 0) {
- // Read LEB128 encoded list of advances.
- while (patches < next_section) {
- DCHECK_LT(patches, patches_end) << "Unexpected end of .oat_patches.";
- to_patch += DecodeUnsignedLeb128(&patches);
- DCHECK_LT(to_patch, to_patch_end) << "Patch past the end of " << section_name;
- // TODO: 32-bit vs 64-bit. What is the right type to use here?
- auto* patch_loc = reinterpret_cast<typename std::make_signed<Elf_Off>::type*>(to_patch);
- *patch_loc += delta;
- }
- return true;
- }
- patches = next_section;
+ typedef __attribute__((__aligned__(1))) Elf_Addr UnalignedAddress;
+ while (patches < patches_end) {
+ to_patch += DecodeUnsignedLeb128(&patches);
+ DCHECK_LE(patches, patches_end) << "Unexpected end of patch list.";
+ DCHECK_LT(to_patch, to_patch_end) << "Patch past the end of section.";
+ *reinterpret_cast<UnalignedAddress*>(to_patch) += delta;
}
- return false;
}
template <typename ElfTypes>
diff --git a/runtime/elf_file_impl.h b/runtime/elf_file_impl.h
index 3ad096f983..0f466bd7b8 100644
--- a/runtime/elf_file_impl.h
+++ b/runtime/elf_file_impl.h
@@ -119,12 +119,9 @@ class ElfFileImpl {
bool FixupProgramHeaders(Elf_Addr base_address);
bool FixupSymbols(Elf_Addr base_address, bool dynamic);
bool FixupRelocations(Elf_Addr base_address);
- bool FixupDebugSections(typename std::make_signed<Elf_Off>::type base_address_delta);
- bool ApplyOatPatchesTo(const char* target_section_name,
- typename std::make_signed<Elf_Off>::type base_address_delta);
- static bool ApplyOatPatches(const uint8_t* patches, const uint8_t* patches_end,
- const char* target_section_name,
- typename std::make_signed<Elf_Off>::type delta,
+ bool FixupDebugSections(Elf_Addr base_address_delta);
+ bool ApplyOatPatchesTo(const char* target_section_name, Elf_Addr base_address_delta);
+ static void ApplyOatPatches(const uint8_t* patches, const uint8_t* patches_end, Elf_Addr delta,
uint8_t* to_patch, const uint8_t* to_patch_end);
bool Strip(std::string* error_msg);
diff --git a/runtime/entrypoints/quick/callee_save_frame.h b/runtime/entrypoints/quick/callee_save_frame.h
index 8cd6ca6777..3bcaf93e6d 100644
--- a/runtime/entrypoints/quick/callee_save_frame.h
+++ b/runtime/entrypoints/quick/callee_save_frame.h
@@ -38,22 +38,24 @@ class ArtMethod;
class ScopedQuickEntrypointChecks {
public:
- explicit ScopedQuickEntrypointChecks(Thread *self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : self_(self) {
- if (kIsDebugBuild) {
+ explicit ScopedQuickEntrypointChecks(Thread *self,
+ bool entry_check = kIsDebugBuild,
+ bool exit_check = kIsDebugBuild)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : self_(self), exit_check_(exit_check) {
+ if (entry_check) {
TestsOnEntry();
}
}
- explicit ScopedQuickEntrypointChecks() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : self_(kIsDebugBuild ? Thread::Current() : nullptr) {
+ ScopedQuickEntrypointChecks() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : self_(kIsDebugBuild ? Thread::Current() : nullptr), exit_check_(kIsDebugBuild) {
if (kIsDebugBuild) {
TestsOnEntry();
}
}
~ScopedQuickEntrypointChecks() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (kIsDebugBuild) {
+ if (exit_check_) {
TestsOnExit();
}
}
@@ -70,6 +72,7 @@ class ScopedQuickEntrypointChecks {
}
Thread* const self_;
+ bool exit_check_;
};
static constexpr size_t GetCalleeSaveFrameSize(InstructionSet isa, Runtime::CalleeSaveType type) {
diff --git a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
index eb1b1056a4..2bb73efa2f 100644
--- a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc
@@ -29,7 +29,9 @@ extern "C" const void* artInstrumentationMethodEntryFromCode(mirror::ArtMethod*
Thread* self,
uintptr_t lr)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ScopedQuickEntrypointChecks sqec(self);
+ // Instrumentation changes the stack. Thus, when exiting, the stack cannot be verified, so skip
+ // that part.
+ ScopedQuickEntrypointChecks sqec(self, kIsDebugBuild, false);
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
const void* result;
if (instrumentation->IsDeoptimized(method)) {
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 838427fcb6..c029eeb74e 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -823,7 +823,10 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called,
Thread* self,
StackReference<mirror::ArtMethod>* sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ScopedQuickEntrypointChecks sqec(self);
+ // The resolution trampoline stashes the resolved method into the callee-save frame to transport
+ // it. Thus, when exiting, the stack cannot be verified (as the resolved method most likely
+ // does not have the same stack layout as the callee-save method).
+ ScopedQuickEntrypointChecks sqec(self, kIsDebugBuild, false);
// Start new JNI local reference state
JNIEnvExt* env = self->GetJniEnv();
ScopedObjectAccessUnchecked soa(env);
@@ -2059,13 +2062,14 @@ extern "C" TwoWordReturn artInvokeVirtualTrampolineWithAccessCheck(
}
// Determine target of interface dispatch. This object is known non-null.
-extern "C" TwoWordReturn artInvokeInterfaceTrampoline(mirror::ArtMethod* interface_method,
+extern "C" TwoWordReturn artInvokeInterfaceTrampoline(uint32_t dex_method_idx,
mirror::Object* this_object,
Thread* self,
StackReference<mirror::ArtMethod>* sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
mirror::ArtMethod* caller_method = QuickArgumentVisitor::GetCallingMethod(sp);
+ mirror::ArtMethod* interface_method = caller_method->GetDexCacheResolvedMethod(dex_method_idx);
mirror::ArtMethod* method;
if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex)) {
method = this_object->GetClass()->FindVirtualMethodForInterface(interface_method);
@@ -2076,21 +2080,21 @@ extern "C" TwoWordReturn artInvokeInterfaceTrampoline(mirror::ArtMethod* interfa
}
} else {
DCHECK(interface_method == Runtime::Current()->GetResolutionMethod());
-
- uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp);
- const DexFile::CodeItem* code = caller_method->GetCodeItem();
- CHECK_LT(dex_pc, code->insns_size_in_code_units_);
- const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
- Instruction::Code instr_code = instr->Opcode();
- CHECK(instr_code == Instruction::INVOKE_INTERFACE ||
- instr_code == Instruction::INVOKE_INTERFACE_RANGE)
- << "Unexpected call into interface trampoline: " << instr->DumpString(nullptr);
- uint32_t dex_method_idx;
- if (instr_code == Instruction::INVOKE_INTERFACE) {
- dex_method_idx = instr->VRegB_35c();
- } else {
- DCHECK_EQ(instr_code, Instruction::INVOKE_INTERFACE_RANGE);
- dex_method_idx = instr->VRegB_3rc();
+ if (kIsDebugBuild) {
+ uint32_t dex_pc = QuickArgumentVisitor::GetCallingDexPc(sp);
+ const DexFile::CodeItem* code = caller_method->GetCodeItem();
+ CHECK_LT(dex_pc, code->insns_size_in_code_units_);
+ const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
+ Instruction::Code instr_code = instr->Opcode();
+ CHECK(instr_code == Instruction::INVOKE_INTERFACE ||
+ instr_code == Instruction::INVOKE_INTERFACE_RANGE)
+ << "Unexpected call into interface trampoline: " << instr->DumpString(nullptr);
+ if (instr_code == Instruction::INVOKE_INTERFACE) {
+ CHECK_EQ(dex_method_idx, instr->VRegB_35c());
+ } else {
+ CHECK_EQ(instr_code, Instruction::INVOKE_INTERFACE_RANGE);
+ CHECK_EQ(dex_method_idx, instr->VRegB_3rc());
+ }
}
const DexFile* dex_file = caller_method->GetDeclaringClass()->GetDexCache()
diff --git a/runtime/gc/accounting/atomic_stack.h b/runtime/gc/accounting/atomic_stack.h
index 399832a377..ac716eaabc 100644
--- a/runtime/gc/accounting/atomic_stack.h
+++ b/runtime/gc/accounting/atomic_stack.h
@@ -22,11 +22,11 @@
#include <string>
#include "atomic.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "base/macros.h"
#include "mem_map.h"
#include "stack.h"
-#include "utils.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/accounting/bitmap-inl.h b/runtime/gc/accounting/bitmap-inl.h
index e87a0c039b..cd3923abbe 100644
--- a/runtime/gc/accounting/bitmap-inl.h
+++ b/runtime/gc/accounting/bitmap-inl.h
@@ -22,8 +22,8 @@
#include <memory>
#include "atomic.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
-#include "utils.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/accounting/bitmap.cc b/runtime/gc/accounting/bitmap.cc
index 13fcdb305e..fdded028e1 100644
--- a/runtime/gc/accounting/bitmap.cc
+++ b/runtime/gc/accounting/bitmap.cc
@@ -16,6 +16,7 @@
#include "bitmap-inl.h"
+#include "base/bit_utils.h"
#include "card_table.h"
#include "mem_map.h"
diff --git a/runtime/gc/accounting/card_table-inl.h b/runtime/gc/accounting/card_table-inl.h
index b936d93b43..f72f219a0d 100644
--- a/runtime/gc/accounting/card_table-inl.h
+++ b/runtime/gc/accounting/card_table-inl.h
@@ -18,11 +18,11 @@
#define ART_RUNTIME_GC_ACCOUNTING_CARD_TABLE_INL_H_
#include "atomic.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "card_table.h"
#include "mem_map.h"
#include "space_bitmap.h"
-#include "utils.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/accounting/read_barrier_table.h b/runtime/gc/accounting/read_barrier_table.h
index bb9aae7886..436df923c5 100644
--- a/runtime/gc/accounting/read_barrier_table.h
+++ b/runtime/gc/accounting/read_barrier_table.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_GC_ACCOUNTING_READ_BARRIER_TABLE_H_
#define ART_RUNTIME_GC_ACCOUNTING_READ_BARRIER_TABLE_H_
+#include "base/bit_utils.h"
#include "base/mutex.h"
#include "gc/space/space.h"
#include "globals.h"
diff --git a/runtime/gc/accounting/space_bitmap-inl.h b/runtime/gc/accounting/space_bitmap-inl.h
index ae912006bb..c16f5d35e0 100644
--- a/runtime/gc/accounting/space_bitmap-inl.h
+++ b/runtime/gc/accounting/space_bitmap-inl.h
@@ -22,8 +22,8 @@
#include <memory>
#include "atomic.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
-#include "utils.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/allocator/dlmalloc.cc b/runtime/gc/allocator/dlmalloc.cc
index 8558f96730..3d85395377 100644
--- a/runtime/gc/allocator/dlmalloc.cc
+++ b/runtime/gc/allocator/dlmalloc.cc
@@ -16,6 +16,7 @@
#include "dlmalloc.h"
+#include "base/bit_utils.h"
#include "base/logging.h"
// ART specific morecore implementation defined in space.cc.
diff --git a/runtime/gc/allocator/rosalloc.h b/runtime/gc/allocator/rosalloc.h
index a54edccff9..0fcfe72b06 100644
--- a/runtime/gc/allocator/rosalloc.h
+++ b/runtime/gc/allocator/rosalloc.h
@@ -27,11 +27,11 @@
#include <vector>
#include "base/allocator.h"
+#include "base/bit_utils.h"
#include "base/mutex.h"
#include "base/logging.h"
#include "globals.h"
#include "thread.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/gc/collector/garbage_collector.cc b/runtime/gc/collector/garbage_collector.cc
index 47d6ada4e6..afd0a30fe4 100644
--- a/runtime/gc/collector/garbage_collector.cc
+++ b/runtime/gc/collector/garbage_collector.cc
@@ -25,11 +25,13 @@
#include "base/histogram-inl.h"
#include "base/logging.h"
#include "base/mutex-inl.h"
+#include "base/time_utils.h"
#include "gc/accounting/heap_bitmap.h"
#include "gc/space/large_object_space.h"
#include "gc/space/space-inl.h"
#include "thread-inl.h"
#include "thread_list.h"
+#include "utils.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc
index 5401b56449..2a9c03dcef 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -29,6 +29,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/mutex-inl.h"
+#include "base/time_utils.h"
#include "base/timing_logger.h"
#include "gc/accounting/card_table-inl.h"
#include "gc/accounting/heap_bitmap-inl.h"
@@ -389,6 +390,9 @@ class MarkSweepMarkObjectSlowPath {
ArtField* field = holder_->FindFieldByOffset(offset_);
LOG(INTERNAL_FATAL) << "Field info: "
<< " holder=" << holder_
+ << " holder is "
+ << (mark_sweep_->GetHeap()->IsLiveObjectLocked(holder_)
+ ? "alive" : "dead")
<< " holder_size=" << holder_size
<< " holder_type=" << PrettyTypeOf(holder_)
<< " offset=" << offset_.Uint32Value()
@@ -404,6 +408,12 @@ class MarkSweepMarkObjectSlowPath {
? holder_->AsClass()->NumReferenceStaticFields()
: holder_->GetClass()->NumReferenceInstanceFields())
<< "\n";
+ // Print the memory content of the holder.
+ for (size_t i = 0; i < holder_size / sizeof(uint32_t); ++i) {
+ uint32_t* p = reinterpret_cast<uint32_t*>(holder_);
+ LOG(INTERNAL_FATAL) << &p[i] << ": " << "holder+" << (i * sizeof(uint32_t)) << " = "
+ << std::hex << p[i];
+ }
}
PrintFileToLog("/proc/self/maps", LogSeverity::INTERNAL_FATAL);
MemMap::DumpMaps(LOG(INTERNAL_FATAL), true);
diff --git a/runtime/gc/heap-inl.h b/runtime/gc/heap-inl.h
index fbf36e880d..eb0e9beea9 100644
--- a/runtime/gc/heap-inl.h
+++ b/runtime/gc/heap-inl.h
@@ -19,6 +19,7 @@
#include "heap.h"
+#include "base/time_utils.h"
#include "debugger.h"
#include "gc/accounting/card_table-inl.h"
#include "gc/collector/semi_space.h"
@@ -31,6 +32,7 @@
#include "handle_scope-inl.h"
#include "thread.h"
#include "thread-inl.h"
+#include "utils.h"
#include "verify_object-inl.h"
namespace art {
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 11a0e3c3b8..fbde4947c0 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -28,6 +28,7 @@
#include "base/dumpable.h"
#include "base/histogram-inl.h"
#include "base/stl_util.h"
+#include "base/time_utils.h"
#include "common_throws.h"
#include "cutils/sched_policy.h"
#include "debugger.h"
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 90249f90f4..c72414a1ab 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -24,6 +24,7 @@
#include "allocator_type.h"
#include "arch/instruction_set.h"
#include "atomic.h"
+#include "base/time_utils.h"
#include "base/timing_logger.h"
#include "gc/accounting/atomic_stack.h"
#include "gc/accounting/card_table.h"
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc
index 01e8795669..5af2a53ab2 100644
--- a/runtime/gc/reference_processor.cc
+++ b/runtime/gc/reference_processor.cc
@@ -16,6 +16,7 @@
#include "reference_processor.h"
+#include "base/time_utils.h"
#include "mirror/object-inl.h"
#include "mirror/reference.h"
#include "mirror/reference-inl.h"
@@ -24,6 +25,7 @@
#include "ScopedLocalRef.h"
#include "scoped_thread_state_change.h"
#include "task_processor.h"
+#include "utils.h"
#include "well_known_classes.h"
namespace art {
diff --git a/runtime/gc/space/bump_pointer_space-inl.h b/runtime/gc/space/bump_pointer_space-inl.h
index 14a93d1611..d9ad9a38ca 100644
--- a/runtime/gc/space/bump_pointer_space-inl.h
+++ b/runtime/gc/space/bump_pointer_space-inl.h
@@ -17,6 +17,7 @@
#ifndef ART_RUNTIME_GC_SPACE_BUMP_POINTER_SPACE_INL_H_
#define ART_RUNTIME_GC_SPACE_BUMP_POINTER_SPACE_INL_H_
+#include "base/bit_utils.h"
#include "bump_pointer_space.h"
namespace art {
diff --git a/runtime/gc/space/dlmalloc_space.cc b/runtime/gc/space/dlmalloc_space.cc
index 7b1a421f4a..5237c7b08e 100644
--- a/runtime/gc/space/dlmalloc_space.cc
+++ b/runtime/gc/space/dlmalloc_space.cc
@@ -16,6 +16,7 @@
#include "dlmalloc_space-inl.h"
+#include "base/time_utils.h"
#include "gc/accounting/card_table.h"
#include "gc/accounting/space_bitmap-inl.h"
#include "gc/heap.h"
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 99f5d459bb..ade9cec031 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -25,8 +25,9 @@
#include "base/macros.h"
#include "base/stl_util.h"
-#include "base/unix_file/fd_file.h"
#include "base/scoped_flock.h"
+#include "base/time_utils.h"
+#include "base/unix_file/fd_file.h"
#include "gc/accounting/space_bitmap-inl.h"
#include "mirror/art_method.h"
#include "mirror/class-inl.h"
diff --git a/runtime/gc/space/large_object_space.cc b/runtime/gc/space/large_object_space.cc
index 4dfdaa5907..da4a930f15 100644
--- a/runtime/gc/space/large_object_space.cc
+++ b/runtime/gc/space/large_object_space.cc
@@ -27,7 +27,6 @@
#include "os.h"
#include "space-inl.h"
#include "thread-inl.h"
-#include "utils.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/space/large_object_space_test.cc b/runtime/gc/space/large_object_space_test.cc
index a261663ec7..f04a7ca4b2 100644
--- a/runtime/gc/space/large_object_space_test.cc
+++ b/runtime/gc/space/large_object_space_test.cc
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "base/time_utils.h"
#include "space_test.h"
#include "large_object_space.h"
diff --git a/runtime/gc/space/rosalloc_space.cc b/runtime/gc/space/rosalloc_space.cc
index 2c7d93ecd1..bc4414daab 100644
--- a/runtime/gc/space/rosalloc_space.cc
+++ b/runtime/gc/space/rosalloc_space.cc
@@ -20,6 +20,7 @@
#define ATRACE_TAG ATRACE_TAG_DALVIK
#include "cutils/trace.h"
+#include "base/time_utils.h"
#include "gc/accounting/card_table.h"
#include "gc/accounting/space_bitmap-inl.h"
#include "gc/heap.h"
diff --git a/runtime/gc/task_processor.cc b/runtime/gc/task_processor.cc
index ef34c68cc4..a49121b0e6 100644
--- a/runtime/gc/task_processor.cc
+++ b/runtime/gc/task_processor.cc
@@ -16,6 +16,7 @@
#include "task_processor.h"
+#include "base/time_utils.h"
#include "scoped_thread_state_change.h"
namespace art {
diff --git a/runtime/gc/task_processor_test.cc b/runtime/gc/task_processor_test.cc
index 5dd6d8fb7b..f06f68d3cf 100644
--- a/runtime/gc/task_processor_test.cc
+++ b/runtime/gc/task_processor_test.cc
@@ -14,11 +14,11 @@
* limitations under the License.
*/
+#include "base/time_utils.h"
#include "common_runtime_test.h"
#include "task_processor.h"
#include "thread_pool.h"
#include "thread-inl.h"
-#include "utils.h"
namespace art {
namespace gc {
diff --git a/runtime/handle_scope.h b/runtime/handle_scope.h
index 271312ea9f..ac28c8ad6e 100644
--- a/runtime/handle_scope.h
+++ b/runtime/handle_scope.h
@@ -23,7 +23,6 @@
#include "base/macros.h"
#include "handle.h"
#include "stack.h"
-#include "utils.h"
#include "verify_object.h"
namespace art {
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index efead51800..88a72ec664 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -40,6 +40,7 @@
#include "art_field-inl.h"
#include "base/logging.h"
#include "base/stringprintf.h"
+#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "common_throws.h"
diff --git a/runtime/image.cc b/runtime/image.cc
index 2d8c1c4b6e..d9bd2a8937 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -16,10 +16,10 @@
#include "image.h"
+#include "base/bit_utils.h"
#include "mirror/object_array.h"
#include "mirror/object_array-inl.h"
#include "mirror/object-inl.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/image.h b/runtime/image.h
index 613414aa25..52995edb52 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -21,7 +21,6 @@
#include "globals.h"
#include "mirror/object.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index b795d72a6a..3142089862 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -562,6 +562,11 @@ mirror::Object* JavaVMExt::DecodeGlobal(Thread* self, IndirectRef ref) {
return globals_.SynchronizedGet(self, &globals_lock_, ref);
}
+void JavaVMExt::UpdateGlobal(Thread* self, IndirectRef ref, mirror::Object* result) {
+ WriterMutexLock mu(self, globals_lock_);
+ globals_.Update(ref, result);
+}
+
mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
MutexLock mu(self, weak_globals_lock_);
while (UNLIKELY(!allow_new_weak_globals_)) {
@@ -570,6 +575,11 @@ mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
return weak_globals_.Get(ref);
}
+void JavaVMExt::UpdateWeakGlobal(Thread* self, IndirectRef ref, mirror::Object* result) {
+ MutexLock mu(self, weak_globals_lock_);
+ weak_globals_.Update(ref, result);
+}
+
void JavaVMExt::DumpReferenceTables(std::ostream& os) {
Thread* self = Thread::Current();
{
diff --git a/runtime/java_vm_ext.h b/runtime/java_vm_ext.h
index deec6a98f3..594027c3c9 100644
--- a/runtime/java_vm_ext.h
+++ b/runtime/java_vm_ext.h
@@ -125,9 +125,17 @@ class JavaVMExt : public JavaVM {
mirror::Object* DecodeGlobal(Thread* self, IndirectRef ref)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void UpdateGlobal(Thread* self, IndirectRef ref, mirror::Object* result)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ LOCKS_EXCLUDED(globals_lock_);
+
mirror::Object* DecodeWeakGlobal(Thread* self, IndirectRef ref)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void UpdateWeakGlobal(Thread* self, IndirectRef ref, mirror::Object* result)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ LOCKS_EXCLUDED(weak_globals_lock_);
+
const JNIInvokeInterface* GetUncheckedFunctions() const {
return unchecked_functions_;
}
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 8e9ab32c88..f7f70f6ed7 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -32,6 +32,7 @@
#include "jdwp/jdwp_priv.h"
#include "runtime.h"
#include "thread-inl.h"
+#include "utils.h"
namespace art {
diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc
index 5b30f0cd8c..e6b97a2083 100644
--- a/runtime/jdwp/jdwp_main.cc
+++ b/runtime/jdwp/jdwp_main.cc
@@ -22,6 +22,7 @@
#include "atomic.h"
#include "base/logging.h"
+#include "base/time_utils.h"
#include "debugger.h"
#include "jdwp/jdwp_priv.h"
#include "scoped_thread_state_change.h"
diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h
index c698cfc180..8f92453866 100644
--- a/runtime/jit/jit.h
+++ b/runtime/jit/jit.h
@@ -33,6 +33,10 @@ namespace art {
class CompilerCallbacks;
struct RuntimeArgumentMap;
+namespace mirror {
+class ArtMethod;
+} // namespace mirror
+
namespace jit {
class JitCodeCache;
diff --git a/runtime/jit/jit_code_cache_test.cc b/runtime/jit/jit_code_cache_test.cc
index 2155552bba..afa5a3e7ee 100644
--- a/runtime/jit/jit_code_cache_test.cc
+++ b/runtime/jit/jit_code_cache_test.cc
@@ -21,7 +21,6 @@
#include "mirror/art_method-inl.h"
#include "scoped_thread_state_change.h"
#include "thread-inl.h"
-#include "utils.h"
namespace art {
namespace jit {
diff --git a/runtime/leb128.h b/runtime/leb128.h
index 2e27b8ea3d..14683d4063 100644
--- a/runtime/leb128.h
+++ b/runtime/leb128.h
@@ -17,8 +17,11 @@
#ifndef ART_RUNTIME_LEB128_H_
#define ART_RUNTIME_LEB128_H_
+#include <vector>
+
+#include "base/bit_utils.h"
+#include "base/logging.h"
#include "globals.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/leb128_test.cc b/runtime/leb128_test.cc
index 87e13ff693..1bb493d4f6 100644
--- a/runtime/leb128_test.cc
+++ b/runtime/leb128_test.cc
@@ -18,6 +18,7 @@
#include "gtest/gtest.h"
#include "base/histogram-inl.h"
+#include "base/time_utils.h"
namespace art {
diff --git a/runtime/lock_word.h b/runtime/lock_word.h
index 655aa3a65d..aafbfe4159 100644
--- a/runtime/lock_word.h
+++ b/runtime/lock_word.h
@@ -20,9 +20,9 @@
#include <iosfwd>
#include <stdint.h>
+#include "base/bit_utils.h"
#include "base/logging.h"
#include "read_barrier.h"
-#include "utils.h"
namespace art {
namespace mirror {
diff --git a/runtime/memory_region.h b/runtime/memory_region.h
index 6a784eb061..13c69ace57 100644
--- a/runtime/memory_region.h
+++ b/runtime/memory_region.h
@@ -18,13 +18,15 @@
#define ART_RUNTIME_MEMORY_REGION_H_
#include <stdint.h>
+#include <type_traits>
+#include "arch/instruction_set.h"
+#include "base/bit_utils.h"
#include "base/casts.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/value_object.h"
#include "globals.h"
-#include "utils.h"
namespace art {
@@ -71,7 +73,7 @@ class MemoryRegion FINAL : public ValueObject {
template<typename T>
ALWAYS_INLINE T LoadUnaligned(uintptr_t offset) const {
// Equivalent unsigned integer type corresponding to T.
- typedef typename UnsignedIntegerType<sizeof(T)>::type U;
+ typedef typename std::make_unsigned<T>::type U;
U equivalent_unsigned_integer_value = 0;
// Read the value byte by byte in a little-endian fashion.
for (size_t i = 0; i < sizeof(U); ++i) {
@@ -86,7 +88,7 @@ class MemoryRegion FINAL : public ValueObject {
template<typename T>
ALWAYS_INLINE void StoreUnaligned(uintptr_t offset, T value) const {
// Equivalent unsigned integer type corresponding to T.
- typedef typename UnsignedIntegerType<sizeof(T)>::type U;
+ typedef typename std::make_unsigned<T>::type U;
U equivalent_unsigned_integer_value = bit_cast<U, T>(value);
// Write the value byte by byte in a little-endian fashion.
for (size_t i = 0; i < sizeof(U); ++i) {
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index 8b3418d6be..f3546b165b 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -19,11 +19,13 @@
#include "array.h"
+#include "base/bit_utils.h"
+#include "base/logging.h"
#include "base/stringprintf.h"
+#include "base/casts.h"
#include "class.h"
#include "gc/heap-inl.h"
#include "thread.h"
-#include "utils.h"
namespace art {
namespace mirror {
@@ -237,7 +239,7 @@ inline void PrimitiveArray<T>::Set(int32_t i, T value) {
}
template<typename T>
-template<bool kTransactionActive, bool kCheckTransaction>
+template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
inline void PrimitiveArray<T>::SetWithoutChecks(int32_t i, T value) {
if (kCheckTransaction) {
DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
@@ -245,7 +247,7 @@ inline void PrimitiveArray<T>::SetWithoutChecks(int32_t i, T value) {
if (kTransactionActive) {
Runtime::Current()->RecordWriteArray(this, i, GetWithoutChecks(i));
}
- DCHECK(CheckIsValidIndex(i));
+ DCHECK(CheckIsValidIndex<kVerifyFlags>(i));
GetData()[i] = value;
}
// Backward copy where elements are of aligned appropriately for T. Count is in T sized units.
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 832ad68dcd..167f824d14 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -131,7 +131,9 @@ class MANAGED PrimitiveArray : public Array {
// TODO fix thread safety analysis broken by the use of template. This should be
// SHARED_LOCKS_REQUIRED(Locks::mutator_lock_).
- template<bool kTransactionActive, bool kCheckTransaction = true>
+ template<bool kTransactionActive,
+ bool kCheckTransaction = true,
+ VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
void SetWithoutChecks(int32_t i, T value) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS;
/*
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 0f306e8699..7c8067adcd 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -31,6 +31,7 @@
#include "quick/quick_method_frame_info.h"
#include "read_barrier-inl.h"
#include "runtime-inl.h"
+#include "utils.h"
namespace art {
namespace mirror {
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index cc6f5c4cd6..5752a15b8b 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -32,6 +32,7 @@
#include "reference-inl.h"
#include "runtime.h"
#include "string.h"
+#include "utils.h"
namespace art {
namespace mirror {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index d3cfd01160..b99fc68933 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -27,7 +27,6 @@
#include "object_callbacks.h"
#include "primitive.h"
#include "read_barrier_option.h"
-#include "utils.h"
#ifndef IMT_SIZE
#error IMT_SIZE not defined
diff --git a/runtime/mirror/field.cc b/runtime/mirror/field.cc
index 933784e7ff..ac56129a16 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -69,6 +69,7 @@ ArtField* Field::GetArtField() {
mirror::DexCache* const dex_cache = declaring_class->GetDexCache();
ArtField* const art_field = dex_cache->GetResolvedField(GetDexFieldIndex(), sizeof(void*));
CHECK(art_field != nullptr);
+ CHECK_EQ(declaring_class, art_field->GetDeclaringClass());
return art_field;
}
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index 39d0f5664f..7760ea2cfd 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -59,19 +59,23 @@ inline void Object::SetClass(Class* new_klass) {
OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass);
}
+template<VerifyObjectFlags kVerifyFlags>
inline LockWord Object::GetLockWord(bool as_volatile) {
if (as_volatile) {
- return LockWord(GetField32Volatile(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
+ return LockWord(GetField32Volatile<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
}
- return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
+ return LockWord(GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_)));
}
+template<VerifyObjectFlags kVerifyFlags>
inline void Object::SetLockWord(LockWord new_val, bool as_volatile) {
// Force use of non-transactional mode and do not check.
if (as_volatile) {
- SetField32Volatile<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
+ SetField32Volatile<false, false, kVerifyFlags>(
+ OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
} else {
- SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
+ SetField32<false, false, kVerifyFlags>(
+ OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue());
}
}
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index 5afe99f3f8..2c0e626771 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -125,7 +125,9 @@ class MANAGED LOCKABLE Object {
// As_volatile can be false if the mutators are suspended. This is an optimization since it
// avoids the barriers.
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
LockWord GetLockWord(bool as_volatile) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
void SetLockWord(LockWord new_val, bool as_volatile) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h
index d473816448..bef4af617a 100644
--- a/runtime/mirror/object_array-inl.h
+++ b/runtime/mirror/object_array-inl.h
@@ -17,6 +17,8 @@
#ifndef ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_
#define ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_
+#include <string>
+
#include "object_array.h"
#include "array-inl.h"
@@ -26,7 +28,7 @@
#include "runtime.h"
#include "handle_scope-inl.h"
#include "thread.h"
-#include <string>
+#include "utils.h"
namespace art {
namespace mirror {
diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h
index cd5d2f66d2..35b8aef10a 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -25,6 +25,7 @@
#include "string.h"
#include "thread.h"
#include "utf.h"
+#include "utils.h"
namespace art {
namespace mirror {
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 4b412253f3..dc016a5006 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -23,6 +23,7 @@
#include "base/mutex.h"
#include "base/stl_util.h"
+#include "base/time_utils.h"
#include "class_linker.h"
#include "dex_file-inl.h"
#include "dex_instruction.h"
diff --git a/runtime/monitor_test.cc b/runtime/monitor_test.cc
index 30cb2d835d..2a29c60a13 100644
--- a/runtime/monitor_test.cc
+++ b/runtime/monitor_test.cc
@@ -20,6 +20,7 @@
#include <string>
#include "atomic.h"
+#include "base/time_utils.h"
#include "class_linker-inl.h"
#include "common_runtime_test.h"
#include "handle_scope-inl.h"
@@ -27,7 +28,6 @@
#include "mirror/string-inl.h" // Strings are easiest to allocate
#include "scoped_thread_state_change.h"
#include "thread_pool.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc
index 46881b00fa..1078492d08 100644
--- a/runtime/native/dalvik_system_VMDebug.cc
+++ b/runtime/native/dalvik_system_VMDebug.cc
@@ -22,6 +22,7 @@
#include <sstream>
#include "base/histogram-inl.h"
+#include "base/time_utils.h"
#include "class_linker.h"
#include "common_throws.h"
#include "debugger.h"
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 9736e1507f..a172197d71 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -16,6 +16,9 @@
#include "dalvik_system_VMRuntime.h"
+#ifdef HAVE_ANDROID_OS
+extern "C" void android_set_application_target_sdk_version(uint32_t version);
+#endif
#include <limits.h>
#include <ScopedUtfChars.h>
@@ -192,6 +195,12 @@ static void VMRuntime_setTargetSdkVersionNative(JNIEnv*, jobject, jint target_sd
// Note that targetSdkVersion may be CUR_DEVELOPMENT (10000).
// Note that targetSdkVersion may be 0, meaning "current".
Runtime::Current()->SetTargetSdkVersion(target_sdk_version);
+
+#ifdef HAVE_ANDROID_OS
+ // This part is letting libc/dynamic linker know about current app's
+ // target sdk version to enable compatibility workarounds.
+ android_set_application_target_sdk_version(static_cast<uint32_t>(target_sdk_version));
+#endif
}
static void VMRuntime_registerNativeAllocation(JNIEnv* env, jobject, jint bytes) {
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 1a7a3e5ba7..1d067063a4 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -65,7 +65,7 @@ static void EnableDebugFeatures(uint32_t debug_flags) {
DEBUG_ENABLE_SAFEMODE = 1 << 3,
DEBUG_ENABLE_JNI_LOGGING = 1 << 4,
DEBUG_ENABLE_JIT = 1 << 5,
- DEBUG_GENERATE_CFI = 1 << 6,
+ DEBUG_GENERATE_DEBUG_INFO = 1 << 6,
};
Runtime* const runtime = Runtime::Current();
@@ -112,10 +112,10 @@ static void EnableDebugFeatures(uint32_t debug_flags) {
}
runtime->GetJITOptions()->SetUseJIT(use_jit);
- const bool generate_cfi = (debug_flags & DEBUG_GENERATE_CFI) != 0;
- if (generate_cfi) {
- runtime->AddCompilerOption("--include-cfi");
- debug_flags &= ~DEBUG_GENERATE_CFI;
+ const bool generate_debug_info = (debug_flags & DEBUG_GENERATE_DEBUG_INFO) != 0;
+ if (generate_debug_info) {
+ runtime->AddCompilerOption("--generate-debug-info");
+ debug_flags &= ~DEBUG_GENERATE_DEBUG_INFO;
}
// This is for backwards compatibility with Dalvik.
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 721b7a3b76..d6aa9b5fbf 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -26,6 +26,7 @@
#include "mirror/field.h"
#include "reflection-inl.h"
#include "scoped_fast_native_object_access.h"
+#include "utils.h"
namespace art {
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 4f6aabc8e5..1dd2aad611 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -20,8 +20,8 @@
#include <zlib.h>
#include "arch/instruction_set_features.h"
+#include "base/bit_utils.h"
#include "base/stringprintf.h"
-#include "utils.h"
namespace art {
diff --git a/runtime/profiler.cc b/runtime/profiler.cc
index 3b0e6c1062..b149d4bdc4 100644
--- a/runtime/profiler.cc
+++ b/runtime/profiler.cc
@@ -23,6 +23,7 @@
#include <fstream>
#include "base/stl_util.h"
+#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "common_throws.h"
@@ -39,6 +40,7 @@
#include "ScopedLocalRef.h"
#include "thread.h"
#include "thread_list.h"
+#include "utils.h"
#include "entrypoints/quick/quick_entrypoints.h"
diff --git a/runtime/read_barrier-inl.h b/runtime/read_barrier-inl.h
index 5631ff4e25..d341ee1017 100644
--- a/runtime/read_barrier-inl.h
+++ b/runtime/read_barrier-inl.h
@@ -24,6 +24,7 @@
#include "mirror/object_reference.h"
#include "mirror/reference.h"
#include "runtime.h"
+#include "utils.h"
namespace art {
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index d321d272ea..f8c70815b2 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -464,7 +464,7 @@ JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject o
InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
if (is_string_init) {
// For string init, remap original receiver to StringFactory result.
- soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+ UpdateReference(soa.Self(), obj, result.GetL());
}
return result;
}
@@ -494,7 +494,7 @@ JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, jobject o
InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
if (is_string_init) {
// For string init, remap original receiver to StringFactory result.
- soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+ UpdateReference(soa.Self(), obj, result.GetL());
}
return result;
}
@@ -525,7 +525,7 @@ JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnab
InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
if (is_string_init) {
// For string init, remap original receiver to StringFactory result.
- soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+ UpdateReference(soa.Self(), obj, result.GetL());
}
return result;
}
@@ -556,7 +556,7 @@ JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnab
InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
if (is_string_init) {
// For string init, remap original receiver to StringFactory result.
- soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+ UpdateReference(soa.Self(), obj, result.GetL());
}
return result;
}
@@ -882,4 +882,21 @@ void InvalidReceiverError(mirror::Object* o, mirror::Class* c) {
actual_class_name.c_str()).c_str());
}
+// This only works if there's one reference which points to the object in obj.
+// Will need to be fixed if there's cases where it's not.
+void UpdateReference(Thread* self, jobject obj, mirror::Object* result) {
+ IndirectRef ref = reinterpret_cast<IndirectRef>(obj);
+ IndirectRefKind kind = GetIndirectRefKind(ref);
+ if (kind == kLocal) {
+ self->GetJniEnv()->locals.Update(obj, result);
+ } else if (kind == kHandleScopeOrInvalid) {
+ LOG(FATAL) << "Unsupported UpdateReference for kind kHandleScopeOrInvalid";
+ } else if (kind == kGlobal) {
+ self->GetJniEnv()->vm->UpdateGlobal(self, ref, result);
+ } else {
+ DCHECK_EQ(kind, kWeakGlobal);
+ self->GetJniEnv()->vm->UpdateWeakGlobal(self, ref, result);
+ }
+}
+
} // namespace art
diff --git a/runtime/reflection.h b/runtime/reflection.h
index 6b5ffc72f2..df3b9d3694 100644
--- a/runtime/reflection.h
+++ b/runtime/reflection.h
@@ -85,6 +85,9 @@ mirror::Class* GetCallingClass(Thread* self, size_t num_frames)
void InvalidReceiverError(mirror::Object* o, mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+void UpdateReference(Thread* self, jobject obj, mirror::Object* result)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
} // namespace art
#endif // ART_RUNTIME_REFLECTION_H_
diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc
index d65e18e124..f0b3c4e4cb 100644
--- a/runtime/runtime_linux.cc
+++ b/runtime/runtime_linux.cc
@@ -340,6 +340,9 @@ void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_contex
<< "Thread: " << tid << " \"" << thread_name << "\"\n"
<< "Registers:\n" << Dumpable<UContext>(thread_context) << "\n"
<< "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace);
+ if (kIsDebugBuild && signal_number == SIGSEGV) {
+ PrintFileToLog("/proc/self/maps", LogSeverity::INTERNAL_FATAL);
+ }
Runtime* runtime = Runtime::Current();
if (runtime != nullptr) {
if (IsTimeoutSignal(signal_number)) {
diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc
index 863d59bd66..9f8c55c980 100644
--- a/runtime/signal_catcher.cc
+++ b/runtime/signal_catcher.cc
@@ -28,6 +28,7 @@
#include <sstream>
#include "arch/instruction_set.h"
+#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "gc/heap.h"
diff --git a/runtime/stack.h b/runtime/stack.h
index 5b43848de0..0db0266a37 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -21,11 +21,11 @@
#include <string>
#include "arch/instruction_set.h"
+#include "base/bit_utils.h"
#include "dex_file.h"
#include "gc_root.h"
#include "mirror/object_reference.h"
#include "read_barrier.h"
-#include "utils.h"
#include "verify_object.h"
namespace art {
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index 6a0c07d2bc..c36ee05eaa 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -18,6 +18,8 @@
#include <stdint.h>
+#include "indenter.h"
+
namespace art {
constexpr size_t DexRegisterLocationCatalog::kNoLocationEntryIndex;
@@ -203,72 +205,95 @@ static void DumpRegisterMapping(std::ostream& os,
DexRegisterLocation location,
const std::string& prefix = "v",
const std::string& suffix = "") {
- os << " " << prefix << dex_register_num << ": "
- << DexRegisterLocation::PrettyDescriptor(location.GetInternalKind())
- << " (" << location.GetValue() << ")" << suffix << '\n';
+ Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
+ std::ostream indented_os(&indent_filter);
+ indented_os << prefix << dex_register_num << ": "
+ << DexRegisterLocation::PrettyDescriptor(location.GetInternalKind())
+ << " (" << location.GetValue() << ")" << suffix << '\n';
+}
+
+void CodeInfo::DumpStackMap(std::ostream& os,
+ size_t stack_map_num,
+ uint16_t number_of_dex_registers) const {
+ StackMap stack_map = GetStackMapAt(stack_map_num);
+ DumpStackMapHeader(os, stack_map_num);
+ if (stack_map.HasDexRegisterMap(*this)) {
+ DexRegisterMap dex_register_map = GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+ dex_register_map.Dump(os, *this, number_of_dex_registers);
+ }
}
void CodeInfo::DumpStackMapHeader(std::ostream& os, size_t stack_map_num) const {
StackMap stack_map = GetStackMapAt(stack_map_num);
- os << " StackMap " << stack_map_num
- << std::hex
- << " (dex_pc=0x" << stack_map.GetDexPc(*this)
- << ", native_pc_offset=0x" << stack_map.GetNativePcOffset(*this)
- << ", dex_register_map_offset=0x" << stack_map.GetDexRegisterMapOffset(*this)
- << ", inline_info_offset=0x" << stack_map.GetInlineDescriptorOffset(*this)
- << ", register_mask=0x" << stack_map.GetRegisterMask(*this)
- << std::dec
- << ", stack_mask=0b";
+ Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
+ std::ostream indented_os(&indent_filter);
+ indented_os << "StackMap " << stack_map_num
+ << std::hex
+ << " (dex_pc=0x" << stack_map.GetDexPc(*this)
+ << ", native_pc_offset=0x" << stack_map.GetNativePcOffset(*this)
+ << ", dex_register_map_offset=0x" << stack_map.GetDexRegisterMapOffset(*this)
+ << ", inline_info_offset=0x" << stack_map.GetInlineDescriptorOffset(*this)
+ << ", register_mask=0x" << stack_map.GetRegisterMask(*this)
+ << std::dec
+ << ", stack_mask=0b";
MemoryRegion stack_mask = stack_map.GetStackMask(*this);
for (size_t i = 0, e = stack_mask.size_in_bits(); i < e; ++i) {
- os << stack_mask.LoadBit(e - i - 1);
+ indented_os << stack_mask.LoadBit(e - i - 1);
}
- os << ")\n";
+ indented_os << ")\n";
};
-void CodeInfo::Dump(std::ostream& os, uint16_t number_of_dex_registers) const {
+void CodeInfo::Dump(std::ostream& os,
+ uint16_t number_of_dex_registers,
+ bool dump_stack_maps) const {
uint32_t code_info_size = GetOverallSize();
size_t number_of_stack_maps = GetNumberOfStackMaps();
- os << " Optimized CodeInfo (size=" << code_info_size
- << ", number_of_dex_registers=" << number_of_dex_registers
- << ", number_of_stack_maps=" << number_of_stack_maps
- << ", has_inline_info=" << HasInlineInfo()
- << ", number_of_bytes_for_inline_info=" << NumberOfBytesForInlineInfo()
- << ", number_of_bytes_for_dex_register_map=" << NumberOfBytesForDexRegisterMap()
- << ", number_of_bytes_for_dex_pc=" << NumberOfBytesForDexPc()
- << ", number_of_bytes_for_native_pc=" << NumberOfBytesForNativePc()
- << ", number_of_bytes_for_register_mask=" << NumberOfBytesForRegisterMask()
- << ")\n";
-
+ Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
+ std::ostream indented_os(&indent_filter);
+ indented_os << "Optimized CodeInfo (size=" << code_info_size
+ << ", number_of_dex_registers=" << number_of_dex_registers
+ << ", number_of_stack_maps=" << number_of_stack_maps
+ << ", has_inline_info=" << HasInlineInfo()
+ << ", number_of_bytes_for_inline_info=" << NumberOfBytesForInlineInfo()
+ << ", number_of_bytes_for_dex_register_map=" << NumberOfBytesForDexRegisterMap()
+ << ", number_of_bytes_for_dex_pc=" << NumberOfBytesForDexPc()
+ << ", number_of_bytes_for_native_pc=" << NumberOfBytesForNativePc()
+ << ", number_of_bytes_for_register_mask=" << NumberOfBytesForRegisterMask()
+ << ")\n";
// Display the Dex register location catalog.
- size_t number_of_location_catalog_entries = GetNumberOfDexRegisterLocationCatalogEntries();
- size_t location_catalog_size_in_bytes = GetDexRegisterLocationCatalogSize();
- os << " DexRegisterLocationCatalog (number_of_entries=" << number_of_location_catalog_entries
- << ", size_in_bytes=" << location_catalog_size_in_bytes << ")\n";
- DexRegisterLocationCatalog dex_register_location_catalog = GetDexRegisterLocationCatalog();
- for (size_t i = 0; i < number_of_location_catalog_entries; ++i) {
- DexRegisterLocation location = dex_register_location_catalog.GetDexRegisterLocation(i);
- DumpRegisterMapping(os, i, location, "entry ");
- }
-
+ GetDexRegisterLocationCatalog().Dump(indented_os, *this);
// Display stack maps along with (live) Dex register maps.
- for (size_t i = 0; i < number_of_stack_maps; ++i) {
- StackMap stack_map = GetStackMapAt(i);
- DumpStackMapHeader(os, i);
- if (stack_map.HasDexRegisterMap(*this)) {
- DexRegisterMap dex_register_map = GetDexRegisterMapOf(stack_map, number_of_dex_registers);
- dex_register_map.Dump(os, *this, number_of_dex_registers);
+ if (dump_stack_maps) {
+ for (size_t i = 0; i < number_of_stack_maps; ++i) {
+ DumpStackMap(indented_os, i, number_of_dex_registers);
}
}
// TODO: Dump the stack map's inline information? We need to know more from the caller:
// we need to know the number of dex registers for each inlined method.
}
+void DexRegisterLocationCatalog::Dump(std::ostream& os, const CodeInfo& code_info) {
+ size_t number_of_location_catalog_entries =
+ code_info.GetNumberOfDexRegisterLocationCatalogEntries();
+ size_t location_catalog_size_in_bytes = code_info.GetDexRegisterLocationCatalogSize();
+ Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
+ std::ostream indented_os(&indent_filter);
+ indented_os
+ << "DexRegisterLocationCatalog (number_of_entries=" << number_of_location_catalog_entries
+ << ", size_in_bytes=" << location_catalog_size_in_bytes << ")\n";
+ for (size_t i = 0; i < number_of_location_catalog_entries; ++i) {
+ DexRegisterLocation location = GetDexRegisterLocation(i);
+ DumpRegisterMapping(indented_os, i, location, "entry ");
+ }
+}
+
void DexRegisterMap::Dump(std::ostream& os,
const CodeInfo& code_info,
uint16_t number_of_dex_registers) const {
size_t number_of_location_catalog_entries =
code_info.GetNumberOfDexRegisterLocationCatalogEntries();
+ Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
+ std::ostream indented_os(&indent_filter);
// TODO: Display the bit mask of live Dex registers.
for (size_t j = 0; j < number_of_dex_registers; ++j) {
if (IsDexRegisterLive(j)) {
@@ -276,7 +301,7 @@ void DexRegisterMap::Dump(std::ostream& os,
j, number_of_dex_registers, number_of_location_catalog_entries);
DexRegisterLocation location = GetDexRegisterLocation(j, number_of_dex_registers, code_info);
DumpRegisterMapping(
- os, j, location, "v",
+ indented_os, j, location, "v",
"\t[entry " + std::to_string(static_cast<int>(location_catalog_entry_index)) + "]");
}
}
@@ -285,18 +310,20 @@ void DexRegisterMap::Dump(std::ostream& os,
void InlineInfo::Dump(std::ostream& os,
const CodeInfo& code_info,
uint16_t number_of_dex_registers[]) const {
- os << "InlineInfo with depth " << static_cast<uint32_t>(GetDepth()) << "\n";
+ Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
+ std::ostream indented_os(&indent_filter);
+ indented_os << "InlineInfo with depth " << static_cast<uint32_t>(GetDepth()) << "\n";
for (size_t i = 0; i < GetDepth(); ++i) {
- os << " At depth " << i
- << std::hex
- << " (dex_pc=0x" << GetDexPcAtDepth(i)
- << ", method_index=0x" << GetMethodIndexAtDepth(i)
- << ")\n";
+ indented_os << " At depth " << i
+ << std::hex
+ << " (dex_pc=0x" << GetDexPcAtDepth(i)
+ << ", method_index=0x" << GetMethodIndexAtDepth(i)
+ << ")\n";
if (HasDexRegisterMapAtDepth(i)) {
DexRegisterMap dex_register_map =
code_info.GetDexRegisterMapAtDepth(i, *this, number_of_dex_registers[i]);
- dex_register_map.Dump(os, code_info, number_of_dex_registers[i]);
+ dex_register_map.Dump(indented_os, code_info, number_of_dex_registers[i]);
}
}
}
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index b425a465b4..eefdaa7391 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -18,8 +18,8 @@
#define ART_RUNTIME_STACK_MAP_H_
#include "base/bit_vector.h"
+#include "base/bit_utils.h"
#include "memory_region.h"
-#include "utils.h"
namespace art {
@@ -356,6 +356,8 @@ class DexRegisterLocationCatalog {
return region_.size();
}
+ void Dump(std::ostream& os, const CodeInfo& code_info);
+
// Special (invalid) Dex register location catalog entry index meaning
// that there is no location for a given Dex register (i.e., it is
// mapped to a DexRegisterLocation::Kind::kNone location).
@@ -1046,7 +1048,15 @@ class CodeInfo {
return StackMap();
}
- void Dump(std::ostream& os, uint16_t number_of_dex_registers) const;
+ // Dump this CodeInfo object on `os`. If `dump_stack_maps` is true,
+ // also dump the stack maps and the associated Dex register maps.
+ void Dump(std::ostream& os, uint16_t number_of_dex_registers, bool dump_stack_maps) const;
+
+ // Dump stack map number `stack_map_num` as well as associated data on `os`,
+ // such as Dex register locations.
+ void DumpStackMap(std::ostream& os, size_t stack_map_num, uint16_t number_of_dex_registers) const;
+ // Dump the header of stack map number `stack_map_num` on `os`, without
+ // associated data.
void DumpStackMapHeader(std::ostream& os, size_t stack_map_num) const;
private:
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 9b1600f7c7..6f734dd524 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -33,6 +33,7 @@
#include "arch/context.h"
#include "art_field-inl.h"
+#include "base/bit_utils.h"
#include "base/mutex.h"
#include "base/timing_logger.h"
#include "base/to_str.h"
diff --git a/runtime/thread.h b/runtime/thread.h
index 9346813ec3..96e0916dd5 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -61,6 +61,7 @@ namespace mirror {
template<class T> class PrimitiveArray;
typedef PrimitiveArray<int32_t> IntArray;
class StackTraceElement;
+ class String;
class Throwable;
} // namespace mirror
diff --git a/runtime/thread_linux.cc b/runtime/thread_linux.cc
index 0526f49913..0731f3091b 100644
--- a/runtime/thread_linux.cc
+++ b/runtime/thread_linux.cc
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-#include "thread.h"
-
#include <signal.h>
+#include "thread.h"
+#include "utils.h"
+
namespace art {
void Thread::SetNativePriority(int) {
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index cc54bbdae0..7719bb8012 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -30,6 +30,7 @@
#include "base/histogram-inl.h"
#include "base/mutex.h"
#include "base/mutex-inl.h"
+#include "base/time_utils.h"
#include "base/timing_logger.h"
#include "debugger.h"
#include "jni_internal.h"
@@ -38,7 +39,6 @@
#include "scoped_thread_state_change.h"
#include "thread.h"
#include "trace.h"
-#include "utils.h"
#include "well_known_classes.h"
namespace art {
diff --git a/runtime/thread_pool.cc b/runtime/thread_pool.cc
index ce76eae95a..1e84c9ddb3 100644
--- a/runtime/thread_pool.cc
+++ b/runtime/thread_pool.cc
@@ -18,6 +18,7 @@
#include "base/casts.h"
#include "base/stl_util.h"
+#include "base/time_utils.h"
#include "runtime.h"
#include "thread-inl.h"
diff --git a/runtime/trace.cc b/runtime/trace.cc
index 76367923c0..f8747168b3 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -24,6 +24,7 @@
#include "base/casts.h"
#include "base/stl_util.h"
+#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "common_throws.h"
@@ -40,6 +41,7 @@
#include "ScopedLocalRef.h"
#include "thread.h"
#include "thread_list.h"
+#include "utils.h"
#include "entrypoints/quick/quick_entrypoints.h"
namespace art {
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 7986cdcbf9..2671b46bad 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -42,7 +42,6 @@
#if defined(__APPLE__)
#include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
#include <sys/syscall.h>
-#include <sys/time.h>
#endif
#include <backtrace/Backtrace.h> // For DumpNativeStack.
@@ -204,102 +203,6 @@ bool PrintFileToLog(const std::string& file_name, LogSeverity level) {
}
}
-std::string GetIsoDate() {
- time_t now = time(nullptr);
- tm tmbuf;
- tm* ptm = localtime_r(&now, &tmbuf);
- return StringPrintf("%04d-%02d-%02d %02d:%02d:%02d",
- ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday,
- ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
-}
-
-uint64_t MilliTime() {
-#if defined(__linux__)
- timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_nsec / UINT64_C(1000000);
-#else // __APPLE__
- timeval now;
- gettimeofday(&now, nullptr);
- return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000) + now.tv_usec / UINT64_C(1000);
-#endif
-}
-
-uint64_t MicroTime() {
-#if defined(__linux__)
- timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_nsec / UINT64_C(1000);
-#else // __APPLE__
- timeval now;
- gettimeofday(&now, nullptr);
- return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000) + now.tv_usec;
-#endif
-}
-
-uint64_t NanoTime() {
-#if defined(__linux__)
- timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
-#else // __APPLE__
- timeval now;
- gettimeofday(&now, nullptr);
- return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_usec * UINT64_C(1000);
-#endif
-}
-
-uint64_t ThreadCpuNanoTime() {
-#if defined(__linux__)
- timespec now;
- clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
- return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
-#else // __APPLE__
- UNIMPLEMENTED(WARNING);
- return -1;
-#endif
-}
-
-void NanoSleep(uint64_t ns) {
- timespec tm;
- tm.tv_sec = ns / MsToNs(1000);
- tm.tv_nsec = ns - static_cast<uint64_t>(tm.tv_sec) * MsToNs(1000);
- nanosleep(&tm, nullptr);
-}
-
-void InitTimeSpec(bool absolute, int clock, int64_t ms, int32_t ns, timespec* ts) {
- int64_t endSec;
-
- if (absolute) {
-#if !defined(__APPLE__)
- clock_gettime(clock, ts);
-#else
- UNUSED(clock);
- timeval tv;
- gettimeofday(&tv, nullptr);
- ts->tv_sec = tv.tv_sec;
- ts->tv_nsec = tv.tv_usec * 1000;
-#endif
- } else {
- ts->tv_sec = 0;
- ts->tv_nsec = 0;
- }
- endSec = ts->tv_sec + ms / 1000;
- if (UNLIKELY(endSec >= 0x7fffffff)) {
- std::ostringstream ss;
- LOG(INFO) << "Note: end time exceeds epoch: " << ss.str();
- endSec = 0x7ffffffe;
- }
- ts->tv_sec = endSec;
- ts->tv_nsec = (ts->tv_nsec + (ms % 1000) * 1000000) + ns;
-
- // Catch rollover.
- if (ts->tv_nsec >= 1000000000L) {
- ts->tv_sec++;
- ts->tv_nsec -= 1000000000L;
- }
-}
-
std::string PrettyDescriptor(mirror::String* java_descriptor) {
if (java_descriptor == nullptr) {
return "null";
@@ -578,88 +481,6 @@ std::string PrettySize(int64_t byte_count) {
negative_str, byte_count / kBytesPerUnit[i], kUnitStrings[i]);
}
-std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits) {
- if (nano_duration == 0) {
- return "0";
- } else {
- return FormatDuration(nano_duration, GetAppropriateTimeUnit(nano_duration),
- max_fraction_digits);
- }
-}
-
-TimeUnit GetAppropriateTimeUnit(uint64_t nano_duration) {
- const uint64_t one_sec = 1000 * 1000 * 1000;
- const uint64_t one_ms = 1000 * 1000;
- const uint64_t one_us = 1000;
- if (nano_duration >= one_sec) {
- return kTimeUnitSecond;
- } else if (nano_duration >= one_ms) {
- return kTimeUnitMillisecond;
- } else if (nano_duration >= one_us) {
- return kTimeUnitMicrosecond;
- } else {
- return kTimeUnitNanosecond;
- }
-}
-
-uint64_t GetNsToTimeUnitDivisor(TimeUnit time_unit) {
- const uint64_t one_sec = 1000 * 1000 * 1000;
- const uint64_t one_ms = 1000 * 1000;
- const uint64_t one_us = 1000;
-
- switch (time_unit) {
- case kTimeUnitSecond:
- return one_sec;
- case kTimeUnitMillisecond:
- return one_ms;
- case kTimeUnitMicrosecond:
- return one_us;
- case kTimeUnitNanosecond:
- return 1;
- }
- return 0;
-}
-
-std::string FormatDuration(uint64_t nano_duration, TimeUnit time_unit,
- size_t max_fraction_digits) {
- const char* unit = nullptr;
- uint64_t divisor = GetNsToTimeUnitDivisor(time_unit);
- switch (time_unit) {
- case kTimeUnitSecond:
- unit = "s";
- break;
- case kTimeUnitMillisecond:
- unit = "ms";
- break;
- case kTimeUnitMicrosecond:
- unit = "us";
- break;
- case kTimeUnitNanosecond:
- unit = "ns";
- break;
- }
- const uint64_t whole_part = nano_duration / divisor;
- uint64_t fractional_part = nano_duration % divisor;
- if (fractional_part == 0) {
- return StringPrintf("%" PRIu64 "%s", whole_part, unit);
- } else {
- static constexpr size_t kMaxDigits = 30;
- size_t avail_digits = kMaxDigits;
- char fraction_buffer[kMaxDigits];
- char* ptr = fraction_buffer;
- uint64_t multiplier = 10;
- // This infinite loops if fractional part is 0.
- while (avail_digits > 1 && fractional_part * multiplier < divisor) {
- multiplier *= 10;
- *ptr++ = '0';
- avail_digits--;
- }
- snprintf(ptr, avail_digits, "%" PRIu64, fractional_part);
- fraction_buffer[std::min(kMaxDigits - 1, max_fraction_digits)] = '\0';
- return StringPrintf("%" PRIu64 ".%s%s", whole_part, fraction_buffer, unit);
- }
-}
-
std::string PrintableChar(uint16_t ch) {
std::string result;
result += '\'';
diff --git a/runtime/utils.h b/runtime/utils.h
index 71ccf85277..e7532e1c84 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -43,13 +43,6 @@ class Object;
class String;
} // namespace mirror
-enum TimeUnit {
- kTimeUnitNanosecond,
- kTimeUnitMicrosecond,
- kTimeUnitMillisecond,
- kTimeUnitSecond,
-};
-
template <typename T>
bool ParseUint(const char *in, T* out) {
char* end;
@@ -78,228 +71,6 @@ bool ParseInt(const char* in, T* out) {
return true;
}
-template<typename T>
-static constexpr bool IsPowerOfTwo(T x) {
- return (x & (x - 1)) == 0;
-}
-
-template<int n, typename T>
-static inline bool IsAligned(T x) {
- static_assert((n & (n - 1)) == 0, "n is not a power of two");
- return (x & (n - 1)) == 0;
-}
-
-template<int n, typename T>
-static inline bool IsAligned(T* x) {
- return IsAligned<n>(reinterpret_cast<const uintptr_t>(x));
-}
-
-template<typename T>
-static inline bool IsAlignedParam(T x, int n) {
- return (x & (n - 1)) == 0;
-}
-
-#define CHECK_ALIGNED(value, alignment) \
- CHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value)
-
-#define DCHECK_ALIGNED(value, alignment) \
- DCHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value)
-
-#define DCHECK_ALIGNED_PARAM(value, alignment) \
- DCHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value)
-
-// Check whether an N-bit two's-complement representation can hold value.
-template <typename T>
-static inline bool IsInt(int N, T value) {
- int bitsPerT = sizeof(T) * kBitsPerByte;
- if (N == bitsPerT) {
- return true;
- } else {
- CHECK_LT(0, N);
- CHECK_LT(N, bitsPerT);
- T limit = static_cast<T>(1) << (N - 1);
- return (-limit <= value) && (value < limit);
- }
-}
-
-template <typename T>
-static constexpr T GetIntLimit(size_t bits) {
- return
- DCHECK_CONSTEXPR(bits > 0, "bits cannot be zero", 0)
- DCHECK_CONSTEXPR(bits < kBitsPerByte * sizeof(T), "kBits must be < max.", 0)
- static_cast<T>(1) << (bits - 1);
-}
-
-template <size_t kBits, typename T>
-static constexpr bool IsInt(T value) {
- static_assert(kBits > 0, "kBits cannot be zero.");
- static_assert(kBits <= kBitsPerByte * sizeof(T), "kBits must be <= max.");
- static_assert(std::is_signed<T>::value, "Needs a signed type.");
- // Corner case for "use all bits." Can't use the limits, as they would overflow, but it is
- // trivially true.
- return (kBits == kBitsPerByte * sizeof(T)) ?
- true :
- (-GetIntLimit<T>(kBits) <= value) && (value < GetIntLimit<T>(kBits));
-}
-
-template <size_t kBits, typename T>
-static constexpr bool IsUint(T value) {
- static_assert(kBits > 0, "kBits cannot be zero.");
- static_assert(kBits <= kBitsPerByte * sizeof(T), "kBits must be <= max.");
- static_assert(std::is_integral<T>::value, "Needs an integral type.");
- // Corner case for "use all bits." Can't use the limits, as they would overflow, but it is
- // trivially true.
- return (0 <= value) &&
- (kBits == kBitsPerByte * sizeof(T) ||
- (static_cast<typename std::make_unsigned<T>::type>(value) <=
- GetIntLimit<typename std::make_unsigned<T>::type>(kBits + 1) - 1));
-}
-
-template <size_t kBits, typename T>
-static constexpr bool IsAbsoluteUint(T value) {
- static_assert(kBits <= kBitsPerByte * sizeof(T), "kBits must be < max.");
- return (kBits == kBitsPerByte * sizeof(T)) ?
- true :
- IsUint<kBits, T>(value < 0 ? -value : value);
-}
-
-static inline uint16_t Low16Bits(uint32_t value) {
- return static_cast<uint16_t>(value);
-}
-
-static inline uint16_t High16Bits(uint32_t value) {
- return static_cast<uint16_t>(value >> 16);
-}
-
-static inline uint32_t Low32Bits(uint64_t value) {
- return static_cast<uint32_t>(value);
-}
-
-static inline uint32_t High32Bits(uint64_t value) {
- return static_cast<uint32_t>(value >> 32);
-}
-
-// Traits class providing an unsigned integer type of (byte) size `n`.
-template <size_t n>
-struct UnsignedIntegerType {
- // No defined `type`.
-};
-
-template <>
-struct UnsignedIntegerType<1> { typedef uint8_t type; };
-
-template <>
-struct UnsignedIntegerType<2> { typedef uint16_t type; };
-
-template <>
-struct UnsignedIntegerType<4> { typedef uint32_t type; };
-
-template <>
-struct UnsignedIntegerType<8> { typedef uint64_t type; };
-
-// Type identity.
-template <typename T>
-struct TypeIdentity {
- typedef T type;
-};
-
-// Like sizeof, but count how many bits a type takes. Pass type explicitly.
-template <typename T>
-static constexpr size_t BitSizeOf() {
- return sizeof(T) * CHAR_BIT;
-}
-
-// Like sizeof, but count how many bits a type takes. Infers type from parameter.
-template <typename T>
-static constexpr size_t BitSizeOf(T /*x*/) {
- return sizeof(T) * CHAR_BIT;
-}
-
-// For rounding integers.
-template<typename T>
-static constexpr T RoundDown(T x, typename TypeIdentity<T>::type n) WARN_UNUSED;
-
-template<typename T>
-static constexpr T RoundDown(T x, typename TypeIdentity<T>::type n) {
- return
- DCHECK_CONSTEXPR(IsPowerOfTwo(n), , T(0))
- (x & -n);
-}
-
-template<typename T>
-static constexpr T RoundUp(T x, typename TypeIdentity<T>::type n) WARN_UNUSED;
-
-template<typename T>
-static constexpr T RoundUp(T x, typename TypeIdentity<T>::type n) {
- return RoundDown(x + n - 1, n);
-}
-
-// For aligning pointers.
-template<typename T>
-static inline T* AlignDown(T* x, uintptr_t n) WARN_UNUSED;
-
-template<typename T>
-static inline T* AlignDown(T* x, uintptr_t n) {
- return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uintptr_t>(x), n));
-}
-
-template<typename T>
-static inline T* AlignUp(T* x, uintptr_t n) WARN_UNUSED;
-
-template<typename T>
-static inline T* AlignUp(T* x, uintptr_t n) {
- return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uintptr_t>(x), n));
-}
-
-namespace utils {
-namespace detail { // Private, implementation-specific namespace. Do not poke outside of this file.
-template <typename T>
-static constexpr inline T RoundUpToPowerOfTwoRecursive(T x, size_t bit) {
- return bit == (BitSizeOf<T>()) ? x: RoundUpToPowerOfTwoRecursive(x | x >> bit, bit << 1);
-}
-} // namespace detail
-} // namespace utils
-
-// Recursive implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
-// figure 3-3, page 48, where the function is called clp2.
-template <typename T>
-static constexpr inline T RoundUpToPowerOfTwo(T x) {
- return art::utils::detail::RoundUpToPowerOfTwoRecursive(x - 1, 1) + 1;
-}
-
-// Find the bit position of the most significant bit (0-based), or -1 if there were no bits set.
-template <typename T>
-static constexpr ssize_t MostSignificantBit(T value) {
- return (value == 0) ? -1 : (MostSignificantBit(value >> 1) + 1);
-}
-
-// How many bits (minimally) does it take to store the constant 'value'? i.e. 1 for 1, 3 for 5, etc.
-template <typename T>
-static constexpr size_t MinimumBitsToStore(T value) {
- return static_cast<size_t>(MostSignificantBit(value) + 1);
-}
-
-template<typename T>
-static constexpr int CLZ(T x) {
- static_assert(sizeof(T) <= sizeof(long long), "T too large, must be smaller than long long"); // NOLINT [runtime/int] [4]
- return (sizeof(T) == sizeof(uint32_t))
- ? __builtin_clz(x) // TODO: __builtin_clz[ll] has undefined behavior for x=0
- : __builtin_clzll(x);
-}
-
-template<typename T>
-static constexpr int CTZ(T x) {
- return (sizeof(T) == sizeof(uint32_t))
- ? __builtin_ctz(x)
- : __builtin_ctzll(x);
-}
-
-template<typename T>
-static inline int WhichPowerOf2(T x) {
- DCHECK((x != 0) && IsPowerOfTwo(x));
- return CTZ(x);
-}
-
// Return whether x / divisor == x * (1.0f / divisor), for every float x.
static constexpr bool CanDivideByReciprocalMultiplyFloat(int32_t divisor) {
// True, if the most significant bits of divisor are 0.
@@ -312,13 +83,6 @@ static constexpr bool CanDivideByReciprocalMultiplyDouble(int64_t divisor) {
return ((divisor & ((UINT64_C(1) << 52) - 1)) == 0);
}
-template<typename T>
-static constexpr int POPCOUNT(T x) {
- return (sizeof(T) == sizeof(uint32_t))
- ? __builtin_popcount(x)
- : __builtin_popcountll(x);
-}
-
static inline uint32_t PointerToLowMemUInt32(const void* p) {
uintptr_t intp = reinterpret_cast<uintptr_t>(p);
DCHECK_LE(intp, 0xFFFFFFFFU);
@@ -392,21 +156,6 @@ std::string PrettyJavaAccessFlags(uint32_t access_flags);
// Returns a human-readable size string such as "1MB".
std::string PrettySize(int64_t size_in_bytes);
-// Returns a human-readable time string which prints every nanosecond while trying to limit the
-// number of trailing zeros. Prints using the largest human readable unit up to a second.
-// e.g. "1ms", "1.000000001s", "1.001us"
-std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits = 3);
-
-// Format a nanosecond time to specified units.
-std::string FormatDuration(uint64_t nano_duration, TimeUnit time_unit,
- size_t max_fraction_digits);
-
-// Get the appropriate unit for a nanosecond duration.
-TimeUnit GetAppropriateTimeUnit(uint64_t nano_duration);
-
-// Get the divisor to convert from a nanoseconds to a time unit.
-uint64_t GetNsToTimeUnitDivisor(TimeUnit time_unit);
-
// Performs JNI name mangling as described in section 11.3 "Linking Native Methods"
// of the JNI spec.
std::string MangleForJni(const std::string& s);
@@ -441,43 +190,6 @@ std::string JniLongName(mirror::ArtMethod* m)
bool ReadFileToString(const std::string& file_name, std::string* result);
bool PrintFileToLog(const std::string& file_name, LogSeverity level);
-// Returns the current date in ISO yyyy-mm-dd hh:mm:ss format.
-std::string GetIsoDate();
-
-// Returns the monotonic time since some unspecified starting point in milliseconds.
-uint64_t MilliTime();
-
-// Returns the monotonic time since some unspecified starting point in microseconds.
-uint64_t MicroTime();
-
-// Returns the monotonic time since some unspecified starting point in nanoseconds.
-uint64_t NanoTime();
-
-// Returns the thread-specific CPU-time clock in nanoseconds or -1 if unavailable.
-uint64_t ThreadCpuNanoTime();
-
-// Converts the given number of nanoseconds to milliseconds.
-static constexpr inline uint64_t NsToMs(uint64_t ns) {
- return ns / 1000 / 1000;
-}
-
-// Converts the given number of milliseconds to nanoseconds
-static constexpr inline uint64_t MsToNs(uint64_t ns) {
- return ns * 1000 * 1000;
-}
-
-#if defined(__APPLE__)
-// No clocks to specify on OS/X, fake value to pass to routines that require a clock.
-#define CLOCK_REALTIME 0xebadf00d
-#endif
-
-// Sleep for the given number of nanoseconds, a bad way to handle contention.
-void NanoSleep(uint64_t ns);
-
-// Initialize a timespec to either a relative time (ms,ns), or to the absolute
-// time corresponding to the indicated clock value plus the supplied offset.
-void InitTimeSpec(bool absolute, int clock, int64_t ms, int32_t ns, timespec* ts);
-
// Splits a string using the given separator character into a vector of
// strings. Empty strings will be omitted.
void Split(const std::string& s, char separator, std::vector<std::string>* result);
diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc
index 869d305120..8a7f8052ce 100644
--- a/runtime/utils_test.cc
+++ b/runtime/utils_test.cc
@@ -172,35 +172,6 @@ TEST_F(UtilsTest, PrettySize) {
EXPECT_EQ("512B", PrettySize(512));
}
-TEST_F(UtilsTest, PrettyDuration) {
- const uint64_t one_sec = 1000000000;
- const uint64_t one_ms = 1000000;
- const uint64_t one_us = 1000;
-
- EXPECT_EQ("1s", PrettyDuration(1 * one_sec));
- EXPECT_EQ("10s", PrettyDuration(10 * one_sec));
- EXPECT_EQ("100s", PrettyDuration(100 * one_sec));
- EXPECT_EQ("1.001s", PrettyDuration(1 * one_sec + one_ms));
- EXPECT_EQ("1.000001s", PrettyDuration(1 * one_sec + one_us, 6));
- EXPECT_EQ("1.000000001s", PrettyDuration(1 * one_sec + 1, 9));
- EXPECT_EQ("1.000s", PrettyDuration(1 * one_sec + one_us, 3));
-
- EXPECT_EQ("1ms", PrettyDuration(1 * one_ms));
- EXPECT_EQ("10ms", PrettyDuration(10 * one_ms));
- EXPECT_EQ("100ms", PrettyDuration(100 * one_ms));
- EXPECT_EQ("1.001ms", PrettyDuration(1 * one_ms + one_us));
- EXPECT_EQ("1.000001ms", PrettyDuration(1 * one_ms + 1, 6));
-
- EXPECT_EQ("1us", PrettyDuration(1 * one_us));
- EXPECT_EQ("10us", PrettyDuration(10 * one_us));
- EXPECT_EQ("100us", PrettyDuration(100 * one_us));
- EXPECT_EQ("1.001us", PrettyDuration(1 * one_us + 1));
-
- EXPECT_EQ("1ns", PrettyDuration(1));
- EXPECT_EQ("10ns", PrettyDuration(10));
- EXPECT_EQ("100ns", PrettyDuration(100));
-}
-
TEST_F(UtilsTest, MangleForJni) {
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("hello_00024world", MangleForJni("hello$world"));
@@ -408,119 +379,6 @@ TEST_F(UtilsTest, ExecError) {
}
}
-TEST_F(UtilsTest, RoundUpToPowerOfTwo) {
- // Tests the constexpr variant since all the parameters are constexpr
- EXPECT_EQ(0, RoundUpToPowerOfTwo(0));
- EXPECT_EQ(1, RoundUpToPowerOfTwo(1));
- EXPECT_EQ(2, RoundUpToPowerOfTwo(2));
- EXPECT_EQ(4, RoundUpToPowerOfTwo(3));
- EXPECT_EQ(8, RoundUpToPowerOfTwo(7));
-
- EXPECT_EQ(0b10000L, RoundUpToPowerOfTwo(0b01101L));
- EXPECT_EQ(1ULL << 63, RoundUpToPowerOfTwo(1ULL << 62 | 1ULL));
-}
-
-TEST_F(UtilsTest, MostSignificantBit) {
- EXPECT_EQ(-1, MostSignificantBit(0));
- EXPECT_EQ(0, MostSignificantBit(1));
- EXPECT_EQ(31, MostSignificantBit(~static_cast<uint32_t>(0)));
- EXPECT_EQ(2, MostSignificantBit(0b110));
- EXPECT_EQ(2, MostSignificantBit(0b100));
-}
-
-TEST_F(UtilsTest, MinimumBitsToStore) {
- EXPECT_EQ(0u, MinimumBitsToStore(0));
- EXPECT_EQ(1u, MinimumBitsToStore(1));
- EXPECT_EQ(2u, MinimumBitsToStore(0b10));
- EXPECT_EQ(2u, MinimumBitsToStore(0b11));
- EXPECT_EQ(3u, MinimumBitsToStore(0b100));
- EXPECT_EQ(3u, MinimumBitsToStore(0b110));
- EXPECT_EQ(3u, MinimumBitsToStore(0b101));
- EXPECT_EQ(8u, MinimumBitsToStore(0xFF));
- EXPECT_EQ(32u, MinimumBitsToStore(~static_cast<uint32_t>(0)));
-}
-
-static constexpr int64_t INT_MIN_minus1 = static_cast<int64_t>(INT_MIN) - 1;
-static constexpr int64_t INT_MAX_plus1 = static_cast<int64_t>(INT_MAX) + 1;
-static constexpr int64_t UINT_MAX_plus1 = static_cast<int64_t>(UINT_MAX) + 1;
-
-TEST_F(UtilsTest, IsInt) {
- EXPECT_FALSE(IsInt(1, -2));
- EXPECT_TRUE(IsInt(1, -1));
- EXPECT_TRUE(IsInt(1, 0));
- EXPECT_FALSE(IsInt(1, 1));
-
- EXPECT_FALSE(IsInt(4, -9));
- EXPECT_TRUE(IsInt(4, -8));
- EXPECT_TRUE(IsInt(4, 7));
- EXPECT_FALSE(IsInt(4, 8));
-
- EXPECT_FALSE(IsInt(32, INT_MIN_minus1));
- EXPECT_TRUE(IsInt(32, INT_MIN));
- EXPECT_TRUE(IsInt(32, INT_MAX));
- EXPECT_FALSE(IsInt(32, INT_MAX_plus1));
-}
-
-TEST_F(UtilsTest, IsInt_Static) {
- EXPECT_FALSE(IsInt<1>(-2));
- EXPECT_TRUE(IsInt<1>(-1));
- EXPECT_TRUE(IsInt<1>(0));
- EXPECT_FALSE(IsInt<1>(1));
-
- EXPECT_FALSE(IsInt<4>(-9));
- EXPECT_TRUE(IsInt<4>(-8));
- EXPECT_TRUE(IsInt<4>(7));
- EXPECT_FALSE(IsInt<4>(8));
-
- EXPECT_FALSE(IsInt<32>(INT_MIN_minus1));
- EXPECT_TRUE(IsInt<32>(INT_MIN));
- EXPECT_TRUE(IsInt<32>(INT_MAX));
- EXPECT_FALSE(IsInt<32>(INT_MAX_plus1));
-}
-
-TEST_F(UtilsTest, IsUint) {
- EXPECT_FALSE(IsUint<1>(-1));
- EXPECT_TRUE(IsUint<1>(0));
- EXPECT_TRUE(IsUint<1>(1));
- EXPECT_FALSE(IsUint<1>(2));
-
- EXPECT_FALSE(IsUint<4>(-1));
- EXPECT_TRUE(IsUint<4>(0));
- EXPECT_TRUE(IsUint<4>(15));
- EXPECT_FALSE(IsUint<4>(16));
-
- EXPECT_FALSE(IsUint<32>(-1));
- EXPECT_TRUE(IsUint<32>(0));
- EXPECT_TRUE(IsUint<32>(UINT_MAX));
- EXPECT_FALSE(IsUint<32>(UINT_MAX_plus1));
-}
-
-TEST_F(UtilsTest, IsAbsoluteUint) {
- EXPECT_FALSE(IsAbsoluteUint<1>(-2));
- EXPECT_TRUE(IsAbsoluteUint<1>(-1));
- EXPECT_TRUE(IsAbsoluteUint<32>(0));
- EXPECT_TRUE(IsAbsoluteUint<1>(1));
- EXPECT_FALSE(IsAbsoluteUint<1>(2));
-
- EXPECT_FALSE(IsAbsoluteUint<4>(-16));
- EXPECT_TRUE(IsAbsoluteUint<4>(-15));
- EXPECT_TRUE(IsAbsoluteUint<32>(0));
- EXPECT_TRUE(IsAbsoluteUint<4>(15));
- EXPECT_FALSE(IsAbsoluteUint<4>(16));
-
- EXPECT_FALSE(IsAbsoluteUint<32>(-UINT_MAX_plus1));
- EXPECT_TRUE(IsAbsoluteUint<32>(-UINT_MAX));
- EXPECT_TRUE(IsAbsoluteUint<32>(0));
- EXPECT_TRUE(IsAbsoluteUint<32>(UINT_MAX));
- EXPECT_FALSE(IsAbsoluteUint<32>(UINT_MAX_plus1));
-}
-
-TEST_F(UtilsTest, TestSleep) {
- auto start = NanoTime();
- NanoSleep(MsToNs(1500));
- EXPECT_GT(NanoTime() - start, MsToNs(1000));
-}
-
TEST_F(UtilsTest, IsValidDescriptor) {
std::vector<uint8_t> descriptor(
{ 'L', 'a', '/', 'b', '$', 0xed, 0xa0, 0x80, 0xed, 0xb0, 0x80, ';', 0x00 });
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 6c58d55f99..b08883ef01 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -21,6 +21,7 @@
#include "art_field-inl.h"
#include "base/logging.h"
#include "base/mutex-inl.h"
+#include "base/time_utils.h"
#include "class_linker.h"
#include "compiler_callbacks.h"
#include "dex_file-inl.h"
@@ -41,6 +42,7 @@
#include "register_line-inl.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
+#include "utils.h"
#include "handle_scope-inl.h"
#include "verifier/dex_gc_map.h"
diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc
index 1ec0cf2d43..71a2b2dddc 100644
--- a/test/004-JniTest/jni_test.cc
+++ b/test/004-JniTest/jni_test.cc
@@ -604,4 +604,20 @@ extern "C" JNIEXPORT void JNICALL Java_Main_testNewStringObject(JNIEnv* env, jcl
args4[0].l = string_arg;
env->CallVoidMethodA(s3, mid3, args3);
env->CallNonvirtualVoidMethodA(s4, c, mid4, args4);
+
+ // Test with global and weak global references
+ jstring s5 = reinterpret_cast<jstring>(env->AllocObject(c));
+ assert(s5 != nullptr);
+ s5 = reinterpret_cast<jstring>(env->NewGlobalRef(s5));
+ jstring s6 = reinterpret_cast<jstring>(env->AllocObject(c));
+ assert(s6 != nullptr);
+ s6 = reinterpret_cast<jstring>(env->NewWeakGlobalRef(s6));
+
+ env->CallVoidMethod(s5, mid1);
+ env->CallNonvirtualVoidMethod(s6, c, mid2, byte_array);
+ assert(env->GetStringLength(s5) == 0);
+ assert(env->GetStringLength(s6) == byte_array_length);
+ const char* chars6 = env->GetStringUTFChars(s6, nullptr);
+ assert(strcmp(test_array, chars6) == 0);
+ env->ReleaseStringUTFChars(s6, chars6);
}
diff --git a/test/441-checker-inliner/src/Main.java b/test/441-checker-inliner/src/Main.java
index 8894d4e5ce..df969a488e 100644
--- a/test/441-checker-inliner/src/Main.java
+++ b/test/441-checker-inliner/src/Main.java
@@ -16,133 +16,133 @@
public class Main {
- // CHECK-START: void Main.InlineVoid() inliner (before)
- // CHECK-DAG: <<Const42:i\d+>> IntConstant 42
- // CHECK-DAG: InvokeStaticOrDirect
- // CHECK-DAG: InvokeStaticOrDirect [<<Const42>>]
+ /// CHECK-START: void Main.InlineVoid() inliner (before)
+ /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
+ /// CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-DAG: InvokeStaticOrDirect [<<Const42>>]
- // CHECK-START: void Main.InlineVoid() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.InlineVoid() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static void InlineVoid() {
returnVoid();
returnVoidWithOneParameter(42);
}
- // CHECK-START: int Main.InlineParameter(int) inliner (before)
- // CHECK-DAG: <<Param:i\d+>> ParameterValue
- // CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Param>>]
- // CHECK-DAG: Return [<<Result>>]
+ /// CHECK-START: int Main.InlineParameter(int) inliner (before)
+ /// CHECK-DAG: <<Param:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Param>>]
+ /// CHECK-DAG: Return [<<Result>>]
- // CHECK-START: int Main.InlineParameter(int) inliner (after)
- // CHECK-DAG: <<Param:i\d+>> ParameterValue
- // CHECK-DAG: Return [<<Param>>]
+ /// CHECK-START: int Main.InlineParameter(int) inliner (after)
+ /// CHECK-DAG: <<Param:i\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Param>>]
public static int InlineParameter(int a) {
return returnParameter(a);
}
- // CHECK-START: long Main.InlineWideParameter(long) inliner (before)
- // CHECK-DAG: <<Param:j\d+>> ParameterValue
- // CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<Param>>]
- // CHECK-DAG: Return [<<Result>>]
+ /// CHECK-START: long Main.InlineWideParameter(long) inliner (before)
+ /// CHECK-DAG: <<Param:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<Param>>]
+ /// CHECK-DAG: Return [<<Result>>]
- // CHECK-START: long Main.InlineWideParameter(long) inliner (after)
- // CHECK-DAG: <<Param:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Param>>]
+ /// CHECK-START: long Main.InlineWideParameter(long) inliner (after)
+ /// CHECK-DAG: <<Param:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Param>>]
public static long InlineWideParameter(long a) {
return returnWideParameter(a);
}
- // CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (before)
- // CHECK-DAG: <<Param:l\d+>> ParameterValue
- // CHECK-DAG: <<Result:l\d+>> InvokeStaticOrDirect [<<Param>>]
- // CHECK-DAG: Return [<<Result>>]
+ /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (before)
+ /// CHECK-DAG: <<Param:l\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:l\d+>> InvokeStaticOrDirect [<<Param>>]
+ /// CHECK-DAG: Return [<<Result>>]
- // CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (after)
- // CHECK-DAG: <<Param:l\d+>> ParameterValue
- // CHECK-DAG: Return [<<Param>>]
+ /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (after)
+ /// CHECK-DAG: <<Param:l\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Param>>]
public static Object InlineReferenceParameter(Object o) {
return returnReferenceParameter(o);
}
- // CHECK-START: int Main.InlineInt() inliner (before)
- // CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Result>>]
+ /// CHECK-START: int Main.InlineInt() inliner (before)
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Result>>]
- // CHECK-START: int Main.InlineInt() inliner (after)
- // CHECK-DAG: <<Const4:i\d+>> IntConstant 4
- // CHECK-DAG: Return [<<Const4>>]
+ /// CHECK-START: int Main.InlineInt() inliner (after)
+ /// CHECK-DAG: <<Const4:i\d+>> IntConstant 4
+ /// CHECK-DAG: Return [<<Const4>>]
public static int InlineInt() {
return returnInt();
}
- // CHECK-START: long Main.InlineWide() inliner (before)
- // CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Result>>]
+ /// CHECK-START: long Main.InlineWide() inliner (before)
+ /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Result>>]
- // CHECK-START: long Main.InlineWide() inliner (after)
- // CHECK-DAG: <<Const8:j\d+>> LongConstant 8
- // CHECK-DAG: Return [<<Const8>>]
+ /// CHECK-START: long Main.InlineWide() inliner (after)
+ /// CHECK-DAG: <<Const8:j\d+>> LongConstant 8
+ /// CHECK-DAG: Return [<<Const8>>]
public static long InlineWide() {
return returnWide();
}
- // CHECK-START: int Main.InlineAdd() inliner (before)
- // CHECK-DAG: <<Const3:i\d+>> IntConstant 3
- // CHECK-DAG: <<Const5:i\d+>> IntConstant 5
- // CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Result>>]
+ /// CHECK-START: int Main.InlineAdd() inliner (before)
+ /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
+ /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
+ /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Result>>]
- // CHECK-START: int Main.InlineAdd() inliner (after)
- // CHECK-DAG: <<Const3:i\d+>> IntConstant 3
- // CHECK-DAG: <<Const5:i\d+>> IntConstant 5
- // CHECK-DAG: <<Add:i\d+>> Add [<<Const3>>,<<Const5>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: int Main.InlineAdd() inliner (after)
+ /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
+ /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Const3>>,<<Const5>>]
+ /// CHECK-DAG: Return [<<Add>>]
public static int InlineAdd() {
return returnAdd(3, 5);
}
- // CHECK-START: int Main.InlineFieldAccess() inliner (before)
- // CHECK-DAG: <<After:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<After>>]
+ /// CHECK-START: int Main.InlineFieldAccess() inliner (before)
+ /// CHECK-DAG: <<After:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<After>>]
- // CHECK-START: int Main.InlineFieldAccess() inliner (after)
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Before:i\d+>> StaticFieldGet
- // CHECK-DAG: <<After:i\d+>> Add [<<Before>>,<<Const1>>]
- // CHECK-DAG: StaticFieldSet [{{l\d+}},<<After>>]
- // CHECK-DAG: Return [<<After>>]
+ /// CHECK-START: int Main.InlineFieldAccess() inliner (after)
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Before:i\d+>> StaticFieldGet
+ /// CHECK-DAG: <<After:i\d+>> Add [<<Before>>,<<Const1>>]
+ /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<After>>]
+ /// CHECK-DAG: Return [<<After>>]
- // CHECK-START: int Main.InlineFieldAccess() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.InlineFieldAccess() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static int InlineFieldAccess() {
return incCounter();
}
- // CHECK-START: int Main.InlineWithControlFlow(boolean) inliner (before)
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Const3:i\d+>> IntConstant 3
- // CHECK-DAG: <<Const5:i\d+>> IntConstant 5
- // CHECK-DAG: <<Add:i\d+>> InvokeStaticOrDirect [<<Const1>>,<<Const3>>]
- // CHECK-DAG: <<Sub:i\d+>> InvokeStaticOrDirect [<<Const5>>,<<Const3>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
- // CHECK-DAG: Return [<<Phi>>]
-
- // CHECK-START: int Main.InlineWithControlFlow(boolean) inliner (after)
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Const3:i\d+>> IntConstant 3
- // CHECK-DAG: <<Const5:i\d+>> IntConstant 5
- // CHECK-DAG: <<Add:i\d+>> Add [<<Const1>>,<<Const3>>]
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Const5>>,<<Const3>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
- // CHECK-DAG: Return [<<Phi>>]
+ /// CHECK-START: int Main.InlineWithControlFlow(boolean) inliner (before)
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
+ /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
+ /// CHECK-DAG: <<Add:i\d+>> InvokeStaticOrDirect [<<Const1>>,<<Const3>>]
+ /// CHECK-DAG: <<Sub:i\d+>> InvokeStaticOrDirect [<<Const5>>,<<Const3>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ /// CHECK-START: int Main.InlineWithControlFlow(boolean) inliner (after)
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
+ /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Const1>>,<<Const3>>]
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const5>>,<<Const3>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
+ /// CHECK-DAG: Return [<<Phi>>]
public static int InlineWithControlFlow(boolean cond) {
int x, const1, const3, const5;
diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java
index c258db9c45..b7863be6ce 100644
--- a/test/442-checker-constant-folding/src/Main.java
+++ b/test/442-checker-constant-folding/src/Main.java
@@ -51,14 +51,14 @@ public class Main {
* on negation.
*/
- // CHECK-START: int Main.IntNegation() constant_folding (before)
- // CHECK-DAG: <<Const42:i\d+>> IntConstant 42
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Const42>>]
- // CHECK-DAG: Return [<<Neg>>]
+ /// CHECK-START: int Main.IntNegation() constant_folding (before)
+ /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Const42>>]
+ /// CHECK-DAG: Return [<<Neg>>]
- // CHECK-START: int Main.IntNegation() constant_folding (after)
- // CHECK-DAG: <<ConstN42:i\d+>> IntConstant -42
- // CHECK-DAG: Return [<<ConstN42>>]
+ /// CHECK-START: int Main.IntNegation() constant_folding (after)
+ /// CHECK-DAG: <<ConstN42:i\d+>> IntConstant -42
+ /// CHECK-DAG: Return [<<ConstN42>>]
public static int IntNegation() {
int x, y;
@@ -72,15 +72,15 @@ public class Main {
* on addition.
*/
- // CHECK-START: int Main.IntAddition1() constant_folding (before)
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Const2:i\d+>> IntConstant 2
- // CHECK-DAG: <<Add:i\d+>> Add [<<Const1>>,<<Const2>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: int Main.IntAddition1() constant_folding (before)
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Const1>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Add>>]
- // CHECK-START: int Main.IntAddition1() constant_folding (after)
- // CHECK-DAG: <<Const3:i\d+>> IntConstant 3
- // CHECK-DAG: Return [<<Const3>>]
+ /// CHECK-START: int Main.IntAddition1() constant_folding (after)
+ /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
+ /// CHECK-DAG: Return [<<Const3>>]
public static int IntAddition1() {
int a, b, c;
@@ -95,19 +95,19 @@ public class Main {
* on addition.
*/
- // CHECK-START: int Main.IntAddition2() constant_folding (before)
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Const2:i\d+>> IntConstant 2
- // CHECK-DAG: <<Const5:i\d+>> IntConstant 5
- // CHECK-DAG: <<Const6:i\d+>> IntConstant 6
- // CHECK-DAG: <<Add1:i\d+>> Add [<<Const1>>,<<Const2>>]
- // CHECK-DAG: <<Add2:i\d+>> Add [<<Const5>>,<<Const6>>]
- // CHECK-DAG: <<Add3:i\d+>> Add [<<Add1>>,<<Add2>>]
- // CHECK-DAG: Return [<<Add3>>]
+ /// CHECK-START: int Main.IntAddition2() constant_folding (before)
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
+ /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
+ /// CHECK-DAG: <<Const6:i\d+>> IntConstant 6
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Const1>>,<<Const2>>]
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Const5>>,<<Const6>>]
+ /// CHECK-DAG: <<Add3:i\d+>> Add [<<Add1>>,<<Add2>>]
+ /// CHECK-DAG: Return [<<Add3>>]
- // CHECK-START: int Main.IntAddition2() constant_folding (after)
- // CHECK-DAG: <<Const14:i\d+>> IntConstant 14
- // CHECK-DAG: Return [<<Const14>>]
+ /// CHECK-START: int Main.IntAddition2() constant_folding (after)
+ /// CHECK-DAG: <<Const14:i\d+>> IntConstant 14
+ /// CHECK-DAG: Return [<<Const14>>]
public static int IntAddition2() {
int a, b, c;
@@ -126,15 +126,15 @@ public class Main {
* on subtraction.
*/
- // CHECK-START: int Main.IntSubtraction() constant_folding (before)
- // CHECK-DAG: <<Const6:i\d+>> IntConstant 6
- // CHECK-DAG: <<Const2:i\d+>> IntConstant 2
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Const6>>,<<Const2>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: int Main.IntSubtraction() constant_folding (before)
+ /// CHECK-DAG: <<Const6:i\d+>> IntConstant 6
+ /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const6>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: int Main.IntSubtraction() constant_folding (after)
- // CHECK-DAG: <<Const4:i\d+>> IntConstant 4
- // CHECK-DAG: Return [<<Const4>>]
+ /// CHECK-START: int Main.IntSubtraction() constant_folding (after)
+ /// CHECK-DAG: <<Const4:i\d+>> IntConstant 4
+ /// CHECK-DAG: Return [<<Const4>>]
public static int IntSubtraction() {
int a, b, c;
@@ -149,15 +149,15 @@ public class Main {
* on addition.
*/
- // CHECK-START: long Main.LongAddition() constant_folding (before)
- // CHECK-DAG: <<Const1:j\d+>> LongConstant 1
- // CHECK-DAG: <<Const2:j\d+>> LongConstant 2
- // CHECK-DAG: <<Add:j\d+>> Add [<<Const1>>,<<Const2>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: long Main.LongAddition() constant_folding (before)
+ /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1
+ /// CHECK-DAG: <<Const2:j\d+>> LongConstant 2
+ /// CHECK-DAG: <<Add:j\d+>> Add [<<Const1>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Add>>]
- // CHECK-START: long Main.LongAddition() constant_folding (after)
- // CHECK-DAG: <<Const3:j\d+>> LongConstant 3
- // CHECK-DAG: Return [<<Const3>>]
+ /// CHECK-START: long Main.LongAddition() constant_folding (after)
+ /// CHECK-DAG: <<Const3:j\d+>> LongConstant 3
+ /// CHECK-DAG: Return [<<Const3>>]
public static long LongAddition() {
long a, b, c;
@@ -172,15 +172,15 @@ public class Main {
* on subtraction.
*/
- // CHECK-START: long Main.LongSubtraction() constant_folding (before)
- // CHECK-DAG: <<Const6:j\d+>> LongConstant 6
- // CHECK-DAG: <<Const2:j\d+>> LongConstant 2
- // CHECK-DAG: <<Sub:j\d+>> Sub [<<Const6>>,<<Const2>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: long Main.LongSubtraction() constant_folding (before)
+ /// CHECK-DAG: <<Const6:j\d+>> LongConstant 6
+ /// CHECK-DAG: <<Const2:j\d+>> LongConstant 2
+ /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Const6>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: long Main.LongSubtraction() constant_folding (after)
- // CHECK-DAG: <<Const4:j\d+>> LongConstant 4
- // CHECK-DAG: Return [<<Const4>>]
+ /// CHECK-START: long Main.LongSubtraction() constant_folding (after)
+ /// CHECK-DAG: <<Const4:j\d+>> LongConstant 4
+ /// CHECK-DAG: Return [<<Const4>>]
public static long LongSubtraction() {
long a, b, c;
@@ -194,15 +194,15 @@ public class Main {
* Three-register program with a constant (static) condition.
*/
- // CHECK-START: int Main.StaticCondition() constant_folding (before)
- // CHECK-DAG: <<Const7:i\d+>> IntConstant 7
- // CHECK-DAG: <<Const2:i\d+>> IntConstant 2
- // CHECK-DAG: <<Cond:z\d+>> GreaterThanOrEqual [<<Const7>>,<<Const2>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.StaticCondition() constant_folding (before)
+ /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
+ /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
+ /// CHECK-DAG: <<Cond:z\d+>> GreaterThanOrEqual [<<Const7>>,<<Const2>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.StaticCondition() constant_folding (after)
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: If [<<Const1>>]
+ /// CHECK-START: int Main.StaticCondition() constant_folding (after)
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: If [<<Const1>>]
public static int StaticCondition() {
int a, b, c;
@@ -224,19 +224,19 @@ public class Main {
* (forward) post-order traversal of the the dominator tree.
*/
- // CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (before)
- // CHECK-DAG: <<Const2:i\d+>> IntConstant 2
- // CHECK-DAG: <<Const5:i\d+>> IntConstant 5
- // CHECK-DAG: <<Add:i\d+>> Add [<<Const5>>,<<Const2>>]
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Const5>>,<<Const2>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
- // CHECK-DAG: Return [<<Phi>>]
+ /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (before)
+ /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
+ /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Const5>>,<<Const2>>]
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const5>>,<<Const2>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
+ /// CHECK-DAG: Return [<<Phi>>]
- // CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (after)
- // CHECK-DAG: <<Const3:i\d+>> IntConstant 3
- // CHECK-DAG: <<Const7:i\d+>> IntConstant 7
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Const7>>,<<Const3>>]
- // CHECK-DAG: Return [<<Phi>>]
+ /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (after)
+ /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
+ /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const7>>,<<Const3>>]
+ /// CHECK-DAG: Return [<<Phi>>]
public static int JumpsAndConditionals(boolean cond) {
int a, b, c;
@@ -253,388 +253,388 @@ public class Main {
* Test optimizations of arithmetic identities yielding a constant result.
*/
- // CHECK-START: int Main.And0(int) constant_folding (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<Const0>>]
- // CHECK-DAG: Return [<<And>>]
+ /// CHECK-START: int Main.And0(int) constant_folding (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<And>>]
- // CHECK-START: int Main.And0(int) constant_folding (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-NOT: And
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: int Main.And0(int) constant_folding (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-NOT: And
+ /// CHECK-DAG: Return [<<Const0>>]
public static int And0(int arg) {
return arg & 0;
}
- // CHECK-START: long Main.Mul0(long) constant_folding (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-DAG: <<Mul:j\d+>> Mul [<<Arg>>,<<Const0>>]
- // CHECK-DAG: Return [<<Mul>>]
+ /// CHECK-START: long Main.Mul0(long) constant_folding (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<Mul>>]
- // CHECK-START: long Main.Mul0(long) constant_folding (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-NOT: Mul
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: long Main.Mul0(long) constant_folding (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-NOT: Mul
+ /// CHECK-DAG: Return [<<Const0>>]
public static long Mul0(long arg) {
return arg * 0;
}
- // CHECK-START: int Main.OrAllOnes(int) constant_folding (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
- // CHECK-DAG: <<Or:i\d+>> Or [<<Arg>>,<<ConstF>>]
- // CHECK-DAG: Return [<<Or>>]
+ /// CHECK-START: int Main.OrAllOnes(int) constant_folding (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Arg>>,<<ConstF>>]
+ /// CHECK-DAG: Return [<<Or>>]
- // CHECK-START: int Main.OrAllOnes(int) constant_folding (after)
- // CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
- // CHECK-NOT: Or
- // CHECK-DAG: Return [<<ConstF>>]
+ /// CHECK-START: int Main.OrAllOnes(int) constant_folding (after)
+ /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
+ /// CHECK-NOT: Or
+ /// CHECK-DAG: Return [<<ConstF>>]
public static int OrAllOnes(int arg) {
return arg | -1;
}
- // CHECK-START: long Main.Rem0(long) constant_folding (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-DAG: <<DivZeroCheck:j\d+>> DivZeroCheck [<<Arg>>]
- // CHECK-DAG: <<Rem:j\d+>> Rem [<<Const0>>,<<DivZeroCheck>>]
- // CHECK-DAG: Return [<<Rem>>]
+ /// CHECK-START: long Main.Rem0(long) constant_folding (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-DAG: <<DivZeroCheck:j\d+>> DivZeroCheck [<<Arg>>]
+ /// CHECK-DAG: <<Rem:j\d+>> Rem [<<Const0>>,<<DivZeroCheck>>]
+ /// CHECK-DAG: Return [<<Rem>>]
- // CHECK-START: long Main.Rem0(long) constant_folding (after)
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-NOT: Rem
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: long Main.Rem0(long) constant_folding (after)
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-NOT: Rem
+ /// CHECK-DAG: Return [<<Const0>>]
public static long Rem0(long arg) {
return 0 % arg;
}
- // CHECK-START: int Main.Rem1(int) constant_folding (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Rem:i\d+>> Rem [<<Arg>>,<<Const1>>]
- // CHECK-DAG: Return [<<Rem>>]
+ /// CHECK-START: int Main.Rem1(int) constant_folding (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Rem:i\d+>> Rem [<<Arg>>,<<Const1>>]
+ /// CHECK-DAG: Return [<<Rem>>]
- // CHECK-START: int Main.Rem1(int) constant_folding (after)
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-NOT: Rem
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: int Main.Rem1(int) constant_folding (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-NOT: Rem
+ /// CHECK-DAG: Return [<<Const0>>]
public static int Rem1(int arg) {
return arg % 1;
}
- // CHECK-START: long Main.RemN1(long) constant_folding (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<ConstN1:j\d+>> LongConstant -1
- // CHECK-DAG: <<DivZeroCheck:j\d+>> DivZeroCheck [<<ConstN1>>]
- // CHECK-DAG: <<Rem:j\d+>> Rem [<<Arg>>,<<DivZeroCheck>>]
- // CHECK-DAG: Return [<<Rem>>]
+ /// CHECK-START: long Main.RemN1(long) constant_folding (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstN1:j\d+>> LongConstant -1
+ /// CHECK-DAG: <<DivZeroCheck:j\d+>> DivZeroCheck [<<ConstN1>>]
+ /// CHECK-DAG: <<Rem:j\d+>> Rem [<<Arg>>,<<DivZeroCheck>>]
+ /// CHECK-DAG: Return [<<Rem>>]
- // CHECK-START: long Main.RemN1(long) constant_folding (after)
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-NOT: Rem
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: long Main.RemN1(long) constant_folding (after)
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-NOT: Rem
+ /// CHECK-DAG: Return [<<Const0>>]
public static long RemN1(long arg) {
return arg % -1;
}
- // CHECK-START: int Main.Shl0(int) constant_folding (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Shl:i\d+>> Shl [<<Const0>>,<<Arg>>]
- // CHECK-DAG: Return [<<Shl>>]
+ /// CHECK-START: int Main.Shl0(int) constant_folding (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Const0>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Shl>>]
- // CHECK-START: int Main.Shl0(int) constant_folding (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-NOT: Shl
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: int Main.Shl0(int) constant_folding (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-NOT: Shl
+ /// CHECK-DAG: Return [<<Const0>>]
public static int Shl0(int arg) {
return 0 << arg;
}
- // CHECK-START: long Main.Shr0(int) constant_folding (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-DAG: <<Shr:j\d+>> Shr [<<Const0>>,<<Arg>>]
- // CHECK-DAG: Return [<<Shr>>]
+ /// CHECK-START: long Main.Shr0(int) constant_folding (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Const0>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Shr>>]
- // CHECK-START: long Main.Shr0(int) constant_folding (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-NOT: Shr
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: long Main.Shr0(int) constant_folding (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-NOT: Shr
+ /// CHECK-DAG: Return [<<Const0>>]
public static long Shr0(int arg) {
return (long)0 >> arg;
}
- // CHECK-START: long Main.SubSameLong(long) constant_folding (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg>>,<<Arg>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: long Main.SubSameLong(long) constant_folding (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: long Main.SubSameLong(long) constant_folding (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-NOT: Sub
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: long Main.SubSameLong(long) constant_folding (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-NOT: Sub
+ /// CHECK-DAG: Return [<<Const0>>]
public static long SubSameLong(long arg) {
return arg - arg;
}
- // CHECK-START: int Main.UShr0(int) constant_folding (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<UShr:i\d+>> UShr [<<Const0>>,<<Arg>>]
- // CHECK-DAG: Return [<<UShr>>]
+ /// CHECK-START: int Main.UShr0(int) constant_folding (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Const0>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<UShr>>]
- // CHECK-START: int Main.UShr0(int) constant_folding (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-NOT: UShr
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: int Main.UShr0(int) constant_folding (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-NOT: UShr
+ /// CHECK-DAG: Return [<<Const0>>]
public static int UShr0(int arg) {
return 0 >>> arg;
}
- // CHECK-START: int Main.XorSameInt(int) constant_folding (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<Arg>>]
- // CHECK-DAG: Return [<<Xor>>]
+ /// CHECK-START: int Main.XorSameInt(int) constant_folding (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Xor>>]
- // CHECK-START: int Main.XorSameInt(int) constant_folding (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-NOT: Xor
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: int Main.XorSameInt(int) constant_folding (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-NOT: Xor
+ /// CHECK-DAG: Return [<<Const0>>]
public static int XorSameInt(int arg) {
return arg ^ arg;
}
- // CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (before)
- // CHECK-DAG: <<Arg:f\d+>> ParameterValue
- // CHECK-DAG: <<ConstNan:f\d+>> FloatConstant nan
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: IntConstant 1
- // CHECK-DAG: <<Cmp:i\d+>> Compare [<<Arg>>,<<ConstNan>>]
- // CHECK-DAG: <<Le:z\d+>> LessThanOrEqual [<<Cmp>>,<<Const0>>]
- // CHECK-DAG: If [<<Le>>]
+ /// CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (before)
+ /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstNan:f\d+>> FloatConstant nan
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: IntConstant 1
+ /// CHECK-DAG: <<Cmp:i\d+>> Compare [<<Arg>>,<<ConstNan>>]
+ /// CHECK-DAG: <<Le:z\d+>> LessThanOrEqual [<<Cmp>>,<<Const0>>]
+ /// CHECK-DAG: If [<<Le>>]
- // CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (after)
- // CHECK-DAG: ParameterValue
- // CHECK-DAG: FloatConstant nan
- // CHECK-DAG: IntConstant 0
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: If [<<Const1>>]
+ /// CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (after)
+ /// CHECK-DAG: ParameterValue
+ /// CHECK-DAG: FloatConstant nan
+ /// CHECK-DAG: IntConstant 0
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: If [<<Const1>>]
- // CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (after)
- // CHECK-NOT: Compare
- // CHECK-NOT: LessThanOrEqual
+ /// CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (after)
+ /// CHECK-NOT: Compare
+ /// CHECK-NOT: LessThanOrEqual
public static boolean CmpFloatGreaterThanNaN(float arg) {
return arg > Float.NaN;
}
- // CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (before)
- // CHECK-DAG: <<Arg:d\d+>> ParameterValue
- // CHECK-DAG: <<ConstNan:d\d+>> DoubleConstant nan
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: IntConstant 1
- // CHECK-DAG: <<Cmp:i\d+>> Compare [<<Arg>>,<<ConstNan>>]
- // CHECK-DAG: <<Ge:z\d+>> GreaterThanOrEqual [<<Cmp>>,<<Const0>>]
- // CHECK-DAG: If [<<Ge>>]
+ /// CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (before)
+ /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstNan:d\d+>> DoubleConstant nan
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: IntConstant 1
+ /// CHECK-DAG: <<Cmp:i\d+>> Compare [<<Arg>>,<<ConstNan>>]
+ /// CHECK-DAG: <<Ge:z\d+>> GreaterThanOrEqual [<<Cmp>>,<<Const0>>]
+ /// CHECK-DAG: If [<<Ge>>]
- // CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (after)
- // CHECK-DAG: ParameterValue
- // CHECK-DAG: DoubleConstant nan
- // CHECK-DAG: IntConstant 0
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: If [<<Const1>>]
+ /// CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (after)
+ /// CHECK-DAG: ParameterValue
+ /// CHECK-DAG: DoubleConstant nan
+ /// CHECK-DAG: IntConstant 0
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: If [<<Const1>>]
- // CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (after)
- // CHECK-NOT: Compare
- // CHECK-NOT: GreaterThanOrEqual
+ /// CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (after)
+ /// CHECK-NOT: Compare
+ /// CHECK-NOT: GreaterThanOrEqual
public static boolean CmpDoubleLessThanNaN(double arg) {
return arg < Double.NaN;
}
- // CHECK-START: int Main.ReturnInt33() constant_folding (before)
- // CHECK-DAG: <<Const33:j\d+>> LongConstant 33
- // CHECK-DAG: <<Convert:i\d+>> TypeConversion [<<Const33>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: int Main.ReturnInt33() constant_folding (before)
+ /// CHECK-DAG: <<Const33:j\d+>> LongConstant 33
+ /// CHECK-DAG: <<Convert:i\d+>> TypeConversion [<<Const33>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: int Main.ReturnInt33() constant_folding (after)
- // CHECK-DAG: <<Const33:i\d+>> IntConstant 33
- // CHECK-DAG: Return [<<Const33>>]
+ /// CHECK-START: int Main.ReturnInt33() constant_folding (after)
+ /// CHECK-DAG: <<Const33:i\d+>> IntConstant 33
+ /// CHECK-DAG: Return [<<Const33>>]
public static int ReturnInt33() {
long imm = 33L;
return (int) imm;
}
- // CHECK-START: int Main.ReturnIntMax() constant_folding (before)
- // CHECK-DAG: <<ConstMax:f\d+>> FloatConstant 1e+34
- // CHECK-DAG: <<Convert:i\d+>> TypeConversion [<<ConstMax>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: int Main.ReturnIntMax() constant_folding (before)
+ /// CHECK-DAG: <<ConstMax:f\d+>> FloatConstant 1e+34
+ /// CHECK-DAG: <<Convert:i\d+>> TypeConversion [<<ConstMax>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: int Main.ReturnIntMax() constant_folding (after)
- // CHECK-DAG: <<ConstMax:i\d+>> IntConstant 2147483647
- // CHECK-DAG: Return [<<ConstMax>>]
+ /// CHECK-START: int Main.ReturnIntMax() constant_folding (after)
+ /// CHECK-DAG: <<ConstMax:i\d+>> IntConstant 2147483647
+ /// CHECK-DAG: Return [<<ConstMax>>]
public static int ReturnIntMax() {
float imm = 1.0e34f;
return (int) imm;
}
- // CHECK-START: int Main.ReturnInt0() constant_folding (before)
- // CHECK-DAG: <<ConstNaN:d\d+>> DoubleConstant nan
- // CHECK-DAG: <<Convert:i\d+>> TypeConversion [<<ConstNaN>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: int Main.ReturnInt0() constant_folding (before)
+ /// CHECK-DAG: <<ConstNaN:d\d+>> DoubleConstant nan
+ /// CHECK-DAG: <<Convert:i\d+>> TypeConversion [<<ConstNaN>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: int Main.ReturnInt0() constant_folding (after)
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: int Main.ReturnInt0() constant_folding (after)
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: Return [<<Const0>>]
public static int ReturnInt0() {
double imm = Double.NaN;
return (int) imm;
}
- // CHECK-START: long Main.ReturnLong33() constant_folding (before)
- // CHECK-DAG: <<Const33:i\d+>> IntConstant 33
- // CHECK-DAG: <<Convert:j\d+>> TypeConversion [<<Const33>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: long Main.ReturnLong33() constant_folding (before)
+ /// CHECK-DAG: <<Const33:i\d+>> IntConstant 33
+ /// CHECK-DAG: <<Convert:j\d+>> TypeConversion [<<Const33>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: long Main.ReturnLong33() constant_folding (after)
- // CHECK-DAG: <<Const33:j\d+>> LongConstant 33
- // CHECK-DAG: Return [<<Const33>>]
+ /// CHECK-START: long Main.ReturnLong33() constant_folding (after)
+ /// CHECK-DAG: <<Const33:j\d+>> LongConstant 33
+ /// CHECK-DAG: Return [<<Const33>>]
public static long ReturnLong33() {
int imm = 33;
return (long) imm;
}
- // CHECK-START: long Main.ReturnLong34() constant_folding (before)
- // CHECK-DAG: <<Const34:f\d+>> FloatConstant 34
- // CHECK-DAG: <<Convert:j\d+>> TypeConversion [<<Const34>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: long Main.ReturnLong34() constant_folding (before)
+ /// CHECK-DAG: <<Const34:f\d+>> FloatConstant 34
+ /// CHECK-DAG: <<Convert:j\d+>> TypeConversion [<<Const34>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: long Main.ReturnLong34() constant_folding (after)
- // CHECK-DAG: <<Const34:j\d+>> LongConstant 34
- // CHECK-DAG: Return [<<Const34>>]
+ /// CHECK-START: long Main.ReturnLong34() constant_folding (after)
+ /// CHECK-DAG: <<Const34:j\d+>> LongConstant 34
+ /// CHECK-DAG: Return [<<Const34>>]
public static long ReturnLong34() {
float imm = 34.0f;
return (long) imm;
}
- // CHECK-START: long Main.ReturnLong0() constant_folding (before)
- // CHECK-DAG: <<ConstNaN:d\d+>> DoubleConstant nan
- // CHECK-DAG: <<Convert:j\d+>> TypeConversion [<<ConstNaN>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: long Main.ReturnLong0() constant_folding (before)
+ /// CHECK-DAG: <<ConstNaN:d\d+>> DoubleConstant nan
+ /// CHECK-DAG: <<Convert:j\d+>> TypeConversion [<<ConstNaN>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: long Main.ReturnLong0() constant_folding (after)
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-DAG: Return [<<Const0>>]
+ /// CHECK-START: long Main.ReturnLong0() constant_folding (after)
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-DAG: Return [<<Const0>>]
public static long ReturnLong0() {
double imm = -Double.NaN;
return (long) imm;
}
- // CHECK-START: float Main.ReturnFloat33() constant_folding (before)
- // CHECK-DAG: <<Const33:i\d+>> IntConstant 33
- // CHECK-DAG: <<Convert:f\d+>> TypeConversion [<<Const33>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: float Main.ReturnFloat33() constant_folding (before)
+ /// CHECK-DAG: <<Const33:i\d+>> IntConstant 33
+ /// CHECK-DAG: <<Convert:f\d+>> TypeConversion [<<Const33>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: float Main.ReturnFloat33() constant_folding (after)
- // CHECK-DAG: <<Const33:f\d+>> FloatConstant 33
- // CHECK-DAG: Return [<<Const33>>]
+ /// CHECK-START: float Main.ReturnFloat33() constant_folding (after)
+ /// CHECK-DAG: <<Const33:f\d+>> FloatConstant 33
+ /// CHECK-DAG: Return [<<Const33>>]
public static float ReturnFloat33() {
int imm = 33;
return (float) imm;
}
- // CHECK-START: float Main.ReturnFloat34() constant_folding (before)
- // CHECK-DAG: <<Const34:j\d+>> LongConstant 34
- // CHECK-DAG: <<Convert:f\d+>> TypeConversion [<<Const34>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: float Main.ReturnFloat34() constant_folding (before)
+ /// CHECK-DAG: <<Const34:j\d+>> LongConstant 34
+ /// CHECK-DAG: <<Convert:f\d+>> TypeConversion [<<Const34>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: float Main.ReturnFloat34() constant_folding (after)
- // CHECK-DAG: <<Const34:f\d+>> FloatConstant 34
- // CHECK-DAG: Return [<<Const34>>]
+ /// CHECK-START: float Main.ReturnFloat34() constant_folding (after)
+ /// CHECK-DAG: <<Const34:f\d+>> FloatConstant 34
+ /// CHECK-DAG: Return [<<Const34>>]
public static float ReturnFloat34() {
long imm = 34L;
return (float) imm;
}
- // CHECK-START: float Main.ReturnFloat99P25() constant_folding (before)
- // CHECK-DAG: <<Const:d\d+>> DoubleConstant 99.25
- // CHECK-DAG: <<Convert:f\d+>> TypeConversion [<<Const>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: float Main.ReturnFloat99P25() constant_folding (before)
+ /// CHECK-DAG: <<Const:d\d+>> DoubleConstant 99.25
+ /// CHECK-DAG: <<Convert:f\d+>> TypeConversion [<<Const>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: float Main.ReturnFloat99P25() constant_folding (after)
- // CHECK-DAG: <<Const:f\d+>> FloatConstant 99.25
- // CHECK-DAG: Return [<<Const>>]
+ /// CHECK-START: float Main.ReturnFloat99P25() constant_folding (after)
+ /// CHECK-DAG: <<Const:f\d+>> FloatConstant 99.25
+ /// CHECK-DAG: Return [<<Const>>]
public static float ReturnFloat99P25() {
double imm = 99.25;
return (float) imm;
}
- // CHECK-START: double Main.ReturnDouble33() constant_folding (before)
- // CHECK-DAG: <<Const33:i\d+>> IntConstant 33
- // CHECK-DAG: <<Convert:d\d+>> TypeConversion [<<Const33>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: double Main.ReturnDouble33() constant_folding (before)
+ /// CHECK-DAG: <<Const33:i\d+>> IntConstant 33
+ /// CHECK-DAG: <<Convert:d\d+>> TypeConversion [<<Const33>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: double Main.ReturnDouble33() constant_folding (after)
- // CHECK-DAG: <<Const33:d\d+>> DoubleConstant 33
- // CHECK-DAG: Return [<<Const33>>]
+ /// CHECK-START: double Main.ReturnDouble33() constant_folding (after)
+ /// CHECK-DAG: <<Const33:d\d+>> DoubleConstant 33
+ /// CHECK-DAG: Return [<<Const33>>]
public static double ReturnDouble33() {
int imm = 33;
return (double) imm;
}
- // CHECK-START: double Main.ReturnDouble34() constant_folding (before)
- // CHECK-DAG: <<Const34:j\d+>> LongConstant 34
- // CHECK-DAG: <<Convert:d\d+>> TypeConversion [<<Const34>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: double Main.ReturnDouble34() constant_folding (before)
+ /// CHECK-DAG: <<Const34:j\d+>> LongConstant 34
+ /// CHECK-DAG: <<Convert:d\d+>> TypeConversion [<<Const34>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: double Main.ReturnDouble34() constant_folding (after)
- // CHECK-DAG: <<Const34:d\d+>> DoubleConstant 34
- // CHECK-DAG: Return [<<Const34>>]
+ /// CHECK-START: double Main.ReturnDouble34() constant_folding (after)
+ /// CHECK-DAG: <<Const34:d\d+>> DoubleConstant 34
+ /// CHECK-DAG: Return [<<Const34>>]
public static double ReturnDouble34() {
long imm = 34L;
return (double) imm;
}
- // CHECK-START: double Main.ReturnDouble99P25() constant_folding (before)
- // CHECK-DAG: <<Const:f\d+>> FloatConstant 99.25
- // CHECK-DAG: <<Convert:d\d+>> TypeConversion [<<Const>>]
- // CHECK-DAG: Return [<<Convert>>]
+ /// CHECK-START: double Main.ReturnDouble99P25() constant_folding (before)
+ /// CHECK-DAG: <<Const:f\d+>> FloatConstant 99.25
+ /// CHECK-DAG: <<Convert:d\d+>> TypeConversion [<<Const>>]
+ /// CHECK-DAG: Return [<<Convert>>]
- // CHECK-START: double Main.ReturnDouble99P25() constant_folding (after)
- // CHECK-DAG: <<Const:d\d+>> DoubleConstant 99.25
- // CHECK-DAG: Return [<<Const>>]
+ /// CHECK-START: double Main.ReturnDouble99P25() constant_folding (after)
+ /// CHECK-DAG: <<Const:d\d+>> DoubleConstant 99.25
+ /// CHECK-DAG: Return [<<Const>>]
public static double ReturnDouble99P25() {
float imm = 99.25f;
diff --git a/test/444-checker-nce/src/Main.java b/test/444-checker-nce/src/Main.java
index 501d79c9a4..6ac0cad7e8 100644
--- a/test/444-checker-nce/src/Main.java
+++ b/test/444-checker-nce/src/Main.java
@@ -16,63 +16,63 @@
public class Main {
- // CHECK-START: Main Main.keepTest(Main) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
- // CHECK: InvokeStaticOrDirect
+ /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
+ /// CHECK: InvokeStaticOrDirect
- // CHECK-START: Main Main.keepTest(Main) instruction_simplifier_after_types (after)
- // CHECK: NullCheck
- // CHECK: InvokeStaticOrDirect
+ /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier_after_types (after)
+ /// CHECK: NullCheck
+ /// CHECK: InvokeStaticOrDirect
public Main keepTest(Main m) {
return m.g();
}
- // CHECK-START: Main Main.thisTest() instruction_simplifier (before)
- // CHECK: NullCheck
- // CHECK: InvokeStaticOrDirect
+ /// CHECK-START: Main Main.thisTest() instruction_simplifier (before)
+ /// CHECK: NullCheck
+ /// CHECK: InvokeStaticOrDirect
- // CHECK-START: Main Main.thisTest() instruction_simplifier (after)
- // CHECK-NOT: NullCheck
- // CHECK: InvokeStaticOrDirect
+ /// CHECK-START: Main Main.thisTest() instruction_simplifier (after)
+ /// CHECK-NOT: NullCheck
+ /// CHECK: InvokeStaticOrDirect
public Main thisTest() {
return g();
}
- // CHECK-START: Main Main.newInstanceRemoveTest() instruction_simplifier (before)
- // CHECK: NewInstance
- // CHECK: NullCheck
- // CHECK: InvokeStaticOrDirect
- // CHECK: NullCheck
- // CHECK: InvokeStaticOrDirect
+ /// CHECK-START: Main Main.newInstanceRemoveTest() instruction_simplifier (before)
+ /// CHECK: NewInstance
+ /// CHECK: NullCheck
+ /// CHECK: InvokeStaticOrDirect
+ /// CHECK: NullCheck
+ /// CHECK: InvokeStaticOrDirect
- // CHECK-START: Main Main.newInstanceRemoveTest() instruction_simplifier (after)
- // CHECK-NOT: NullCheck
+ /// CHECK-START: Main Main.newInstanceRemoveTest() instruction_simplifier (after)
+ /// CHECK-NOT: NullCheck
public Main newInstanceRemoveTest() {
Main m = new Main();
return m.g();
}
- // CHECK-START: Main Main.newArrayRemoveTest() instruction_simplifier (before)
- // CHECK: NewArray
- // CHECK: NullCheck
- // CHECK: ArrayGet
+ /// CHECK-START: Main Main.newArrayRemoveTest() instruction_simplifier (before)
+ /// CHECK: NewArray
+ /// CHECK: NullCheck
+ /// CHECK: ArrayGet
- // CHECK-START: Main Main.newArrayRemoveTest() instruction_simplifier (after)
- // CHECK: NewArray
- // CHECK-NOT: NullCheck
- // CHECK: ArrayGet
+ /// CHECK-START: Main Main.newArrayRemoveTest() instruction_simplifier (after)
+ /// CHECK: NewArray
+ /// CHECK-NOT: NullCheck
+ /// CHECK: ArrayGet
public Main newArrayRemoveTest() {
Main[] ms = new Main[1];
return ms[0];
}
- // CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier_after_types (before)
- // CHECK: NewInstance
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier_after_types (before)
+ /// CHECK: NewInstance
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier_after_types (after)
- // CHECK: NewInstance
- // CHECK-NOT: NullCheck
+ /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier_after_types (after)
+ /// CHECK: NewInstance
+ /// CHECK-NOT: NullCheck
public Main ifRemoveTest(boolean flag) {
Main m = null;
if (flag) {
@@ -83,13 +83,13 @@ public class Main {
return m.g();
}
- // CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier_after_types (before)
- // CHECK: NewInstance
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier_after_types (before)
+ /// CHECK: NewInstance
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier_after_types (after)
- // CHECK: NewInstance
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier_after_types (after)
+ /// CHECK: NewInstance
+ /// CHECK: NullCheck
public Main ifKeepTest(boolean flag) {
Main m = null;
if (flag) {
@@ -98,11 +98,11 @@ public class Main {
return m.g();
}
- // CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: NullCheck
+ /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: NullCheck
public Main forRemoveTest(int count) {
Main a = new Main();
Main m = new Main();
@@ -114,11 +114,11 @@ public class Main {
return m.g();
}
- // CHECK-START: Main Main.forKeepTest(int) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.forKeepTest(int) instruction_simplifier_after_types (after)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier_after_types (after)
+ /// CHECK: NullCheck
public Main forKeepTest(int count) {
Main a = new Main();
Main m = new Main();
@@ -132,11 +132,11 @@ public class Main {
return m.g();
}
- // CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: NullCheck
+ /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: NullCheck
public Main phiFlowRemoveTest(int count) {
Main a = new Main();
Main m = new Main();
@@ -154,11 +154,11 @@ public class Main {
return n.g();
}
- // CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier_after_types (after)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier_after_types (after)
+ /// CHECK: NullCheck
public Main phiFlowKeepTest(int count) {
Main a = new Main();
Main m = new Main();
@@ -178,11 +178,11 @@ public class Main {
return n.g();
}
- // CHECK-START: Main Main.scopeRemoveTest(int, Main) instruction_simplifier (before)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.scopeRemoveTest(int, Main) instruction_simplifier (before)
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.scopeRemoveTest(int, Main) instruction_simplifier (after)
- // CHECK-NOT: NullCheck
+ /// CHECK-START: Main Main.scopeRemoveTest(int, Main) instruction_simplifier (after)
+ /// CHECK-NOT: NullCheck
public Main scopeRemoveTest(int count, Main a) {
Main m = null;
for (int i = 0; i < count; i++) {
@@ -196,11 +196,11 @@ public class Main {
return m;
}
- // CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier_after_types (after)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier_after_types (after)
+ /// CHECK: NullCheck
public Main scopeKeepTest(int count, Main a) {
Main m = new Main();
for (int i = 0; i < count; i++) {
@@ -214,11 +214,11 @@ public class Main {
return m;
}
- // CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier_after_types (after)
- // CHECK-NOT: NullCheck
+ /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: NullCheck
public Main scopeIfNotNullRemove(Main m) {
if (m != null) {
return m.g();
@@ -226,11 +226,11 @@ public class Main {
return m;
}
- // CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
- // CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier_after_types (after)
- // CHECK: NullCheck
+ /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier_after_types (after)
+ /// CHECK: NullCheck
public Main scopeIfKeep(Main m) {
if (m == null) {
m = new Main();
@@ -258,12 +258,12 @@ public class Main {
class ListElement {
private ListElement next;
- // CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier_after_types (before)
- // CHECK: NullCheck
- // CHECK: NullCheck
+ /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier_after_types (before)
+ /// CHECK: NullCheck
+ /// CHECK: NullCheck
- // CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier_after_types (after)
- // CHECK-NOT: NullCheck
+ /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: NullCheck
static boolean isShorter(ListElement x, ListElement y) {
ListElement xTail = x;
ListElement yTail = y;
diff --git a/test/445-checker-licm/src/Main.java b/test/445-checker-licm/src/Main.java
index 96918d3e3a..42f9a11092 100644
--- a/test/445-checker-licm/src/Main.java
+++ b/test/445-checker-licm/src/Main.java
@@ -16,14 +16,14 @@
public class Main {
- // CHECK-START: int Main.div() licm (before)
- // CHECK-DAG: Div loop:{{B\d+}}
+ /// CHECK-START: int Main.div() licm (before)
+ /// CHECK-DAG: Div loop:{{B\d+}}
- // CHECK-START: int Main.div() licm (after)
- // CHECK-NOT: Div loop:{{B\d+}}
+ /// CHECK-START: int Main.div() licm (after)
+ /// CHECK-NOT: Div loop:{{B\d+}}
- // CHECK-START: int Main.div() licm (after)
- // CHECK-DAG: Div loop:none
+ /// CHECK-START: int Main.div() licm (after)
+ /// CHECK-DAG: Div loop:none
public static int div() {
int result = 0;
@@ -33,14 +33,14 @@ public class Main {
return result;
}
- // CHECK-START: int Main.innerDiv() licm (before)
- // CHECK-DAG: Div loop:{{B\d+}}
+ /// CHECK-START: int Main.innerDiv() licm (before)
+ /// CHECK-DAG: Div loop:{{B\d+}}
- // CHECK-START: int Main.innerDiv() licm (after)
- // CHECK-NOT: Div loop:{{B\d+}}
+ /// CHECK-START: int Main.innerDiv() licm (after)
+ /// CHECK-NOT: Div loop:{{B\d+}}
- // CHECK-START: int Main.innerDiv() licm (after)
- // CHECK-DAG: Div loop:none
+ /// CHECK-START: int Main.innerDiv() licm (after)
+ /// CHECK-DAG: Div loop:none
public static int innerDiv() {
int result = 0;
@@ -52,11 +52,11 @@ public class Main {
return result;
}
- // CHECK-START: int Main.innerDiv2() licm (before)
- // CHECK-DAG: Mul loop:B4
+ /// CHECK-START: int Main.innerDiv2() licm (before)
+ /// CHECK-DAG: Mul loop:B4
- // CHECK-START: int Main.innerDiv2() licm (after)
- // CHECK-DAG: Mul loop:B2
+ /// CHECK-START: int Main.innerDiv2() licm (after)
+ /// CHECK-DAG: Mul loop:B2
public static int innerDiv2() {
int result = 0;
@@ -71,11 +71,11 @@ public class Main {
return result;
}
- // CHECK-START: int Main.innerDiv3(int, int) licm (before)
- // CHECK-DAG: Div loop:{{B\d+}}
+ /// CHECK-START: int Main.innerDiv3(int, int) licm (before)
+ /// CHECK-DAG: Div loop:{{B\d+}}
- // CHECK-START: int Main.innerDiv3(int, int) licm (after)
- // CHECK-DAG: Div loop:{{B\d+}}
+ /// CHECK-START: int Main.innerDiv3(int, int) licm (after)
+ /// CHECK-DAG: Div loop:{{B\d+}}
public static int innerDiv3(int a, int b) {
int result = 0;
@@ -87,17 +87,17 @@ public class Main {
return result;
}
- // CHECK-START: int Main.arrayLength(int[]) licm (before)
- // CHECK-DAG: <<NullCheck:l\d+>> NullCheck loop:{{B\d+}}
- // CHECK-DAG: ArrayLength [<<NullCheck>>] loop:{{B\d+}}
+ /// CHECK-START: int Main.arrayLength(int[]) licm (before)
+ /// CHECK-DAG: <<NullCheck:l\d+>> NullCheck loop:{{B\d+}}
+ /// CHECK-DAG: ArrayLength [<<NullCheck>>] loop:{{B\d+}}
- // CHECK-START: int Main.arrayLength(int[]) licm (after)
- // CHECK-NOT: NullCheck loop:{{B\d+}}
- // CHECK-NOT: ArrayLength loop:{{B\d+}}
+ /// CHECK-START: int Main.arrayLength(int[]) licm (after)
+ /// CHECK-NOT: NullCheck loop:{{B\d+}}
+ /// CHECK-NOT: ArrayLength loop:{{B\d+}}
- // CHECK-START: int Main.arrayLength(int[]) licm (after)
- // CHECK-DAG: <<NullCheck:l\d+>> NullCheck loop:none
- // CHECK-DAG: ArrayLength [<<NullCheck>>] loop:none
+ /// CHECK-START: int Main.arrayLength(int[]) licm (after)
+ /// CHECK-DAG: <<NullCheck:l\d+>> NullCheck loop:none
+ /// CHECK-DAG: ArrayLength [<<NullCheck>>] loop:none
public static int arrayLength(int[] array) {
int result = 0;
diff --git a/test/446-checker-inliner2/src/Main.java b/test/446-checker-inliner2/src/Main.java
index 9ed66d64e3..de00a09256 100644
--- a/test/446-checker-inliner2/src/Main.java
+++ b/test/446-checker-inliner2/src/Main.java
@@ -16,16 +16,16 @@
public class Main {
- // CHECK-START: int Main.inlineInstanceCall(Main) inliner (before)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.inlineInstanceCall(Main) inliner (before)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: int Main.inlineInstanceCall(Main) inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineInstanceCall(Main) inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
- // CHECK-START: int Main.inlineInstanceCall(Main) inliner (after)
- // CHECK-DAG: <<Field:i\d+>> InstanceFieldGet
- // CHECK-DAG: Return [<<Field>>]
+ /// CHECK-START: int Main.inlineInstanceCall(Main) inliner (after)
+ /// CHECK-DAG: <<Field:i\d+>> InstanceFieldGet
+ /// CHECK-DAG: Return [<<Field>>]
public static int inlineInstanceCall(Main m) {
return m.foo();
@@ -37,16 +37,16 @@ public class Main {
int field = 42;
- // CHECK-START: int Main.inlineNestedCall() inliner (before)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.inlineNestedCall() inliner (before)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: int Main.inlineNestedCall() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineNestedCall() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
- // CHECK-START: int Main.inlineNestedCall() inliner (after)
- // CHECK-DAG: <<Const38:i\d+>> IntConstant 38
- // CHECK-DAG: Return [<<Const38>>]
+ /// CHECK-START: int Main.inlineNestedCall() inliner (after)
+ /// CHECK-DAG: <<Const38:i\d+>> IntConstant 38
+ /// CHECK-DAG: Return [<<Const38>>]
public static int inlineNestedCall() {
return nestedCall();
diff --git a/test/447-checker-inliner3/src/Main.java b/test/447-checker-inliner3/src/Main.java
index 9d022b95be..e3fdffdd46 100644
--- a/test/447-checker-inliner3/src/Main.java
+++ b/test/447-checker-inliner3/src/Main.java
@@ -16,12 +16,12 @@
public class Main {
- // CHECK-START: int Main.inlineIfThenElse() inliner (before)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.inlineIfThenElse() inliner (before)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: int Main.inlineIfThenElse() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineIfThenElse() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static int inlineIfThenElse() {
return foo(true);
@@ -35,11 +35,11 @@ public class Main {
}
}
- // CHECK-START: int Main.inlineInLoop() inliner (before)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineInLoop() inliner (before)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: int Main.inlineInLoop() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineInLoop() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static int inlineInLoop() {
int result = 0;
@@ -49,11 +49,11 @@ public class Main {
return result;
}
- // CHECK-START: int Main.inlineInLoopHeader() inliner (before)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineInLoopHeader() inliner (before)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: int Main.inlineInLoopHeader() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineInLoopHeader() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static int inlineInLoopHeader() {
int result = 0;
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index f90d85dac3..8960df896b 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -16,21 +16,21 @@
public class Main {
- // CHECK-START: int Main.sieve(int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: int Main.sieve(int) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: int Main.sieve(int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: int Main.sieve(int) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
static int sieve(int size) {
int primeCount = 0;
@@ -47,25 +47,25 @@ public class Main {
}
- // CHECK-START: void Main.narrow(int[], int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: void Main.narrow(int[], int) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.narrow(int[], int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.narrow(int[], int) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
static void narrow(int[] array, int offset) {
if (offset < 0) {
@@ -108,18 +108,18 @@ public class Main {
}
- // CHECK-START: void Main.constantIndexing1(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.constantIndexing1(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.constantIndexing1(int[]) BCE (after)
- // CHECK-NOT: Deoptimize
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.constantIndexing1(int[]) BCE (after)
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
static void constantIndexing1(int[] array) {
array[5] = 1;
@@ -127,29 +127,29 @@ public class Main {
}
- // CHECK-START: void Main.constantIndexing2(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: void Main.constantIndexing2(int[]) BCE (after)
- // CHECK: LessThanOrEqual
- // CHECK: Deoptimize
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.constantIndexing2(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.constantIndexing2(int[]) BCE (after)
+ /// CHECK: LessThanOrEqual
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
static void constantIndexing2(int[] array) {
array[1] = 1;
@@ -160,45 +160,45 @@ public class Main {
}
- // CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (after)
- // CHECK: LessThanOrEqual
- // CHECK: Deoptimize
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: LessThanOrEqual
- // CHECK: Deoptimize
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: int[] Main.constantIndexing3(int[], int[], boolean) BCE (after)
+ /// CHECK: LessThanOrEqual
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: LessThanOrEqual
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
static int[] constantIndexing3(int[] array1, int[] array2, boolean copy) {
if (!copy) {
@@ -212,14 +212,14 @@ public class Main {
}
- // CHECK-START: void Main.constantIndexing4(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.constantIndexing4(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.constantIndexing4(int[]) BCE (after)
- // CHECK-NOT: LessThanOrEqual
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.constantIndexing4(int[]) BCE (after)
+ /// CHECK-NOT: LessThanOrEqual
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
// There is only one array access. It's not beneficial
// to create a compare with deoptimization instruction.
@@ -228,18 +228,18 @@ public class Main {
}
- // CHECK-START: void Main.constantIndexing5(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.constantIndexing5(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.constantIndexing5(int[]) BCE (after)
- // CHECK-NOT: Deoptimize
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.constantIndexing5(int[]) BCE (after)
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
static void constantIndexing5(int[] array) {
// We don't apply the deoptimization for very large constant index
@@ -249,37 +249,37 @@ public class Main {
array[Integer.MAX_VALUE - 998] = 1;
}
- // CHECK-START: void Main.loopPattern1(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: void Main.loopPattern1(int[]) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.loopPattern1(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.loopPattern1(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
static void loopPattern1(int[] array) {
for (int i = 0; i < array.length; i++) {
@@ -316,33 +316,33 @@ public class Main {
}
- // CHECK-START: void Main.loopPattern2(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: void Main.loopPattern2(int[]) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.loopPattern2(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.loopPattern2(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
static void loopPattern2(int[] array) {
for (int i = array.length - 1; i >= 0; i--) {
@@ -372,13 +372,13 @@ public class Main {
}
- // CHECK-START: void Main.loopPattern3(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.loopPattern3(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.loopPattern3(int[]) BCE (after)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.loopPattern3(int[]) BCE (after)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
static void loopPattern3(int[] array) {
java.util.Random random = new java.util.Random();
@@ -393,29 +393,29 @@ public class Main {
}
- // CHECK-START: void Main.constantNewArray() BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: void Main.constantNewArray() BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.constantNewArray() BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.constantNewArray() BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
static void constantNewArray() {
int[] array = new int[10];
@@ -437,13 +437,13 @@ public class Main {
return 1;
}
- // CHECK-START: void Main.circularBufferProducer() BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.circularBufferProducer() BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.circularBufferProducer() BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.circularBufferProducer() BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
static void circularBufferProducer() {
byte[] array = new byte[4096];
@@ -455,17 +455,17 @@ public class Main {
}
- // CHECK-START: void Main.pyramid1(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.pyramid1(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.pyramid1(int[]) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.pyramid1(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
// Set array to something like {0, 1, 2, 3, 2, 1, 0}.
static void pyramid1(int[] array) {
@@ -476,17 +476,17 @@ public class Main {
}
- // CHECK-START: void Main.pyramid2(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.pyramid2(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.pyramid2(int[]) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.pyramid2(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
// Set array to something like {0, 1, 2, 3, 2, 1, 0}.
static void pyramid2(int[] array) {
@@ -497,17 +497,17 @@ public class Main {
}
- // CHECK-START: void Main.pyramid3(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.pyramid3(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.pyramid3(int[]) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.pyramid3(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
// Set array to something like {0, 1, 2, 3, 2, 1, 0}.
static void pyramid3(int[] array) {
@@ -518,17 +518,17 @@ public class Main {
}
- // CHECK-START: boolean Main.isPyramid(int[]) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: boolean Main.isPyramid(int[]) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
- // CHECK-START: boolean Main.isPyramid(int[]) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: boolean Main.isPyramid(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
static boolean isPyramid(int[] array) {
int i = 0;
@@ -546,43 +546,43 @@ public class Main {
}
- // CHECK-START: void Main.bubbleSort(int[]) GVN (before)
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: void Main.bubbleSort(int[]) GVN (after)
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: ArrayGet
- // CHECK-NOT: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: void Main.bubbleSort(int[]) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: ArrayGet
- // CHECK-NOT: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.bubbleSort(int[]) GVN (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.bubbleSort(int[]) GVN (after)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+ /// CHECK-NOT: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.bubbleSort(int[]) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: ArrayGet
+ /// CHECK-NOT: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
static void bubbleSort(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
@@ -610,22 +610,22 @@ public class Main {
int sum;
- // CHECK-START: void Main.foo1(int[], int, int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
-
- // CHECK-START: void Main.foo1(int[], int, int) BCE (after)
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK-NOT: Deoptimize
- // CHECK: Phi
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo1(int[], int, int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+
+ /// CHECK-START: void Main.foo1(int[], int, int) BCE (after)
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: Phi
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
void foo1(int[] array, int start, int end) {
// Three HDeoptimize will be added. One for
@@ -639,22 +639,22 @@ public class Main {
}
- // CHECK-START: void Main.foo2(int[], int, int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo2(int[], int, int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
- // CHECK-START: void Main.foo2(int[], int, int) BCE (after)
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK-NOT: Deoptimize
- // CHECK: Phi
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo2(int[], int, int) BCE (after)
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: Phi
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
void foo2(int[] array, int start, int end) {
// Three HDeoptimize will be added. One for
@@ -668,21 +668,21 @@ public class Main {
}
- // CHECK-START: void Main.foo3(int[], int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo3(int[], int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
- // CHECK-START: void Main.foo3(int[], int) BCE (after)
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK-NOT: Deoptimize
- // CHECK: Phi
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo3(int[], int) BCE (after)
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: Phi
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
void foo3(int[] array, int end) {
// Two HDeoptimize will be added. One for end < array.length,
@@ -694,21 +694,21 @@ public class Main {
}
}
- // CHECK-START: void Main.foo4(int[], int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
-
- // CHECK-START: void Main.foo4(int[], int) BCE (after)
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK-NOT: Deoptimize
- // CHECK: Phi
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo4(int[], int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+
+ /// CHECK-START: void Main.foo4(int[], int) BCE (after)
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: Phi
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
void foo4(int[] array, int end) {
// Two HDeoptimize will be added. One for end <= array.length,
@@ -721,28 +721,28 @@ public class Main {
}
- // CHECK-START: void Main.foo5(int[], int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
-
- // CHECK-START: void Main.foo5(int[], int) BCE (after)
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
- // CHECK: Deoptimize
- // CHECK-NOT: Deoptimize
- // CHECK: Phi
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo5(int[], int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+
+ /// CHECK-START: void Main.foo5(int[], int) BCE (after)
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: Phi
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
void foo5(int[] array, int end) {
// Bounds check in this loop can be eliminated without deoptimization.
@@ -759,38 +759,38 @@ public class Main {
}
- // CHECK-START: void Main.foo6(int[], int, int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
-
- // CHECK-START: void Main.foo6(int[], int, int) BCE (after)
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK-NOT: Deoptimize
- // CHECK: Phi
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.foo6(int[], int, int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.foo6(int[], int, int) BCE (after)
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: Phi
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArraySet
void foo6(int[] array, int start, int end) {
// Three HDeoptimize will be added. One for
@@ -803,22 +803,22 @@ public class Main {
}
- // CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
- // CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (after)
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK: Deoptimize
- // CHECK-NOT: Deoptimize
- // CHECK: Phi
- // CHECK: BoundsCheck
- // CHECK: ArrayGet
- // CHECK-NOT: BoundsCheck
- // CHECK: ArrayGet
+ /// CHECK-START: void Main.foo7(int[], int, int, boolean) BCE (after)
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK: Deoptimize
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: Phi
+ /// CHECK: BoundsCheck
+ /// CHECK: ArrayGet
+ /// CHECK-NOT: BoundsCheck
+ /// CHECK: ArrayGet
void foo7(int[] array, int start, int end, boolean lowEnd) {
// Three HDeoptimize will be added. One for
@@ -837,14 +837,14 @@ public class Main {
}
- // CHECK-START: void Main.partialLooping(int[], int, int) BCE (before)
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (before)
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
- // CHECK-START: void Main.partialLooping(int[], int, int) BCE (after)
- // CHECK-NOT: Deoptimize
- // CHECK: BoundsCheck
- // CHECK: ArraySet
+ /// CHECK-START: void Main.partialLooping(int[], int, int) BCE (after)
+ /// CHECK-NOT: Deoptimize
+ /// CHECK: BoundsCheck
+ /// CHECK: ArraySet
void partialLooping(int[] array, int start, int end) {
// This loop doesn't cover the full range of [start, end) so
@@ -983,8 +983,8 @@ public class Main {
}
// Make sure this method is compiled with optimizing.
- // CHECK-START: void Main.main(java.lang.String[]) register (after)
- // CHECK: ParallelMove
+ /// CHECK-START: void Main.main(java.lang.String[]) register (after)
+ /// CHECK: ParallelMove
public static void main(String[] args) {
sieve(20);
diff --git a/test/450-checker-types/src/Main.java b/test/450-checker-types/src/Main.java
index 9fbd387850..9bf7cdf496 100644
--- a/test/450-checker-types/src/Main.java
+++ b/test/450-checker-types/src/Main.java
@@ -54,50 +54,50 @@ class SubclassB extends Super {
public class Main {
- // CHECK-START: void Main.testSimpleRemove() instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testSimpleRemove() instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testSimpleRemove() instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testSimpleRemove() instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testSimpleRemove() {
Super s = new SubclassA();
((SubclassA)s).g();
}
- // CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier_after_types (after)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier_after_types (after)
+ /// CHECK: CheckCast
public void testSimpleKeep(Super s) {
((SubclassA)s).f();
}
- // CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public String testClassRemove() {
Object s = SubclassA.class;
return ((Class)s).getName();
}
- // CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier_after_types (after)
- // CHECK: CheckCast
+ /// CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier_after_types (after)
+ /// CHECK: CheckCast
public String testClassKeep() {
Object s = SubclassA.class;
return ((SubclassA)s).h();
}
- // CHECK-START: void Main.testIfRemove(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testIfRemove(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testIfRemove(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testIfRemove(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testIfRemove(int x) {
Super s;
if (x % 2 == 0) {
@@ -108,11 +108,11 @@ public class Main {
((SubclassA)s).g();
}
- // CHECK-START: void Main.testIfKeep(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testIfKeep(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testIfKeep(int) instruction_simplifier_after_types (after)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testIfKeep(int) instruction_simplifier_after_types (after)
+ /// CHECK: CheckCast
public void testIfKeep(int x) {
Super s;
if (x % 2 == 0) {
@@ -123,11 +123,11 @@ public class Main {
((SubclassA)s).g();
}
- // CHECK-START: void Main.testForRemove(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testForRemove(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testForRemove(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testForRemove(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testForRemove(int x) {
Super s = new SubclassA();
for (int i = 0 ; i < x; i++) {
@@ -138,11 +138,11 @@ public class Main {
((SubclassA)s).g();
}
- // CHECK-START: void Main.testForKeep(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testForKeep(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testForKeep(int) instruction_simplifier_after_types (after)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testForKeep(int) instruction_simplifier_after_types (after)
+ /// CHECK: CheckCast
public void testForKeep(int x) {
Super s = new SubclassA();
for (int i = 0 ; i < x; i++) {
@@ -153,11 +153,11 @@ public class Main {
((SubclassC)s).g();
}
- // CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier_after_types (after)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier_after_types (after)
+ /// CHECK: CheckCast
public void testPhiFromCall(int i) {
Object x;
if (i % 2 == 0) {
@@ -168,12 +168,12 @@ public class Main {
((SubclassC)x).g();
}
- // CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOf(Object o) {
if (o instanceof SubclassC) {
((SubclassC)o).g();
@@ -183,13 +183,13 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier_after_types (after)
- // CHECK: CheckCast
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier_after_types (after)
+ /// CHECK: CheckCast
+ /// CHECK: CheckCast
public void testInstanceOfKeep(Object o) {
if (o instanceof SubclassC) {
((SubclassB)o).g();
@@ -199,12 +199,12 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOfNested(Object o) {
if (o instanceof SubclassC) {
if (o instanceof SubclassB) {
@@ -215,11 +215,11 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOfWithPhi(int i) {
Object o;
if (i == 0) {
@@ -233,11 +233,11 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOfInFor(int n) {
Object o = new SubclassA();
for (int i = 0; i < n; i++) {
@@ -250,11 +250,11 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOfSubclass() {
Object o = new SubclassA();
if (o instanceof Super) {
@@ -262,11 +262,11 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOfWithPhiSubclass(int i) {
Object o;
if (i == 0) {
@@ -280,11 +280,11 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOfWithPhiTop(int i) {
Object o;
if (i == 0) {
@@ -298,11 +298,11 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOfSubclassInFor(int n) {
Object o = new SubclassA();
for (int i = 0; i < n; i++) {
@@ -315,11 +315,11 @@ public class Main {
}
}
- // CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier_after_types (before)
- // CHECK: CheckCast
+ /// CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier_after_types (before)
+ /// CHECK: CheckCast
- // CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier_after_types (after)
- // CHECK-NOT: CheckCast
+ /// CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier_after_types (after)
+ /// CHECK-NOT: CheckCast
public void testInstanceOfTopInFor(int n) {
Object o = new SubclassA();
for (int i = 0; i < n; i++) {
diff --git a/test/455-checker-gvn/src/Main.java b/test/455-checker-gvn/src/Main.java
index e94fc46654..9824f27815 100644
--- a/test/455-checker-gvn/src/Main.java
+++ b/test/455-checker-gvn/src/Main.java
@@ -19,15 +19,15 @@ public class Main {
System.out.println(foo(3, 4));
}
- // CHECK-START: int Main.foo(int, int) GVN (before)
- // CHECK: Add
- // CHECK: Add
- // CHECK: Add
+ /// CHECK-START: int Main.foo(int, int) GVN (before)
+ /// CHECK: Add
+ /// CHECK: Add
+ /// CHECK: Add
- // CHECK-START: int Main.foo(int, int) GVN (after)
- // CHECK: Add
- // CHECK: Add
- // CHECK-NOT: Add
+ /// CHECK-START: int Main.foo(int, int) GVN (after)
+ /// CHECK: Add
+ /// CHECK: Add
+ /// CHECK-NOT: Add
public static int foo(int x, int y) {
int sum1 = x + y;
diff --git a/test/458-checker-instruction-simplification/src/Main.java b/test/458-checker-instruction-simplification/src/Main.java
index 742210c8fd..ad5fc8ef93 100644
--- a/test/458-checker-instruction-simplification/src/Main.java
+++ b/test/458-checker-instruction-simplification/src/Main.java
@@ -50,296 +50,296 @@ public class Main {
* Tiny programs exercising optimizations of arithmetic identities.
*/
- // CHECK-START: long Main.Add0(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-DAG: <<Add:j\d+>> Add [<<Const0>>,<<Arg>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: long Main.Add0(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-DAG: <<Add:j\d+>> Add [<<Const0>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Add>>]
- // CHECK-START: long Main.Add0(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.Add0(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.Add0(long) instruction_simplifier (after)
- // CHECK-NOT: Add
+ /// CHECK-START: long Main.Add0(long) instruction_simplifier (after)
+ /// CHECK-NOT: Add
public static long Add0(long arg) {
return 0 + arg;
}
- // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
- // CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<ConstF>>]
- // CHECK-DAG: Return [<<And>>]
+ /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
+ /// CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<ConstF>>]
+ /// CHECK-DAG: Return [<<And>>]
- // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
- // CHECK-NOT: And
+ /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
+ /// CHECK-NOT: And
public static int AndAllOnes(int arg) {
return arg & -1;
}
- // CHECK-START: long Main.Div1(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const1:j\d+>> LongConstant 1
- // CHECK-DAG: <<Div:j\d+>> Div [<<Arg>>,<<Const1>>]
- // CHECK-DAG: Return [<<Div>>]
+ /// CHECK-START: long Main.Div1(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1
+ /// CHECK-DAG: <<Div:j\d+>> Div [<<Arg>>,<<Const1>>]
+ /// CHECK-DAG: Return [<<Div>>]
- // CHECK-START: long Main.Div1(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.Div1(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.Div1(long) instruction_simplifier (after)
- // CHECK-NOT: Div
+ /// CHECK-START: long Main.Div1(long) instruction_simplifier (after)
+ /// CHECK-NOT: Div
public static long Div1(long arg) {
return arg / 1;
}
- // CHECK-START: int Main.DivN1(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
- // CHECK-DAG: <<Div:i\d+>> Div [<<Arg>>,<<ConstN1>>]
- // CHECK-DAG: Return [<<Div>>]
+ /// CHECK-START: int Main.DivN1(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
+ /// CHECK-DAG: <<Div:i\d+>> Div [<<Arg>>,<<ConstN1>>]
+ /// CHECK-DAG: Return [<<Div>>]
- // CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
- // CHECK-DAG: Return [<<Neg>>]
+ /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
+ /// CHECK-DAG: Return [<<Neg>>]
- // CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
- // CHECK-NOT: Div
+ /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
+ /// CHECK-NOT: Div
public static int DivN1(int arg) {
return arg / -1;
}
- // CHECK-START: long Main.Mul1(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const1:j\d+>> LongConstant 1
- // CHECK-DAG: <<Mul:j\d+>> Mul [<<Arg>>,<<Const1>>]
- // CHECK-DAG: Return [<<Mul>>]
+ /// CHECK-START: long Main.Mul1(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1
+ /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Arg>>,<<Const1>>]
+ /// CHECK-DAG: Return [<<Mul>>]
- // CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
- // CHECK-NOT: Mul
+ /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
+ /// CHECK-NOT: Mul
public static long Mul1(long arg) {
return arg * 1;
}
- // CHECK-START: int Main.MulN1(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
- // CHECK-DAG: <<Mul:i\d+>> Mul [<<Arg>>,<<ConstN1>>]
- // CHECK-DAG: Return [<<Mul>>]
+ /// CHECK-START: int Main.MulN1(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
+ /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Arg>>,<<ConstN1>>]
+ /// CHECK-DAG: Return [<<Mul>>]
- // CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
- // CHECK-DAG: Return [<<Neg>>]
+ /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
+ /// CHECK-DAG: Return [<<Neg>>]
- // CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
- // CHECK-NOT: Mul
+ /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
+ /// CHECK-NOT: Mul
public static int MulN1(int arg) {
return arg * -1;
}
- // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const128:j\d+>> LongConstant 128
- // CHECK-DAG: <<Mul:j\d+>> Mul [<<Arg>>,<<Const128>>]
- // CHECK-DAG: Return [<<Mul>>]
+ /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const128:j\d+>> LongConstant 128
+ /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Arg>>,<<Const128>>]
+ /// CHECK-DAG: Return [<<Mul>>]
- // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const7:i\d+>> IntConstant 7
- // CHECK-DAG: <<Shl:j\d+>> Shl [<<Arg>>,<<Const7>>]
- // CHECK-DAG: Return [<<Shl>>]
+ /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
+ /// CHECK-DAG: <<Shl:j\d+>> Shl [<<Arg>>,<<Const7>>]
+ /// CHECK-DAG: Return [<<Shl>>]
- // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
- // CHECK-NOT: Mul
+ /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
+ /// CHECK-NOT: Mul
public static long MulPowerOfTwo128(long arg) {
return arg * 128;
}
- // CHECK-START: int Main.Or0(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Or:i\d+>> Or [<<Arg>>,<<Const0>>]
- // CHECK-DAG: Return [<<Or>>]
+ /// CHECK-START: int Main.Or0(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<Or>>]
- // CHECK-START: int Main.Or0(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: int Main.Or0(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: int Main.Or0(int) instruction_simplifier (after)
- // CHECK-NOT: Or
+ /// CHECK-START: int Main.Or0(int) instruction_simplifier (after)
+ /// CHECK-NOT: Or
public static int Or0(int arg) {
return arg | 0;
}
- // CHECK-START: long Main.OrSame(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Or:j\d+>> Or [<<Arg>>,<<Arg>>]
- // CHECK-DAG: Return [<<Or>>]
+ /// CHECK-START: long Main.OrSame(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Or:j\d+>> Or [<<Arg>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Or>>]
- // CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
- // CHECK-NOT: Or
+ /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
+ /// CHECK-NOT: Or
public static long OrSame(long arg) {
return arg | arg;
}
- // CHECK-START: int Main.Shl0(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const0>>]
- // CHECK-DAG: Return [<<Shl>>]
+ /// CHECK-START: int Main.Shl0(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<Shl>>]
- // CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
- // CHECK-NOT: Shl
+ /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
+ /// CHECK-NOT: Shl
public static int Shl0(int arg) {
return arg << 0;
}
- // CHECK-START: int Main.Shl1(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const1>>]
- // CHECK-DAG: Return [<<Shl>>]
+ /// CHECK-START: int Main.Shl1(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const1>>]
+ /// CHECK-DAG: Return [<<Shl>>]
- // CHECK-START: int Main.Shl1(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Add:i\d+>> Add [<<Arg>>,<<Arg>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: int Main.Shl1(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Add>>]
- // CHECK-START: int Main.Shl1(int) instruction_simplifier (after)
- // CHECK-NOT: Shl
+ /// CHECK-START: int Main.Shl1(int) instruction_simplifier (after)
+ /// CHECK-NOT: Shl
public static int Shl1(int arg) {
return arg << 1;
}
- // CHECK-START: long Main.Shr0(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const0>>]
- // CHECK-DAG: Return [<<Shr>>]
+ /// CHECK-START: long Main.Shr0(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<Shr>>]
- // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
- // CHECK-NOT: Shr
+ /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
+ /// CHECK-NOT: Shr
public static long Shr0(long arg) {
return arg >> 0;
}
- // CHECK-START: long Main.Sub0(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg>>,<<Const0>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: long Main.Sub0(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
- // CHECK-NOT: Sub
+ /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
+ /// CHECK-NOT: Sub
public static long Sub0(long arg) {
return arg - 0;
}
- // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Const0>>,<<Arg>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const0>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
- // CHECK-DAG: Return [<<Neg>>]
+ /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
+ /// CHECK-DAG: Return [<<Neg>>]
- // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
- // CHECK-NOT: Sub
+ /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
+ /// CHECK-NOT: Sub
public static int SubAliasNeg(int arg) {
return 0 - arg;
}
- // CHECK-START: long Main.UShr0(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const0>>]
- // CHECK-DAG: Return [<<UShr>>]
+ /// CHECK-START: long Main.UShr0(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<UShr>>]
- // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
- // CHECK-NOT: UShr
+ /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
+ /// CHECK-NOT: UShr
public static long UShr0(long arg) {
return arg >>> 0;
}
- // CHECK-START: int Main.Xor0(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<Const0>>]
- // CHECK-DAG: Return [<<Xor>>]
+ /// CHECK-START: int Main.Xor0(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<Xor>>]
- // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
- // CHECK-NOT: Xor
+ /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
+ /// CHECK-NOT: Xor
public static int Xor0(int arg) {
return arg ^ 0;
}
- // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
- // CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<ConstF>>]
- // CHECK-DAG: Return [<<Xor>>]
+ /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
+ /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<ConstF>>]
+ /// CHECK-DAG: Return [<<Xor>>]
- // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>]
- // CHECK-DAG: Return [<<Not>>]
+ /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>]
+ /// CHECK-DAG: Return [<<Not>>]
- // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
- // CHECK-NOT: Xor
+ /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
+ /// CHECK-NOT: Xor
public static int XorAllOnes(int arg) {
return arg ^ -1;
@@ -352,21 +352,21 @@ public class Main {
* `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
*/
- // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
- // CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK-DAG: Return [<<Add>>]
-
- // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-NOT: Neg
- // CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>]
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>]
- // CHECK-DAG: Return [<<Neg>>]
+ /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK-DAG: Return [<<Add>>]
+
+ /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-NOT: Neg
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>]
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>]
+ /// CHECK-DAG: Return [<<Neg>>]
public static int AddNegs1(int arg1, int arg2) {
return -arg1 + -arg2;
@@ -383,35 +383,35 @@ public class Main {
* increasing the register pressure by creating or extending live ranges.
*/
- // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
- // CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>]
- // CHECK-DAG: Return [<<Or>>]
-
- // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
- // CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK-NOT: Neg
- // CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>]
- // CHECK-DAG: Return [<<Or>>]
-
- // CHECK-START: int Main.AddNegs2(int, int) GVN (after)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
- // CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK-DAG: <<Or:i\d+>> Or [<<Add>>,<<Add>>]
- // CHECK-DAG: Return [<<Or>>]
+ /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>]
+ /// CHECK-DAG: Return [<<Or>>]
+
+ /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
+ /// CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK-NOT: Neg
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>]
+ /// CHECK-DAG: Return [<<Or>>]
+
+ /// CHECK-START: int Main.AddNegs2(int, int) GVN (after)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Add>>,<<Add>>]
+ /// CHECK-DAG: Return [<<Or>>]
public static int AddNegs2(int arg1, int arg2) {
int temp1 = -arg1;
@@ -427,30 +427,30 @@ public class Main {
* the loop.
*/
- // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
- // -------------- Arguments and initial negation operations.
- // CHECK-DAG: <<Arg1:j\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:j\d+>> ParameterValue
- // CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>]
- // CHECK: Goto
- // -------------- Loop
- // CHECK: SuspendCheck
- // CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK: Goto
-
- // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
- // -------------- Arguments and initial negation operations.
- // CHECK-DAG: <<Arg1:j\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:j\d+>> ParameterValue
- // CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>]
- // CHECK: Goto
- // -------------- Loop
- // CHECK: SuspendCheck
- // CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK-NOT: Neg
- // CHECK: Goto
+ /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
+ // -------------- Arguments and initial negation operations.
+ /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>]
+ /// CHECK: Goto
+ // -------------- Loop
+ /// CHECK: SuspendCheck
+ /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK: Goto
+
+ /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
+ // -------------- Arguments and initial negation operations.
+ /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>]
+ /// CHECK: Goto
+ // -------------- Loop
+ /// CHECK: SuspendCheck
+ /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK-NOT: Neg
+ /// CHECK: Goto
public static long AddNegs3(long arg1, long arg2) {
long res = 0;
@@ -468,22 +468,22 @@ public class Main {
* The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
*/
- // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg1:j\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:j\d+>> ParameterValue
- // CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Add:j\d+>> Add [<<Neg>>,<<Arg2>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Add:j\d+>> Add [<<Neg>>,<<Arg2>>]
+ /// CHECK-DAG: Return [<<Add>>]
- // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg1:j\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:j\d+>> ParameterValue
- // CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg2>>,<<Arg1>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg2>>,<<Arg1>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
- // CHECK-NOT: Neg
- // CHECK-NOT: Add
+ /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
+ /// CHECK-NOT: Neg
+ /// CHECK-NOT: Add
public static long AddNeg1(long arg1, long arg2) {
return -arg1 + arg2;
@@ -498,26 +498,26 @@ public class Main {
* increasing the register pressure by creating or extending live ranges.
*/
- // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg1:j\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:j\d+>> ParameterValue
- // CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>]
- // CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>]
- // CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>]
- // CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>]
- // CHECK-DAG: Return [<<Res>>]
-
- // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg1:j\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:j\d+>> ParameterValue
- // CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>]
- // CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>]
- // CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>]
- // CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>]
- // CHECK-DAG: Return [<<Res>>]
-
- // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
- // CHECK-NOT: Sub
+ /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>]
+ /// CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>]
+ /// CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>]
+ /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>]
+ /// CHECK-DAG: Return [<<Res>>]
+
+ /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>]
+ /// CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>]
+ /// CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>]
+ /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>]
+ /// CHECK-DAG: Return [<<Res>>]
+
+ /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
+ /// CHECK-NOT: Sub
public static long AddNeg2(long arg1, long arg2) {
long temp = -arg2;
@@ -529,18 +529,18 @@ public class Main {
* The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
*/
- // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg>>]
- // CHECK-DAG: <<Neg2:j\d+>> Neg [<<Neg1>>]
- // CHECK-DAG: Return [<<Neg2>>]
+ /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg>>]
+ /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Neg1>>]
+ /// CHECK-DAG: Return [<<Neg2>>]
- // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
- // CHECK-NOT: Neg
+ /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
+ /// CHECK-NOT: Neg
public static long NegNeg1(long arg) {
return -(-arg);
@@ -553,27 +553,27 @@ public class Main {
* and in `InstructionSimplifierVisitor::VisitAdd`.
*/
- // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg>>]
- // CHECK-DAG: <<Neg2:i\d+>> Neg [<<Neg1>>]
- // CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg>>]
+ /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Neg1>>]
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
+ /// CHECK-DAG: Return [<<Add>>]
- // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg>>,<<Arg>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
- // CHECK-NOT: Neg
- // CHECK-NOT: Add
+ /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
+ /// CHECK-NOT: Neg
+ /// CHECK-NOT: Add
- // CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after)
- // CHECK: <<Const0:i\d+>> IntConstant 0
- // CHECK-NOT: Neg
- // CHECK-NOT: Add
- // CHECK: Return [<<Const0>>]
+ /// CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after)
+ /// CHECK: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-NOT: Neg
+ /// CHECK-NOT: Add
+ /// CHECK: Return [<<Const0>>]
public static int NegNeg2(int arg) {
int temp = -arg;
@@ -587,20 +587,20 @@ public class Main {
* and in `InstructionSimplifierVisitor::VisitSub`.
*/
- // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<Const0:j\d+>> LongConstant 0
- // CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg>>]
- // CHECK-DAG: <<Sub:j\d+>> Sub [<<Const0>>,<<Neg>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
+ /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg>>]
+ /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Const0>>,<<Neg>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
- // CHECK-NOT: Neg
- // CHECK-NOT: Sub
+ /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
+ /// CHECK-NOT: Neg
+ /// CHECK-NOT: Sub
public static long NegNeg3(long arg) {
return 0 - -arg;
@@ -612,21 +612,21 @@ public class Main {
* The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
*/
- // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Sub>>]
- // CHECK-DAG: Return [<<Neg>>]
+ /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Sub>>]
+ /// CHECK-DAG: Return [<<Neg>>]
- // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg2>>,<<Arg1>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg2>>,<<Arg1>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
- // CHECK-NOT: Neg
+ /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
+ /// CHECK-NOT: Neg
public static int NegSub1(int arg1, int arg2) {
return -(arg1 - arg2);
@@ -642,23 +642,23 @@ public class Main {
* increasing the register pressure by creating or extending live ranges.
*/
- // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
- // CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>]
- // CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>]
- // CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>]
- // CHECK-DAG: Return [<<Or>>]
-
- // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
- // CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>]
- // CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>]
- // CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>]
- // CHECK-DAG: Return [<<Or>>]
+ /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
+ /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>]
+ /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>]
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>]
+ /// CHECK-DAG: Return [<<Or>>]
+
+ /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
+ /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>]
+ /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>]
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>]
+ /// CHECK-DAG: Return [<<Or>>]
public static int NegSub2(int arg1, int arg2) {
int temp = arg1 - arg2;
@@ -670,40 +670,40 @@ public class Main {
* The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
*/
- // CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: <<ConstF1:j\d+>> LongConstant -1
- // CHECK-DAG: <<Xor1:j\d+>> Xor [<<Arg>>,<<ConstF1>>]
- // CHECK-DAG: <<Xor2:j\d+>> Xor [<<Xor1>>,<<ConstF1>>]
- // CHECK-DAG: Return [<<Xor2>>]
+ /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstF1:j\d+>> LongConstant -1
+ /// CHECK-DAG: <<Xor1:j\d+>> Xor [<<Arg>>,<<ConstF1>>]
+ /// CHECK-DAG: <<Xor2:j\d+>> Xor [<<Xor1>>,<<ConstF1>>]
+ /// CHECK-DAG: Return [<<Xor2>>]
- // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:j\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
- // CHECK-NOT: Xor
+ /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
+ /// CHECK-NOT: Xor
public static long NotNot1(long arg) {
return ~~arg;
}
- // CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<ConstF1:i\d+>> IntConstant -1
- // CHECK-DAG: <<Xor1:i\d+>> Xor [<<Arg>>,<<ConstF1>>]
- // CHECK-DAG: <<Xor2:i\d+>> Xor [<<Xor1>>,<<ConstF1>>]
- // CHECK-DAG: <<Add:i\d+>> Add [<<Xor1>>,<<Xor2>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstF1:i\d+>> IntConstant -1
+ /// CHECK-DAG: <<Xor1:i\d+>> Xor [<<Arg>>,<<ConstF1>>]
+ /// CHECK-DAG: <<Xor2:i\d+>> Xor [<<Xor1>>,<<ConstF1>>]
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Xor1>>,<<Xor2>>]
+ /// CHECK-DAG: Return [<<Add>>]
- // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>]
- // CHECK-DAG: <<Add:i\d+>> Add [<<Not>>,<<Arg>>]
- // CHECK-DAG: Return [<<Add>>]
+ /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>]
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Not>>,<<Arg>>]
+ /// CHECK-DAG: Return [<<Add>>]
- // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
- // CHECK-NOT: Xor
+ /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
+ /// CHECK-NOT: Xor
public static int NotNot2(int arg) {
int temp = ~arg;
@@ -715,22 +715,22 @@ public class Main {
* The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
*/
- // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<Neg>>,<<Arg2>>]
- // CHECK-DAG: Return [<<Sub>>]
+ /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Neg>>,<<Arg2>>]
+ /// CHECK-DAG: Return [<<Sub>>]
- // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>]
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>]
- // CHECK-DAG: Return [<<Neg>>]
+ /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>]
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>]
+ /// CHECK-DAG: Return [<<Neg>>]
- // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
- // CHECK-NOT: Sub
+ /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
+ /// CHECK-NOT: Sub
public static int SubNeg1(int arg1, int arg2) {
return -arg1 - arg2;
@@ -746,26 +746,26 @@ public class Main {
* increasing the register pressure by creating or extending live ranges.
*/
- // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>]
- // CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>]
- // CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>]
- // CHECK-DAG: Return [<<Or>>]
-
- // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
- // CHECK-DAG: <<Arg1:i\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:i\d+>> ParameterValue
- // CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>]
- // CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>]
- // CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>]
- // CHECK-DAG: Return [<<Or>>]
-
- // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
- // CHECK-NOT: Add
+ /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>]
+ /// CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>]
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>]
+ /// CHECK-DAG: Return [<<Or>>]
+
+ /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>]
+ /// CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>]
+ /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>]
+ /// CHECK-DAG: Return [<<Or>>]
+
+ /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
+ /// CHECK-NOT: Add
public static int SubNeg2(int arg1, int arg2) {
int temp = -arg1;
@@ -779,28 +779,28 @@ public class Main {
* the loop.
*/
- // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
- // -------------- Arguments and initial negation operation.
- // CHECK-DAG: <<Arg1:j\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:j\d+>> ParameterValue
- // CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
- // CHECK: Goto
- // -------------- Loop
- // CHECK: SuspendCheck
- // CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>]
- // CHECK: Goto
-
- // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
- // -------------- Arguments and initial negation operation.
- // CHECK-DAG: <<Arg1:j\d+>> ParameterValue
- // CHECK-DAG: <<Arg2:j\d+>> ParameterValue
- // CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
- // CHECK-DAG: Goto
- // -------------- Loop
- // CHECK: SuspendCheck
- // CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>]
- // CHECK-NOT: Neg
- // CHECK: Goto
+ /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
+ // -------------- Arguments and initial negation operation.
+ /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
+ /// CHECK: Goto
+ // -------------- Loop
+ /// CHECK: SuspendCheck
+ /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>]
+ /// CHECK: Goto
+
+ /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
+ // -------------- Arguments and initial negation operation.
+ /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
+ /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
+ /// CHECK-DAG: Goto
+ // -------------- Loop
+ /// CHECK: SuspendCheck
+ /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>]
+ /// CHECK-NOT: Neg
+ /// CHECK: Goto
public static long SubNeg3(long arg1, long arg2) {
long res = 0;
@@ -811,117 +811,117 @@ public class Main {
return res;
}
- // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Cond:z\d+>> Equal [<<Arg>>,<<Const1>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Arg>>,<<Const1>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: If [<<Arg>>]
+ /// CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: If [<<Arg>>]
public static int EqualTrueRhs(boolean arg) {
return (arg != true) ? 3 : 5;
}
- // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Cond:z\d+>> Equal [<<Const1>>,<<Arg>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Const1>>,<<Arg>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: If [<<Arg>>]
+ /// CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: If [<<Arg>>]
public static int EqualTrueLhs(boolean arg) {
return (true != arg) ? 3 : 5;
}
- // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Cond:z\d+>> Equal [<<Arg>>,<<Const0>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
- // CHECK-DAG: If [<<NotArg>>]
+ /// CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
+ /// CHECK-DAG: If [<<NotArg>>]
public static int EqualFalseRhs(boolean arg) {
return (arg != false) ? 3 : 5;
}
- // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Cond:z\d+>> Equal [<<Const0>>,<<Arg>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Const0>>,<<Arg>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
- // CHECK-DAG: If [<<NotArg>>]
+ /// CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
+ /// CHECK-DAG: If [<<NotArg>>]
public static int EqualFalseLhs(boolean arg) {
return (false != arg) ? 3 : 5;
}
- // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Arg>>,<<Const1>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Arg>>,<<Const1>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
- // CHECK-DAG: If [<<NotArg>>]
+ /// CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
+ /// CHECK-DAG: If [<<NotArg>>]
public static int NotEqualTrueRhs(boolean arg) {
return (arg == true) ? 3 : 5;
}
- // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Const1>>,<<Arg>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Const1>>,<<Arg>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
- // CHECK-DAG: If [<<NotArg>>]
+ /// CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
+ /// CHECK-DAG: If [<<NotArg>>]
public static int NotEqualTrueLhs(boolean arg) {
return (true == arg) ? 3 : 5;
}
- // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Arg>>,<<Const0>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Arg>>,<<Const0>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: If [<<Arg>>]
+ /// CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: If [<<Arg>>]
public static int NotEqualFalseRhs(boolean arg) {
return (arg == false) ? 3 : 5;
}
- // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Const0>>,<<Arg>>]
- // CHECK-DAG: If [<<Cond>>]
+ /// CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Const0>>,<<Arg>>]
+ /// CHECK-DAG: If [<<Cond>>]
- // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: If [<<Arg>>]
+ /// CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: If [<<Arg>>]
public static int NotEqualFalseLhs(boolean arg) {
return (false == arg) ? 3 : 5;
@@ -933,20 +933,20 @@ public class Main {
* remove the second.
*/
- // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (before)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
- // CHECK-DAG: <<NotNotArg:z\d+>> BooleanNot [<<NotArg>>]
- // CHECK-DAG: Return [<<NotNotArg>>]
+ /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
+ /// CHECK-DAG: <<NotNotArg:z\d+>> BooleanNot [<<NotArg>>]
+ /// CHECK-DAG: Return [<<NotNotArg>>]
- // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
- // CHECK-DAG: <<Arg:z\d+>> ParameterValue
- // CHECK-DAG: BooleanNot [<<Arg>>]
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: BooleanNot [<<Arg>>]
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
- // CHECK: BooleanNot
- // CHECK-NOT: BooleanNot
+ /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
+ /// CHECK: BooleanNot
+ /// CHECK-NOT: BooleanNot
public static boolean NegateValue(boolean arg) {
return !arg;
@@ -956,76 +956,76 @@ public class Main {
return !(NegateValue(arg));
}
- // CHECK-START: float Main.Div2(float) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:f\d+>> ParameterValue
- // CHECK-DAG: <<Const2:f\d+>> FloatConstant 2
- // CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<Const2>>]
- // CHECK-DAG: Return [<<Div>>]
+ /// CHECK-START: float Main.Div2(float) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
+ /// CHECK-DAG: <<Const2:f\d+>> FloatConstant 2
+ /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Div>>]
- // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:f\d+>> ParameterValue
- // CHECK-DAG: <<ConstP5:f\d+>> FloatConstant 0.5
- // CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstP5>>]
- // CHECK-DAG: Return [<<Mul>>]
+ /// CHECK-START: float Main.Div2(float) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstP5:f\d+>> FloatConstant 0.5
+ /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstP5>>]
+ /// CHECK-DAG: Return [<<Mul>>]
- // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
- // CHECK-NOT: Div
+ /// CHECK-START: float Main.Div2(float) instruction_simplifier (after)
+ /// CHECK-NOT: Div
public static float Div2(float arg) {
return arg / 2.0f;
}
- // CHECK-START: double Main.Div2(double) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:d\d+>> ParameterValue
- // CHECK-DAG: <<Const2:d\d+>> DoubleConstant 2
- // CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<Const2>>]
- // CHECK-DAG: Return [<<Div>>]
+ /// CHECK-START: double Main.Div2(double) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
+ /// CHECK-DAG: <<Const2:d\d+>> DoubleConstant 2
+ /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<Const2>>]
+ /// CHECK-DAG: Return [<<Div>>]
- // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:d\d+>> ParameterValue
- // CHECK-DAG: <<ConstP5:d\d+>> DoubleConstant 0.5
- // CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstP5>>]
- // CHECK-DAG: Return [<<Mul>>]
+ /// CHECK-START: double Main.Div2(double) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstP5:d\d+>> DoubleConstant 0.5
+ /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstP5>>]
+ /// CHECK-DAG: Return [<<Mul>>]
- // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
- // CHECK-NOT: Div
+ /// CHECK-START: double Main.Div2(double) instruction_simplifier (after)
+ /// CHECK-NOT: Div
public static double Div2(double arg) {
return arg / 2.0;
}
- // CHECK-START: float Main.DivMP25(float) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:f\d+>> ParameterValue
- // CHECK-DAG: <<ConstMP25:f\d+>> FloatConstant -0.25
- // CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<ConstMP25>>]
- // CHECK-DAG: Return [<<Div>>]
+ /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstMP25:f\d+>> FloatConstant -0.25
+ /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<ConstMP25>>]
+ /// CHECK-DAG: Return [<<Div>>]
- // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:f\d+>> ParameterValue
- // CHECK-DAG: <<ConstM4:f\d+>> FloatConstant -4
- // CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstM4>>]
- // CHECK-DAG: Return [<<Mul>>]
+ /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstM4:f\d+>> FloatConstant -4
+ /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstM4>>]
+ /// CHECK-DAG: Return [<<Mul>>]
- // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
- // CHECK-NOT: Div
+ /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
+ /// CHECK-NOT: Div
public static float DivMP25(float arg) {
return arg / -0.25f;
}
- // CHECK-START: double Main.DivMP25(double) instruction_simplifier (before)
- // CHECK-DAG: <<Arg:d\d+>> ParameterValue
- // CHECK-DAG: <<ConstMP25:d\d+>> DoubleConstant -0.25
- // CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<ConstMP25>>]
- // CHECK-DAG: Return [<<Div>>]
+ /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstMP25:d\d+>> DoubleConstant -0.25
+ /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<ConstMP25>>]
+ /// CHECK-DAG: Return [<<Div>>]
- // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
- // CHECK-DAG: <<Arg:d\d+>> ParameterValue
- // CHECK-DAG: <<ConstM4:d\d+>> DoubleConstant -4
- // CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstM4>>]
- // CHECK-DAG: Return [<<Mul>>]
+ /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
+ /// CHECK-DAG: <<ConstM4:d\d+>> DoubleConstant -4
+ /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstM4>>]
+ /// CHECK-DAG: Return [<<Mul>>]
- // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
- // CHECK-NOT: Div
+ /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
+ /// CHECK-NOT: Div
public static double DivMP25(double arg) {
return arg / -0.25f;
}
diff --git a/test/462-checker-inlining-across-dex-files/src/Main.java b/test/462-checker-inlining-across-dex-files/src/Main.java
index 218c7cee12..64979ca7ab 100644
--- a/test/462-checker-inlining-across-dex-files/src/Main.java
+++ b/test/462-checker-inlining-across-dex-files/src/Main.java
@@ -21,105 +21,105 @@ class AAA {
public class Main {
- // CHECK-START: void Main.inlineEmptyMethod() inliner (before)
- // CHECK-DAG: <<Invoke:v\d+>> InvokeStaticOrDirect
- // CHECK-DAG: ReturnVoid
+ /// CHECK-START: void Main.inlineEmptyMethod() inliner (before)
+ /// CHECK-DAG: <<Invoke:v\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: ReturnVoid
- // CHECK-START: void Main.inlineEmptyMethod() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.inlineEmptyMethod() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static void inlineEmptyMethod() {
OtherDex.emptyMethod();
}
- // CHECK-START: int Main.inlineReturnIntMethod() inliner (before)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.inlineReturnIntMethod() inliner (before)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: int Main.inlineReturnIntMethod() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineReturnIntMethod() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
- // CHECK-START: int Main.inlineReturnIntMethod() inliner (after)
- // CHECK-DAG: <<Const38:i\d+>> IntConstant 38
- // CHECK-DAG: Return [<<Const38>>]
+ /// CHECK-START: int Main.inlineReturnIntMethod() inliner (after)
+ /// CHECK-DAG: <<Const38:i\d+>> IntConstant 38
+ /// CHECK-DAG: Return [<<Const38>>]
public static int inlineReturnIntMethod() {
return OtherDex.returnIntMethod();
}
- // CHECK-START: int Main.dontInlineOtherDexStatic() inliner (before)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.dontInlineOtherDexStatic() inliner (before)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: int Main.dontInlineOtherDexStatic() inliner (after)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.dontInlineOtherDexStatic() inliner (after)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
public static int dontInlineOtherDexStatic() {
return OtherDex.returnOtherDexStatic();
}
- // CHECK-START: int Main.inlineMainStatic() inliner (before)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.inlineMainStatic() inliner (before)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: int Main.inlineMainStatic() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineMainStatic() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
- // CHECK-START: int Main.inlineMainStatic() inliner (after)
- // CHECK-DAG: <<Static:i\d+>> StaticFieldGet
- // CHECK-DAG: Return [<<Static>>]
+ /// CHECK-START: int Main.inlineMainStatic() inliner (after)
+ /// CHECK-DAG: <<Static:i\d+>> StaticFieldGet
+ /// CHECK-DAG: Return [<<Static>>]
public static int inlineMainStatic() {
return OtherDex.returnMainStatic();
}
- // CHECK-START: int Main.dontInlineRecursiveCall() inliner (before)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.dontInlineRecursiveCall() inliner (before)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: int Main.dontInlineRecursiveCall() inliner (after)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.dontInlineRecursiveCall() inliner (after)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
public static int dontInlineRecursiveCall() {
return OtherDex.recursiveCall();
}
- // CHECK-START: java.lang.String Main.dontInlineReturnString() inliner (before)
- // CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: java.lang.String Main.dontInlineReturnString() inliner (before)
+ /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: java.lang.String Main.dontInlineReturnString() inliner (after)
- // CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: java.lang.String Main.dontInlineReturnString() inliner (after)
+ /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
public static String dontInlineReturnString() {
return OtherDex.returnString();
}
- // CHECK-START: java.lang.Class Main.dontInlineOtherDexClass() inliner (before)
- // CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: java.lang.Class Main.dontInlineOtherDexClass() inliner (before)
+ /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: java.lang.Class Main.dontInlineOtherDexClass() inliner (after)
- // CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: java.lang.Class Main.dontInlineOtherDexClass() inliner (after)
+ /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
public static Class dontInlineOtherDexClass() {
return OtherDex.returnOtherDexClass();
}
- // CHECK-START: java.lang.Class Main.inlineMainClass() inliner (before)
- // CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (before)
+ /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: java.lang.Class Main.inlineMainClass() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
- // CHECK-START: java.lang.Class Main.inlineMainClass() inliner (after)
- // CHECK-DAG: Return [<<Class:l\d+>>]
- // CHECK-DAG: <<Class>> LoadClass
+ /// CHECK-START: java.lang.Class Main.inlineMainClass() inliner (after)
+ /// CHECK-DAG: Return [<<Class:l\d+>>]
+ /// CHECK-DAG: <<Class>> LoadClass
// Note: There are two LoadClass instructions. We obtain the correct
// instruction id by matching the Return's input list first.
@@ -127,28 +127,28 @@ public class Main {
return OtherDex.returnMainClass();
}
- // CHECK-START: java.lang.Class Main.dontInlineOtherDexClassStaticCall() inliner (before)
- // CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: java.lang.Class Main.dontInlineOtherDexClassStaticCall() inliner (before)
+ /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: java.lang.Class Main.dontInlineOtherDexClassStaticCall() inliner (after)
- // CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: java.lang.Class Main.dontInlineOtherDexClassStaticCall() inliner (after)
+ /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
public static Class dontInlineOtherDexClassStaticCall() {
return OtherDex.returnOtherDexClassStaticCall();
}
- // CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (before)
- // CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (before)
+ /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
- // CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (after)
- // CHECK-DAG: Return [<<Class:l\d+>>]
- // CHECK-DAG: <<Class>> LoadClass
+ /// CHECK-START: java.lang.Class Main.inlineOtherDexCallingMain() inliner (after)
+ /// CHECK-DAG: Return [<<Class:l\d+>>]
+ /// CHECK-DAG: <<Class>> LoadClass
// Note: There are two LoadClass instructions. We obtain the correct
// instruction id by matching the Return's input list first.
diff --git a/test/463-checker-boolean-simplifier/src/Main.java b/test/463-checker-boolean-simplifier/src/Main.java
index e2374480c6..0b75930146 100644
--- a/test/463-checker-boolean-simplifier/src/Main.java
+++ b/test/463-checker-boolean-simplifier/src/Main.java
@@ -37,33 +37,33 @@ public class Main {
* empty branches removed.
*/
- // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (before)
- // CHECK-DAG: <<Param:z\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: If [<<Param>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Const1>>,<<Const0>>]
- // CHECK-DAG: Return [<<Phi>>]
-
- // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (before)
- // CHECK: Goto
- // CHECK: Goto
- // CHECK: Goto
- // CHECK-NOT: Goto
-
- // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
- // CHECK-DAG: <<Param:z\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<NotParam:z\d+>> BooleanNot [<<Param>>]
- // CHECK-DAG: Return [<<NotParam>>]
-
- // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
- // CHECK-NOT: If
- // CHECK-NOT: Phi
-
- // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
- // CHECK: Goto
- // CHECK-NOT: Goto
+ /// CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (before)
+ /// CHECK-DAG: <<Param:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: If [<<Param>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const1>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ /// CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (before)
+ /// CHECK: Goto
+ /// CHECK: Goto
+ /// CHECK: Goto
+ /// CHECK-NOT: Goto
+
+ /// CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
+ /// CHECK-DAG: <<Param:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<NotParam:z\d+>> BooleanNot [<<Param>>]
+ /// CHECK-DAG: Return [<<NotParam>>]
+
+ /// CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
+ /// CHECK-NOT: If
+ /// CHECK-NOT: Phi
+
+ /// CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
+ /// CHECK: Goto
+ /// CHECK-NOT: Goto
public static boolean BooleanNot(boolean x) {
return !x;
@@ -74,23 +74,23 @@ public class Main {
* and 0 when False.
*/
- // CHECK-START: boolean Main.GreaterThan(int, int) boolean_simplifier (before)
- // CHECK-DAG: <<ParamX:i\d+>> ParameterValue
- // CHECK-DAG: <<ParamY:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Cond:z\d+>> GreaterThan [<<ParamX>>,<<ParamY>>]
- // CHECK-DAG: If [<<Cond>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0>>,<<Const1>>]
- // CHECK-DAG: Return [<<Phi>>]
-
- // CHECK-START: boolean Main.GreaterThan(int, int) boolean_simplifier (after)
- // CHECK-DAG: <<ParamX:i\d+>> ParameterValue
- // CHECK-DAG: <<ParamY:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Cond:z\d+>> GreaterThan [<<ParamX>>,<<ParamY>>]
- // CHECK-DAG: Return [<<Cond>>]
+ /// CHECK-START: boolean Main.GreaterThan(int, int) boolean_simplifier (before)
+ /// CHECK-DAG: <<ParamX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ParamY:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Cond:z\d+>> GreaterThan [<<ParamX>>,<<ParamY>>]
+ /// CHECK-DAG: If [<<Cond>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0>>,<<Const1>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ /// CHECK-START: boolean Main.GreaterThan(int, int) boolean_simplifier (after)
+ /// CHECK-DAG: <<ParamX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ParamY:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Cond:z\d+>> GreaterThan [<<ParamX>>,<<ParamY>>]
+ /// CHECK-DAG: Return [<<Cond>>]
public static boolean GreaterThan(int x, int y) {
return (x <= y) ? false : true;
@@ -101,26 +101,26 @@ public class Main {
* and 1 when False.
*/
- // CHECK-START: boolean Main.LessThan(int, int) boolean_simplifier (before)
- // CHECK-DAG: <<ParamX:i\d+>> ParameterValue
- // CHECK-DAG: <<ParamY:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Cond:z\d+>> GreaterThanOrEqual [<<ParamX>>,<<ParamY>>]
- // CHECK-DAG: If [<<Cond>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Const1>>,<<Const0>>]
- // CHECK-DAG: Return [<<Phi>>]
-
- // CHECK-START: boolean Main.LessThan(int, int) boolean_simplifier (after)
- // CHECK-DAG: <<ParamX:i\d+>> ParameterValue
- // CHECK-DAG: <<ParamY:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<Cond:z\d+>> LessThan [<<ParamX>>,<<ParamY>>]
- // CHECK-DAG: Return [<<Cond>>]
-
- // CHECK-START: boolean Main.LessThan(int, int) boolean_simplifier (after)
- // CHECK-NOT: GreaterThanOrEqual
+ /// CHECK-START: boolean Main.LessThan(int, int) boolean_simplifier (before)
+ /// CHECK-DAG: <<ParamX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ParamY:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Cond:z\d+>> GreaterThanOrEqual [<<ParamX>>,<<ParamY>>]
+ /// CHECK-DAG: If [<<Cond>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const1>>,<<Const0>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ /// CHECK-START: boolean Main.LessThan(int, int) boolean_simplifier (after)
+ /// CHECK-DAG: <<ParamX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ParamY:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Cond:z\d+>> LessThan [<<ParamX>>,<<ParamY>>]
+ /// CHECK-DAG: Return [<<Cond>>]
+
+ /// CHECK-START: boolean Main.LessThan(int, int) boolean_simplifier (after)
+ /// CHECK-NOT: GreaterThanOrEqual
public static boolean LessThan(int x, int y) {
return (x < y) ? true : false;
@@ -131,57 +131,57 @@ public class Main {
* Note that Phis are discovered retrospectively.
*/
- // CHECK-START: boolean Main.ValuesOrdered(int, int, int) boolean_simplifier (before)
- // CHECK-DAG: <<ParamX:i\d+>> ParameterValue
- // CHECK-DAG: <<ParamY:i\d+>> ParameterValue
- // CHECK-DAG: <<ParamZ:i\d+>> ParameterValue
- // CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- // CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- // CHECK-DAG: <<CondXY:z\d+>> GreaterThan [<<ParamX>>,<<ParamY>>]
- // CHECK-DAG: If [<<CondXY>>]
- // CHECK-DAG: <<CondYZ:z\d+>> GreaterThan [<<ParamY>>,<<ParamZ>>]
- // CHECK-DAG: If [<<CondYZ>>]
- // CHECK-DAG: <<CondXYZ:z\d+>> NotEqual [<<PhiXY:i\d+>>,<<PhiYZ:i\d+>>]
- // CHECK-DAG: If [<<CondXYZ>>]
- // CHECK-DAG: Return [<<PhiXYZ:i\d+>>]
- // CHECK-DAG: <<PhiXY>> Phi [<<Const1>>,<<Const0>>]
- // CHECK-DAG: <<PhiYZ>> Phi [<<Const1>>,<<Const0>>]
- // CHECK-DAG: <<PhiXYZ>> Phi [<<Const1>>,<<Const0>>]
-
- // CHECK-START: boolean Main.ValuesOrdered(int, int, int) boolean_simplifier (after)
- // CHECK-DAG: <<ParamX:i\d+>> ParameterValue
- // CHECK-DAG: <<ParamY:i\d+>> ParameterValue
- // CHECK-DAG: <<ParamZ:i\d+>> ParameterValue
- // CHECK-DAG: <<CmpXY:z\d+>> LessThanOrEqual [<<ParamX>>,<<ParamY>>]
- // CHECK-DAG: <<CmpYZ:z\d+>> LessThanOrEqual [<<ParamY>>,<<ParamZ>>]
- // CHECK-DAG: <<CmpXYZ:z\d+>> Equal [<<CmpXY>>,<<CmpYZ>>]
- // CHECK-DAG: Return [<<CmpXYZ>>]
+ /// CHECK-START: boolean Main.ValuesOrdered(int, int, int) boolean_simplifier (before)
+ /// CHECK-DAG: <<ParamX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ParamY:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ParamZ:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<CondXY:z\d+>> GreaterThan [<<ParamX>>,<<ParamY>>]
+ /// CHECK-DAG: If [<<CondXY>>]
+ /// CHECK-DAG: <<CondYZ:z\d+>> GreaterThan [<<ParamY>>,<<ParamZ>>]
+ /// CHECK-DAG: If [<<CondYZ>>]
+ /// CHECK-DAG: <<CondXYZ:z\d+>> NotEqual [<<PhiXY:i\d+>>,<<PhiYZ:i\d+>>]
+ /// CHECK-DAG: If [<<CondXYZ>>]
+ /// CHECK-DAG: Return [<<PhiXYZ:i\d+>>]
+ /// CHECK-DAG: <<PhiXY>> Phi [<<Const1>>,<<Const0>>]
+ /// CHECK-DAG: <<PhiYZ>> Phi [<<Const1>>,<<Const0>>]
+ /// CHECK-DAG: <<PhiXYZ>> Phi [<<Const1>>,<<Const0>>]
+
+ /// CHECK-START: boolean Main.ValuesOrdered(int, int, int) boolean_simplifier (after)
+ /// CHECK-DAG: <<ParamX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ParamY:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ParamZ:i\d+>> ParameterValue
+ /// CHECK-DAG: <<CmpXY:z\d+>> LessThanOrEqual [<<ParamX>>,<<ParamY>>]
+ /// CHECK-DAG: <<CmpYZ:z\d+>> LessThanOrEqual [<<ParamY>>,<<ParamZ>>]
+ /// CHECK-DAG: <<CmpXYZ:z\d+>> Equal [<<CmpXY>>,<<CmpYZ>>]
+ /// CHECK-DAG: Return [<<CmpXYZ>>]
public static boolean ValuesOrdered(int x, int y, int z) {
return (x <= y) == (y <= z);
}
- // CHECK-START: int Main.NegatedCondition(boolean) boolean_simplifier (before)
- // CHECK-DAG: <<Param:z\d+>> ParameterValue
- // CHECK-DAG: <<Const42:i\d+>> IntConstant 42
- // CHECK-DAG: <<Const43:i\d+>> IntConstant 43
- // CHECK-DAG: <<NotParam:z\d+>> BooleanNot [<<Param>>]
- // CHECK-DAG: If [<<NotParam>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Const42>>,<<Const43>>]
- // CHECK-DAG: Return [<<Phi>>]
-
- // CHECK-START: int Main.NegatedCondition(boolean) boolean_simplifier (after)
- // CHECK-DAG: <<Param:z\d+>> ParameterValue
- // CHECK-DAG: <<Const42:i\d+>> IntConstant 42
- // CHECK-DAG: <<Const43:i\d+>> IntConstant 43
- // CHECK-DAG: If [<<Param>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Const42>>,<<Const43>>]
- // CHECK-DAG: Return [<<Phi>>]
+ /// CHECK-START: int Main.NegatedCondition(boolean) boolean_simplifier (before)
+ /// CHECK-DAG: <<Param:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
+ /// CHECK-DAG: <<Const43:i\d+>> IntConstant 43
+ /// CHECK-DAG: <<NotParam:z\d+>> BooleanNot [<<Param>>]
+ /// CHECK-DAG: If [<<NotParam>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const42>>,<<Const43>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ /// CHECK-START: int Main.NegatedCondition(boolean) boolean_simplifier (after)
+ /// CHECK-DAG: <<Param:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
+ /// CHECK-DAG: <<Const43:i\d+>> IntConstant 43
+ /// CHECK-DAG: If [<<Param>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const42>>,<<Const43>>]
+ /// CHECK-DAG: Return [<<Phi>>]
// Note: The fact that branches are swapped is verified by running the test.
- // CHECK-START: int Main.NegatedCondition(boolean) boolean_simplifier (after)
- // CHECK-NOT: BooleanNot
+ /// CHECK-START: int Main.NegatedCondition(boolean) boolean_simplifier (after)
+ /// CHECK-NOT: BooleanNot
public static int NegatedCondition(boolean x) {
if (x != false) {
diff --git a/test/464-checker-inline-sharpen-calls/src/Main.java b/test/464-checker-inline-sharpen-calls/src/Main.java
index e451f703c2..876496fdc4 100644
--- a/test/464-checker-inline-sharpen-calls/src/Main.java
+++ b/test/464-checker-inline-sharpen-calls/src/Main.java
@@ -19,27 +19,27 @@ public final class Main {
public void invokeVirtual() {
}
- // CHECK-START: void Main.inlineSharpenInvokeVirtual(Main) inliner (before)
- // CHECK-DAG: <<Invoke:v\d+>> InvokeStaticOrDirect
- // CHECK-DAG: ReturnVoid
+ /// CHECK-START: void Main.inlineSharpenInvokeVirtual(Main) inliner (before)
+ /// CHECK-DAG: <<Invoke:v\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: ReturnVoid
- // CHECK-START: void Main.inlineSharpenInvokeVirtual(Main) inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.inlineSharpenInvokeVirtual(Main) inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static void inlineSharpenInvokeVirtual(Main m) {
m.invokeVirtual();
}
- // CHECK-START: int Main.inlineSharpenStringInvoke() inliner (before)
- // CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
- // CHECK-DAG: Return [<<Invoke>>]
+ /// CHECK-START: int Main.inlineSharpenStringInvoke() inliner (before)
+ /// CHECK-DAG: <<Invoke:i\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: Return [<<Invoke>>]
- // CHECK-START: int Main.inlineSharpenStringInvoke() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: int Main.inlineSharpenStringInvoke() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
- // CHECK-START: int Main.inlineSharpenStringInvoke() inliner (after)
- // CHECK-DAG: <<Field:i\d+>> InstanceFieldGet
- // CHECK-DAG: Return [<<Field>>]
+ /// CHECK-START: int Main.inlineSharpenStringInvoke() inliner (after)
+ /// CHECK-DAG: <<Field:i\d+>> InstanceFieldGet
+ /// CHECK-DAG: Return [<<Field>>]
public static int inlineSharpenStringInvoke() {
return "Foo".length();
diff --git a/test/465-checker-clinit-gvn/src/Main.java b/test/465-checker-clinit-gvn/src/Main.java
index ac2863ceb4..704e9fe123 100644
--- a/test/465-checker-clinit-gvn/src/Main.java
+++ b/test/465-checker-clinit-gvn/src/Main.java
@@ -26,31 +26,31 @@ class OtherClass {
public final class Main {
- // CHECK-START: int Main.accessTwoStatics() GVN (before)
- // CHECK-DAG: <<Class1:l\d+>> LoadClass
- // CHECK-DAG: ClinitCheck [<<Class1>>]
- // CHECK-DAG: <<Class2:l\d+>> LoadClass
- // CHECK-DAG: ClinitCheck [<<Class2>>]
+ /// CHECK-START: int Main.accessTwoStatics() GVN (before)
+ /// CHECK-DAG: <<Class1:l\d+>> LoadClass
+ /// CHECK-DAG: ClinitCheck [<<Class1>>]
+ /// CHECK-DAG: <<Class2:l\d+>> LoadClass
+ /// CHECK-DAG: ClinitCheck [<<Class2>>]
- // CHECK-START: int Main.accessTwoStatics() GVN (after)
- // CHECK-DAG: <<Class:l\d+>> LoadClass
- // CHECK-DAG: ClinitCheck [<<Class>>]
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: int Main.accessTwoStatics() GVN (after)
+ /// CHECK-DAG: <<Class:l\d+>> LoadClass
+ /// CHECK-DAG: ClinitCheck [<<Class>>]
+ /// CHECK-NOT: ClinitCheck
public static int accessTwoStatics() {
return OtherClass.b - OtherClass.a;
}
- // CHECK-START: int Main.accessTwoStaticsCallInBetween() GVN (before)
- // CHECK-DAG: <<Class1:l\d+>> LoadClass
- // CHECK-DAG: ClinitCheck [<<Class1>>]
- // CHECK-DAG: <<Class2:l\d+>> LoadClass
- // CHECK-DAG: ClinitCheck [<<Class2>>]
+ /// CHECK-START: int Main.accessTwoStaticsCallInBetween() GVN (before)
+ /// CHECK-DAG: <<Class1:l\d+>> LoadClass
+ /// CHECK-DAG: ClinitCheck [<<Class1>>]
+ /// CHECK-DAG: <<Class2:l\d+>> LoadClass
+ /// CHECK-DAG: ClinitCheck [<<Class2>>]
- // CHECK-START: int Main.accessTwoStaticsCallInBetween() GVN (after)
- // CHECK-DAG: <<Class:l\d+>> LoadClass
- // CHECK-DAG: ClinitCheck [<<Class>>]
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: int Main.accessTwoStaticsCallInBetween() GVN (after)
+ /// CHECK-DAG: <<Class:l\d+>> LoadClass
+ /// CHECK-DAG: ClinitCheck [<<Class>>]
+ /// CHECK-NOT: ClinitCheck
public static int accessTwoStaticsCallInBetween() {
int b = OtherClass.b;
diff --git a/test/468-checker-bool-simplifier-regression/smali/TestCase.smali b/test/468-checker-bool-simplifier-regression/smali/TestCase.smali
index 33e6dc3d1e..da1c5ec802 100644
--- a/test/468-checker-bool-simplifier-regression/smali/TestCase.smali
+++ b/test/468-checker-bool-simplifier-regression/smali/TestCase.smali
@@ -18,18 +18,18 @@
.field public static value:Z
-# CHECK-START: boolean TestCase.testCase() boolean_simplifier (before)
-# CHECK-DAG: <<Const0:i\d+>> IntConstant 0
-# CHECK-DAG: <<Const1:i\d+>> IntConstant 1
-# CHECK-DAG: <<Value:z\d+>> StaticFieldGet
-# CHECK-DAG: If [<<Value>>]
-# CHECK-DAG: <<Phi:i\d+>> Phi [<<Const1>>,<<Const0>>]
-# CHECK-DAG: Return [<<Phi>>]
+## CHECK-START: boolean TestCase.testCase() boolean_simplifier (before)
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+## CHECK-DAG: <<Value:z\d+>> StaticFieldGet
+## CHECK-DAG: If [<<Value>>]
+## CHECK-DAG: <<Phi:i\d+>> Phi [<<Const1>>,<<Const0>>]
+## CHECK-DAG: Return [<<Phi>>]
-# CHECK-START: boolean TestCase.testCase() boolean_simplifier (after)
-# CHECK-DAG: <<Value:z\d+>> StaticFieldGet
-# CHECK-DAG: <<Not:z\d+>> BooleanNot [<<Value>>]
-# CHECK-DAG: Return [<<Not>>]
+## CHECK-START: boolean TestCase.testCase() boolean_simplifier (after)
+## CHECK-DAG: <<Value:z\d+>> StaticFieldGet
+## CHECK-DAG: <<Not:z\d+>> BooleanNot [<<Value>>]
+## CHECK-DAG: Return [<<Not>>]
.method public static testCase()Z
.registers 2
diff --git a/test/473-checker-inliner-constants/src/Main.java b/test/473-checker-inliner-constants/src/Main.java
index 79d89b0cfe..85f6565503 100644
--- a/test/473-checker-inliner-constants/src/Main.java
+++ b/test/473-checker-inliner-constants/src/Main.java
@@ -16,13 +16,13 @@
public class Main {
- // CHECK-START: java.lang.Object Main.InlineNullConstant() inliner (before)
- // CHECK: NullConstant
- // CHECK-NOT: NullConstant
+ /// CHECK-START: java.lang.Object Main.InlineNullConstant() inliner (before)
+ /// CHECK: NullConstant
+ /// CHECK-NOT: NullConstant
- // CHECK-START: java.lang.Object Main.InlineNullConstant() inliner (after)
- // CHECK: NullConstant
- // CHECK-NOT: NullConstant
+ /// CHECK-START: java.lang.Object Main.InlineNullConstant() inliner (after)
+ /// CHECK: NullConstant
+ /// CHECK-NOT: NullConstant
public static Object returnNullConstant(Object x) {
return null;
@@ -32,13 +32,13 @@ public class Main {
return returnNullConstant(null);
}
- // CHECK-START: int Main.InlineIntConstant() inliner (before)
- // CHECK: IntConstant 42
- // CHECK-NOT: IntConstant 42
+ /// CHECK-START: int Main.InlineIntConstant() inliner (before)
+ /// CHECK: IntConstant 42
+ /// CHECK-NOT: IntConstant 42
- // CHECK-START: int Main.InlineIntConstant() inliner (after)
- // CHECK: IntConstant 42
- // CHECK-NOT: IntConstant 42
+ /// CHECK-START: int Main.InlineIntConstant() inliner (after)
+ /// CHECK: IntConstant 42
+ /// CHECK-NOT: IntConstant 42
public static int returnIntConstant(int x) {
return 42;
@@ -48,13 +48,13 @@ public class Main {
return returnIntConstant(42);
}
- // CHECK-START: long Main.InlineLongConstant() inliner (before)
- // CHECK: LongConstant 42
- // CHECK-NOT: LongConstant 42
+ /// CHECK-START: long Main.InlineLongConstant() inliner (before)
+ /// CHECK: LongConstant 42
+ /// CHECK-NOT: LongConstant 42
- // CHECK-START: long Main.InlineLongConstant() inliner (after)
- // CHECK: LongConstant 42
- // CHECK-NOT: LongConstant 42
+ /// CHECK-START: long Main.InlineLongConstant() inliner (after)
+ /// CHECK: LongConstant 42
+ /// CHECK-NOT: LongConstant 42
public static long returnLongConstant(long x) {
return 42L;
diff --git a/test/474-checker-boolean-input/src/Main.java b/test/474-checker-boolean-input/src/Main.java
index 490f7f9cbc..86d0f7c916 100644
--- a/test/474-checker-boolean-input/src/Main.java
+++ b/test/474-checker-boolean-input/src/Main.java
@@ -27,9 +27,9 @@ public class Main {
* we implement a suitable type analysis.
*/
- // CHECK-START: boolean Main.TestPhiAsBoolean(int) boolean_simplifier (after)
- // CHECK-DAG: <<Phi:i\d+>> Phi
- // CHECK-DAG: BooleanNot [<<Phi>>]
+ /// CHECK-START: boolean Main.TestPhiAsBoolean(int) boolean_simplifier (after)
+ /// CHECK-DAG: <<Phi:i\d+>> Phi
+ /// CHECK-DAG: BooleanNot [<<Phi>>]
public static boolean f1;
public static boolean f2;
@@ -47,9 +47,9 @@ public class Main {
* we implement a suitable type analysis.
*/
- // CHECK-START: boolean Main.TestAndAsBoolean(boolean, boolean) boolean_simplifier (after)
- // CHECK-DAG: <<And:i\d+>> And
- // CHECK-DAG: BooleanNot [<<And>>]
+ /// CHECK-START: boolean Main.TestAndAsBoolean(boolean, boolean) boolean_simplifier (after)
+ /// CHECK-DAG: <<And:i\d+>> And
+ /// CHECK-DAG: BooleanNot [<<And>>]
public static boolean InlineAnd(boolean x, boolean y) {
return x & y;
@@ -64,9 +64,9 @@ public class Main {
* we implement a suitable type analysis.
*/
- // CHECK-START: boolean Main.TestOrAsBoolean(boolean, boolean) boolean_simplifier (after)
- // CHECK-DAG: <<Or:i\d+>> Or
- // CHECK-DAG: BooleanNot [<<Or>>]
+ /// CHECK-START: boolean Main.TestOrAsBoolean(boolean, boolean) boolean_simplifier (after)
+ /// CHECK-DAG: <<Or:i\d+>> Or
+ /// CHECK-DAG: BooleanNot [<<Or>>]
public static boolean InlineOr(boolean x, boolean y) {
return x | y;
@@ -81,9 +81,9 @@ public class Main {
* we implement a suitable type analysis.
*/
- // CHECK-START: boolean Main.TestXorAsBoolean(boolean, boolean) boolean_simplifier (after)
- // CHECK-DAG: <<Xor:i\d+>> Xor
- // CHECK-DAG: BooleanNot [<<Xor>>]
+ /// CHECK-START: boolean Main.TestXorAsBoolean(boolean, boolean) boolean_simplifier (after)
+ /// CHECK-DAG: <<Xor:i\d+>> Xor
+ /// CHECK-DAG: BooleanNot [<<Xor>>]
public static boolean InlineXor(boolean x, boolean y) {
return x ^ y;
diff --git a/test/476-checker-ctor-memory-barrier/src/Main.java b/test/476-checker-ctor-memory-barrier/src/Main.java
index f24dc4abae..e709ba0902 100644
--- a/test/476-checker-ctor-memory-barrier/src/Main.java
+++ b/test/476-checker-ctor-memory-barrier/src/Main.java
@@ -17,8 +17,8 @@
// TODO: Add more tests after we can inline functions with calls.
class ClassWithoutFinals {
- // CHECK-START: void ClassWithoutFinals.<init>() register (after)
- // CHECK-NOT: MemoryBarrier kind:StoreStore
+ /// CHECK-START: void ClassWithoutFinals.<init>() register (after)
+ /// CHECK-NOT: MemoryBarrier kind:StoreStore
public ClassWithoutFinals() {}
}
@@ -26,9 +26,9 @@ class ClassWithFinals {
public final int x;
public ClassWithFinals obj;
- // CHECK-START: void ClassWithFinals.<init>(boolean) register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void ClassWithFinals.<init>(boolean) register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
public ClassWithFinals(boolean cond) {
x = 0;
if (cond) {
@@ -37,17 +37,17 @@ class ClassWithFinals {
}
}
- // CHECK-START: void ClassWithFinals.<init>() register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void ClassWithFinals.<init>() register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
public ClassWithFinals() {
x = 0;
}
- // CHECK-START: void ClassWithFinals.<init>(int) register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void ClassWithFinals.<init>(int) register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
public ClassWithFinals(int x) {
// This should have two barriers:
// - one for the constructor
@@ -58,33 +58,33 @@ class ClassWithFinals {
}
class InheritFromClassWithFinals extends ClassWithFinals {
- // CHECK-START: void InheritFromClassWithFinals.<init>() register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void InheritFromClassWithFinals.<init>() register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
- // CHECK-START: void InheritFromClassWithFinals.<init>() register (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void InheritFromClassWithFinals.<init>() register (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public InheritFromClassWithFinals() {
// Should inline the super constructor.
}
- // CHECK-START: void InheritFromClassWithFinals.<init>(boolean) register (after)
- // CHECK: InvokeStaticOrDirect
+ /// CHECK-START: void InheritFromClassWithFinals.<init>(boolean) register (after)
+ /// CHECK: InvokeStaticOrDirect
- // CHECK-START: void InheritFromClassWithFinals.<init>(boolean) register (after)
- // CHECK-NOT: MemoryBarrier kind:StoreStore
+ /// CHECK-START: void InheritFromClassWithFinals.<init>(boolean) register (after)
+ /// CHECK-NOT: MemoryBarrier kind:StoreStore
public InheritFromClassWithFinals(boolean cond) {
super(cond);
// should not inline the super constructor
}
- // CHECK-START: void InheritFromClassWithFinals.<init>(int) register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK: ReturnVoid
+ /// CHECK-START: void InheritFromClassWithFinals.<init>(int) register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK: ReturnVoid
- // CHECK-START: void InheritFromClassWithFinals.<init>(int) register (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void InheritFromClassWithFinals.<init>(int) register (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public InheritFromClassWithFinals(int unused) {
// Should inline the super constructor and insert a memory barrier.
@@ -96,35 +96,35 @@ class InheritFromClassWithFinals extends ClassWithFinals {
class HaveFinalsAndInheritFromClassWithFinals extends ClassWithFinals {
final int y;
- // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
- // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() register (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>() register (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public HaveFinalsAndInheritFromClassWithFinals() {
// Should inline the super constructor and remove the memory barrier.
y = 0;
}
- // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(boolean) register (after)
- // CHECK: InvokeStaticOrDirect
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(boolean) register (after)
+ /// CHECK: InvokeStaticOrDirect
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
public HaveFinalsAndInheritFromClassWithFinals(boolean cond) {
super(cond);
// should not inline the super constructor
y = 0;
}
- // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
- // CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) register (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void HaveFinalsAndInheritFromClassWithFinals.<init>(int) register (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public HaveFinalsAndInheritFromClassWithFinals(int unused) {
// Should inline the super constructor and keep just one memory barrier.
y = 0;
@@ -138,52 +138,52 @@ class HaveFinalsAndInheritFromClassWithFinals extends ClassWithFinals {
public class Main {
- // CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() register (after)
- // CHECK: InvokeStaticOrDirect
+ /// CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() register (after)
+ /// CHECK: InvokeStaticOrDirect
- // CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() register (after)
- // CHECK-NOT: MemoryBarrier kind:StoreStore
+ /// CHECK-START: ClassWithFinals Main.noInlineNoConstructorBarrier() register (after)
+ /// CHECK-NOT: MemoryBarrier kind:StoreStore
public static ClassWithFinals noInlineNoConstructorBarrier() {
return new ClassWithFinals(false);
}
- // CHECK-START: void Main.inlineNew() register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void Main.inlineNew() register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
- // CHECK-START: void Main.inlineNew() register (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.inlineNew() register (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static void inlineNew() {
new ClassWithFinals();
}
- // CHECK-START: void Main.inlineNew1() register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void Main.inlineNew1() register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
- // CHECK-START: void Main.inlineNew1() register (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.inlineNew1() register (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static void inlineNew1() {
new InheritFromClassWithFinals();
}
- // CHECK-START: void Main.inlineNew2() register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void Main.inlineNew2() register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
- // CHECK-START: void Main.inlineNew2() register (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.inlineNew2() register (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static void inlineNew2() {
new HaveFinalsAndInheritFromClassWithFinals();
}
- // CHECK-START: void Main.inlineNew3() register (after)
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK: MemoryBarrier kind:StoreStore
- // CHECK-NEXT: ReturnVoid
+ /// CHECK-START: void Main.inlineNew3() register (after)
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK: MemoryBarrier kind:StoreStore
+ /// CHECK-NEXT: ReturnVoid
- // CHECK-START: void Main.inlineNew3() register (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.inlineNew3() register (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
public static void inlineNew3() {
new HaveFinalsAndInheritFromClassWithFinals();
new HaveFinalsAndInheritFromClassWithFinals();
diff --git a/test/477-checker-bound-type/src/Main.java b/test/477-checker-bound-type/src/Main.java
index b30028ddd4..fe52e83664 100644
--- a/test/477-checker-bound-type/src/Main.java
+++ b/test/477-checker-bound-type/src/Main.java
@@ -17,8 +17,8 @@
public class Main {
- // CHECK-START: java.lang.Object Main.boundTypeForIf(java.lang.Object) reference_type_propagation (after)
- // CHECK: BoundType
+ /// CHECK-START: java.lang.Object Main.boundTypeForIf(java.lang.Object) reference_type_propagation (after)
+ /// CHECK: BoundType
public static Object boundTypeForIf(Object a) {
if (a != null) {
return a.toString();
@@ -27,8 +27,8 @@ public class Main {
}
}
- // CHECK-START: java.lang.Object Main.boundTypeForInstanceOf(java.lang.Object) reference_type_propagation (after)
- // CHECK: BoundType
+ /// CHECK-START: java.lang.Object Main.boundTypeForInstanceOf(java.lang.Object) reference_type_propagation (after)
+ /// CHECK: BoundType
public static Object boundTypeForInstanceOf(Object a) {
if (a instanceof Main) {
return (Main)a;
@@ -37,8 +37,8 @@ public class Main {
}
}
- // CHECK-START: java.lang.Object Main.noBoundTypeForIf(java.lang.Object) reference_type_propagation (after)
- // CHECK-NOT: BoundType
+ /// CHECK-START: java.lang.Object Main.noBoundTypeForIf(java.lang.Object) reference_type_propagation (after)
+ /// CHECK-NOT: BoundType
public static Object noBoundTypeForIf(Object a) {
if (a == null) {
return new Object();
@@ -47,8 +47,8 @@ public class Main {
}
}
- // CHECK-START: java.lang.Object Main.noBoundTypeForInstanceOf(java.lang.Object) reference_type_propagation (after)
- // CHECK-NOT: BoundType
+ /// CHECK-START: java.lang.Object Main.noBoundTypeForInstanceOf(java.lang.Object) reference_type_propagation (after)
+ /// CHECK-NOT: BoundType
public static Object noBoundTypeForInstanceOf(Object a) {
if (a instanceof Main) {
return new Object();
diff --git a/test/478-checker-clinit-check-pruning/src/Main.java b/test/478-checker-clinit-check-pruning/src/Main.java
index e8739b8d85..d5592aa49b 100644
--- a/test/478-checker-clinit-check-pruning/src/Main.java
+++ b/test/478-checker-clinit-check-pruning/src/Main.java
@@ -23,17 +23,17 @@ public class Main {
* removed before register allocation & code generation.
*/
- // CHECK-START: void Main.invokeStaticInlined() builder (after)
- // CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
- // CHECK-DAG: <<ClinitCheck:l\d+>> ClinitCheck [<<LoadClass>>]
- // CHECK-DAG: InvokeStaticOrDirect [<<ClinitCheck>>]
+ /// CHECK-START: void Main.invokeStaticInlined() builder (after)
+ /// CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
+ /// CHECK-DAG: <<ClinitCheck:l\d+>> ClinitCheck [<<LoadClass>>]
+ /// CHECK-DAG: InvokeStaticOrDirect [<<ClinitCheck>>]
- // CHECK-START: void Main.invokeStaticInlined() inliner (after)
- // CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
- // CHECK-DAG: <<ClinitCheck:l\d+>> ClinitCheck [<<LoadClass>>]
+ /// CHECK-START: void Main.invokeStaticInlined() inliner (after)
+ /// CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
+ /// CHECK-DAG: <<ClinitCheck:l\d+>> ClinitCheck [<<LoadClass>>]
- // CHECK-START: void Main.invokeStaticInlined() inliner (after)
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.invokeStaticInlined() inliner (after)
+ /// CHECK-NOT: InvokeStaticOrDirect
// The following checks ensure the clinit check instruction added by
// the builder is pruned by the PrepareForRegisterAllocation, while
@@ -41,12 +41,12 @@ public class Main {
// graph is not dumped after (nor before) this step, we check the
// CFG as it is before the next pass (liveness analysis) instead.
- // CHECK-START: void Main.invokeStaticInlined() liveness (before)
- // CHECK-DAG: LoadClass gen_clinit_check:true
+ /// CHECK-START: void Main.invokeStaticInlined() liveness (before)
+ /// CHECK-DAG: LoadClass gen_clinit_check:true
- // CHECK-START: void Main.invokeStaticInlined() liveness (before)
- // CHECK-NOT: ClinitCheck
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main.invokeStaticInlined() liveness (before)
+ /// CHECK-NOT: ClinitCheck
+ /// CHECK-NOT: InvokeStaticOrDirect
static void invokeStaticInlined() {
ClassWithClinit1.$opt$inline$StaticMethod();
@@ -66,15 +66,15 @@ public class Main {
* initialization check of the called method's declaring class.
*/
- // CHECK-START: void Main.invokeStaticNotInlined() builder (after)
- // CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
- // CHECK-DAG: <<ClinitCheck:l\d+>> ClinitCheck [<<LoadClass>>]
- // CHECK-DAG: InvokeStaticOrDirect [<<ClinitCheck>>]
+ /// CHECK-START: void Main.invokeStaticNotInlined() builder (after)
+ /// CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
+ /// CHECK-DAG: <<ClinitCheck:l\d+>> ClinitCheck [<<LoadClass>>]
+ /// CHECK-DAG: InvokeStaticOrDirect [<<ClinitCheck>>]
- // CHECK-START: void Main.invokeStaticNotInlined() inliner (after)
- // CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
- // CHECK-DAG: <<ClinitCheck:l\d+>> ClinitCheck [<<LoadClass>>]
- // CHECK-DAG: InvokeStaticOrDirect [<<ClinitCheck>>]
+ /// CHECK-START: void Main.invokeStaticNotInlined() inliner (after)
+ /// CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
+ /// CHECK-DAG: <<ClinitCheck:l\d+>> ClinitCheck [<<LoadClass>>]
+ /// CHECK-DAG: InvokeStaticOrDirect [<<ClinitCheck>>]
// The following checks ensure the clinit check and load class
// instructions added by the builder are pruned by the
@@ -82,12 +82,12 @@ public class Main {
// dumped after (nor before) this step, we check the CFG as it is
// before the next pass (liveness analysis) instead.
- // CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main.invokeStaticNotInlined() liveness (before)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
static void invokeStaticNotInlined() {
ClassWithClinit2.staticMethod();
@@ -114,17 +114,17 @@ public class Main {
* explicit clinit check.
*/
- // CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() builder (after)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() builder (after)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() builder (after)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() builder (after)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
- // CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() inliner (after)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main$ClassWithClinit3.invokeStaticInlined() inliner (after)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
+ /// CHECK-NOT: InvokeStaticOrDirect
static class ClassWithClinit3 {
static void invokeStaticInlined() {
@@ -149,19 +149,19 @@ public class Main {
* require an explicit clinit check.
*/
- // CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() builder (after)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() builder (after)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() builder (after)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() builder (after)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
- // CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() inliner (after)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() inliner (after)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() inliner (after)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main$ClassWithClinit4.invokeStaticNotInlined() inliner (after)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
static class ClassWithClinit4 {
static void invokeStaticNotInlined() {
@@ -192,17 +192,17 @@ public class Main {
* explicit clinit check.
*/
- // CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() builder (after)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
- // CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() inliner (after)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
- // CHECK-NOT: InvokeStaticOrDirect
+ /// CHECK-START: void Main$SubClassOfClassWithClinit5.invokeStaticInlined() inliner (after)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
+ /// CHECK-NOT: InvokeStaticOrDirect
static class ClassWithClinit5 {
static void $opt$inline$StaticMethod() {
@@ -225,19 +225,19 @@ public class Main {
* explicit clinit check.
*/
- // CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() builder (after)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
- // CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
- // CHECK-NOT: LoadClass
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main$SubClassOfClassWithClinit6.invokeStaticNotInlined() inliner (after)
+ /// CHECK-NOT: LoadClass
+ /// CHECK-NOT: ClinitCheck
static class ClassWithClinit6 {
static boolean doThrow = false;
@@ -266,14 +266,14 @@ public class Main {
* we don't do generate a clinit check.
*/
- // CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
- // CHECK-DAG: <<IntConstant:i\d+>> IntConstant 0
- // CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
- // CHECK-DAG: InvokeStaticOrDirect
- // CHECK-DAG: StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
+ /// CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
+ /// CHECK-DAG: <<IntConstant:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:false
+ /// CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-DAG: StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
- // CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main.noClinitBecauseOfInvokeStatic() liveness (before)
+ /// CHECK-NOT: ClinitCheck
static void noClinitBecauseOfInvokeStatic() {
ClassWithClinit2.staticMethod();
@@ -285,14 +285,14 @@ public class Main {
* will generate a clinit check.
*/
- // CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
- // CHECK-DAG: <<IntConstant:i\d+>> IntConstant 0
- // CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:true
- // CHECK-DAG: StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
- // CHECK-DAG: InvokeStaticOrDirect
+ /// CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
+ /// CHECK-DAG: <<IntConstant:i\d+>> IntConstant 0
+ /// CHECK-DAG: <<LoadClass:l\d+>> LoadClass gen_clinit_check:true
+ /// CHECK-DAG: StaticFieldSet [<<LoadClass>>,<<IntConstant>>]
+ /// CHECK-DAG: InvokeStaticOrDirect
- // CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
- // CHECK-NOT: ClinitCheck
+ /// CHECK-START: void Main.clinitBecauseOfFieldAccess() liveness (before)
+ /// CHECK-NOT: ClinitCheck
static void clinitBecauseOfFieldAccess() {
ClassWithClinit2.doThrow = false;
ClassWithClinit2.staticMethod();
diff --git a/test/478-checker-inliner-nested-loop/src/Main.java b/test/478-checker-inliner-nested-loop/src/Main.java
index df583d9302..aa023491a5 100644
--- a/test/478-checker-inliner-nested-loop/src/Main.java
+++ b/test/478-checker-inliner-nested-loop/src/Main.java
@@ -33,12 +33,12 @@ public class Main {
return result;
}
- // CHECK-START: int Main.NestedLoop(int, int) inliner (before)
- // CHECK-NOT: Mul
+ /// CHECK-START: int Main.NestedLoop(int, int) inliner (before)
+ /// CHECK-NOT: Mul
- // CHECK-START: int Main.NestedLoop(int, int) inliner (after)
- // CHECK: Mul
- // CHECK-NOT: Mul
+ /// CHECK-START: int Main.NestedLoop(int, int) inliner (after)
+ /// CHECK: Mul
+ /// CHECK-NOT: Mul
public static int NestedLoop(int max_x, int max_y) {
int total = 0;
diff --git a/test/480-checker-dead-blocks/src/Main.java b/test/480-checker-dead-blocks/src/Main.java
index b76755e07c..4cc16344a4 100644
--- a/test/480-checker-dead-blocks/src/Main.java
+++ b/test/480-checker-dead-blocks/src/Main.java
@@ -30,25 +30,25 @@ public class Main {
return false;
}
- // CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (before)
- // CHECK-DAG: <<ArgX:i\d+>> ParameterValue
- // CHECK-DAG: <<ArgY:i\d+>> ParameterValue
- // CHECK-DAG: If
- // CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
- // CHECK-DAG: Return [<<Phi>>]
-
- // CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
- // CHECK-DAG: <<ArgX:i\d+>> ParameterValue
- // CHECK-DAG: <<ArgY:i\d+>> ParameterValue
- // CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
- // CHECK-DAG: Return [<<Add>>]
-
- // CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
- // CHECK-NOT: If
- // CHECK-NOT: Sub
- // CHECK-NOT: Phi
+ /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (before)
+ /// CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ArgY:i\d+>> ParameterValue
+ /// CHECK-DAG: If
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
+ /// CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ArgY:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
+ /// CHECK-DAG: Return [<<Add>>]
+
+ /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
+ /// CHECK-NOT: If
+ /// CHECK-NOT: Sub
+ /// CHECK-NOT: Phi
public static int testTrueBranch(int x, int y) {
int z;
@@ -60,25 +60,25 @@ public class Main {
return z;
}
- // CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (before)
- // CHECK-DAG: <<ArgX:i\d+>> ParameterValue
- // CHECK-DAG: <<ArgY:i\d+>> ParameterValue
- // CHECK-DAG: If
- // CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
- // CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
- // CHECK-DAG: Return [<<Phi>>]
-
- // CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
- // CHECK-DAG: <<ArgX:i\d+>> ParameterValue
- // CHECK-DAG: <<ArgY:i\d+>> ParameterValue
- // CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
- // CHECK-DAG: Return [<<Sub>>]
-
- // CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
- // CHECK-NOT: If
- // CHECK-NOT: Add
- // CHECK-NOT: Phi
+ /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (before)
+ /// CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ArgY:i\d+>> ParameterValue
+ /// CHECK-DAG: If
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<ArgX>>,<<ArgY>>]
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
+ /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Add>>,<<Sub>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
+ /// CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+ /// CHECK-DAG: <<ArgY:i\d+>> ParameterValue
+ /// CHECK-DAG: <<Sub:i\d+>> Sub [<<ArgX>>,<<ArgY>>]
+ /// CHECK-DAG: Return [<<Sub>>]
+
+ /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
+ /// CHECK-NOT: If
+ /// CHECK-NOT: Add
+ /// CHECK-NOT: Phi
public static int testFalseBranch(int x, int y) {
int z;
@@ -90,11 +90,11 @@ public class Main {
return z;
}
- // CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (before)
- // CHECK: Mul
+ /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (before)
+ /// CHECK: Mul
- // CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (after)
- // CHECK-NOT: Mul
+ /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (after)
+ /// CHECK-NOT: Mul
public static int testRemoveLoop(int x) {
if (inlineFalse()) {
@@ -105,13 +105,13 @@ public class Main {
return x;
}
- // CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (before)
- // CHECK-DAG: Return
- // CHECK-DAG: Exit
+ /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (before)
+ /// CHECK-DAG: Return
+ /// CHECK-DAG: Exit
- // CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (after)
- // CHECK-NOT: Return
- // CHECK-NOT: Exit
+ /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (after)
+ /// CHECK-NOT: Return
+ /// CHECK-NOT: Exit
public static int testInfiniteLoop(int x) {
while (inlineTrue()) {
@@ -120,17 +120,17 @@ public class Main {
return x;
}
- // CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (before)
- // CHECK-DAG: If
- // CHECK-DAG: Add
+ /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (before)
+ /// CHECK-DAG: If
+ /// CHECK-DAG: Add
- // CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
- // CHECK-NOT: If
- // CHECK-NOT: Add
+ /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
+ /// CHECK-NOT: If
+ /// CHECK-NOT: Add
public static int testDeadLoop(int x) {
while (inlineFalse()) {
@@ -139,18 +139,18 @@ public class Main {
return x;
}
- // CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (before)
- // CHECK-DAG: If
- // CHECK-DAG: If
- // CHECK-DAG: Add
+ /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (before)
+ /// CHECK-DAG: If
+ /// CHECK-DAG: If
+ /// CHECK-DAG: Add
- // CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
- // CHECK-DAG: <<Arg:i\d+>> ParameterValue
- // CHECK-DAG: Return [<<Arg>>]
+ /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
+ /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
+ /// CHECK-DAG: Return [<<Arg>>]
- // CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
- // CHECK-NOT: If
- // CHECK-NOT: Add
+ /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
+ /// CHECK-NOT: If
+ /// CHECK-NOT: Add
public static int testUpdateLoopInformation(int x) {
// Use of Or in the condition generates a dead loop where not all of its
@@ -161,16 +161,16 @@ public class Main {
return x;
}
- // CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (before)
- // CHECK: SuspendCheck
- // CHECK: SuspendCheck
- // CHECK: SuspendCheck
- // CHECK-NOT: SuspendCheck
+ /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (before)
+ /// CHECK: SuspendCheck
+ /// CHECK: SuspendCheck
+ /// CHECK: SuspendCheck
+ /// CHECK-NOT: SuspendCheck
- // CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (after)
- // CHECK: SuspendCheck
- // CHECK: SuspendCheck
- // CHECK-NOT: SuspendCheck
+ /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (after)
+ /// CHECK: SuspendCheck
+ /// CHECK: SuspendCheck
+ /// CHECK-NOT: SuspendCheck
public static int testRemoveSuspendCheck(int x, int y) {
// Inner loop will leave behind the header with its SuspendCheck. DCE must
diff --git a/test/482-checker-loop-back-edge-use/src/Main.java b/test/482-checker-loop-back-edge-use/src/Main.java
index 0ed926703d..5754723d8a 100644
--- a/test/482-checker-loop-back-edge-use/src/Main.java
+++ b/test/482-checker-loop-back-edge-use/src/Main.java
@@ -17,17 +17,17 @@
public class Main {
- // CHECK-START: void Main.loop1(boolean) liveness (after)
- // CHECK: ParameterValue liveness:2 ranges:{[2,22)} uses:[17,22]
- // CHECK: Goto liveness:20
+ /// CHECK-START: void Main.loop1(boolean) liveness (after)
+ /// CHECK: ParameterValue liveness:2 ranges:{[2,22)} uses:[17,22]
+ /// CHECK: Goto liveness:20
public static void loop1(boolean incoming) {
while (incoming) {}
}
- // CHECK-START: void Main.loop2(boolean) liveness (after)
- // CHECK: ParameterValue liveness:2 ranges:{[2,42)} uses:[33,38,42]
- // CHECK: Goto liveness:36
- // CHECK: Goto liveness:40
+ /// CHECK-START: void Main.loop2(boolean) liveness (after)
+ /// CHECK: ParameterValue liveness:4 ranges:{[4,44)} uses:[35,40,44]
+ /// CHECK: Goto liveness:38
+ /// CHECK: Goto liveness:42
public static void loop2(boolean incoming) {
while (true) {
System.out.println("foo");
@@ -35,12 +35,12 @@ public class Main {
}
}
- // CHECK-START: void Main.loop3(boolean) liveness (after)
- // CHECK: ParameterValue liveness:2 ranges:{[2,60)} uses:[56,60]
- // CHECK: Goto liveness:58
+ /// CHECK-START: void Main.loop3(boolean) liveness (after)
+ /// CHECK: ParameterValue liveness:4 ranges:{[4,62)} uses:[58,62]
+ /// CHECK: Goto liveness:60
- // CHECK-START: void Main.loop3(boolean) liveness (after)
- // CHECK-NOT: Goto liveness:54
+ /// CHECK-START: void Main.loop3(boolean) liveness (after)
+ /// CHECK-NOT: Goto liveness:56
public static void loop3(boolean incoming) {
// 'incoming' only needs a use at the outer loop's back edge.
while (System.currentTimeMillis() != 42) {
@@ -49,11 +49,11 @@ public class Main {
}
}
- // CHECK-START: void Main.loop4(boolean) liveness (after)
- // CHECK: ParameterValue liveness:2 ranges:{[2,22)} uses:[22]
+ /// CHECK-START: void Main.loop4(boolean) liveness (after)
+ /// CHECK: ParameterValue liveness:4 ranges:{[4,24)} uses:[24]
- // CHECK-START: void Main.loop4(boolean) liveness (after)
- // CHECK-NOT: Goto liveness:20
+ /// CHECK-START: void Main.loop4(boolean) liveness (after)
+ /// CHECK-NOT: Goto liveness:22
public static void loop4(boolean incoming) {
// 'incoming' has no loop use, so should not have back edge uses.
System.out.println(incoming);
@@ -62,10 +62,10 @@ public class Main {
}
}
- // CHECK-START: void Main.loop5(boolean) liveness (after)
- // CHECK: ParameterValue liveness:2 ranges:{[2,50)} uses:[33,42,46,50]
- // CHECK: Goto liveness:44
- // CHECK: Goto liveness:48
+ /// CHECK-START: void Main.loop5(boolean) liveness (after)
+ /// CHECK: ParameterValue liveness:4 ranges:{[4,52)} uses:[35,44,48,52]
+ /// CHECK: Goto liveness:46
+ /// CHECK: Goto liveness:50
public static void loop5(boolean incoming) {
// 'incoming' must have a use at both back edges.
while (Runtime.getRuntime() != null) {
@@ -75,12 +75,12 @@ public class Main {
}
}
- // CHECK-START: void Main.loop6(boolean) liveness (after)
- // CHECK ParameterValue liveness:2 ranges:{[2,46)} uses:[24,46]
- // CHECK: Goto liveness:44
+ /// CHECK-START: void Main.loop6(boolean) liveness (after)
+ /// CHECK: ParameterValue liveness:4 ranges:{[4,48)} uses:[26,48]
+ /// CHECK: Goto liveness:46
- // CHECK-START: void Main.loop6(boolean) liveness (after)
- // CHECK-NOT: Goto liveness:22
+ /// CHECK-START: void Main.loop6(boolean) liveness (after)
+ /// CHECK-NOT: Goto liveness:24
public static void loop6(boolean incoming) {
// 'incoming' must have a use only at the first loop's back edge.
while (true) {
@@ -89,10 +89,10 @@ public class Main {
}
}
- // CHECK-START: void Main.loop7(boolean) liveness (after)
- // CHECK: ParameterValue liveness:2 ranges:{[2,50)} uses:[32,41,46,50]
- // CHECK: Goto liveness:44
- // CHECK: Goto liveness:48
+ /// CHECK-START: void Main.loop7(boolean) liveness (after)
+ /// CHECK: ParameterValue liveness:4 ranges:{[4,52)} uses:[34,43,48,52]
+ /// CHECK: Goto liveness:46
+ /// CHECK: Goto liveness:50
public static void loop7(boolean incoming) {
// 'incoming' must have a use at both back edges.
while (Runtime.getRuntime() != null) {
@@ -101,10 +101,10 @@ public class Main {
}
}
- // CHECK-START: void Main.loop8() liveness (after)
- // CHECK: StaticFieldGet liveness:12 ranges:{[12,44)} uses:[35,40,44]
- // CHECK: Goto liveness:38
- // CHECK: Goto liveness:42
+ /// CHECK-START: void Main.loop8() liveness (after)
+ /// CHECK: StaticFieldGet liveness:14 ranges:{[14,46)} uses:[37,42,46]
+ /// CHECK: Goto liveness:40
+ /// CHECK: Goto liveness:44
public static void loop8() {
// 'incoming' must have a use at both back edges.
boolean incoming = field;
@@ -113,9 +113,9 @@ public class Main {
}
}
- // CHECK-START: void Main.loop9() liveness (after)
- // CHECK: StaticFieldGet liveness:22 ranges:{[22,36)} uses:[31,36]
- // CHECK: Goto liveness:38
+ /// CHECK-START: void Main.loop9() liveness (after)
+ /// CHECK: StaticFieldGet liveness:24 ranges:{[24,38)} uses:[33,38]
+ /// CHECK: Goto liveness:40
public static void loop9() {
while (Runtime.getRuntime() != null) {
// 'incoming' must only have a use in the inner loop.
diff --git a/test/484-checker-register-hints/src/Main.java b/test/484-checker-register-hints/src/Main.java
index 33952d9f7e..3715ca2b14 100644
--- a/test/484-checker-register-hints/src/Main.java
+++ b/test/484-checker-register-hints/src/Main.java
@@ -16,21 +16,21 @@
public class Main {
- // CHECK-START: void Main.test1(boolean, int, int, int, int, int) register (after)
- // CHECK: name "B0"
- // CHECK-NOT: ParallelMove
- // CHECK: name "B1"
- // CHECK-NOT: end_block
- // CHECK: If
- // CHECK-NOT: ParallelMove
- // CHECK: name "B3"
- // CHECK-NOT: end_block
- // CHECK: ArraySet
+ /// CHECK-START: void Main.test1(boolean, int, int, int, int, int) register (after)
+ /// CHECK: name "B0"
+ /// CHECK-NOT: ParallelMove
+ /// CHECK: name "B1"
+ /// CHECK-NOT: end_block
+ /// CHECK: If
+ /// CHECK-NOT: ParallelMove
+ /// CHECK: name "B3"
+ /// CHECK-NOT: end_block
+ /// CHECK: ArraySet
// We could check here that there is a parallel move, but it's only valid
// for some architectures (for example x86), as other architectures may
// not do move at all.
- // CHECK: end_block
- // CHECK-NOT: ParallelMove
+ /// CHECK: end_block
+ /// CHECK-NOT: ParallelMove
public static void test1(boolean z, int a, int b, int c, int d, int m) {
int e = live1;
@@ -51,21 +51,21 @@ public class Main {
live1 = e + f + g;
}
- // CHECK-START: void Main.test2(boolean, int, int, int, int, int) register (after)
- // CHECK: name "B0"
- // CHECK-NOT: ParallelMove
- // CHECK: name "B1"
- // CHECK-NOT: end_block
- // CHECK: If
- // CHECK-NOT: ParallelMove
- // CHECK: name "B3"
- // CHECK-NOT: end_block
- // CHECK: ArraySet
+ /// CHECK-START: void Main.test2(boolean, int, int, int, int, int) register (after)
+ /// CHECK: name "B0"
+ /// CHECK-NOT: ParallelMove
+ /// CHECK: name "B1"
+ /// CHECK-NOT: end_block
+ /// CHECK: If
+ /// CHECK-NOT: ParallelMove
+ /// CHECK: name "B3"
+ /// CHECK-NOT: end_block
+ /// CHECK: ArraySet
// We could check here that there is a parallel move, but it's only valid
// for some architectures (for example x86), as other architectures may
// not do move at all.
- // CHECK: end_block
- // CHECK-NOT: ParallelMove
+ /// CHECK: end_block
+ /// CHECK-NOT: ParallelMove
public static void test2(boolean z, int a, int b, int c, int d, int m) {
int e = live1;
@@ -85,21 +85,21 @@ public class Main {
live1 = e + f + g;
}
- // CHECK-START: void Main.test3(boolean, int, int, int, int, int) register (after)
- // CHECK: name "B0"
- // CHECK-NOT: ParallelMove
- // CHECK: name "B1"
- // CHECK-NOT: end_block
- // CHECK: If
- // CHECK-NOT: ParallelMove
- // CHECK: name "B6"
- // CHECK-NOT: end_block
- // CHECK: ArraySet
+ /// CHECK-START: void Main.test3(boolean, int, int, int, int, int) register (after)
+ /// CHECK: name "B0"
+ /// CHECK-NOT: ParallelMove
+ /// CHECK: name "B1"
+ /// CHECK-NOT: end_block
+ /// CHECK: If
+ /// CHECK-NOT: ParallelMove
+ /// CHECK: name "B6"
+ /// CHECK-NOT: end_block
+ /// CHECK: ArraySet
// We could check here that there is a parallel move, but it's only valid
// for some architectures (for example x86), as other architectures may
// not do move at all.
- // CHECK: end_block
- // CHECK-NOT: ParallelMove
+ /// CHECK: end_block
+ /// CHECK-NOT: ParallelMove
public static void test3(boolean z, int a, int b, int c, int d, int m) {
// Same version as test2, but with branches reversed, to ensure
diff --git a/test/485-checker-dce-loop-update/smali/TestCase.smali b/test/485-checker-dce-loop-update/smali/TestCase.smali
index 487a5dfbff..da27bf6cf1 100644
--- a/test/485-checker-dce-loop-update/smali/TestCase.smali
+++ b/test/485-checker-dce-loop-update/smali/TestCase.smali
@@ -23,27 +23,27 @@
.end method
-# CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (before)
-# CHECK-DAG: <<ArgX:i\d+>> ParameterValue
-# CHECK-DAG: <<ArgY:z\d+>> ParameterValue
-# CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
-# CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
-# CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
-# CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
-# CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
-# CHECK-DAG: If [<<Cst1>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add5>> Add [<<PhiX>>,<<Cst5>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
-# CHECK-DAG: Return [<<PhiX>>] loop:none
-
-# CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (after)
-# CHECK-DAG: <<ArgX:i\d+>> ParameterValue
-# CHECK-DAG: <<ArgY:z\d+>> ParameterValue
-# CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
-# CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<AddX:i\d+>>] loop:<<HeaderY:B\d+>>
-# CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
-# CHECK-DAG: <<AddX>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
-# CHECK-DAG: Return [<<PhiX>>] loop:none
+## CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (before)
+## CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+## CHECK-DAG: <<ArgY:z\d+>> ParameterValue
+## CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
+## CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
+## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
+## CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
+## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
+## CHECK-DAG: If [<<Cst1>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add5>> Add [<<PhiX>>,<<Cst5>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
+## CHECK-DAG: Return [<<PhiX>>] loop:none
+
+## CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (after)
+## CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+## CHECK-DAG: <<ArgY:z\d+>> ParameterValue
+## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
+## CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<AddX:i\d+>>] loop:<<HeaderY:B\d+>>
+## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
+## CHECK-DAG: <<AddX>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
+## CHECK-DAG: Return [<<PhiX>>] loop:none
.method public static testSingleExit(IZ)I
.registers 3
@@ -73,31 +73,31 @@
.end method
-# CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (before)
-# CHECK-DAG: <<ArgX:i\d+>> ParameterValue
-# CHECK-DAG: <<ArgY:z\d+>> ParameterValue
-# CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
-# CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
-# CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
-# CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
-# CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
-# CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
-# CHECK-DAG: If [<<ArgZ>>] loop:<<HeaderY>>
-# CHECK-DAG: If [<<Cst1>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add5>> Add [<<PhiX>>,<<Cst5>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
-# CHECK-DAG: Return [<<PhiX>>] loop:none
-
-# CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (after)
-# CHECK-DAG: <<ArgX:i\d+>> ParameterValue
-# CHECK-DAG: <<ArgY:z\d+>> ParameterValue
-# CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
-# CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
-# CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
-# CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
-# CHECK-DAG: If [<<ArgZ>>] loop:none
-# CHECK-DAG: Return [<<PhiX>>] loop:none
+## CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (before)
+## CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+## CHECK-DAG: <<ArgY:z\d+>> ParameterValue
+## CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
+## CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
+## CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
+## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
+## CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
+## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
+## CHECK-DAG: If [<<ArgZ>>] loop:<<HeaderY>>
+## CHECK-DAG: If [<<Cst1>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add5>> Add [<<PhiX>>,<<Cst5>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
+## CHECK-DAG: Return [<<PhiX>>] loop:none
+
+## CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (after)
+## CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+## CHECK-DAG: <<ArgY:z\d+>> ParameterValue
+## CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
+## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
+## CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
+## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
+## CHECK-DAG: If [<<ArgZ>>] loop:none
+## CHECK-DAG: Return [<<PhiX>>] loop:none
.method public static testMultipleExits(IZZ)I
.registers 4
@@ -129,37 +129,37 @@
.end method
-# CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (before)
-# CHECK-DAG: <<ArgX:i\d+>> ParameterValue
-# CHECK-DAG: <<ArgY:z\d+>> ParameterValue
-# CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
-# CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
-# CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
-# CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
-# CHECK-DAG: <<Cst9:i\d+>> IntConstant 9
-# CHECK-DAG: <<PhiX1:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
-# CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
-# CHECK-DAG: If [<<ArgZ>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Mul9:i\d+>> Mul [<<PhiX1>>,<<Cst9>>] loop:<<HeaderY>>
-# CHECK-DAG: <<PhiX2:i\d+>> Phi [<<Mul9>>,<<PhiX1>>] loop:<<HeaderY>>
-# CHECK-DAG: If [<<Cst1>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add5>> Add [<<PhiX2>>,<<Cst5>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add7>> Add [<<PhiX1>>,<<Cst7>>] loop:<<HeaderY>>
-# CHECK-DAG: Return [<<PhiX2>>] loop:none
-
-# CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (after)
-# CHECK-DAG: <<ArgX:i\d+>> ParameterValue
-# CHECK-DAG: <<ArgY:z\d+>> ParameterValue
-# CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
-# CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
-# CHECK-DAG: <<Cst9:i\d+>> IntConstant 9
-# CHECK-DAG: <<PhiX1:i\d+>> Phi [<<ArgX>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
-# CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add7>> Add [<<PhiX1>>,<<Cst7>>] loop:<<HeaderY>>
-# CHECK-DAG: If [<<ArgZ>>] loop:none
-# CHECK-DAG: <<Mul9:i\d+>> Mul [<<PhiX1>>,<<Cst9>>] loop:none
-# CHECK-DAG: <<PhiX2:i\d+>> Phi [<<Mul9>>,<<PhiX1>>] loop:none
-# CHECK-DAG: Return [<<PhiX2>>] loop:none
+## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (before)
+## CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+## CHECK-DAG: <<ArgY:z\d+>> ParameterValue
+## CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
+## CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
+## CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
+## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
+## CHECK-DAG: <<Cst9:i\d+>> IntConstant 9
+## CHECK-DAG: <<PhiX1:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
+## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
+## CHECK-DAG: If [<<ArgZ>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Mul9:i\d+>> Mul [<<PhiX1>>,<<Cst9>>] loop:<<HeaderY>>
+## CHECK-DAG: <<PhiX2:i\d+>> Phi [<<Mul9>>,<<PhiX1>>] loop:<<HeaderY>>
+## CHECK-DAG: If [<<Cst1>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add5>> Add [<<PhiX2>>,<<Cst5>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add7>> Add [<<PhiX1>>,<<Cst7>>] loop:<<HeaderY>>
+## CHECK-DAG: Return [<<PhiX2>>] loop:none
+
+## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (after)
+## CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+## CHECK-DAG: <<ArgY:z\d+>> ParameterValue
+## CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
+## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
+## CHECK-DAG: <<Cst9:i\d+>> IntConstant 9
+## CHECK-DAG: <<PhiX1:i\d+>> Phi [<<ArgX>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
+## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add7>> Add [<<PhiX1>>,<<Cst7>>] loop:<<HeaderY>>
+## CHECK-DAG: If [<<ArgZ>>] loop:none
+## CHECK-DAG: <<Mul9:i\d+>> Mul [<<PhiX1>>,<<Cst9>>] loop:none
+## CHECK-DAG: <<PhiX2:i\d+>> Phi [<<Mul9>>,<<PhiX1>>] loop:none
+## CHECK-DAG: Return [<<PhiX2>>] loop:none
.method public static testExitPredecessors(IZZ)I
.registers 4
@@ -196,48 +196,48 @@
.end method
-# CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (before)
-# CHECK-DAG: <<ArgX:i\d+>> ParameterValue
-# CHECK-DAG: <<ArgY:z\d+>> ParameterValue
-# CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
-# CHECK-DAG: <<Cst0:i\d+>> IntConstant 0
-# CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
-# CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
-# CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
+## CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (before)
+## CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+## CHECK-DAG: <<ArgY:z\d+>> ParameterValue
+## CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
+## CHECK-DAG: <<Cst0:i\d+>> IntConstant 0
+## CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
+## CHECK-DAG: <<Cst5:i\d+>> IntConstant 5
+## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
#
-# CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
-# CHECK-DAG: <<PhiZ1:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>,<<PhiZ1>>] loop:<<HeaderY>>
-# CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
+## CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
+## CHECK-DAG: <<PhiZ1:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>,<<PhiZ1>>] loop:<<HeaderY>>
+## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
#
-# ### Inner loop ###
-# CHECK-DAG: <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<XorZ>>] loop:<<HeaderZ:B\d+>>
-# CHECK-DAG: <<XorZ>> Xor [<<PhiZ2>>,<<Cst1>>] loop:<<HeaderZ>>
-# CHECK-DAG: <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>] loop:<<HeaderZ>>
-# CHECK-DAG: If [<<CondZ>>] loop:<<HeaderZ>>
+# ### Inner loop ###
+## CHECK-DAG: <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<XorZ>>] loop:<<HeaderZ:B\d+>>
+## CHECK-DAG: <<XorZ>> Xor [<<PhiZ2>>,<<Cst1>>] loop:<<HeaderZ>>
+## CHECK-DAG: <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>] loop:<<HeaderZ>>
+## CHECK-DAG: If [<<CondZ>>] loop:<<HeaderZ>>
#
-# CHECK-DAG: <<Add5>> Add [<<PhiX>>,<<Cst5>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
-# CHECK-DAG: Return [<<PhiX>>] loop:none
-
-# CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (after)
-# CHECK-DAG: <<ArgX:i\d+>> ParameterValue
-# CHECK-DAG: <<ArgY:z\d+>> ParameterValue
-# CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
-# CHECK-DAG: <<Cst0:i\d+>> IntConstant 0
-# CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
-# CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
+## CHECK-DAG: <<Add5>> Add [<<PhiX>>,<<Cst5>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
+## CHECK-DAG: Return [<<PhiX>>] loop:none
+
+## CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (after)
+## CHECK-DAG: <<ArgX:i\d+>> ParameterValue
+## CHECK-DAG: <<ArgY:z\d+>> ParameterValue
+## CHECK-DAG: <<ArgZ:z\d+>> ParameterValue
+## CHECK-DAG: <<Cst0:i\d+>> IntConstant 0
+## CHECK-DAG: <<Cst1:i\d+>> IntConstant 1
+## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7
#
-# CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
-# CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
-# CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
+## CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
+## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>>
+## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>>
#
-# ### Inner loop ###
-# CHECK-DAG: <<PhiZ:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>] loop:<<HeaderZ:B\d+>>
-# CHECK-DAG: <<XorZ>> Xor [<<PhiZ>>,<<Cst1>>] loop:<<HeaderZ>>
-# CHECK-DAG: <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>] loop:<<HeaderZ>>
-# CHECK-DAG: If [<<CondZ>>] loop:<<HeaderZ>>
+# ### Inner loop ###
+## CHECK-DAG: <<PhiZ:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>] loop:<<HeaderZ:B\d+>>
+## CHECK-DAG: <<XorZ>> Xor [<<PhiZ>>,<<Cst1>>] loop:<<HeaderZ>>
+## CHECK-DAG: <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>] loop:<<HeaderZ>>
+## CHECK-DAG: If [<<CondZ>>] loop:<<HeaderZ>>
#
-# CHECK-DAG: Return [<<PhiX>>] loop:none
+## CHECK-DAG: Return [<<PhiX>>] loop:none
.method public static testInnerLoop(IZZ)I
.registers 4
diff --git a/test/486-checker-must-do-null-check/src/Main.java b/test/486-checker-must-do-null-check/src/Main.java
index f285566ea7..ea72718ae0 100644
--- a/test/486-checker-must-do-null-check/src/Main.java
+++ b/test/486-checker-must-do-null-check/src/Main.java
@@ -15,8 +15,8 @@
*/
public class Main {
- // CHECK-START: void Main.InstanceOfPreChecked(java.lang.Object) instruction_simplifier (after)
- // CHECK: InstanceOf must_do_null_check:false
+ /// CHECK-START: void Main.InstanceOfPreChecked(java.lang.Object) instruction_simplifier (after)
+ /// CHECK: InstanceOf must_do_null_check:false
public void InstanceOfPreChecked(Object o) throws Exception {
o.toString();
if (o instanceof Main) {
@@ -24,23 +24,23 @@ public class Main {
}
}
- // CHECK-START: void Main.InstanceOf(java.lang.Object) instruction_simplifier (after)
- // CHECK: InstanceOf must_do_null_check:true
+ /// CHECK-START: void Main.InstanceOf(java.lang.Object) instruction_simplifier (after)
+ /// CHECK: InstanceOf must_do_null_check:true
public void InstanceOf(Object o) throws Exception {
if (o instanceof Main) {
throw new Exception();
}
}
- // CHECK-START: void Main.CheckCastPreChecked(java.lang.Object) instruction_simplifier (after)
- // CHECK: CheckCast must_do_null_check:false
+ /// CHECK-START: void Main.CheckCastPreChecked(java.lang.Object) instruction_simplifier (after)
+ /// CHECK: CheckCast must_do_null_check:false
public void CheckCastPreChecked(Object o) {
o.toString();
((Main)o).Bar();
}
- // CHECK-START: void Main.CheckCast(java.lang.Object) instruction_simplifier (after)
- // CHECK: CheckCast must_do_null_check:true
+ /// CHECK-START: void Main.CheckCast(java.lang.Object) instruction_simplifier (after)
+ /// CHECK: CheckCast must_do_null_check:true
public void CheckCast(Object o) {
((Main)o).Bar();
}
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 8b074ae04f..d224f43728 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -32,11 +32,14 @@ art_run_tests_dir := $(call intermediates-dir-for,PACKAGING,art-run-tests)/DATA
# an empty file touched in the intermediate directory.
TEST_ART_RUN_TEST_BUILD_RULES :=
+# Dependencies for actually running a run-test.
+TEST_ART_RUN_TEST_DEPENDENCIES := $(DX) $(HOST_OUT_EXECUTABLES)/jasmin $(HOST_OUT_EXECUTABLES)/smali $(HOST_OUT_EXECUTABLES)/dexmerger
+
# Helper to create individual build targets for tests. Must be called with $(eval).
# $(1): the test number
define define-build-art-run-test
dmart_target := $(art_run_tests_dir)/art-run-tests/$(1)/touch
-$$(dmart_target): $(DX) $(HOST_OUT_EXECUTABLES)/jasmin $(HOST_OUT_EXECUTABLES)/smali $(HOST_OUT_EXECUTABLES)/dexmerger
+$$(dmart_target): $(TEST_ART_RUN_TEST_DEPENDENCIES)
$(hide) rm -rf $$(dir $$@) && mkdir -p $$(dir $$@)
$(hide) DX=$(abspath $(DX)) JASMIN=$(abspath $(HOST_OUT_EXECUTABLES)/jasmin) \
SMALI=$(abspath $(HOST_OUT_EXECUTABLES)/smali) \
diff --git a/tools/art b/tools/art
index f167a732c1..2ee894041f 100644
--- a/tools/art
+++ b/tools/art
@@ -97,7 +97,7 @@ ANDROID_DATA=$ANDROID_DATA \
-XXlib:$LIBART \
-Xnorelocate \
-Ximage:$ANDROID_ROOT/framework/core.art \
- -Xcompiler-option --include-debug-symbols \
+ -Xcompiler-option --generate-debug-info \
"$@"
EXIT_STATUS=$?
diff --git a/tools/buildbot-build.sh b/tools/buildbot-build.sh
new file mode 100755
index 0000000000..77e6b1ad14
--- /dev/null
+++ b/tools/buildbot-build.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+#
+# Copyright (C) 2015 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.
+
+if [ ! -d art ]; then
+ echo "Script needs to be run at the root of the android tree"
+ exit 1
+fi
+
+common_targets="vogar vogar.jar core-tests apache-harmony-jdwp-tests-hostdex out/host/linux-x86/bin/adb jsr166-tests"
+android_root="/data/local/tmp/system"
+linker="linker"
+mode="target"
+j_arg="-j$(nproc)"
+make_command=
+
+if [[ "$TARGET_PRODUCT" == "armv8" ]]; then
+ linker="linker64"
+fi
+
+if [[ "$ART_TEST_ANDROID_ROOT" != "" ]]; then
+ android_root="$ART_TEST_ANDROID_ROOT"
+fi
+
+while true; do
+ if [[ "$1" == "--host" ]]; then
+ mode="host"
+ shift
+ elif [[ "$1" == "--target" ]]; then
+ mode="target"
+ shift
+ elif [[ "$1" == "--32" ]]; then
+ linker="linker"
+ shift
+ elif [[ "$1" == "--64" ]]; then
+ linker="linker64"
+ shift
+ elif [[ "$1" == "--android-root" ]]; then
+ shift
+ android_root=$1
+ shift
+ elif [[ "$1" == -j* ]]; then
+ j_arg=$1
+ shift
+ elif [[ "$1" == "" ]]; then
+ break
+ fi
+done
+
+if [[ $mode == "host" ]]; then
+ make_command="make $j_arg build-art-host-tests $common_targets"
+ echo "Executing $make_command"
+ $make_command
+elif [[ $mode == "target" ]]; then
+ # We need to provide our own linker in case the linker on the device
+ # is out of date.
+ env="TARGET_GLOBAL_LDFLAGS=-Wl,-dynamic-linker=$android_root/bin/$linker"
+ # Use '-e' to force the override of TARGET_GLOBAL_LDFLAGS.
+ # Also, we build extra tools that will be used by tests, so that
+ # they are compiled with our own linker.
+ make_command="make -e $j_arg build-art-target-tests $common_targets libjavacrypto linker toybox toolbox sh"
+ echo "Executing env $env $make_command"
+ env $env $make_command
+fi
+
diff --git a/tools/checker/file_format/checker/parser.py b/tools/checker/file_format/checker/parser.py
index 4eed39129f..33735cbea0 100644
--- a/tools/checker/file_format/checker/parser.py
+++ b/tools/checker/file_format/checker/parser.py
@@ -12,18 +12,22 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from common.logger import Logger
from file_format.common import SplitStream
from file_format.checker.struct import CheckerFile, TestCase, TestAssertion, RegexExpression
import re
+def __isCheckerLine(line):
+ return line.startswith("///") or line.startswith("##")
+
def __extractLine(prefix, line):
""" Attempts to parse a check line. The regex searches for a comment symbol
followed by the CHECK keyword, given attribute and a colon at the very
beginning of the line. Whitespaces are ignored.
"""
rIgnoreWhitespace = r"\s*"
- rCommentSymbols = [r"//", r"#"]
+ rCommentSymbols = [r"///", r"##"]
regexPrefix = rIgnoreWhitespace + \
r"(" + r"|".join(rCommentSymbols) + r")" + \
rIgnoreWhitespace + \
@@ -37,13 +41,16 @@ def __extractLine(prefix, line):
else:
return None
-def __processLine(line, lineNo, prefix):
+def __processLine(line, lineNo, prefix, fileName):
""" This function is invoked on each line of the check file and returns a pair
which instructs the parser how the line should be handled. If the line is
to be included in the current check group, it is returned in the first
value. If the line starts a new check group, the name of the group is
returned in the second value.
"""
+ if not __isCheckerLine(line):
+ return None, None
+
# Lines beginning with 'CHECK-START' start a new test case.
startLine = __extractLine(prefix + "-START", line)
if startLine is not None:
@@ -69,8 +76,7 @@ def __processLine(line, lineNo, prefix):
if notLine is not None:
return (notLine, TestAssertion.Variant.Not, lineNo), None
- # Other lines are ignored.
- return None, None
+ Logger.fail("Checker assertion could not be parsed", fileName, lineNo)
def __isMatchAtStart(match):
""" Tests if the given Match occurred at the beginning of the line. """
@@ -137,9 +143,9 @@ def ParseCheckerAssertion(parent, line, variant, lineNo):
def ParseCheckerStream(fileName, prefix, stream):
checkerFile = CheckerFile(fileName)
- fnProcessLine = lambda line, lineNo: __processLine(line, lineNo, prefix)
+ fnProcessLine = lambda line, lineNo: __processLine(line, lineNo, prefix, fileName)
fnLineOutsideChunk = lambda line, lineNo: \
- Logger.fail("C1visualizer line not inside a group", fileName, lineNo)
+ Logger.fail("Checker line not inside a group", fileName, lineNo)
for caseName, caseLines, startLineNo in SplitStream(stream, fnProcessLine, fnLineOutsideChunk):
testCase = TestCase(checkerFile, caseName, startLineNo)
for caseLine in caseLines:
diff --git a/tools/checker/file_format/checker/test.py b/tools/checker/file_format/checker/test.py
index 453deedf46..ff24cc1239 100644
--- a/tools/checker/file_format/checker/test.py
+++ b/tools/checker/file_format/checker/test.py
@@ -26,43 +26,56 @@ CheckerException = SystemExit
class CheckerParser_PrefixTest(unittest.TestCase):
def tryParse(self, string):
- checkerText = u"// CHECK-START: pass\n" + ToUnicode(string)
- checkFile = ParseCheckerStream("<test-file>", "CHECK", io.StringIO(checkerText))
+ checkerText = u"/// CHECK-START: pass\n" + ToUnicode(string)
+ return ParseCheckerStream("<test-file>", "CHECK", io.StringIO(checkerText))
+
+ def assertParses(self, string):
+ checkFile = self.tryParse(string)
self.assertEqual(len(checkFile.testCases), 1)
- testCase = checkFile.testCases[0]
- return len(testCase.assertions) != 0
+ self.assertNotEqual(len(checkFile.testCases[0].assertions), 0)
- def test_InvalidFormat(self):
- self.assertFalse(self.tryParse("CHECK"))
- self.assertFalse(self.tryParse(":CHECK"))
- self.assertFalse(self.tryParse("CHECK:"))
- self.assertFalse(self.tryParse("//CHECK"))
- self.assertFalse(self.tryParse("#CHECK"))
+ def assertIgnored(self, string):
+ checkFile = self.tryParse(string)
+ self.assertEqual(len(checkFile.testCases), 1)
+ self.assertEqual(len(checkFile.testCases[0].assertions), 0)
- self.assertTrue(self.tryParse("//CHECK:foo"))
- self.assertTrue(self.tryParse("#CHECK:bar"))
+ def assertInvalid(self, string):
+ with self.assertRaises(CheckerException):
+ self.tryParse(string)
- def test_InvalidLabel(self):
- self.assertFalse(self.tryParse("//ACHECK:foo"))
- self.assertFalse(self.tryParse("#ACHECK:foo"))
+ def test_ValidFormat(self):
+ self.assertParses("///CHECK:foo")
+ self.assertParses("##CHECK:bar")
+
+ def test_InvalidFormat(self):
+ self.assertIgnored("CHECK")
+ self.assertIgnored(":CHECK")
+ self.assertIgnored("CHECK:")
+ self.assertIgnored("//CHECK")
+ self.assertIgnored("#CHECK")
+ self.assertInvalid("///CHECK")
+ self.assertInvalid("##CHECK")
+
+ def test_InvalidPrefix(self):
+ self.assertInvalid("///ACHECK:foo")
+ self.assertInvalid("##ACHECK:foo")
def test_NotFirstOnTheLine(self):
- self.assertFalse(self.tryParse("A// CHECK: foo"))
- self.assertFalse(self.tryParse("A # CHECK: foo"))
- self.assertFalse(self.tryParse("// // CHECK: foo"))
- self.assertFalse(self.tryParse("# # CHECK: foo"))
+ self.assertIgnored("A/// CHECK: foo")
+ self.assertIgnored("A # CHECK: foo")
+ self.assertInvalid("/// /// CHECK: foo")
+ self.assertInvalid("## ## CHECK: foo")
def test_WhitespaceAgnostic(self):
- self.assertTrue(self.tryParse(" //CHECK: foo"))
- self.assertTrue(self.tryParse("// CHECK: foo"))
- self.assertTrue(self.tryParse(" //CHECK: foo"))
- self.assertTrue(self.tryParse("// CHECK: foo"))
-
+ self.assertParses(" ///CHECK: foo")
+ self.assertParses("/// CHECK: foo")
+ self.assertParses(" ///CHECK: foo")
+ self.assertParses("/// CHECK: foo")
class CheckerParser_RegexExpressionTest(unittest.TestCase):
def parseAssertion(self, string, variant=""):
- checkerText = u"// CHECK-START: pass\n// CHECK" + ToUnicode(variant) + u": " + ToUnicode(string)
+ checkerText = u"/// CHECK-START: pass\n/// CHECK" + ToUnicode(variant) + u": " + ToUnicode(string)
checkerFile = ParseCheckerStream("<test-file>", "CHECK", io.StringIO(checkerText))
self.assertEqual(len(checkerFile.testCases), 1)
testCase = checkerFile.testCases[0]
@@ -204,9 +217,9 @@ class CheckerParser_FileLayoutTest(unittest.TestCase):
def test_SingleGroup(self):
self.assertParsesTo(
"""
- // CHECK-START: Example Group
- // CHECK: foo
- // CHECK: bar
+ /// CHECK-START: Example Group
+ /// CHECK: foo
+ /// CHECK: bar
""",
[ ( "Example Group", [ ("foo", TestAssertion.Variant.InOrder),
("bar", TestAssertion.Variant.InOrder) ] ) ])
@@ -214,12 +227,12 @@ class CheckerParser_FileLayoutTest(unittest.TestCase):
def test_MultipleGroups(self):
self.assertParsesTo(
"""
- // CHECK-START: Example Group1
- // CHECK: foo
- // CHECK: bar
- // CHECK-START: Example Group2
- // CHECK: abc
- // CHECK: def
+ /// CHECK-START: Example Group1
+ /// CHECK: foo
+ /// CHECK: bar
+ /// CHECK-START: Example Group2
+ /// CHECK: abc
+ /// CHECK: def
""",
[ ( "Example Group1", [ ("foo", TestAssertion.Variant.InOrder),
("bar", TestAssertion.Variant.InOrder) ] ),
@@ -229,14 +242,14 @@ class CheckerParser_FileLayoutTest(unittest.TestCase):
def test_AssertionVariants(self):
self.assertParsesTo(
"""
- // CHECK-START: Example Group
- // CHECK: foo1
- // CHECK: foo2
- // CHECK-NEXT: foo3
- // CHECK-NEXT: foo4
- // CHECK-NOT: bar
- // CHECK-DAG: abc
- // CHECK-DAG: def
+ /// CHECK-START: Example Group
+ /// CHECK: foo1
+ /// CHECK: foo2
+ /// CHECK-NEXT: foo3
+ /// CHECK-NEXT: foo4
+ /// CHECK-NOT: bar
+ /// CHECK-DAG: abc
+ /// CHECK-DAG: def
""",
[ ( "Example Group", [ ("foo1", TestAssertion.Variant.InOrder),
("foo2", TestAssertion.Variant.InOrder),
@@ -250,20 +263,20 @@ class CheckerParser_FileLayoutTest(unittest.TestCase):
with self.assertRaises(CheckerException):
self.parse(
"""
- // CHECK-START: Example Group
- // CHECK-DAG: foo
- // CHECK-NEXT: bar
+ /// CHECK-START: Example Group
+ /// CHECK-DAG: foo
+ /// CHECK-NEXT: bar
""")
with self.assertRaises(CheckerException):
self.parse(
"""
- // CHECK-START: Example Group
- // CHECK-NOT: foo
- // CHECK-NEXT: bar
+ /// CHECK-START: Example Group
+ /// CHECK-NOT: foo
+ /// CHECK-NEXT: bar
""")
with self.assertRaises(CheckerException):
self.parse(
"""
- // CHECK-START: Example Group
- // CHECK-NEXT: bar
+ /// CHECK-START: Example Group
+ /// CHECK-NEXT: bar
""")
diff --git a/tools/checker/match/test.py b/tools/checker/match/test.py
index 348c1d2b30..ca748c7726 100644
--- a/tools/checker/match/test.py
+++ b/tools/checker/match/test.py
@@ -105,7 +105,7 @@ class MatchFiles_Test(unittest.TestCase):
def assertMatches(self, checkerString, c1String):
checkerString = \
"""
- // CHECK-START: MyMethod MyPass
+ /// CHECK-START: MyMethod MyPass
""" + checkerString
c1String = \
"""
@@ -131,18 +131,18 @@ class MatchFiles_Test(unittest.TestCase):
self.assertMatches(checkerString, c1String)
def test_Text(self):
- self.assertMatches("// CHECK: foo bar", "foo bar")
- self.assertDoesNotMatch("// CHECK: foo bar", "abc def")
+ self.assertMatches("/// CHECK: foo bar", "foo bar")
+ self.assertDoesNotMatch("/// CHECK: foo bar", "abc def")
def test_Pattern(self):
- self.assertMatches("// CHECK: abc {{de.}}", "abc de#")
- self.assertDoesNotMatch("// CHECK: abc {{de.}}", "abc d#f")
+ self.assertMatches("/// CHECK: abc {{de.}}", "abc de#")
+ self.assertDoesNotMatch("/// CHECK: abc {{de.}}", "abc d#f")
def test_Variables(self):
self.assertMatches(
"""
- // CHECK: foo<<X:.>>bar
- // CHECK: abc<<X>>def
+ /// CHECK: foo<<X:.>>bar
+ /// CHECK: abc<<X>>def
""",
"""
foo0bar
@@ -150,9 +150,9 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertMatches(
"""
- // CHECK: foo<<X:([0-9]+)>>bar
- // CHECK: abc<<X>>def
- // CHECK: ### <<X>> ###
+ /// CHECK: foo<<X:([0-9]+)>>bar
+ /// CHECK: abc<<X>>def
+ /// CHECK: ### <<X>> ###
""",
"""
foo1234bar
@@ -161,8 +161,8 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK: foo<<X:([0-9]+)>>bar
- // CHECK: abc<<X>>def
+ /// CHECK: foo<<X:([0-9]+)>>bar
+ /// CHECK: abc<<X>>def
""",
"""
foo1234bar
@@ -170,16 +170,16 @@ class MatchFiles_Test(unittest.TestCase):
""")
def test_WholeWordMustMatch(self):
- self.assertMatches("// CHECK: b{{.}}r", "abc bar def")
- self.assertDoesNotMatch("// CHECK: b{{.}}r", "abc Xbar def")
- self.assertDoesNotMatch("// CHECK: b{{.}}r", "abc barX def")
- self.assertDoesNotMatch("// CHECK: b{{.}}r", "abc b r def")
+ self.assertMatches("/// CHECK: b{{.}}r", "abc bar def")
+ self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc Xbar def")
+ self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc barX def")
+ self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc b r def")
def test_InOrderAssertions(self):
self.assertMatches(
"""
- // CHECK: foo
- // CHECK: bar
+ /// CHECK: foo
+ /// CHECK: bar
""",
"""
foo
@@ -187,8 +187,8 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK: foo
- // CHECK: bar
+ /// CHECK: foo
+ /// CHECK: bar
""",
"""
bar
@@ -198,10 +198,10 @@ class MatchFiles_Test(unittest.TestCase):
def test_NextLineAssertions(self):
self.assertMatches(
"""
- // CHECK: foo
- // CHECK-NEXT: bar
- // CHECK-NEXT: abc
- // CHECK: def
+ /// CHECK: foo
+ /// CHECK-NEXT: bar
+ /// CHECK-NEXT: abc
+ /// CHECK: def
""",
"""
foo
@@ -211,9 +211,9 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertMatches(
"""
- // CHECK: foo
- // CHECK-NEXT: bar
- // CHECK: def
+ /// CHECK: foo
+ /// CHECK-NEXT: bar
+ /// CHECK: def
""",
"""
foo
@@ -223,8 +223,8 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK: foo
- // CHECK-NEXT: bar
+ /// CHECK: foo
+ /// CHECK-NEXT: bar
""",
"""
foo
@@ -234,8 +234,8 @@ class MatchFiles_Test(unittest.TestCase):
self.assertDoesNotMatch(
"""
- // CHECK: foo
- // CHECK-NEXT: bar
+ /// CHECK: foo
+ /// CHECK-NEXT: bar
""",
"""
bar
@@ -246,8 +246,8 @@ class MatchFiles_Test(unittest.TestCase):
def test_DagAssertions(self):
self.assertMatches(
"""
- // CHECK-DAG: foo
- // CHECK-DAG: bar
+ /// CHECK-DAG: foo
+ /// CHECK-DAG: bar
""",
"""
foo
@@ -255,8 +255,8 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertMatches(
"""
- // CHECK-DAG: foo
- // CHECK-DAG: bar
+ /// CHECK-DAG: foo
+ /// CHECK-DAG: bar
""",
"""
bar
@@ -266,10 +266,10 @@ class MatchFiles_Test(unittest.TestCase):
def test_DagAssertionsScope(self):
self.assertMatches(
"""
- // CHECK: foo
- // CHECK-DAG: abc
- // CHECK-DAG: def
- // CHECK: bar
+ /// CHECK: foo
+ /// CHECK-DAG: abc
+ /// CHECK-DAG: def
+ /// CHECK: bar
""",
"""
foo
@@ -279,10 +279,10 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK: foo
- // CHECK-DAG: abc
- // CHECK-DAG: def
- // CHECK: bar
+ /// CHECK: foo
+ /// CHECK-DAG: abc
+ /// CHECK-DAG: def
+ /// CHECK: bar
""",
"""
foo
@@ -292,10 +292,10 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK: foo
- // CHECK-DAG: abc
- // CHECK-DAG: def
- // CHECK: bar
+ /// CHECK: foo
+ /// CHECK-DAG: abc
+ /// CHECK-DAG: def
+ /// CHECK: bar
""",
"""
foo
@@ -307,7 +307,7 @@ class MatchFiles_Test(unittest.TestCase):
def test_NotAssertions(self):
self.assertMatches(
"""
- // CHECK-NOT: foo
+ /// CHECK-NOT: foo
""",
"""
abc
@@ -315,7 +315,7 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK-NOT: foo
+ /// CHECK-NOT: foo
""",
"""
abc foo
@@ -323,8 +323,8 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK-NOT: foo
- // CHECK-NOT: bar
+ /// CHECK-NOT: foo
+ /// CHECK-NOT: bar
""",
"""
abc
@@ -334,9 +334,9 @@ class MatchFiles_Test(unittest.TestCase):
def test_NotAssertionsScope(self):
self.assertMatches(
"""
- // CHECK: abc
- // CHECK-NOT: foo
- // CHECK: def
+ /// CHECK: abc
+ /// CHECK-NOT: foo
+ /// CHECK: def
""",
"""
abc
@@ -344,9 +344,9 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertMatches(
"""
- // CHECK: abc
- // CHECK-NOT: foo
- // CHECK: def
+ /// CHECK: abc
+ /// CHECK-NOT: foo
+ /// CHECK: def
""",
"""
abc
@@ -355,9 +355,9 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK: abc
- // CHECK-NOT: foo
- // CHECK: def
+ /// CHECK: abc
+ /// CHECK-NOT: foo
+ /// CHECK: def
""",
"""
abc
@@ -368,8 +368,8 @@ class MatchFiles_Test(unittest.TestCase):
def test_LineOnlyMatchesOnce(self):
self.assertMatches(
"""
- // CHECK-DAG: foo
- // CHECK-DAG: foo
+ /// CHECK-DAG: foo
+ /// CHECK-DAG: foo
""",
"""
foo
@@ -378,8 +378,8 @@ class MatchFiles_Test(unittest.TestCase):
""")
self.assertDoesNotMatch(
"""
- // CHECK-DAG: foo
- // CHECK-DAG: foo
+ /// CHECK-DAG: foo
+ /// CHECK-DAG: foo
""",
"""
foo
diff --git a/tools/libcore_failures.txt b/tools/libcore_failures.txt
index 064abc1f03..b053f0d844 100644
--- a/tools/libcore_failures.txt
+++ b/tools/libcore_failures.txt
@@ -36,14 +36,20 @@
names: ["libcore.io.OsTest#testUnixDomainSockets_in_file_system"]
},
{
- description: "Failures needing investigation",
+ description: "Issue with incorrect device time (1970)",
result: EXEC_FAILED,
modes: [device],
names: ["libcore.java.util.TimeZoneTest#testDisplayNames",
"libcore.java.util.TimeZoneTest#test_useDaylightTime_Taiwan",
- "org.apache.harmony.tests.java.util.DateTest#test_Constructor",
- "org.apache.harmony.tests.java.util.ScannerTest#test_Constructor_LReadableByteChannel",
- "org.apache.harmony.tests.java.util.TimeZoneTest#test_hasSameRules_Ljava_util_TimeZone"]
+ "org.apache.harmony.tests.java.util.TimeZoneTest#test_hasSameRules_Ljava_util_TimeZone"],
+ bug: 20879084
+},
+{
+ description: "Issue with incorrect device time (1970). Test assumes that DateTime.now()
+ is greater then a date in 1998.",
+ result: EXEC_FAILED,
+ modes: [device],
+ names: ["org.apache.harmony.tests.java.util.DateTest#test_Constructor"]
},
{
description: "Failing due to a locale problem on hammerhead.",
@@ -75,7 +81,8 @@
"libcore.net.NetworkSecurityPolicyTest#testCleartextTrafficPolicyWithJarHttpURLConnection",
"org.apache.harmony.luni.tests.internal.net.www.protocol.http.HttpURLConnectionTest",
"org.apache.harmony.luni.tests.internal.net.www.protocol.https.HttpsURLConnectionTest",
- "org.apache.harmony.luni.tests.java.net.URLConnectionTest"
+ "org.apache.harmony.luni.tests.java.net.URLConnectionTest",
+ "org.apache.harmony.tests.java.util.ScannerTest#test_Constructor_LReadableByteChannel"
]
},
{