summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/Android.gtest.mk4
-rw-r--r--cmdline/cmdline.h12
-rw-r--r--compiler/dex/dex_to_dex_compiler.cc4
-rw-r--r--compiler/driver/dex_compilation_unit.cc1
-rw-r--r--compiler/elf_writer_test.cc1
-rw-r--r--compiler/image_test.cc5
-rw-r--r--compiler/image_writer.cc14
-rw-r--r--compiler/jit/jit_compiler.cc4
-rw-r--r--compiler/oat_test.cc4
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc73
-rw-r--r--compiler/optimizing/common_arm.h18
-rw-r--r--compiler/optimizing/graph_checker.cc5
-rw-r--r--compiler/optimizing/graph_test.cc1
-rw-r--r--compiler/optimizing/induction_var_analysis.cc61
-rw-r--r--compiler/optimizing/induction_var_analysis.h13
-rw-r--r--compiler/optimizing/induction_var_analysis_test.cc41
-rw-r--r--compiler/optimizing/induction_var_range.cc6
-rw-r--r--compiler/optimizing/instruction_simplifier.cc3
-rw-r--r--compiler/optimizing/intrinsics_arm_vixl.cc2
-rw-r--r--compiler/optimizing/linearize_test.cc1
-rw-r--r--compiler/optimizing/optimizing_compiler.cc3
-rw-r--r--compiler/optimizing/pretty_printer.h5
-rw-r--r--compiler/optimizing/pretty_printer_test.cc1
-rw-r--r--compiler/optimizing/ssa_test.cc5
-rw-r--r--compiler/utils/arm/assembler_thumb2_test.cc5
-rw-r--r--compiler/utils/dedupe_set-inl.h17
-rw-r--r--dex2oat/dex2oat.cc4
-rw-r--r--dex2oat/dex2oat_test.cc11
-rw-r--r--dexdump/dexdump.cc9
-rw-r--r--dexdump/dexdump_test.cc1
-rw-r--r--dexlayout/dexlayout.cc5
-rw-r--r--dexlayout/dexlayout_test.cc1
-rw-r--r--dexlist/dexlist_test.cc1
-rw-r--r--imgdiag/imgdiag.cc5
-rw-r--r--imgdiag/imgdiag_test.cc5
-rw-r--r--oatdump/oatdump.cc9
-rw-r--r--oatdump/oatdump_test.cc1
-rw-r--r--patchoat/patchoat.cc4
-rw-r--r--profman/profman.cc4
-rw-r--r--runtime/Android.bp2
-rw-r--r--runtime/arch/arm/instruction_set_features_arm.cc6
-rw-r--r--runtime/arch/arm64/instruction_set_features_arm64.cc6
-rw-r--r--runtime/arch/instruction_set_features_test.cc5
-rw-r--r--runtime/arch/instruction_set_test.cc1
-rw-r--r--runtime/arch/mips/instruction_set_features_mips.cc6
-rw-r--r--runtime/arch/mips64/instruction_set_features_mips64.cc6
-rw-r--r--runtime/arch/x86/instruction_set_features_x86.cc6
-rw-r--r--runtime/art_method.cc4
-rw-r--r--runtime/asm_support.h10
-rw-r--r--runtime/base/file_magic.cc5
-rw-r--r--runtime/base/mutex-inl.h1
-rw-r--r--runtime/base/mutex.cc4
-rw-r--r--runtime/base/scoped_flock.cc5
-rw-r--r--runtime/base/stringprintf.cc81
-rw-r--r--runtime/base/stringprintf.h38
-rw-r--r--runtime/base/time_utils.cc5
-rw-r--r--runtime/check_jni.cc5
-rw-r--r--runtime/class_linker-inl.h2
-rw-r--r--runtime/class_linker.cc164
-rw-r--r--runtime/class_linker_test.cc21
-rw-r--r--runtime/common_runtime_test.cc5
-rw-r--r--runtime/common_throws.cc4
-rw-r--r--runtime/debugger.cc4
-rw-r--r--runtime/dex_file.cc5
-rw-r--r--runtime/dex_file_annotations.cc4
-rw-r--r--runtime/dex_file_verifier.cc6
-rw-r--r--runtime/dex_instruction.cc5
-rw-r--r--runtime/elf_file.cc4
-rw-r--r--runtime/gc/accounting/space_bitmap.cc5
-rw-r--r--runtime/gc/allocator/rosalloc.cc14
-rw-r--r--runtime/gc/collector/garbage_collector.cc4
-rw-r--r--runtime/gc/heap.cc6
-rw-r--r--runtime/gc/space/image_space.cc4
-rw-r--r--runtime/gc/space/image_space_fs.h5
-rw-r--r--runtime/gc/space/malloc_space.cc4
-rw-r--r--runtime/generated/asm_support_gen.h2
-rw-r--r--runtime/hprof/hprof.cc8
-rw-r--r--runtime/image.cc2
-rw-r--r--runtime/image.h5
-rw-r--r--runtime/indirect_reference_table-inl.h18
-rw-r--r--runtime/indirect_reference_table_test.cc4
-rw-r--r--runtime/instrumentation.cc12
-rw-r--r--runtime/interpreter/interpreter_common.cc2
-rw-r--r--runtime/interpreter/interpreter_common.h8
-rw-r--r--runtime/interpreter/unstarted_runtime.cc4
-rw-r--r--runtime/java_vm_ext.cc5
-rw-r--r--runtime/jdwp/jdwp_adb.cc5
-rw-r--r--runtime/jdwp/jdwp_event.cc5
-rw-r--r--runtime/jdwp/jdwp_handler.cc5
-rw-r--r--runtime/jdwp/jdwp_main.cc4
-rw-r--r--runtime/jdwp/jdwp_request.cc5
-rw-r--r--runtime/jdwp/jdwp_socket.cc5
-rw-r--r--runtime/jit/jit_code_cache.cc23
-rw-r--r--runtime/jit/jit_code_cache.h15
-rw-r--r--runtime/jni_env_ext.cc4
-rw-r--r--runtime/jni_internal_test.cc4
-rw-r--r--runtime/mem_map.cc5
-rw-r--r--runtime/method_handles.cc7
-rw-r--r--runtime/mirror/array-inl.h9
-rw-r--r--runtime/mirror/array.cc5
-rw-r--r--runtime/mirror/class-inl.h14
-rw-r--r--runtime/mirror/class.cc5
-rw-r--r--runtime/mirror/class.h10
-rw-r--r--runtime/mirror/object_array-inl.h17
-rw-r--r--runtime/mirror/string-inl.h12
-rw-r--r--runtime/mirror/throwable.cc4
-rw-r--r--runtime/monitor.cc4
-rw-r--r--runtime/native/dalvik_system_DexFile.cc5
-rw-r--r--runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc4
-rw-r--r--runtime/native/dalvik_system_VMRuntime.cc4
-rw-r--r--runtime/native/dalvik_system_ZygoteHooks.cc4
-rw-r--r--runtime/native/java_lang_ref_Reference.cc4
-rw-r--r--runtime/native/java_lang_reflect_Executable.cc4
-rw-r--r--runtime/native/java_lang_reflect_Field.cc4
-rw-r--r--runtime/native/java_lang_reflect_Parameter.cc4
-rw-r--r--runtime/native_stack_dump.cc5
-rw-r--r--runtime/oat.cc5
-rw-r--r--runtime/oat_file.cc4
-rw-r--r--runtime/oat_file_assistant.cc1
-rw-r--r--runtime/oat_file_manager.cc4
-rw-r--r--runtime/openjdkjvmti/OpenjdkJvmTi.cc2
-rw-r--r--runtime/openjdkjvmti/ti_method.cc59
-rw-r--r--runtime/openjdkjvmti/ti_method.h5
-rw-r--r--runtime/openjdkjvmti/ti_redefine.cc13
-rw-r--r--runtime/parsed_options_test.cc1
-rw-r--r--runtime/plugin.cc6
-rw-r--r--runtime/reference_table.cc5
-rw-r--r--runtime/reference_table_test.cc4
-rw-r--r--runtime/reflection-inl.h16
-rw-r--r--runtime/reflection.cc2
-rw-r--r--runtime/runtime.cc2
-rw-r--r--runtime/runtime_android.cc1
-rw-r--r--runtime/runtime_linux.cc5
-rw-r--r--runtime/stack.cc4
-rw-r--r--runtime/thread.cc5
-rw-r--r--runtime/thread_list.cc4
-rw-r--r--runtime/thread_pool.cc4
-rw-r--r--runtime/ti/agent.cc5
-rw-r--r--runtime/ti/agent.h1
-rw-r--r--runtime/trace.cc4
-rw-r--r--runtime/utils.cc4
-rw-r--r--runtime/utils.h6
-rw-r--r--runtime/verifier/method_verifier.cc4
-rw-r--r--runtime/verifier/reg_type.cc4
-rw-r--r--runtime/verifier/register_line.cc5
-rw-r--r--runtime/well_known_classes.cc4
-rw-r--r--runtime/zip_archive.cc1
-rw-r--r--test/137-cfi/cfi.cc4
-rw-r--r--test/530-checker-loops4/src/Main.java28
-rw-r--r--test/618-checker-induction/src/Main.java28
-rw-r--r--test/624-checker-stringops/src/Main.java16
-rw-r--r--test/911-get-stack-trace/expected.txt358
-rw-r--r--test/911-get-stack-trace/stack_trace.cc53
-rw-r--r--test/913-heaps/expected.txt16
-rw-r--r--test/913-heaps/heaps.cc7
-rw-r--r--test/Android.run-test.mk18
-rw-r--r--test/ErroneousA/ErroneousA.java17
-rw-r--r--test/ErroneousB/ErroneousB.java (renamed from runtime/base/stringprintf_test.cc)17
-rw-r--r--tools/cpp-define-generator/offset_dexcache.def1
-rwxr-xr-xtools/jfuzz/run_jfuzz_test.py23
160 files changed, 1181 insertions, 701 deletions
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index d59d8f690c..bd7f900965 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -26,6 +26,8 @@ GTEST_DEX_DIRECTORIES := \
AbstractMethod \
AllFields \
DexToDexDecompiler \
+ ErroneousA \
+ ErroneousB \
ExceptionHandle \
GetMethodSignature \
ImageLayoutA \
@@ -85,7 +87,7 @@ $(ART_TEST_TARGET_GTEST_VerifierDeps_DEX): $(ART_TEST_GTEST_VerifierDeps_SRC) $(
ART_GTEST_dex2oat_environment_tests_DEX_DEPS := Main MainStripped MultiDex MultiDexModifiedSecondary Nested
ART_GTEST_atomic_method_ref_map_test_DEX_DEPS := Interfaces
-ART_GTEST_class_linker_test_DEX_DEPS := Interfaces MethodTypes MultiDex MyClass Nested Statics StaticsFromCode
+ART_GTEST_class_linker_test_DEX_DEPS := ErroneousA ErroneousB Interfaces MethodTypes MultiDex MyClass Nested Statics StaticsFromCode
ART_GTEST_class_table_test_DEX_DEPS := XandY
ART_GTEST_compiler_driver_test_DEX_DEPS := AbstractMethod StaticLeafMethods ProfileTestMultiDex
ART_GTEST_dex_cache_test_DEX_DEPS := Main Packages MethodTypes
diff --git a/cmdline/cmdline.h b/cmdline/cmdline.h
index 6e042c3c27..f4540ff655 100644
--- a/cmdline/cmdline.h
+++ b/cmdline/cmdline.h
@@ -24,10 +24,12 @@
#include <iostream>
#include <string>
-#include "runtime.h"
+#include "android-base/stringprintf.h"
+
+#include "base/logging.h"
#include "base/stringpiece.h"
#include "noop_compiler_callbacks.h"
-#include "base/logging.h"
+#include "runtime.h"
#if !defined(NDEBUG)
#define DBG_LOG LOG(INFO)
@@ -197,7 +199,7 @@ struct CmdlineArgs {
" Example: --boot-image=/system/framework/boot.art\n"
" (specifies /system/framework/<arch>/boot.art as the image file)\n"
"\n";
- usage += StringPrintf( // Optional.
+ usage += android::base::StringPrintf( // Optional.
" --instruction-set=(arm|arm64|mips|mips64|x86|x86_64): for locating the image\n"
" file based on the image location set.\n"
" Example: --instruction-set=x86\n"
@@ -264,8 +266,8 @@ struct CmdlineArgs {
// Check that the boot image location points to a valid file name.
std::string file_name;
if (!LocationToFilename(boot_image_location, instruction_set_, &file_name)) {
- *error_msg = StringPrintf("No corresponding file for location '%s' exists",
- file_name.c_str());
+ *error_msg = android::base::StringPrintf("No corresponding file for location '%s' exists",
+ file_name.c_str());
return false;
}
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index cf69f469a0..d4f6545c59 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -16,6 +16,8 @@
#include "dex_to_dex_compiler.h"
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/logging.h"
@@ -32,6 +34,8 @@
namespace art {
namespace optimizer {
+using android::base::StringPrintf;
+
// Controls quickening activation.
const bool kEnableQuickening = true;
// Control check-cast elision.
diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc
index 64fd9e7f0f..47b19297e5 100644
--- a/compiler/driver/dex_compilation_unit.cc
+++ b/compiler/driver/dex_compilation_unit.cc
@@ -16,7 +16,6 @@
#include "dex_compilation_unit.h"
-#include "base/stringprintf.h"
#include "mirror/dex_cache.h"
#include "utils.h"
diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc
index 6f48779258..9669c4a9d3 100644
--- a/compiler/elf_writer_test.cc
+++ b/compiler/elf_writer_test.cc
@@ -16,7 +16,6 @@
#include "elf_file.h"
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
#include "common_compiler_test.h"
#include "elf_file.h"
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 9bbe595fa9..1290379569 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -20,6 +20,8 @@
#include <string>
#include <vector>
+#include "android-base/stringprintf.h"
+
#include "base/unix_file/fd_file.h"
#include "class_linker-inl.h"
#include "common_compiler_test.h"
@@ -134,7 +136,8 @@ void CompilationHelper::Compile(CompilerDriver* driver,
// Create a generic tmp file, to be the base of the .art and .oat temporary files.
ScratchFile location;
for (int i = 0; i < static_cast<int>(class_path.size()); ++i) {
- std::string cur_location(StringPrintf("%s-%d.art", location.GetFilename().c_str(), i));
+ std::string cur_location =
+ android::base::StringPrintf("%s-%d.art", location.GetFilename().c_str(), i);
image_locations.push_back(ScratchFile(cur_location));
}
}
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index b22ca470b5..9c38445276 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -1113,11 +1113,15 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots(size_t oat_index) const {
}
// build an Object[] of the roots needed to restore the runtime
+ int32_t image_roots_size = ImageHeader::NumberOfImageRoots(compile_app_image_);
auto image_roots(hs.NewHandle(
- ObjectArray<Object>::Alloc(self, object_array_class.Get(), ImageHeader::kImageRootsMax)));
+ ObjectArray<Object>::Alloc(self, object_array_class.Get(), image_roots_size)));
image_roots->Set<false>(ImageHeader::kDexCaches, dex_caches.Get());
image_roots->Set<false>(ImageHeader::kClassRoots, class_linker->GetClassRoots());
- for (int i = 0; i < ImageHeader::kImageRootsMax; i++) {
+ // image_roots[ImageHeader::kClassLoader] will be set later for app image.
+ static_assert(ImageHeader::kClassLoader + 1u == ImageHeader::kImageRootsMax,
+ "Class loader should be the last image root.");
+ for (int32_t i = 0; i < ImageHeader::kImageRootsMax - 1; ++i) {
CHECK(image_roots->Get(i) != nullptr);
}
return image_roots.Get();
@@ -1539,6 +1543,12 @@ void ImageWriter::CalculateNewObjectOffsets() {
}
// Process the work stack in case anything was added by TryAssignBinSlot.
ProcessWorkStack(&work_stack);
+
+ // Store the class loader in the class roots.
+ CHECK_EQ(class_loaders_.size(), 1u);
+ CHECK_EQ(image_roots.size(), 1u);
+ CHECK(*class_loaders_.begin() != nullptr);
+ image_roots[0]->Set<false>(ImageHeader::kClassLoader, *class_loaders_.begin());
}
// Verify that all objects have assigned image bin slots.
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index 9dfb434b10..148ce4f9ee 100644
--- a/compiler/jit/jit_compiler.cc
+++ b/compiler/jit/jit_compiler.cc
@@ -16,6 +16,8 @@
#include "jit_compiler.h"
+#include "android-base/stringprintf.h"
+
#include "arch/instruction_set.h"
#include "arch/instruction_set_features.h"
#include "art_method-inl.h"
@@ -81,7 +83,7 @@ NO_RETURN static void Usage(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
std::string error;
- StringAppendV(&error, fmt, ap);
+ android::base::StringAppendV(&error, fmt, ap);
LOG(FATAL) << error;
va_end(ap);
exit(EXIT_FAILURE);
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 0a778b0954..edc93ab0c4 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "android-base/stringprintf.h"
+
#include "arch/instruction_set_features.h"
#include "art_method-inl.h"
#include "base/enums.h"
@@ -48,7 +50,7 @@ NO_RETURN static void Usage(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
std::string error;
- StringAppendV(&error, fmt, ap);
+ android::base::StringAppendV(&error, fmt, ap);
LOG(FATAL) << error;
va_end(ap);
UNREACHABLE();
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index 55f3c3ceef..1c5aec01c6 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -46,8 +46,10 @@ using helpers::InputOperandAt;
using helpers::InputRegister;
using helpers::InputRegisterAt;
using helpers::InputSRegisterAt;
+using helpers::InputVRegister;
using helpers::InputVRegisterAt;
using helpers::Int32ConstantFrom;
+using helpers::Int64ConstantFrom;
using helpers::LocationFrom;
using helpers::LowRegisterFrom;
using helpers::LowSRegisterFrom;
@@ -56,6 +58,7 @@ using helpers::OutputSRegister;
using helpers::OutputVRegister;
using helpers::RegisterFrom;
using helpers::SRegisterFrom;
+using helpers::Uint64ConstantFrom;
using vixl::ExactAssemblyScope;
using vixl::CodeBufferCheckScope;
@@ -1378,7 +1381,7 @@ void CodeGeneratorARMVIXL::GenerateFrameEntry() {
if (!skip_overflow_check) {
UseScratchRegisterScope temps(GetVIXLAssembler());
vixl32::Register temp = temps.Acquire();
- __ Sub(temp, sp, static_cast<int32_t>(GetStackOverflowReservedBytes(kArm)));
+ __ Sub(temp, sp, Operand::From(GetStackOverflowReservedBytes(kArm)));
// The load must immediately precede RecordPcInfo.
ExactAssemblyScope aas(GetVIXLAssembler(),
vixl32::kMaxInstructionSizeInBytes,
@@ -1795,7 +1798,7 @@ void InstructionCodeGeneratorARMVIXL::GenerateLongComparesAndJumps(HCondition* c
break;
}
if (right.IsConstant()) {
- int64_t value = right.GetConstant()->AsLongConstant()->GetValue();
+ int64_t value = Int64ConstantFrom(right);
int32_t val_low = Low32Bits(value);
int32_t val_high = High32Bits(value);
@@ -1880,7 +1883,7 @@ void InstructionCodeGeneratorARMVIXL::GenerateTestAndBranch(HInstruction* instru
__ B(true_target);
}
} else {
- DCHECK(cond->AsIntConstant()->IsFalse()) << cond->AsIntConstant()->GetValue();
+ DCHECK(cond->AsIntConstant()->IsFalse()) << Int32ConstantFrom(cond);
if (false_target != nullptr) {
__ B(false_target);
}
@@ -2482,9 +2485,7 @@ void InstructionCodeGeneratorARMVIXL::VisitNeg(HNeg* neg) {
case Primitive::kPrimFloat:
case Primitive::kPrimDouble:
- // TODO(VIXL): Consider introducing an InputVRegister()
- // helper function (equivalent to InputRegister()).
- __ Vneg(OutputVRegister(neg), InputVRegisterAt(neg, 0));
+ __ Vneg(OutputVRegister(neg), InputVRegister(neg));
break;
default:
@@ -2774,8 +2775,8 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve
} else {
DCHECK(in.IsConstant());
DCHECK(in.GetConstant()->IsLongConstant());
- int64_t value = in.GetConstant()->AsLongConstant()->GetValue();
- __ Mov(OutputRegister(conversion), static_cast<int32_t>(value));
+ int32_t value = Int32ConstantFrom(in);
+ __ Mov(OutputRegister(conversion), value);
}
break;
@@ -3114,8 +3115,8 @@ void InstructionCodeGeneratorARMVIXL::VisitMul(HMul* mul) {
// Extra checks to protect caused by the existence of R1_R2.
// The algorithm is wrong if out.hi is either in1.lo or in2.lo:
// (e.g. in1=r0_r1, in2=r2_r3 and out=r1_r2);
- DCHECK_NE(out_hi.GetCode(), in1_lo.GetCode());
- DCHECK_NE(out_hi.GetCode(), in2_lo.GetCode());
+ DCHECK(!out_hi.Is(in1_lo));
+ DCHECK(!out_hi.Is(in2_lo));
// input: in1 - 64 bits, in2 - 64 bits
// output: out
@@ -3155,7 +3156,7 @@ void InstructionCodeGeneratorARMVIXL::DivRemOneOrMinusOne(HBinaryOperation* inst
vixl32::Register out = OutputRegister(instruction);
vixl32::Register dividend = InputRegisterAt(instruction, 0);
- int32_t imm = second.GetConstant()->AsIntConstant()->GetValue();
+ int32_t imm = Int32ConstantFrom(second);
DCHECK(imm == 1 || imm == -1);
if (instruction->IsRem()) {
@@ -3180,7 +3181,7 @@ void InstructionCodeGeneratorARMVIXL::DivRemByPowerOfTwo(HBinaryOperation* instr
vixl32::Register out = OutputRegister(instruction);
vixl32::Register dividend = InputRegisterAt(instruction, 0);
vixl32::Register temp = RegisterFrom(locations->GetTemp(0));
- int32_t imm = second.GetConstant()->AsIntConstant()->GetValue();
+ int32_t imm = Int32ConstantFrom(second);
uint32_t abs_imm = static_cast<uint32_t>(AbsOrMin(imm));
int ctz_imm = CTZ(abs_imm);
@@ -3253,7 +3254,7 @@ void InstructionCodeGeneratorARMVIXL::GenerateDivRemConstantIntegral(
Location second = instruction->GetLocations()->InAt(1);
DCHECK(second.IsConstant());
- int32_t imm = second.GetConstant()->AsIntConstant()->GetValue();
+ int32_t imm = Int32ConstantFrom(second);
if (imm == 0) {
// Do not generate anything. DivZeroCheck would prevent any code to be executed.
} else if (imm == 1 || imm == -1) {
@@ -3287,7 +3288,7 @@ void LocationsBuilderARMVIXL::VisitDiv(HDiv* div) {
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::ConstantLocation(div->InputAt(1)->AsConstant()));
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
- int32_t value = div->InputAt(1)->AsIntConstant()->GetValue();
+ int32_t value = Int32ConstantFrom(div->InputAt(1));
if (value == 1 || value == 0 || value == -1) {
// No temp register required.
} else {
@@ -3400,7 +3401,7 @@ void LocationsBuilderARMVIXL::VisitRem(HRem* rem) {
locations->SetInAt(0, Location::RequiresRegister());
locations->SetInAt(1, Location::ConstantLocation(rem->InputAt(1)->AsConstant()));
locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap);
- int32_t value = rem->InputAt(1)->AsIntConstant()->GetValue();
+ int32_t value = Int32ConstantFrom(rem->InputAt(1));
if (value == 1 || value == 0 || value == -1) {
// No temp register required.
} else {
@@ -3535,7 +3536,7 @@ void InstructionCodeGeneratorARMVIXL::VisitDivZeroCheck(HDivZeroCheck* instructi
__ CompareAndBranchIfZero(InputRegisterAt(instruction, 0), slow_path->GetEntryLabel());
} else {
DCHECK(value.IsConstant()) << value;
- if (value.GetConstant()->AsIntConstant()->GetValue() == 0) {
+ if (Int32ConstantFrom(value) == 0) {
__ B(slow_path->GetEntryLabel());
}
}
@@ -3549,7 +3550,7 @@ void InstructionCodeGeneratorARMVIXL::VisitDivZeroCheck(HDivZeroCheck* instructi
__ B(eq, slow_path->GetEntryLabel());
} else {
DCHECK(value.IsConstant()) << value;
- if (value.GetConstant()->AsLongConstant()->GetValue() == 0) {
+ if (Int64ConstantFrom(value) == 0) {
__ B(slow_path->GetEntryLabel());
}
}
@@ -3759,7 +3760,7 @@ void InstructionCodeGeneratorARMVIXL::HandleShift(HBinaryOperation* op) {
__ Lsr(out_reg, first_reg, out_reg);
}
} else {
- int32_t cst = second.GetConstant()->AsIntConstant()->GetValue();
+ int32_t cst = Int32ConstantFrom(second);
uint32_t shift_value = cst & kMaxIntShiftDistance;
if (shift_value == 0) { // ARM does not support shifting with 0 immediate.
__ Mov(out_reg, first_reg);
@@ -3844,7 +3845,7 @@ void InstructionCodeGeneratorARMVIXL::HandleShift(HBinaryOperation* op) {
// Register allocator doesn't create partial overlap.
DCHECK(!o_l.Is(high));
DCHECK(!o_h.Is(low));
- int32_t cst = second.GetConstant()->AsIntConstant()->GetValue();
+ int32_t cst = Int32ConstantFrom(second);
uint32_t shift_value = cst & kMaxLongShiftDistance;
if (shift_value > 32) {
if (op->IsShl()) {
@@ -4911,7 +4912,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) {
codegen_->MaybeRecordImplicitNullCheck(instruction);
}
if (index.IsConstant()) {
- int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue();
+ int32_t const_index = Int32ConstantFrom(index);
if (maybe_compressed_char_at) {
vixl32::Label uncompressed_load, done;
__ Lsrs(length, length, 1u); // LSRS has a 16-bit encoding, TST (immediate) does not.
@@ -4945,7 +4946,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) {
// `TryExtractArrayAccessAddress()`.
if (kIsDebugBuild) {
HIntermediateAddress* tmp = array_instr->AsIntermediateAddress();
- DCHECK_EQ(tmp->GetOffset()->AsIntConstant()->GetValueAsUint64(), data_offset);
+ DCHECK_EQ(Uint64ConstantFrom(tmp->GetOffset()), data_offset);
}
temp = obj;
} else {
@@ -4990,7 +4991,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) {
vixl32::Register out = OutputRegister(instruction);
if (index.IsConstant()) {
size_t offset =
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
+ (Int32ConstantFrom(index) << TIMES_4) + data_offset;
GetAssembler()->LoadFromOffset(kLoadWord, out, obj, offset);
// TODO(VIXL): Here and for other calls to `MaybeRecordImplicitNullCheck` in this method,
// we should use a scope and the assembler to emit the load instruction to guarantee that
@@ -5012,7 +5013,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) {
// `TryExtractArrayAccessAddress()`.
if (kIsDebugBuild) {
HIntermediateAddress* tmp = array_instr->AsIntermediateAddress();
- DCHECK_EQ(tmp->GetOffset()->AsIntConstant()->GetValueAsUint64(), data_offset);
+ DCHECK_EQ(Uint64ConstantFrom(tmp->GetOffset()), data_offset);
}
temp = obj;
} else {
@@ -5037,7 +5038,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) {
case Primitive::kPrimLong: {
if (index.IsConstant()) {
size_t offset =
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
+ (Int32ConstantFrom(index) << TIMES_8) + data_offset;
GetAssembler()->LoadFromOffset(kLoadWordPair, LowRegisterFrom(out_loc), obj, offset);
} else {
UseScratchRegisterScope temps(GetVIXLAssembler());
@@ -5051,7 +5052,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) {
case Primitive::kPrimFloat: {
vixl32::SRegister out = SRegisterFrom(out_loc);
if (index.IsConstant()) {
- size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
+ size_t offset = (Int32ConstantFrom(index) << TIMES_4) + data_offset;
GetAssembler()->LoadSFromOffset(out, obj, offset);
} else {
UseScratchRegisterScope temps(GetVIXLAssembler());
@@ -5064,7 +5065,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) {
case Primitive::kPrimDouble: {
if (index.IsConstant()) {
- size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
+ size_t offset = (Int32ConstantFrom(index) << TIMES_8) + data_offset;
GetAssembler()->LoadDFromOffset(DRegisterFrom(out_loc), obj, offset);
} else {
UseScratchRegisterScope temps(GetVIXLAssembler());
@@ -5138,7 +5139,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) {
case Primitive::kPrimChar:
case Primitive::kPrimInt: {
if (index.IsConstant()) {
- int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue();
+ int32_t const_index = Int32ConstantFrom(index);
uint32_t full_offset =
data_offset + (const_index << Primitive::ComponentSizeShift(value_type));
StoreOperandType store_type = GetStoreOperandType(value_type);
@@ -5153,7 +5154,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) {
// `TryExtractArrayAccessAddress()`.
if (kIsDebugBuild) {
HIntermediateAddress* tmp = array_instr->AsIntermediateAddress();
- DCHECK(tmp->GetOffset()->AsIntConstant()->GetValueAsUint64() == data_offset);
+ DCHECK_EQ(Uint64ConstantFrom(tmp->GetOffset()), data_offset);
}
temp = array;
} else {
@@ -5174,7 +5175,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) {
// Just setting null.
if (index.IsConstant()) {
size_t offset =
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
+ (Int32ConstantFrom(index) << TIMES_4) + data_offset;
GetAssembler()->StoreToOffset(kStoreWord, value, array, offset);
} else {
DCHECK(index.IsRegister()) << index;
@@ -5210,7 +5211,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) {
__ CompareAndBranchIfNonZero(value, &non_zero);
if (index.IsConstant()) {
size_t offset =
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
+ (Int32ConstantFrom(index) << TIMES_4) + data_offset;
GetAssembler()->StoreToOffset(kStoreWord, value, array, offset);
} else {
DCHECK(index.IsRegister()) << index;
@@ -5284,7 +5285,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) {
if (index.IsConstant()) {
size_t offset =
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
+ (Int32ConstantFrom(index) << TIMES_4) + data_offset;
GetAssembler()->StoreToOffset(kStoreWord, source, array, offset);
} else {
DCHECK(index.IsRegister()) << index;
@@ -5321,7 +5322,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) {
Location value = locations->InAt(2);
if (index.IsConstant()) {
size_t offset =
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
+ (Int32ConstantFrom(index) << TIMES_8) + data_offset;
GetAssembler()->StoreToOffset(kStoreWordPair, LowRegisterFrom(value), array, offset);
} else {
UseScratchRegisterScope temps(GetVIXLAssembler());
@@ -5336,7 +5337,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) {
Location value = locations->InAt(2);
DCHECK(value.IsFpuRegister());
if (index.IsConstant()) {
- size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset;
+ size_t offset = (Int32ConstantFrom(index) << TIMES_4) + data_offset;
GetAssembler()->StoreSToOffset(SRegisterFrom(value), array, offset);
} else {
UseScratchRegisterScope temps(GetVIXLAssembler());
@@ -5351,7 +5352,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) {
Location value = locations->InAt(2);
DCHECK(value.IsFpuRegisterPair());
if (index.IsConstant()) {
- size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset;
+ size_t offset = (Int32ConstantFrom(index) << TIMES_8) + data_offset;
GetAssembler()->StoreDToOffset(DRegisterFrom(value), array, offset);
} else {
UseScratchRegisterScope temps(GetVIXLAssembler());
@@ -5416,7 +5417,7 @@ void InstructionCodeGeneratorARMVIXL::VisitIntermediateAddress(HIntermediateAddr
if (second.IsRegister()) {
__ Add(out, first, RegisterFrom(second));
} else {
- __ Add(out, first, second.GetConstant()->AsIntConstant()->GetValue());
+ __ Add(out, first, Int32ConstantFrom(second));
}
}
@@ -5612,7 +5613,7 @@ void ParallelMoveResolverARMVIXL::EmitMove(size_t index) {
GetAssembler()->StoreToOffset(kStoreWord, temp, sp, destination.GetStackIndex());
}
} else if (constant->IsLongConstant()) {
- int64_t value = constant->AsLongConstant()->GetValue();
+ int64_t value = Int64ConstantFrom(source);
if (destination.IsRegisterPair()) {
__ Mov(LowRegisterFrom(destination), Low32Bits(value));
__ Mov(HighRegisterFrom(destination), High32Bits(value));
diff --git a/compiler/optimizing/common_arm.h b/compiler/optimizing/common_arm.h
index eabdbad13c..21c3ae628a 100644
--- a/compiler/optimizing/common_arm.h
+++ b/compiler/optimizing/common_arm.h
@@ -122,10 +122,16 @@ inline vixl::aarch32::VRegister InputVRegisterAt(HInstruction* instr, int input_
if (type == Primitive::kPrimFloat) {
return InputSRegisterAt(instr, input_index);
} else {
+ DCHECK_EQ(type, Primitive::kPrimDouble);
return InputDRegisterAt(instr, input_index);
}
}
+inline vixl::aarch32::VRegister InputVRegister(HInstruction* instr) {
+ DCHECK_EQ(instr->InputCount(), 1u);
+ return InputVRegisterAt(instr, 0);
+}
+
inline vixl::aarch32::Register OutputRegister(HInstruction* instr) {
return RegisterFrom(instr->GetLocations()->Out(), instr->GetType());
}
@@ -140,8 +146,7 @@ inline vixl::aarch32::Register InputRegister(HInstruction* instr) {
return InputRegisterAt(instr, 0);
}
-inline int32_t Int32ConstantFrom(Location location) {
- HConstant* instr = location.GetConstant();
+inline int32_t Int32ConstantFrom(HInstruction* instr) {
if (instr->IsIntConstant()) {
return instr->AsIntConstant()->GetValue();
} else if (instr->IsNullConstant()) {
@@ -155,6 +160,10 @@ inline int32_t Int32ConstantFrom(Location location) {
}
}
+inline int32_t Int32ConstantFrom(Location location) {
+ return Int32ConstantFrom(location.GetConstant());
+}
+
inline int64_t Int64ConstantFrom(Location location) {
HConstant* instr = location.GetConstant();
if (instr->IsIntConstant()) {
@@ -167,6 +176,11 @@ inline int64_t Int64ConstantFrom(Location location) {
}
}
+inline uint64_t Uint64ConstantFrom(HInstruction* instr) {
+ DCHECK(instr->IsConstant()) << instr->DebugName();
+ return instr->AsConstant()->GetValueAsUint64();
+}
+
inline vixl::aarch32::Operand OperandFrom(Location location, Primitive::Type type) {
if (location.IsRegister()) {
return vixl::aarch32::Operand(RegisterFrom(location, type));
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 188ee3a8d1..34b52a87b5 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -20,12 +20,15 @@
#include <string>
#include <sstream>
+#include "android-base/stringprintf.h"
+
#include "base/arena_containers.h"
#include "base/bit_vector-inl.h"
-#include "base/stringprintf.h"
namespace art {
+using android::base::StringPrintf;
+
static bool IsAllowedToJumpToExitBlock(HInstruction* instruction) {
return instruction->IsThrow() || instruction->IsReturn() || instruction->IsReturnVoid();
}
diff --git a/compiler/optimizing/graph_test.cc b/compiler/optimizing/graph_test.cc
index d5305646a8..28ee3a5e8b 100644
--- a/compiler/optimizing/graph_test.cc
+++ b/compiler/optimizing/graph_test.cc
@@ -15,7 +15,6 @@
*/
#include "base/arena_allocator.h"
-#include "base/stringprintf.h"
#include "builder.h"
#include "nodes.h"
#include "optimizing_unit_test.h"
diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc
index c240c67e79..b21bc09cbd 100644
--- a/compiler/optimizing/induction_var_analysis.cc
+++ b/compiler/optimizing/induction_var_analysis.cc
@@ -211,7 +211,7 @@ uint32_t HInductionVarAnalysis::VisitDescendant(HLoopInformation* loop, HInstruc
void HInductionVarAnalysis::ClassifyTrivial(HLoopInformation* loop, HInstruction* instruction) {
InductionInfo* info = nullptr;
if (instruction->IsPhi()) {
- info = TransferPhi(loop, instruction, /* input_index */ 0);
+ info = TransferPhi(loop, instruction, /*input_index*/ 0, /*adjust_input_size*/ 0);
} else if (instruction->IsAdd()) {
info = TransferAddSub(LookupInfo(loop, instruction->InputAt(0)),
LookupInfo(loop, instruction->InputAt(1)), kAdd);
@@ -224,11 +224,13 @@ void HInductionVarAnalysis::ClassifyTrivial(HLoopInformation* loop, HInstruction
info = TransferMul(LookupInfo(loop, instruction->InputAt(0)),
LookupInfo(loop, instruction->InputAt(1)));
} else if (instruction->IsShl()) {
- HInstruction* mulc = GetMultConstantForShift(loop, instruction);
+ HInstruction* mulc = GetShiftConstant(loop, instruction, /*initial*/ nullptr);
if (mulc != nullptr) {
info = TransferMul(LookupInfo(loop, instruction->InputAt(0)),
LookupInfo(loop, mulc));
}
+ } else if (instruction->IsSelect()) {
+ info = TransferPhi(loop, instruction, /*input_index*/ 0, /*adjust_input_size*/ 1);
} else if (instruction->IsTypeConversion()) {
info = TransferCnv(LookupInfo(loop, instruction->InputAt(0)),
instruction->AsTypeConversion()->GetInputType(),
@@ -270,7 +272,7 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) {
// Singleton is wrap-around induction if all internal links have the same meaning.
if (size == 1) {
- InductionInfo* update = TransferPhi(loop, phi, /* input_index */ 1);
+ InductionInfo* update = TransferPhi(loop, phi, /*input_index*/ 1, /*adjust_input_size*/ 0);
if (update != nullptr) {
AssignInfo(loop, phi, CreateInduction(kWrapAround,
kNop,
@@ -305,10 +307,15 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) {
update = SolveOp(
loop, phi, instruction, instruction->InputAt(0), instruction->InputAt(1), kRem);
} else if (instruction->IsShl()) {
- HInstruction* mulc = GetMultConstantForShift(loop, instruction);
+ HInstruction* mulc = GetShiftConstant(loop, instruction, /*initial*/ nullptr);
if (mulc != nullptr) {
update = SolveOp(loop, phi, instruction, instruction->InputAt(0), mulc, kMul);
}
+ } else if (instruction->IsShr() || instruction->IsUShr()) {
+ HInstruction* divc = GetShiftConstant(loop, instruction, initial);
+ if (divc != nullptr) {
+ update = SolveOp(loop, phi, instruction, instruction->InputAt(0), divc, kDiv);
+ }
} else if (instruction->IsXor()) {
update = SolveOp(
loop, phi, instruction, instruction->InputAt(0), instruction->InputAt(1), kXor);
@@ -316,6 +323,8 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) {
update = SolveTest(loop, phi, instruction, 0);
} else if (instruction->IsNotEqual()) {
update = SolveTest(loop, phi, instruction, 1);
+ } else if (instruction->IsSelect()) {
+ update = SolvePhi(instruction, /*input_index*/ 0, /*adjust_input_size*/ 1); // acts like Phi
} else if (instruction->IsTypeConversion()) {
update = SolveCnv(instruction->AsTypeConversion());
}
@@ -326,7 +335,7 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) {
}
// Success if all internal links received the same temporary meaning.
- InductionInfo* induction = SolvePhi(phi, /* input_index */ 1);
+ InductionInfo* induction = SolvePhi(phi, /*input_index*/ 1, /*adjust_input_size*/ 0);
if (induction != nullptr) {
switch (induction->induction_class) {
case kInvariant:
@@ -385,12 +394,13 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::RotatePeriodicInduc
HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::TransferPhi(HLoopInformation* loop,
HInstruction* phi,
- size_t input_index) {
+ size_t input_index,
+ size_t adjust_input_size) {
// Match all phi inputs from input_index onwards exactly.
HInputsRef inputs = phi->GetInputs();
DCHECK_LT(input_index, inputs.size());
InductionInfo* a = LookupInfo(loop, inputs[input_index]);
- for (size_t i = input_index + 1; i < inputs.size(); i++) {
+ for (size_t i = input_index + 1, n = inputs.size() - adjust_input_size; i < n; i++) {
InductionInfo* b = LookupInfo(loop, inputs[i]);
if (!InductionEqual(a, b)) {
return nullptr;
@@ -504,13 +514,14 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::TransferCnv(Inducti
}
HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolvePhi(HInstruction* phi,
- size_t input_index) {
+ size_t input_index,
+ size_t adjust_input_size) {
// Match all phi inputs from input_index onwards exactly.
HInputsRef inputs = phi->GetInputs();
DCHECK_LT(input_index, inputs.size());
auto ita = cycle_.find(inputs[input_index]);
if (ita != cycle_.end()) {
- for (size_t i = input_index + 1; i < inputs.size(); i++) {
+ for (size_t i = input_index + 1, n = inputs.size() - adjust_input_size; i < n; i++) {
auto itb = cycle_.find(inputs[i]);
if (itb == cycle_.end() ||
!HInductionVarAnalysis::InductionEqual(ita->second, itb->second)) {
@@ -527,7 +538,7 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolvePhiAllInputs(
HInstruction* entry_phi,
HInstruction* phi) {
// Match all phi inputs.
- InductionInfo* match = SolvePhi(phi, /* input_index */ 0);
+ InductionInfo* match = SolvePhi(phi, /*input_index*/ 0, /*adjust_input_size*/ 0);
if (match != nullptr) {
return match;
}
@@ -542,7 +553,7 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolvePhiAllInputs(
InductionInfo* initial = LookupInfo(loop, entry_phi->InputAt(0));
return CreateInduction(kPeriodic, kNop, a, initial, /*fetch*/ nullptr, type_);
}
- InductionInfo* b = SolvePhi(phi, /* input_index */ 1);
+ InductionInfo* b = SolvePhi(phi, /*input_index*/ 1, /*adjust_input_size*/ 0);
if (b != nullptr && b->induction_class == kPeriodic) {
return CreateInduction(kPeriodic, kNop, a, b, /*fetch*/ nullptr, type_);
}
@@ -574,14 +585,14 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolveAddSub(HLoopIn
return CreateInvariantOp(op, a, b);
}
}
- } else if (op == kAdd && b->induction_class == kLinear) {
+ } else if (b->induction_class == kLinear) {
// Solve within a tight cycle that adds a term that is already classified as a linear
// induction for a polynomial induction k = k + i (represented as sum over linear terms).
if (x == entry_phi && entry_phi->InputCount() == 2 && instruction == entry_phi->InputAt(1)) {
InductionInfo* initial = LookupInfo(loop, entry_phi->InputAt(0));
return CreateInduction(kPolynomial,
kNop,
- b,
+ op == kAdd ? b : TransferNeg(b),
initial,
/*fetch*/ nullptr,
type_);
@@ -1038,13 +1049,23 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::CreateSimplifiedInv
return new (graph_->GetArena()) InductionInfo(kInvariant, op, a, b, nullptr, b->type);
}
-HInstruction* HInductionVarAnalysis::GetMultConstantForShift(HLoopInformation* loop,
- HInstruction* instruction) {
- // Obtain the constant needed to treat shift as equivalent multiplication. This yields an
- // existing instruction if the constant is already there. Otherwise, this has a side effect
- // on the HIR. The restriction on the shift factor avoids generating a negative constant
- // (viz. 1 << 31 and 1L << 63 set the sign bit). The code assumes that generalization for
- // shift factors outside [0,32) and [0,64) ranges is done by earlier simplification.
+HInstruction* HInductionVarAnalysis::GetShiftConstant(HLoopInformation* loop,
+ HInstruction* instruction,
+ InductionInfo* initial) {
+ DCHECK(instruction->IsShl() || instruction->IsShr() || instruction->IsUShr());
+ // Shift-rights are only the same as division for non-negative initial inputs.
+ // Otherwise we would round incorrectly.
+ if (initial != nullptr) {
+ int64_t value = -1;
+ if (!IsAtLeast(initial, &value) || value < 0) {
+ return nullptr;
+ }
+ }
+ // Obtain the constant needed to treat shift as equivalent multiplication or division.
+ // This yields an existing instruction if the constant is already there. Otherwise, this
+ // has a side effect on the HIR. The restriction on the shift factor avoids generating a
+ // negative constant (viz. 1 << 31 and 1L << 63 set the sign bit). The code assumes that
+ // generalization for shift factors outside [0,32) and [0,64) ranges is done earlier.
InductionInfo* b = LookupInfo(loop, instruction->InputAt(1));
int64_t value = -1;
if (IsExact(b, &value)) {
diff --git a/compiler/optimizing/induction_var_analysis.h b/compiler/optimizing/induction_var_analysis.h
index 4720f2d61c..293aa70525 100644
--- a/compiler/optimizing/induction_var_analysis.h
+++ b/compiler/optimizing/induction_var_analysis.h
@@ -115,7 +115,7 @@ class HInductionVarAnalysis : public HOptimization {
InductionInfo* op_a;
InductionInfo* op_b;
HInstruction* fetch;
- Primitive::Type type; // precision of induction
+ Primitive::Type type; // precision of operation
};
bool IsVisitedNode(HInstruction* instruction) const {
@@ -160,14 +160,17 @@ class HInductionVarAnalysis : public HOptimization {
InductionInfo* RotatePeriodicInduction(InductionInfo* induction, InductionInfo* last);
// Transfer operations.
- InductionInfo* TransferPhi(HLoopInformation* loop, HInstruction* phi, size_t input_index);
+ InductionInfo* TransferPhi(HLoopInformation* loop,
+ HInstruction* phi,
+ size_t input_index,
+ size_t adjust_input_size);
InductionInfo* TransferAddSub(InductionInfo* a, InductionInfo* b, InductionOp op);
InductionInfo* TransferNeg(InductionInfo* a);
InductionInfo* TransferMul(InductionInfo* a, InductionInfo* b);
InductionInfo* TransferCnv(InductionInfo* a, Primitive::Type from, Primitive::Type to);
// Solvers.
- InductionInfo* SolvePhi(HInstruction* phi, size_t input_index);
+ InductionInfo* SolvePhi(HInstruction* phi, size_t input_index, size_t adjust_input_size);
InductionInfo* SolvePhiAllInputs(HLoopInformation* loop,
HInstruction* entry_phi,
HInstruction* phi);
@@ -220,7 +223,9 @@ class HInductionVarAnalysis : public HOptimization {
InductionInfo* LookupInfo(HLoopInformation* loop, HInstruction* instruction);
InductionInfo* CreateConstant(int64_t value, Primitive::Type type);
InductionInfo* CreateSimplifiedInvariant(InductionOp op, InductionInfo* a, InductionInfo* b);
- HInstruction* GetMultConstantForShift(HLoopInformation* loop, HInstruction* instruction);
+ HInstruction* GetShiftConstant(HLoopInformation* loop,
+ HInstruction* instruction,
+ InductionInfo* initial);
void AssignCycle(HPhi* phi);
ArenaSet<HInstruction*>* LookupCycle(HPhi* phi);
diff --git a/compiler/optimizing/induction_var_analysis_test.cc b/compiler/optimizing/induction_var_analysis_test.cc
index 2d182f6483..f52a1aad5a 100644
--- a/compiler/optimizing/induction_var_analysis_test.cc
+++ b/compiler/optimizing/induction_var_analysis_test.cc
@@ -87,6 +87,7 @@ class InductionVarAnalysisTest : public CommonCompilerTest {
constant2_ = graph_->GetIntConstant(2);
constant7_ = graph_->GetIntConstant(7);
constant100_ = graph_->GetIntConstant(100);
+ constantm1_ = graph_->GetIntConstant(-1);
float_constant0_ = graph_->GetFloatConstant(0.0f);
return_->AddInstruction(new (&allocator_) HReturnVoid());
exit_->AddInstruction(new (&allocator_) HExit());
@@ -196,6 +197,7 @@ class InductionVarAnalysisTest : public CommonCompilerTest {
HInstruction* constant2_;
HInstruction* constant7_;
HInstruction* constant100_;
+ HInstruction* constantm1_;
HInstruction* float_constant0_;
// Loop specifics.
@@ -612,6 +614,45 @@ TEST_F(InductionVarAnalysisTest, FindGeometricDivInductionAndDerived) {
EXPECT_STREQ("", GetInductionInfo(div, 0).c_str());
}
+TEST_F(InductionVarAnalysisTest, FindGeometricShrInduction) {
+ // Setup:
+ // k = 100;
+ // for (int i = 0; i < 100; i++) {
+ // k = k >> 1; // geometric (/ 2)
+ // }
+ BuildLoopNest(1);
+ HPhi* k_header = InsertLoopPhi(0, 0);
+ k_header->AddInput(constant100_);
+
+ HInstruction* shr = InsertInstruction(
+ new (&allocator_) HShr(Primitive::kPrimInt, k_header, constant1_), 0);
+ k_header->AddInput(shr);
+ PerformInductionVarAnalysis();
+
+ // Note, only the phi in the cycle is classified.
+ EXPECT_STREQ("geo((100) * 2 ^ -i + (0)):PrimInt", GetInductionInfo(k_header, 0).c_str());
+ EXPECT_STREQ("", GetInductionInfo(shr, 0).c_str());
+}
+
+TEST_F(InductionVarAnalysisTest, FindNotGeometricShrInduction) {
+ // Setup:
+ // k = -1;
+ // for (int i = 0; i < 100; i++) {
+ // k = k >> 1; // initial value is negative
+ // }
+ BuildLoopNest(1);
+ HPhi* k_header = InsertLoopPhi(0, 0);
+ k_header->AddInput(constantm1_);
+
+ HInstruction* shr = InsertInstruction(
+ new (&allocator_) HShr(Primitive::kPrimInt, k_header, constant1_), 0);
+ k_header->AddInput(shr);
+ PerformInductionVarAnalysis();
+
+ EXPECT_STREQ("", GetInductionInfo(k_header, 0).c_str());
+ EXPECT_STREQ("", GetInductionInfo(shr, 0).c_str());
+}
+
TEST_F(InductionVarAnalysisTest, FindRemWrapAroundInductionAndDerived) {
// Setup:
// k = 100;
diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc
index e665551012..7bcc3845e7 100644
--- a/compiler/optimizing/induction_var_range.cc
+++ b/compiler/optimizing/induction_var_range.cc
@@ -983,10 +983,10 @@ bool InductionVarRange::GenerateLastValuePolynomial(HInductionVarAnalysis::Induc
int64_t a = 0;
int64_t b = 0;
int64_t m = 0;
- if (IsConstant(info->op_a->op_a, kExact, &a) && a >= 0 &&
- IsConstant(info->op_a->op_b, kExact, &b) && b >= 0 &&
+ if (IsConstant(info->op_a->op_a, kExact, &a) &&
+ IsConstant(info->op_a->op_b, kExact, &b) &&
IsConstant(trip->op_a, kExact, &m) && m >= 1) {
- // Evaluate bounds on sum_i=0^m-1(a * i + b) + c with a,b >= 0 for known
+ // Evaluate bounds on sum_i=0^m-1(a * i + b) + c for known
// maximum index value m as a * (m * (m-1)) / 2 + b * m + c.
// TODO: generalize
HInstruction* c_instr = nullptr;
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index c615df1f1d..439e3b66db 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1897,7 +1897,8 @@ void InstructionSimplifierVisitor::SimplifyReturnThis(HInvoke* invoke) {
static bool NoEscapeForStringBufferReference(HInstruction* reference, HInstruction* user) {
if (user->IsInvokeStaticOrDirect()) {
// Any constructor on StringBuffer is okay.
- return user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() &&
+ return user->AsInvokeStaticOrDirect()->GetResolvedMethod() != nullptr &&
+ user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() &&
user->InputAt(0) == reference;
} else if (user->IsInvokeVirtual()) {
switch (user->AsInvokeVirtual()->GetIntrinsic()) {
diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc
index 95551c8fd9..641a5c92ea 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.cc
+++ b/compiler/optimizing/intrinsics_arm_vixl.cc
@@ -1509,7 +1509,7 @@ static void GenerateVisitStringIndexOf(HInvoke* invoke,
SlowPathCodeARMVIXL* slow_path = nullptr;
HInstruction* code_point = invoke->InputAt(1);
if (code_point->IsIntConstant()) {
- if (static_cast<uint32_t>(code_point->AsIntConstant()->GetValue()) >
+ if (static_cast<uint32_t>(Int32ConstantFrom(code_point)) >
std::numeric_limits<uint16_t>::max()) {
// Always needs the slow-path. We could directly dispatch to it, but this case should be
// rare, so for simplicity just put the full slow-path down and branch unconditionally.
diff --git a/compiler/optimizing/linearize_test.cc b/compiler/optimizing/linearize_test.cc
index 13e14c53b5..3831aa6c91 100644
--- a/compiler/optimizing/linearize_test.cc
+++ b/compiler/optimizing/linearize_test.cc
@@ -18,7 +18,6 @@
#include "arch/x86/instruction_set_features_x86.h"
#include "base/arena_allocator.h"
-#include "base/stringprintf.h"
#include "builder.h"
#include "code_generator.h"
#include "code_generator_x86.h"
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index ba7012ab1a..0d0f62a55c 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -1193,7 +1193,7 @@ bool OptimizingCompiler::JitCompile(Thread* self,
}
uint8_t* stack_map_data = nullptr;
uint8_t* roots_data = nullptr;
- code_cache->ReserveData(
+ uint32_t data_size = code_cache->ReserveData(
self, stack_map_size, number_of_roots, method, &stack_map_data, &roots_data);
if (stack_map_data == nullptr || roots_data == nullptr) {
return false;
@@ -1212,6 +1212,7 @@ bool OptimizingCompiler::JitCompile(Thread* self,
codegen->GetFpuSpillMask(),
code_allocator.GetMemory().data(),
code_allocator.GetSize(),
+ data_size,
osr,
roots,
codegen->GetGraph()->HasShouldDeoptimizeFlag(),
diff --git a/compiler/optimizing/pretty_printer.h b/compiler/optimizing/pretty_printer.h
index 5891350894..c6579dc5e0 100644
--- a/compiler/optimizing/pretty_printer.h
+++ b/compiler/optimizing/pretty_printer.h
@@ -17,7 +17,8 @@
#ifndef ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_
#define ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "nodes.h"
namespace art {
@@ -108,7 +109,7 @@ class StringPrettyPrinter : public HPrettyPrinter {
: HPrettyPrinter(graph), str_(""), current_block_(nullptr) { }
void PrintInt(int value) OVERRIDE {
- str_ += StringPrintf("%d", value);
+ str_ += android::base::StringPrintf("%d", value);
}
void PrintString(const char* value) OVERRIDE {
diff --git a/compiler/optimizing/pretty_printer_test.cc b/compiler/optimizing/pretty_printer_test.cc
index 951cdfbd8b..1af94f3445 100644
--- a/compiler/optimizing/pretty_printer_test.cc
+++ b/compiler/optimizing/pretty_printer_test.cc
@@ -15,7 +15,6 @@
*/
#include "base/arena_allocator.h"
-#include "base/stringprintf.h"
#include "builder.h"
#include "dex_file.h"
#include "dex_instruction.h"
diff --git a/compiler/optimizing/ssa_test.cc b/compiler/optimizing/ssa_test.cc
index 429763423c..f69f417efc 100644
--- a/compiler/optimizing/ssa_test.cc
+++ b/compiler/optimizing/ssa_test.cc
@@ -14,8 +14,9 @@
* limitations under the License.
*/
+#include "android-base/stringprintf.h"
+
#include "base/arena_allocator.h"
-#include "base/stringprintf.h"
#include "builder.h"
#include "dex_file.h"
#include "dex_instruction.h"
@@ -35,7 +36,7 @@ class SsaPrettyPrinter : public HPrettyPrinter {
explicit SsaPrettyPrinter(HGraph* graph) : HPrettyPrinter(graph), str_("") {}
void PrintInt(int value) OVERRIDE {
- str_ += StringPrintf("%d", value);
+ str_ += android::base::StringPrintf("%d", value);
}
void PrintString(const char* value) OVERRIDE {
diff --git a/compiler/utils/arm/assembler_thumb2_test.cc b/compiler/utils/arm/assembler_thumb2_test.cc
index 30e8f4e604..0147a76744 100644
--- a/compiler/utils/arm/assembler_thumb2_test.cc
+++ b/compiler/utils/arm/assembler_thumb2_test.cc
@@ -16,12 +16,15 @@
#include "assembler_thumb2.h"
+#include "android-base/stringprintf.h"
+
#include "base/stl_util.h"
-#include "base/stringprintf.h"
#include "utils/assembler_test.h"
namespace art {
+using android::base::StringPrintf;
+
class AssemblerThumb2Test : public AssemblerTest<arm::Thumb2Assembler,
arm::Register, arm::SRegister,
uint32_t> {
diff --git a/compiler/utils/dedupe_set-inl.h b/compiler/utils/dedupe_set-inl.h
index ac5481336b..c06e9cadcc 100644
--- a/compiler/utils/dedupe_set-inl.h
+++ b/compiler/utils/dedupe_set-inl.h
@@ -23,10 +23,11 @@
#include <inttypes.h>
#include <unordered_map>
+#include "android-base/stringprintf.h"
+
#include "base/mutex.h"
#include "base/hash_set.h"
#include "base/stl_util.h"
-#include "base/stringprintf.h"
#include "base/time_utils.h"
namespace art {
@@ -238,13 +239,13 @@ std::string DedupeSet<InKey, StoreKey, Alloc, HashType, HashFunc, kShard>::DumpS
for (HashType shard = 0; shard < kShard; ++shard) {
shards_[shard]->UpdateStats(self, &stats);
}
- return StringPrintf("%zu collisions, %zu max hash collisions, "
- "%zu/%zu probe distance, %" PRIu64 " ns hash time",
- stats.collision_sum,
- stats.collision_max,
- stats.total_probe_distance,
- stats.total_size,
- hash_time_);
+ return android::base::StringPrintf("%zu collisions, %zu max hash collisions, "
+ "%zu/%zu probe distance, %" PRIu64 " ns hash time",
+ stats.collision_sum,
+ stats.collision_max,
+ stats.total_probe_distance,
+ stats.total_size,
+ hash_time_);
}
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 5a0f0c6e50..2346635198 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -33,6 +33,7 @@
#include <sys/utsname.h>
#endif
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "arch/instruction_set_features.h"
@@ -87,6 +88,9 @@
namespace art {
+using android::base::StringAppendV;
+using android::base::StringPrintf;
+
static constexpr size_t kDefaultMinDexFilesForSwap = 2;
static constexpr size_t kDefaultMinDexFileCumulativeSizeForSwap = 20 * MB;
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index b6b62a80dc..cdb3b9fe2a 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -19,11 +19,15 @@
#include <string>
#include <vector>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "android-base/stringprintf.h"
+
#include "common_runtime_test.h"
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stringprintf.h"
#include "dex_file-inl.h"
#include "dex2oat_environment_test.h"
#include "jit/offline_profiling_info.h"
@@ -31,9 +35,6 @@
#include "oat_file.h"
#include "utils.h"
-#include <sys/wait.h>
-#include <unistd.h>
-
namespace art {
class Dex2oatTest : public Dex2oatEnvironmentTest {
@@ -217,7 +218,7 @@ class Dex2oatSwapTest : public Dex2oatTest {
std::unique_ptr<ScratchFile> sf;
if (use_fd) {
sf.reset(new ScratchFile());
- copy.push_back(StringPrintf("--swap-fd=%d", sf->GetFd()));
+ copy.push_back(android::base::StringPrintf("--swap-fd=%d", sf->GetFd()));
} else {
std::string swap_location = GetOdexDir() + "/Dex2OatSwapTest.odex.swap";
copy.push_back("--swap-file=" + swap_location);
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 916984c261..d5776fa61e 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -42,7 +42,8 @@
#include <sstream>
#include <vector>
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "dexdump_cfg.h"
#include "dex_file-inl.h"
#include "dex_file_types.h"
@@ -887,8 +888,10 @@ static std::unique_ptr<char[]> indexString(const DexFile* pDexFile,
const char* name = pDexFile->StringDataByIdx(pMethodId.name_idx_);
const Signature signature = pDexFile->GetMethodSignature(pMethodId);
const char* backDescriptor = pDexFile->StringByTypeIdx(pMethodId.class_idx_);
- method = StringPrintf("%s.%s:%s",
- backDescriptor, name, signature.ToString().c_str());
+ method = android::base::StringPrintf("%s.%s:%s",
+ backDescriptor,
+ name,
+ signature.ToString().c_str());
}
if (secondary_index < pDexFile->GetHeader().proto_ids_size_) {
const DexFile::ProtoId& protoId = pDexFile->GetProtoId(secondary_index);
diff --git a/dexdump/dexdump_test.cc b/dexdump/dexdump_test.cc
index d28ca2834e..53dda6a995 100644
--- a/dexdump/dexdump_test.cc
+++ b/dexdump/dexdump_test.cc
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <unistd.h>
-#include "base/stringprintf.h"
#include "common_runtime_test.h"
#include "runtime/arch/instruction_set.h"
#include "runtime/os.h"
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index cfe48378ae..cac60900bc 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -30,7 +30,8 @@
#include <sstream>
#include <vector>
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "dex_ir_builder.h"
#include "dex_file-inl.h"
#include "dex_instruction-inl.h"
@@ -43,6 +44,8 @@
namespace art {
+using android::base::StringPrintf;
+
/*
* Flags for use with createAccessFlagStr().
*/
diff --git a/dexlayout/dexlayout_test.cc b/dexlayout/dexlayout_test.cc
index 665baa6c73..46a1c43548 100644
--- a/dexlayout/dexlayout_test.cc
+++ b/dexlayout/dexlayout_test.cc
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <unistd.h>
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
#include "common_runtime_test.h"
#include "utils.h"
diff --git a/dexlist/dexlist_test.cc b/dexlist/dexlist_test.cc
index da1dd7fd89..13209427c9 100644
--- a/dexlist/dexlist_test.cc
+++ b/dexlist/dexlist_test.cc
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <unistd.h>
-#include "base/stringprintf.h"
#include "common_runtime_test.h"
#include "runtime/arch/instruction_set.h"
#include "runtime/gc/heap.h"
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index a374686dc5..f307cbc4f5 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -26,9 +26,10 @@
#include <map>
#include <unordered_set>
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "base/unix_file/fd_file.h"
-#include "base/stringprintf.h"
#include "gc/space/image_space.h"
#include "gc/heap.h"
#include "mirror/class-inl.h"
@@ -46,6 +47,8 @@
namespace art {
+using android::base::StringPrintf;
+
class ImgDiagDumper {
public:
explicit ImgDiagDumper(std::ostream* os,
diff --git a/imgdiag/imgdiag_test.cc b/imgdiag/imgdiag_test.cc
index 9f771ba8a3..3f2afc0696 100644
--- a/imgdiag/imgdiag_test.cc
+++ b/imgdiag/imgdiag_test.cc
@@ -20,12 +20,13 @@
#include "common_runtime_test.h"
+#include "android-base/stringprintf.h"
+
#include "runtime/os.h"
#include "runtime/arch/instruction_set.h"
#include "runtime/utils.h"
#include "runtime/gc/space/image_space.h"
#include "runtime/gc/heap.h"
-#include "base/stringprintf.h"
#include <sys/types.h>
#include <unistd.h>
@@ -57,7 +58,7 @@ class ImgDiagTest : public CommonRuntimeTest {
virtual void SetUpRuntimeOptions(RuntimeOptions* options) OVERRIDE {
// Needs to live until CommonRuntimeTest::SetUp finishes, since we pass it a cstring.
- runtime_args_image_ = StringPrintf("-Ximage:%s", GetCoreArtLocation().c_str());
+ runtime_args_image_ = android::base::StringPrintf("-Ximage:%s", GetCoreArtLocation().c_str());
options->push_back(std::make_pair(runtime_args_image_, nullptr));
}
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index e4462d8305..148ee88669 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -26,6 +26,7 @@
#include <unordered_set>
#include <vector>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "arch/instruction_set_features.h"
@@ -76,6 +77,8 @@
namespace art {
+using android::base::StringPrintf;
+
const char* image_methods_descriptions_[] = {
"kResolutionMethod",
"kImtConflictMethod",
@@ -89,6 +92,7 @@ const char* image_methods_descriptions_[] = {
const char* image_roots_descriptions_[] = {
"kDexCaches",
"kClassRoots",
+ "kClassLoader",
};
// Map is so that we don't allocate multiple dex files for the same OatDexFile.
@@ -1506,12 +1510,13 @@ class ImageDumper {
os << "ROOTS: " << reinterpret_cast<void*>(image_header_.GetImageRoots()) << "\n";
static_assert(arraysize(image_roots_descriptions_) ==
static_cast<size_t>(ImageHeader::kImageRootsMax), "sizes must match");
- for (int i = 0; i < ImageHeader::kImageRootsMax; i++) {
+ DCHECK_LE(image_header_.GetImageRoots()->GetLength(), ImageHeader::kImageRootsMax);
+ for (int32_t i = 0, size = image_header_.GetImageRoots()->GetLength(); i != size; ++i) {
ImageHeader::ImageRoot image_root = static_cast<ImageHeader::ImageRoot>(i);
const char* image_root_description = image_roots_descriptions_[i];
mirror::Object* image_root_object = image_header_.GetImageRoot(image_root);
indent_os << StringPrintf("%s: %p\n", image_root_description, image_root_object);
- if (image_root_object->IsObjectArray()) {
+ if (image_root_object != nullptr && image_root_object->IsObjectArray()) {
mirror::ObjectArray<mirror::Object>* image_root_object_array
= image_root_object->AsObjectArray<mirror::Object>();
ScopedIndentation indent2(&vios_);
diff --git a/oatdump/oatdump_test.cc b/oatdump/oatdump_test.cc
index a2eba4514b..e77d03bae7 100644
--- a/oatdump/oatdump_test.cc
+++ b/oatdump/oatdump_test.cc
@@ -22,7 +22,6 @@
#include "common_runtime_test.h"
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
#include "runtime/arch/instruction_set.h"
#include "runtime/gc/heap.h"
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index 62d1ddff75..7ae13a574b 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "art_field-inl.h"
@@ -31,7 +32,6 @@
#include "base/dumpable.h"
#include "base/scoped_flock.h"
#include "base/stringpiece.h"
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
#include "base/unix_file/random_access_file_utils.h"
#include "elf_utils.h"
@@ -939,7 +939,7 @@ static std::string CommandLine() {
static void UsageErrorV(const char* fmt, va_list ap) {
std::string error;
- StringAppendV(&error, fmt, ap);
+ android::base::StringAppendV(&error, fmt, ap);
LOG(ERROR) << error;
}
diff --git a/profman/profman.cc b/profman/profman.cc
index 0b2d172726..e5384078f1 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -25,12 +25,12 @@
#include <string>
#include <vector>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "base/dumpable.h"
#include "base/scoped_flock.h"
#include "base/stringpiece.h"
-#include "base/stringprintf.h"
#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "dex_file.h"
@@ -61,7 +61,7 @@ static bool FdIsValid(int fd) {
static void UsageErrorV(const char* fmt, va_list ap) {
std::string error;
- StringAppendV(&error, fmt, ap);
+ android::base::StringAppendV(&error, fmt, ap);
LOG(ERROR) << error;
}
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 32ebee24c8..86019bf71c 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -40,7 +40,6 @@ cc_defaults {
"base/scoped_arena_allocator.cc",
"base/scoped_flock.cc",
"base/stringpiece.cc",
- "base/stringprintf.cc",
"base/time_utils.cc",
"base/timing_logger.cc",
"base/unix_file/fd_file.cc",
@@ -508,7 +507,6 @@ art_cc_test {
"base/histogram_test.cc",
"base/mutex_test.cc",
"base/scoped_flock_test.cc",
- "base/stringprintf_test.cc",
"base/time_utils_test.cc",
"base/timing_logger_test.cc",
"base/transform_array_ref_test.cc",
diff --git a/runtime/arch/arm/instruction_set_features_arm.cc b/runtime/arch/arm/instruction_set_features_arm.cc
index f264b82448..181b2ed723 100644
--- a/runtime/arch/arm/instruction_set_features_arm.cc
+++ b/runtime/arch/arm/instruction_set_features_arm.cc
@@ -24,10 +24,10 @@
#include "signal.h"
#include <fstream>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
-#include "base/stringprintf.h"
-#include "utils.h" // For Trim.
+#include "base/logging.h"
#if defined(__arm__)
extern "C" bool artCheckForArmSdivInstruction();
@@ -35,6 +35,8 @@ extern "C" bool artCheckForArmSdivInstruction();
namespace art {
+using android::base::StringPrintf;
+
ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg) {
// Assume all ARM processors are SMP.
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc
index f7b5a7649a..52d8b3e367 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.cc
+++ b/runtime/arch/arm64/instruction_set_features_arm64.cc
@@ -19,14 +19,16 @@
#include <fstream>
#include <sstream>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
+#include "base/logging.h"
#include "base/stl_util.h"
-#include "base/stringprintf.h"
-#include "utils.h" // For Trim.
namespace art {
+using android::base::StringPrintf;
+
Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg) {
const bool smp = true; // Conservative default.
diff --git a/runtime/arch/instruction_set_features_test.cc b/runtime/arch/instruction_set_features_test.cc
index 0b8e531896..d4893923d6 100644
--- a/runtime/arch/instruction_set_features_test.cc
+++ b/runtime/arch/instruction_set_features_test.cc
@@ -22,11 +22,14 @@
#include "android-base/properties.h"
#endif
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
-#include "base/stringprintf.h"
namespace art {
+using android::base::StringPrintf;
+
#ifdef ART_TARGET_ANDROID
#if defined(__aarch64__)
TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyVariant) {
diff --git a/runtime/arch/instruction_set_test.cc b/runtime/arch/instruction_set_test.cc
index 5dfc4b4c48..5aae93acc5 100644
--- a/runtime/arch/instruction_set_test.cc
+++ b/runtime/arch/instruction_set_test.cc
@@ -19,7 +19,6 @@
#include <gtest/gtest.h>
#include "base/enums.h"
-#include "base/stringprintf.h"
namespace art {
diff --git a/runtime/arch/mips/instruction_set_features_mips.cc b/runtime/arch/mips/instruction_set_features_mips.cc
index a65c967efd..5b50573695 100644
--- a/runtime/arch/mips/instruction_set_features_mips.cc
+++ b/runtime/arch/mips/instruction_set_features_mips.cc
@@ -19,14 +19,16 @@
#include <fstream>
#include <sstream>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
+#include "base/logging.h"
#include "base/stl_util.h"
-#include "base/stringprintf.h"
-#include "utils.h" // For Trim.
namespace art {
+using android::base::StringPrintf;
+
// An enum for the Mips revision.
enum class MipsLevel {
kBase,
diff --git a/runtime/arch/mips64/instruction_set_features_mips64.cc b/runtime/arch/mips64/instruction_set_features_mips64.cc
index e564d1eab5..92c44e85de 100644
--- a/runtime/arch/mips64/instruction_set_features_mips64.cc
+++ b/runtime/arch/mips64/instruction_set_features_mips64.cc
@@ -19,13 +19,15 @@
#include <fstream>
#include <sstream>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
-#include "base/stringprintf.h"
-#include "utils.h" // For Trim.
+#include "base/logging.h"
namespace art {
+using android::base::StringPrintf;
+
Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromVariant(
const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) {
if (variant != "default" && variant != "mips64r6") {
diff --git a/runtime/arch/x86/instruction_set_features_x86.cc b/runtime/arch/x86/instruction_set_features_x86.cc
index cc102ecedd..c520d63cf3 100644
--- a/runtime/arch/x86/instruction_set_features_x86.cc
+++ b/runtime/arch/x86/instruction_set_features_x86.cc
@@ -19,14 +19,16 @@
#include <fstream>
#include <sstream>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "arch/x86_64/instruction_set_features_x86_64.h"
-#include "base/stringprintf.h"
-#include "utils.h" // For Trim.
+#include "base/logging.h"
namespace art {
+using android::base::StringPrintf;
+
// Feature-support arrays.
static constexpr const char* x86_known_variants[] = {
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 96b6f18403..dfc7837aea 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -18,6 +18,8 @@
#include <cstddef>
+#include "android-base/stringprintf.h"
+
#include "arch/context.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
@@ -46,6 +48,8 @@
namespace art {
+using android::base::StringPrintf;
+
extern "C" void art_quick_invoke_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*,
const char*);
extern "C" void art_quick_invoke_static_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*,
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index 5ef1f06e77..e4972da13d 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -175,19 +175,19 @@ ADD_TEST_EQ(MIRROR_CLASS_COMPONENT_TYPE_OFFSET,
#define MIRROR_CLASS_IF_TABLE_OFFSET (16 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_IF_TABLE_OFFSET,
art::mirror::Class::IfTableOffset().Int32Value())
-#define MIRROR_CLASS_ACCESS_FLAGS_OFFSET (64 + MIRROR_OBJECT_HEADER_SIZE)
+#define MIRROR_CLASS_ACCESS_FLAGS_OFFSET (56 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_ACCESS_FLAGS_OFFSET,
art::mirror::Class::AccessFlagsOffset().Int32Value())
-#define MIRROR_CLASS_OBJECT_SIZE_OFFSET (96 + MIRROR_OBJECT_HEADER_SIZE)
+#define MIRROR_CLASS_OBJECT_SIZE_OFFSET (88 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_OBJECT_SIZE_OFFSET,
art::mirror::Class::ObjectSizeOffset().Int32Value())
-#define MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET (100 + MIRROR_OBJECT_HEADER_SIZE)
+#define MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET (92 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET,
art::mirror::Class::ObjectSizeAllocFastPathOffset().Int32Value())
-#define MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET (104 + MIRROR_OBJECT_HEADER_SIZE)
+#define MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET (96 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET,
art::mirror::Class::PrimitiveTypeOffset().Int32Value())
-#define MIRROR_CLASS_STATUS_OFFSET (112 + MIRROR_OBJECT_HEADER_SIZE)
+#define MIRROR_CLASS_STATUS_OFFSET (104 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_STATUS_OFFSET,
art::mirror::Class::StatusOffset().Int32Value())
diff --git a/runtime/base/file_magic.cc b/runtime/base/file_magic.cc
index de6f4237ff..568a7ae5d6 100644
--- a/runtime/base/file_magic.cc
+++ b/runtime/base/file_magic.cc
@@ -20,13 +20,16 @@
#include <sys/stat.h>
#include <sys/types.h>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
#include "base/unix_file/fd_file.h"
#include "dex_file.h"
-#include "stringprintf.h"
namespace art {
+using android::base::StringPrintf;
+
File OpenAndReadMagic(const char* filename, uint32_t* magic, std::string* error_msg) {
CHECK(magic != nullptr);
File fd(filename, O_RDONLY, /* check_usage */ false);
diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h
index 92b7c6537c..44a84c834f 100644
--- a/runtime/base/mutex-inl.h
+++ b/runtime/base/mutex-inl.h
@@ -21,7 +21,6 @@
#include "mutex.h"
-#include "base/stringprintf.h"
#include "base/value_object.h"
#include "thread.h"
#include "utils.h"
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index ce452cbcf6..9116097604 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -19,6 +19,8 @@
#include <errno.h>
#include <sys/time.h>
+#include "android-base/stringprintf.h"
+
#include "atomic.h"
#include "base/logging.h"
#include "base/time_utils.h"
@@ -30,6 +32,8 @@
namespace art {
+using android::base::StringPrintf;
+
static Atomic<Locks::ClientCallback*> safe_to_call_abort_callback(nullptr);
Mutex* Locks::abort_lock_ = nullptr;
diff --git a/runtime/base/scoped_flock.cc b/runtime/base/scoped_flock.cc
index 0e8031f4f2..d4bb56b62a 100644
--- a/runtime/base/scoped_flock.cc
+++ b/runtime/base/scoped_flock.cc
@@ -19,12 +19,15 @@
#include <sys/file.h>
#include <sys/stat.h>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
namespace art {
+using android::base::StringPrintf;
+
bool ScopedFlock::Init(const char* filename, std::string* error_msg) {
return Init(filename, O_CREAT | O_RDWR, true, error_msg);
}
diff --git a/runtime/base/stringprintf.cc b/runtime/base/stringprintf.cc
deleted file mode 100644
index 8fd9257048..0000000000
--- a/runtime/base/stringprintf.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2011 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 "stringprintf.h"
-
-#include <stdio.h>
-
-namespace art {
-
-void StringAppendV(std::string* dst, const char* format, va_list ap) {
- // First try with a small fixed size buffer
- char space[1024];
-
- // It's possible for methods that use a va_list to invalidate
- // the data in it upon use. The fix is to make a copy
- // of the structure before using it and use that copy instead.
- va_list backup_ap;
- va_copy(backup_ap, ap);
- int result = vsnprintf(space, sizeof(space), format, backup_ap);
- va_end(backup_ap);
-
- if (result < static_cast<int>(sizeof(space))) {
- if (result >= 0) {
- // Normal case -- everything fit.
- dst->append(space, result);
- return;
- }
-
- if (result < 0) {
- // Just an error.
- return;
- }
- }
-
- // Increase the buffer size to the size requested by vsnprintf,
- // plus one for the closing \0.
- int length = result+1;
- char* buf = new char[length];
-
- // Restore the va_list before we use it again
- va_copy(backup_ap, ap);
- result = vsnprintf(buf, length, format, backup_ap);
- va_end(backup_ap);
-
- if (result >= 0 && result < length) {
- // It fit
- dst->append(buf, result);
- }
- delete[] buf;
-}
-
-std::string StringPrintf(const char* fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- std::string result;
- StringAppendV(&result, fmt, ap);
- va_end(ap);
- return result;
-}
-
-void StringAppendF(std::string* dst, const char* format, ...) {
- va_list ap;
- va_start(ap, format);
- StringAppendV(dst, format, ap);
- va_end(ap);
-}
-
-} // namespace art
diff --git a/runtime/base/stringprintf.h b/runtime/base/stringprintf.h
deleted file mode 100644
index 4767a750c3..0000000000
--- a/runtime/base/stringprintf.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2011 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_STRINGPRINTF_H_
-#define ART_RUNTIME_BASE_STRINGPRINTF_H_
-
-#include <stdarg.h>
-#include <string>
-
-namespace art {
-
-// Returns a string corresponding to printf-like formatting of the arguments.
-std::string StringPrintf(const char* fmt, ...)
- __attribute__((__format__(__printf__, 1, 2)));
-
-// Appends a printf-like formatting of the arguments to 'dst'.
-void StringAppendF(std::string* dst, const char* fmt, ...)
- __attribute__((__format__(__printf__, 2, 3)));
-
-// Appends a printf-like formatting of the arguments to 'dst'.
-void StringAppendV(std::string* dst, const char* format, va_list ap);
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_STRINGPRINTF_H_
diff --git a/runtime/base/time_utils.cc b/runtime/base/time_utils.cc
index 57f198d7e5..3c09d5a36f 100644
--- a/runtime/base/time_utils.cc
+++ b/runtime/base/time_utils.cc
@@ -20,8 +20,9 @@
#include "time_utils.h"
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
-#include "base/stringprintf.h"
#if defined(__APPLE__)
#include <sys/time.h>
@@ -29,6 +30,8 @@
namespace art {
+using android::base::StringPrintf;
+
std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits) {
if (nano_duration == 0) {
return "0";
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index 6c27bc61e4..1c3328e484 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -20,6 +20,8 @@
#include <sys/mman.h>
#include <zlib.h>
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/logging.h"
@@ -42,6 +44,9 @@
namespace art {
+using android::base::StringAppendF;
+using android::base::StringPrintf;
+
/*
* ===========================================================================
* JNI function helpers
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 213986ae45..a11257f21b 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -73,7 +73,7 @@ inline mirror::String* ClassLinker::ResolveString(dex::StringIndex string_idx,
// MethodVerifier refuses methods with string_idx out of bounds.
DCHECK_LT(string_idx.index_, declaring_class->GetDexFile().NumStringIds());
ObjPtr<mirror::String> string =
- mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(),
+ mirror::StringDexCachePair::Lookup(declaring_class->GetDexCache()->GetStrings(),
string_idx.index_,
mirror::DexCache::kDexCacheStringCacheSize).Read();
if (UNLIKELY(string == nullptr)) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index f3a5be2172..20aaa429f7 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -28,6 +28,8 @@
#include <utility>
#include <vector>
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/arena_allocator.h"
@@ -106,6 +108,8 @@
namespace art {
+using android::base::StringPrintf;
+
static constexpr bool kSanityCheckObjects = kIsDebugBuild;
static constexpr bool kVerifyArtMethodDeclaringClasses = kIsDebugBuild;
@@ -1401,39 +1405,20 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches(
return true;
}
-// Update the class loader and resolved string dex cache array of classes. Should only be used on
-// classes in the image space.
-class UpdateClassLoaderAndResolvedStringsVisitor {
+// Update the class loader. Should only be used on classes in the image space.
+class UpdateClassLoaderVisitor {
public:
- UpdateClassLoaderAndResolvedStringsVisitor(gc::space::ImageSpace* space,
- ObjPtr<mirror::ClassLoader> class_loader,
- bool forward_strings)
+ UpdateClassLoaderVisitor(gc::space::ImageSpace* space, ObjPtr<mirror::ClassLoader> class_loader)
: space_(space),
- class_loader_(class_loader),
- forward_strings_(forward_strings) {}
+ class_loader_(class_loader) {}
bool operator()(ObjPtr<mirror::Class> klass) const REQUIRES_SHARED(Locks::mutator_lock_) {
- if (forward_strings_) {
- mirror::StringDexCacheType* strings = klass->GetDexCacheStrings();
- if (strings != nullptr) {
- DCHECK(
- space_->GetImageHeader().GetImageSection(ImageHeader::kSectionDexCacheArrays).Contains(
- reinterpret_cast<uint8_t*>(strings) - space_->Begin()))
- << "String dex cache array for " << klass->PrettyClass() << " is not in app image";
- // Dex caches have already been updated, so take the strings pointer from there.
- mirror::StringDexCacheType* new_strings = klass->GetDexCache()->GetStrings();
- DCHECK_NE(strings, new_strings);
- klass->SetDexCacheStrings(new_strings);
- }
- }
- // Finally, update class loader.
klass->SetClassLoader(class_loader_);
return true;
}
gc::space::ImageSpace* const space_;
ObjPtr<mirror::ClassLoader> const class_loader_;
- const bool forward_strings_;
};
static std::unique_ptr<const DexFile> OpenOatDexFile(const OatFile* oat_file,
@@ -1655,13 +1640,6 @@ bool ClassLinker::AddImageSpace(
Runtime* const runtime = Runtime::Current();
gc::Heap* const heap = runtime->GetHeap();
Thread* const self = Thread::Current();
- StackHandleScope<2> hs(self);
- Handle<mirror::ObjectArray<mirror::DexCache>> dex_caches(
- hs.NewHandle(dex_caches_object->AsObjectArray<mirror::DexCache>()));
- Handle<mirror::ObjectArray<mirror::Class>> class_roots(hs.NewHandle(
- header.GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<mirror::Class>()));
- const OatFile* oat_file = space->GetOatFile();
- std::unordered_set<mirror::ClassLoader*> image_class_loaders;
// Check that the image is what we are expecting.
if (image_pointer_size_ != space->GetImageHeader().GetPointerSize()) {
*error_msg = StringPrintf("Application image pointer size does not match runtime: %zu vs %zu",
@@ -1669,6 +1647,22 @@ bool ClassLinker::AddImageSpace(
image_pointer_size_);
return false;
}
+ size_t expected_image_roots = ImageHeader::NumberOfImageRoots(app_image);
+ if (static_cast<size_t>(header.GetImageRoots()->GetLength()) != expected_image_roots) {
+ *error_msg = StringPrintf("Expected %zu image roots but got %d",
+ expected_image_roots,
+ header.GetImageRoots()->GetLength());
+ return false;
+ }
+ StackHandleScope<3> hs(self);
+ Handle<mirror::ObjectArray<mirror::DexCache>> dex_caches(
+ hs.NewHandle(dex_caches_object->AsObjectArray<mirror::DexCache>()));
+ Handle<mirror::ObjectArray<mirror::Class>> class_roots(hs.NewHandle(
+ header.GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<mirror::Class>()));
+ static_assert(ImageHeader::kClassLoader + 1u == ImageHeader::kImageRootsMax,
+ "Class loader should be the last image root.");
+ MutableHandle<mirror::ClassLoader> image_class_loader(hs.NewHandle(
+ app_image ? header.GetImageRoot(ImageHeader::kClassLoader)->AsClassLoader() : nullptr));
DCHECK(class_roots.Get() != nullptr);
if (class_roots->GetLength() != static_cast<int32_t>(kClassRootsMax)) {
*error_msg = StringPrintf("Expected %d class roots but got %d",
@@ -1683,6 +1677,7 @@ bool ClassLinker::AddImageSpace(
return false;
}
}
+ const OatFile* oat_file = space->GetOatFile();
if (oat_file->GetOatHeader().GetDexFileCount() !=
static_cast<uint32_t>(dex_caches->GetLength())) {
*error_msg = "Dex cache count and dex file count mismatch while trying to initialize from "
@@ -1715,15 +1710,11 @@ bool ClassLinker::AddImageSpace(
// The current dex file field is bogus, overwrite it so that we can get the dex file in the
// loop below.
h_dex_cache->SetDexFile(dex_file.get());
- // Check that each class loader resolved the same way.
- // TODO: Store image class loaders as image roots.
GcRoot<mirror::Class>* const types = h_dex_cache->GetResolvedTypes();
for (int32_t j = 0, num_types = h_dex_cache->NumResolvedTypes(); j < num_types; j++) {
ObjPtr<mirror::Class> klass = types[j].Read();
if (klass != nullptr) {
DCHECK_NE(klass->GetStatus(), mirror::Class::kStatusError);
- ObjPtr<mirror::ClassLoader> image_class_loader = klass->GetClassLoader();
- image_class_loaders.insert(image_class_loader.Ptr());
}
}
} else {
@@ -1749,59 +1740,57 @@ bool ClassLinker::AddImageSpace(
// for PathClassLoader does this by looping through the array of dex files. To ensure they
// resolve the same way, simply flatten the hierarchy in the way the resolution order would be,
// and check that the dex file names are the same.
- for (ObjPtr<mirror::ClassLoader> image_class_loader : image_class_loaders) {
- if (IsBootClassLoader(soa, image_class_loader)) {
- // The dex cache can reference types from the boot class loader.
- continue;
- }
- std::list<mirror::String*> image_dex_file_names;
- std::string temp_error_msg;
- if (!FlattenPathClassLoader(image_class_loader, &image_dex_file_names, &temp_error_msg)) {
- *error_msg = StringPrintf("Failed to flatten image class loader hierarchy '%s'",
- temp_error_msg.c_str());
- return false;
- }
- std::list<mirror::String*> loader_dex_file_names;
- if (!FlattenPathClassLoader(class_loader.Get(), &loader_dex_file_names, &temp_error_msg)) {
- *error_msg = StringPrintf("Failed to flatten class loader hierarchy '%s'",
- temp_error_msg.c_str());
- return false;
+ if (IsBootClassLoader(soa, image_class_loader.Get())) {
+ *error_msg = "Unexpected BootClassLoader in app image";
+ return false;
+ }
+ std::list<mirror::String*> image_dex_file_names;
+ std::string temp_error_msg;
+ if (!FlattenPathClassLoader(image_class_loader.Get(), &image_dex_file_names, &temp_error_msg)) {
+ *error_msg = StringPrintf("Failed to flatten image class loader hierarchy '%s'",
+ temp_error_msg.c_str());
+ return false;
+ }
+ std::list<mirror::String*> loader_dex_file_names;
+ if (!FlattenPathClassLoader(class_loader.Get(), &loader_dex_file_names, &temp_error_msg)) {
+ *error_msg = StringPrintf("Failed to flatten class loader hierarchy '%s'",
+ temp_error_msg.c_str());
+ return false;
+ }
+ // Add the temporary dex path list elements at the end.
+ auto elements = soa.Decode<mirror::ObjectArray<mirror::Object>>(dex_elements);
+ for (size_t i = 0, num_elems = elements->GetLength(); i < num_elems; ++i) {
+ ObjPtr<mirror::Object> element = elements->GetWithoutChecks(i);
+ if (element != nullptr) {
+ // If we are somewhere in the middle of the array, there may be nulls at the end.
+ loader_dex_file_names.push_back(GetDexPathListElementName(element));
}
- // Add the temporary dex path list elements at the end.
- auto elements = soa.Decode<mirror::ObjectArray<mirror::Object>>(dex_elements);
- for (size_t i = 0, num_elems = elements->GetLength(); i < num_elems; ++i) {
- ObjPtr<mirror::Object> element = elements->GetWithoutChecks(i);
- if (element != nullptr) {
- // If we are somewhere in the middle of the array, there may be nulls at the end.
- loader_dex_file_names.push_back(GetDexPathListElementName(element));
- }
+ }
+ // Ignore the number of image dex files since we are adding those to the class loader anyways.
+ CHECK_GE(static_cast<size_t>(image_dex_file_names.size()),
+ static_cast<size_t>(dex_caches->GetLength()));
+ size_t image_count = image_dex_file_names.size() - dex_caches->GetLength();
+ // Check that the dex file names match.
+ bool equal = image_count == loader_dex_file_names.size();
+ if (equal) {
+ auto it1 = image_dex_file_names.begin();
+ auto it2 = loader_dex_file_names.begin();
+ for (size_t i = 0; equal && i < image_count; ++i, ++it1, ++it2) {
+ equal = equal && (*it1)->Equals(*it2);
}
- // Ignore the number of image dex files since we are adding those to the class loader anyways.
- CHECK_GE(static_cast<size_t>(image_dex_file_names.size()),
- static_cast<size_t>(dex_caches->GetLength()));
- size_t image_count = image_dex_file_names.size() - dex_caches->GetLength();
- // Check that the dex file names match.
- bool equal = image_count == loader_dex_file_names.size();
- if (equal) {
- auto it1 = image_dex_file_names.begin();
- auto it2 = loader_dex_file_names.begin();
- for (size_t i = 0; equal && i < image_count; ++i, ++it1, ++it2) {
- equal = equal && (*it1)->Equals(*it2);
- }
+ }
+ if (!equal) {
+ VLOG(image) << "Image dex files " << image_dex_file_names.size();
+ for (ObjPtr<mirror::String> name : image_dex_file_names) {
+ VLOG(image) << name->ToModifiedUtf8();
}
- if (!equal) {
- VLOG(image) << "Image dex files " << image_dex_file_names.size();
- for (ObjPtr<mirror::String> name : image_dex_file_names) {
- VLOG(image) << name->ToModifiedUtf8();
- }
- VLOG(image) << "Loader dex files " << loader_dex_file_names.size();
- for (ObjPtr<mirror::String> name : loader_dex_file_names) {
- VLOG(image) << name->ToModifiedUtf8();
- }
- *error_msg = "Rejecting application image due to class loader mismatch";
- // Ignore class loader mismatch for now since these would just use possibly incorrect
- // oat code anyways. The structural class check should be done in the parent.
+ VLOG(image) << "Loader dex files " << loader_dex_file_names.size();
+ for (ObjPtr<mirror::String> name : loader_dex_file_names) {
+ VLOG(image) << name->ToModifiedUtf8();
}
+ *error_msg = "Rejecting application image due to class loader mismatch";
+ // Ignore class loader mismatch for now since these would just use possibly incorrect
+ // oat code anyways. The structural class check should be done in the parent.
}
}
@@ -1856,10 +1845,8 @@ bool ClassLinker::AddImageSpace(
}
// Update class loader and resolved strings. If added_class_table is false, the resolved
// strings were forwarded UpdateAppImageClassLoadersAndDexCaches.
- UpdateClassLoaderAndResolvedStringsVisitor visitor(space,
- class_loader.Get(),
- forward_dex_cache_arrays);
- for (ClassTable::TableSlot& root : temp_set) {
+ UpdateClassLoaderVisitor visitor(space, class_loader.Get());
+ for (const ClassTable::TableSlot& root : temp_set) {
visitor(root.Read());
}
// forward_dex_cache_arrays is true iff we copied all of the dex cache arrays into the .bss.
@@ -2659,6 +2646,8 @@ mirror::Class* ClassLinker::DefineClass(Thread* self,
ObjectLock<mirror::Class> lock(self, klass);
klass->SetClinitThreadId(self->GetTid());
+ // Make sure we have a valid empty iftable even if there are errors.
+ klass->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
// Add the newly loaded class to the loaded classes table.
ObjPtr<mirror::Class> existing = InsertClass(descriptor, klass.Get(), hash);
@@ -3010,7 +2999,6 @@ void ClassLinker::SetupClass(const DexFile& dex_file,
klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def));
klass->SetDexTypeIndex(dex_class_def.class_idx_);
- CHECK(klass->GetDexCacheStrings() != nullptr);
}
void ClassLinker::LoadClass(Thread* self,
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 685677bd80..42108d8621 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -278,8 +278,6 @@ class ClassLinkerTest : public CommonRuntimeTest {
EXPECT_FALSE(klass->IsArrayClass());
EXPECT_TRUE(klass->GetComponentType() == nullptr);
EXPECT_TRUE(klass->IsInSamePackage(klass.Get()));
- EXPECT_TRUE(klass->GetDexCacheStrings() != nullptr);
- EXPECT_EQ(klass->GetDexCacheStrings(), klass->GetDexCache()->GetStrings());
std::string temp2;
EXPECT_TRUE(mirror::Class::IsInSamePackage(klass->GetDescriptor(&temp),
klass->GetDescriptor(&temp2)));
@@ -590,7 +588,6 @@ struct ClassOffsets : public CheckOffsets<mirror::Class> {
addOffset(OFFSETOF_MEMBER(mirror::Class, component_type_), "componentType");
addOffset(OFFSETOF_MEMBER(mirror::Class, copied_methods_offset_), "copiedMethodsOffset");
addOffset(OFFSETOF_MEMBER(mirror::Class, dex_cache_), "dexCache");
- addOffset(OFFSETOF_MEMBER(mirror::Class, dex_cache_strings_), "dexCacheStrings");
addOffset(OFFSETOF_MEMBER(mirror::Class, dex_class_def_idx_), "dexClassDefIndex");
addOffset(OFFSETOF_MEMBER(mirror::Class, dex_type_idx_), "dexTypeIndex");
addOffset(OFFSETOF_MEMBER(mirror::Class, ext_data_), "extData");
@@ -1175,6 +1172,24 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) {
EXPECT_TRUE(init->IsInitialized());
}
+TEST_F(ClassLinkerTest, ErroneousClass) {
+ ScopedObjectAccess soa(Thread::Current());
+ jobject jclass_loader = LoadMultiDex("ErroneousA", "ErroneousB");
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader(
+ hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
+ hs.Self()->AssertNoPendingException();
+ const char* descriptor = "LErroneous;";
+ ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), descriptor, class_loader);
+ // Erronenous since we are extending final class.
+ hs.Self()->AssertPendingException();
+ EXPECT_TRUE(klass == nullptr);
+ klass = class_linker_->LookupClass(soa.Self(), descriptor, class_loader.Get());
+ EXPECT_FALSE(klass == nullptr);
+ EXPECT_TRUE(klass->IsErroneous());
+ EXPECT_TRUE(klass->GetIfTable() != nullptr);
+}
+
TEST_F(ClassLinkerTest, FinalizableBit) {
ScopedObjectAccess soa(Thread::Current());
mirror::Class* c;
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 8226e6049e..743fcc87eb 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -24,11 +24,12 @@
#include <stdlib.h>
#include "../../external/icu/icu4c/source/common/unicode/uvernum.h"
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "base/macros.h"
#include "base/logging.h"
#include "base/stl_util.h"
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "compiler_callbacks.h"
@@ -65,6 +66,8 @@ int main(int argc, char **argv) {
namespace art {
+using android::base::StringPrintf;
+
ScratchFile::ScratchFile() {
// ANDROID_DATA needs to be set
CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) <<
diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc
index 9f0dbbbdd0..c30272e114 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -18,6 +18,7 @@
#include <sstream>
+#include "android-base/stringprintf.h"
#include "ScopedLocalRef.h"
#include "art_field-inl.h"
@@ -37,6 +38,9 @@
namespace art {
+using android::base::StringAppendV;
+using android::base::StringPrintf;
+
static void AddReferrerLocation(std::ostream& os, ObjPtr<mirror::Class> referrer)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (referrer != nullptr) {
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index e33966617f..df4413d52c 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -20,6 +20,8 @@
#include <set>
+#include "android-base/stringprintf.h"
+
#include "arch/context.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
@@ -61,6 +63,8 @@
namespace art {
+using android::base::StringPrintf;
+
// The key identifying the debugger to update instrumentation.
static constexpr const char* kDbgInstrumentationKey = "Debugger";
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index aa8fb38fca..7d704ad0cc 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -28,10 +28,11 @@
#include <sstream>
#include <type_traits>
+#include "android-base/stringprintf.h"
+
#include "base/enums.h"
#include "base/file_magic.h"
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "base/systrace.h"
#include "base/unix_file/fd_file.h"
#include "dex_file-inl.h"
@@ -45,6 +46,8 @@
namespace art {
+using android::base::StringPrintf;
+
static_assert(sizeof(dex::StringIndex) == sizeof(uint32_t), "StringIndex size is wrong");
static_assert(std::is_trivially_copyable<dex::StringIndex>::value, "StringIndex not trivial");
static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong");
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index 52b9f114d2..9504e8bd29 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -18,6 +18,8 @@
#include <stdlib.h>
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "class_linker-inl.h"
@@ -31,6 +33,8 @@
namespace art {
+using android::base::StringPrintf;
+
struct DexFile::AnnotationValue {
JValue value_;
uint8_t type_;
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 07f0fcae56..a3ab9fa5bd 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -22,7 +22,8 @@
#include <limits>
#include <memory>
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "dex_file-inl.h"
#include "experimental_flags.h"
#include "leb128.h"
@@ -32,6 +33,9 @@
namespace art {
+using android::base::StringAppendV;
+using android::base::StringPrintf;
+
static constexpr uint32_t kTypeIdLimit = std::numeric_limits<uint16_t>::max();
static bool IsValidOrNoTypeId(uint16_t low, uint16_t high) {
diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc
index 99023893ba..7b8974fa5a 100644
--- a/runtime/dex_instruction.cc
+++ b/runtime/dex_instruction.cc
@@ -21,12 +21,15 @@
#include <iomanip>
#include <sstream>
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "dex_file-inl.h"
#include "utils.h"
namespace art {
+using android::base::StringPrintf;
+
const char* const Instruction::kInstructionNames[] = {
#define INSTRUCTION_NAME(o, c, pname, f, i, a, v) pname,
#include "dex_instruction_list.h"
diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc
index ee0f34002b..59b734f169 100644
--- a/runtime/elf_file.cc
+++ b/runtime/elf_file.cc
@@ -20,11 +20,11 @@
#include <sys/types.h>
#include <unistd.h>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "arch/instruction_set.h"
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "elf_file_impl.h"
@@ -34,6 +34,8 @@
namespace art {
+using android::base::StringPrintf;
+
template <typename ElfTypes>
ElfFileImpl<ElfTypes>::ElfFileImpl(File* file, bool writable,
bool program_header_only,
diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc
index f4d0bc7dbf..eb9f0395ac 100644
--- a/runtime/gc/accounting/space_bitmap.cc
+++ b/runtime/gc/accounting/space_bitmap.cc
@@ -16,8 +16,9 @@
#include "space_bitmap-inl.h"
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
-#include "base/stringprintf.h"
#include "dex_file-inl.h"
#include "mem_map.h"
#include "mirror/object-inl.h"
@@ -28,6 +29,8 @@ namespace art {
namespace gc {
namespace accounting {
+using android::base::StringPrintf;
+
template<size_t kAlignment>
size_t SpaceBitmap<kAlignment>::ComputeBitmapSize(uint64_t capacity) {
const uint64_t kBytesCoveredPerWord = kAlignment * kBitsPerIntPtrT;
diff --git a/runtime/gc/allocator/rosalloc.cc b/runtime/gc/allocator/rosalloc.cc
index 2e4475f225..35a251fda8 100644
--- a/runtime/gc/allocator/rosalloc.cc
+++ b/runtime/gc/allocator/rosalloc.cc
@@ -16,6 +16,13 @@
#include "rosalloc.h"
+#include <map>
+#include <list>
+#include <sstream>
+#include <vector>
+
+#include "android-base/stringprintf.h"
+
#include "base/memory_tool.h"
#include "base/mutex-inl.h"
#include "gc/space/memory_tool_settings.h"
@@ -26,15 +33,12 @@
#include "thread-inl.h"
#include "thread_list.h"
-#include <map>
-#include <list>
-#include <sstream>
-#include <vector>
-
namespace art {
namespace gc {
namespace allocator {
+using android::base::StringPrintf;
+
static constexpr bool kUsePrefetchDuringAllocRun = false;
static constexpr bool kPrefetchNewRunDataByZeroing = false;
static constexpr size_t kPrefetchStride = 64;
diff --git a/runtime/gc/collector/garbage_collector.cc b/runtime/gc/collector/garbage_collector.cc
index ed16854d66..01bcb7df19 100644
--- a/runtime/gc/collector/garbage_collector.cc
+++ b/runtime/gc/collector/garbage_collector.cc
@@ -18,6 +18,8 @@
#include "garbage_collector.h"
+#include "android-base/stringprintf.h"
+
#include "base/dumpable.h"
#include "base/histogram-inl.h"
#include "base/logging.h"
@@ -81,7 +83,7 @@ void GarbageCollector::ResetCumulativeStatistics() {
}
void GarbageCollector::Run(GcCause gc_cause, bool clear_soft_references) {
- ScopedTrace trace(StringPrintf("%s %s GC", PrettyCause(gc_cause), GetName()));
+ ScopedTrace trace(android::base::StringPrintf("%s %s GC", PrettyCause(gc_cause), GetName()));
Thread* self = Thread::Current();
uint64_t start_time = NanoTime();
Iteration* current_iteration = GetCurrentIteration();
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 3ed138c00e..34d82845dc 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -21,6 +21,8 @@
#include <unwind.h> // For GC verification.
#include <vector>
+#include "android-base/stringprintf.h"
+
#include "allocation_listener.h"
#include "art_field-inl.h"
#include "base/allocator.h"
@@ -82,6 +84,8 @@ namespace art {
namespace gc {
+using android::base::StringPrintf;
+
static constexpr size_t kCollectorTransitionStressIterations = 0;
static constexpr size_t kCollectorTransitionStressWait = 10 * 1000; // Microseconds
// Minimum amount of remaining bytes before a concurrent GC is triggered.
@@ -3919,7 +3923,7 @@ void Heap::RegisterNativeFree(JNIEnv* env, size_t bytes) {
ScopedObjectAccess soa(env);
env->ThrowNew(WellKnownClasses::java_lang_RuntimeException,
StringPrintf("Attempted to free %zd native bytes with only %zd native bytes "
- "registered as allocated", bytes, expected_size).c_str());
+ "registered as allocated", bytes, expected_size).c_str());
break;
}
} while (!native_bytes_allocated_.CompareExchangeWeakRelaxed(expected_size,
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 76f3692f41..e03958d717 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "art_method.h"
@@ -45,6 +46,9 @@ namespace art {
namespace gc {
namespace space {
+using android::base::StringAppendF;
+using android::base::StringPrintf;
+
Atomic<uint32_t> ImageSpace::bitmap_index_(0);
ImageSpace::ImageSpace(const std::string& image_filename,
diff --git a/runtime/gc/space/image_space_fs.h b/runtime/gc/space/image_space_fs.h
index fa941c0376..5999548d2b 100644
--- a/runtime/gc/space/image_space_fs.h
+++ b/runtime/gc/space/image_space_fs.h
@@ -20,9 +20,10 @@
#include <dirent.h>
#include <dlfcn.h>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
#include "globals.h"
#include "os.h"
@@ -56,7 +57,7 @@ static void DeleteDirectoryContents(const std::string& dir, bool recurse) {
continue;
}
// We only want to delete regular files and symbolic links.
- std::string file = StringPrintf("%s/%s", dir.c_str(), name);
+ std::string file = android::base::StringPrintf("%s/%s", dir.c_str(), name);
if (de->d_type != DT_REG && de->d_type != DT_LNK) {
if (de->d_type == DT_DIR) {
if (recurse) {
diff --git a/runtime/gc/space/malloc_space.cc b/runtime/gc/space/malloc_space.cc
index b1572cc7ea..a186f4c922 100644
--- a/runtime/gc/space/malloc_space.cc
+++ b/runtime/gc/space/malloc_space.cc
@@ -16,6 +16,8 @@
#include "malloc_space.h"
+#include "android-base/stringprintf.h"
+
#include "gc/accounting/card_table-inl.h"
#include "gc/accounting/space_bitmap-inl.h"
#include "gc/heap.h"
@@ -33,6 +35,8 @@ namespace art {
namespace gc {
namespace space {
+using android::base::StringPrintf;
+
size_t MallocSpace::bitmap_index_ = 0;
MallocSpace::MallocSpace(const std::string& name, MemMap* mem_map,
diff --git a/runtime/generated/asm_support_gen.h b/runtime/generated/asm_support_gen.h
index f13ff8c9bc..bebcd71951 100644
--- a/runtime/generated/asm_support_gen.h
+++ b/runtime/generated/asm_support_gen.h
@@ -74,8 +74,6 @@ DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_QUICK_CODE_OFFSET_32), (static_c
DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_QUICK_CODE_OFFSET_64), (static_cast<int32_t>(art::ArtMethod:: EntryPointFromQuickCompiledCodeOffset(art::PointerSize::k64).Int32Value())))
#define ART_METHOD_DECLARING_CLASS_OFFSET 0
DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_DECLARING_CLASS_OFFSET), (static_cast<int32_t>(art::ArtMethod:: DeclaringClassOffset().Int32Value())))
-#define DECLARING_CLASS_DEX_CACHE_STRINGS_OFFSET 40
-DEFINE_CHECK_EQ(static_cast<int32_t>(DECLARING_CLASS_DEX_CACHE_STRINGS_OFFSET), (static_cast<int32_t>(art::mirror::Class:: DexCacheStringsOffset().Int32Value())))
#define STRING_DEX_CACHE_ELEMENT_SIZE_SHIFT 3
DEFINE_CHECK_EQ(static_cast<int32_t>(STRING_DEX_CACHE_ELEMENT_SIZE_SHIFT), (static_cast<int32_t>(art::WhichPowerOf2(sizeof(art::mirror::StringDexCachePair)))))
#define STRING_DEX_CACHE_SIZE_MINUS_ONE 1023
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index 8cbe49166a..fe6a6e9140 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -37,9 +37,10 @@
#include <set>
+#include "android-base/stringprintf.h"
+
#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"
@@ -797,8 +798,9 @@ class Hprof : public SingleRootVisitor {
file->Erase();
}
if (!okay) {
- std::string msg(StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s",
- filename_.c_str(), strerror(errno)));
+ std::string msg(android::base::StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s",
+ filename_.c_str(),
+ strerror(errno)));
ThrowRuntimeException("%s", msg.c_str());
LOG(ERROR) << msg;
}
diff --git a/runtime/image.cc b/runtime/image.cc
index 52c9f4edf0..2ef60c3e07 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -25,7 +25,7 @@
namespace art {
const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '3', '\0' };
+const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '4', '\0' }; // mirror::Class update
ImageHeader::ImageHeader(uint32_t image_begin,
uint32_t image_size,
diff --git a/runtime/image.h b/runtime/image.h
index da9976a901..6c76f4915e 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -189,6 +189,7 @@ class PACKED(4) ImageHeader {
enum ImageRoot {
kDexCaches,
kClassRoots,
+ kClassLoader, // App image only.
kImageRootsMax,
};
@@ -206,6 +207,10 @@ class PACKED(4) ImageHeader {
kSectionCount, // Number of elements in enum.
};
+ static size_t NumberOfImageRoots(bool app_image) {
+ return app_image ? kImageRootsMax : kImageRootsMax - 1u;
+ }
+
ArtMethod* GetImageMethod(ImageMethod index) const;
void SetImageMethod(ImageMethod index, ArtMethod* method);
diff --git a/runtime/indirect_reference_table-inl.h b/runtime/indirect_reference_table-inl.h
index 9c634fa861..0e66ae96b5 100644
--- a/runtime/indirect_reference_table-inl.h
+++ b/runtime/indirect_reference_table-inl.h
@@ -19,6 +19,8 @@
#include "indirect_reference_table.h"
+#include "android-base/stringprintf.h"
+
#include "base/dumpable.h"
#include "gc_root-inl.h"
#include "obj_ptr-inl.h"
@@ -38,15 +40,15 @@ inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const {
return false;
}
if (UNLIKELY(GetIndirectRefKind(iref) == kHandleScopeOrInvalid)) {
- AbortIfNoCheckJNI(StringPrintf("JNI ERROR (app bug): invalid %s %p",
- GetIndirectRefKindString(kind_),
- iref));
+ AbortIfNoCheckJNI(android::base::StringPrintf("JNI ERROR (app bug): invalid %s %p",
+ GetIndirectRefKindString(kind_),
+ iref));
return false;
}
const uint32_t top_index = segment_state_.top_index;
uint32_t idx = ExtractIndex(iref);
if (UNLIKELY(idx >= top_index)) {
- std::string msg = StringPrintf(
+ std::string msg = android::base::StringPrintf(
"JNI ERROR (app bug): accessed stale %s %p (index %d in a table of size %d)",
GetIndirectRefKindString(kind_),
iref,
@@ -56,9 +58,9 @@ inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const {
return false;
}
if (UNLIKELY(table_[idx].GetReference()->IsNull())) {
- AbortIfNoCheckJNI(StringPrintf("JNI ERROR (app bug): accessed deleted %s %p",
- GetIndirectRefKindString(kind_),
- iref));
+ AbortIfNoCheckJNI(android::base::StringPrintf("JNI ERROR (app bug): accessed deleted %s %p",
+ GetIndirectRefKindString(kind_),
+ iref));
return false;
}
if (UNLIKELY(!CheckEntry("use", iref, idx))) {
@@ -73,7 +75,7 @@ inline bool IndirectReferenceTable::CheckEntry(const char* what,
uint32_t idx) const {
IndirectRef checkRef = ToIndirectRef(idx);
if (UNLIKELY(checkRef != iref)) {
- std::string msg = StringPrintf(
+ std::string msg = android::base::StringPrintf(
"JNI ERROR (app bug): attempt to %s stale %s %p (should be %p)",
what,
GetIndirectRefKindString(kind_),
diff --git a/runtime/indirect_reference_table_test.cc b/runtime/indirect_reference_table_test.cc
index 722b411f97..bf4cab24cc 100644
--- a/runtime/indirect_reference_table_test.cc
+++ b/runtime/indirect_reference_table_test.cc
@@ -16,6 +16,8 @@
#include "indirect_reference_table-inl.h"
+#include "android-base/stringprintf.h"
+
#include "class_linker-inl.h"
#include "common_runtime_test.h"
#include "mirror/object-inl.h"
@@ -23,6 +25,8 @@
namespace art {
+using android::base::StringPrintf;
+
class IndirectReferenceTableTest : public CommonRuntimeTest {};
static void CheckDump(IndirectReferenceTable* irt, size_t num_objects, size_t num_unique)
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 870d1ae9b5..03ef962f05 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -1098,10 +1098,14 @@ TwoWordReturn Instrumentation::PopInstrumentationStackFrame(Thread* self, uintpt
Dbg::IsForcedInterpreterNeededForUpcall(self, visitor.caller));
if (deoptimize && Runtime::Current()->IsDeoptimizeable(*return_pc)) {
if (kVerboseInstrumentation) {
- LOG(INFO) << StringPrintf("Deoptimizing %s by returning from %s with result %#" PRIx64 " in ",
- visitor.caller->PrettyMethod().c_str(),
- method->PrettyMethod().c_str(),
- return_value.GetJ()) << *self;
+ LOG(INFO) << "Deoptimizing "
+ << visitor.caller->PrettyMethod()
+ << " by returning from "
+ << method->PrettyMethod()
+ << " with result "
+ << std::hex << return_value.GetJ() << std::dec
+ << " in "
+ << *self;
}
self->PushDeoptimizationContext(return_value,
return_shorty == 'L',
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 22da07dd24..a09e71b6c0 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -676,7 +676,7 @@ void AbortTransactionV(Thread* self, const char* fmt, va_list args) {
CHECK(Runtime::Current()->IsActiveTransaction());
// Constructs abort message.
std::string abort_msg;
- StringAppendV(&abort_msg, fmt, args);
+ android::base::StringAppendV(&abort_msg, fmt, args);
// Throws an exception so we can abort the transaction and rollback every change.
Runtime::Current()->AbortTransactionAndThrowAbortError(self, abort_msg);
}
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index c9a5b44c54..423f0543d5 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -25,6 +25,8 @@
#include <sstream>
#include <atomic>
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/enums.h"
@@ -254,7 +256,7 @@ static inline ObjPtr<mirror::String> ResolveString(Thread* self,
DCHECK_LT(string_idx.index_ % mirror::DexCache::kDexCacheStringCacheSize,
declaring_class->GetDexFile().NumStringIds());
ObjPtr<mirror::String> string_ptr =
- mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(),
+ mirror::StringDexCachePair::Lookup(declaring_class->GetDexCache()->GetStrings(),
string_idx.index_,
mirror::DexCache::kDexCacheStringCacheSize).Read();
if (UNLIKELY(string_ptr == nullptr)) {
@@ -430,12 +432,12 @@ static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruc
#define TRACE_LOG std::cerr
std::ostringstream oss;
oss << shadow_frame.GetMethod()->PrettyMethod()
- << StringPrintf("\n0x%x: ", dex_pc)
+ << android::base::StringPrintf("\n0x%x: ", dex_pc)
<< inst->DumpString(shadow_frame.GetMethod()->GetDexFile()) << "\n";
for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
uint32_t raw_value = shadow_frame.GetVReg(i);
ObjPtr<mirror::Object> ref_value = shadow_frame.GetVRegReference(i);
- oss << StringPrintf(" vreg%u=0x%08X", i, raw_value);
+ oss << android::base::StringPrintf(" vreg%u=0x%08X", i, raw_value);
if (ref_value != nullptr) {
if (ref_value->GetClass()->IsStringClass() &&
!ref_value->AsString()->IsValueNull()) {
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index a5b1038d5a..7dd3d3db4d 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -25,6 +25,7 @@
#include <locale>
#include <unordered_map>
+#include "android-base/stringprintf.h"
#include "ScopedLocalRef.h"
#include "art_method-inl.h"
@@ -56,6 +57,9 @@
namespace art {
namespace interpreter {
+using android::base::StringAppendV;
+using android::base::StringPrintf;
+
static void AbortTransactionOrFail(Thread* self, const char* fmt, ...)
__attribute__((__format__(__printf__, 2, 3)))
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index caf705a9cb..f80c43d80c 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -18,6 +18,8 @@
#include <dlfcn.h>
+#include "android-base/stringprintf.h"
+
#include "art_method.h"
#include "base/dumpable.h"
#include "base/mutex.h"
@@ -42,6 +44,9 @@
namespace art {
+using android::base::StringAppendF;
+using android::base::StringAppendV;
+
static constexpr size_t kGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.)
static constexpr size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.)
diff --git a/runtime/jdwp/jdwp_adb.cc b/runtime/jdwp/jdwp_adb.cc
index e9d6d079c1..0eff2ab47b 100644
--- a/runtime/jdwp/jdwp_adb.cc
+++ b/runtime/jdwp/jdwp_adb.cc
@@ -20,8 +20,9 @@
#include <sys/un.h>
#include <unistd.h>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "jdwp/jdwp_priv.h"
#ifdef ART_TARGET_ANDROID
@@ -52,6 +53,8 @@ namespace art {
namespace JDWP {
+using android::base::StringPrintf;
+
struct JdwpAdbState : public JdwpNetStateBase {
public:
explicit JdwpAdbState(JdwpState* state) : JdwpNetStateBase(state) {
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index 5574a117a7..172f52a974 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -21,10 +21,11 @@
#include <string.h>
#include <unistd.h>
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "debugger.h"
#include "jdwp/jdwp_constants.h"
#include "jdwp/jdwp_expand_buf.h"
@@ -103,6 +104,8 @@ namespace art {
namespace JDWP {
+using android::base::StringPrintf;
+
/*
* Stuff to compare against when deciding if a mod matches. Only the
* values for mods valid for the event being evaluated will be filled in.
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 0f2d188bca..964c5679d7 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -20,11 +20,12 @@
#include <memory>
#include <string>
+#include "android-base/stringprintf.h"
+
#include "atomic.h"
#include "base/hex_dump.h"
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stringprintf.h"
#include "debugger.h"
#include "jdwp/jdwp_constants.h"
#include "jdwp/jdwp_event.h"
@@ -39,6 +40,8 @@ namespace art {
namespace JDWP {
+using android::base::StringPrintf;
+
std::string DescribeField(const FieldId& field_id) {
return StringPrintf("%#" PRIx64 " (%s)", field_id, Dbg::GetFieldName(field_id).c_str());
}
diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc
index e3bf3e5a9d..7707ba4932 100644
--- a/runtime/jdwp/jdwp_main.cc
+++ b/runtime/jdwp/jdwp_main.cc
@@ -20,6 +20,8 @@
#include <time.h>
#include <unistd.h>
+#include "android-base/stringprintf.h"
+
#include "atomic.h"
#include "base/logging.h"
#include "base/time_utils.h"
@@ -31,6 +33,8 @@ namespace art {
namespace JDWP {
+using android::base::StringPrintf;
+
static void* StartJdwpThread(void* arg);
/*
diff --git a/runtime/jdwp/jdwp_request.cc b/runtime/jdwp/jdwp_request.cc
index 18f40a143c..6af267e674 100644
--- a/runtime/jdwp/jdwp_request.cc
+++ b/runtime/jdwp/jdwp_request.cc
@@ -18,7 +18,8 @@
#include <inttypes.h>
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "jdwp/jdwp_priv.h"
namespace art {
@@ -100,7 +101,7 @@ MethodId Request::ReadMethodId() {
ObjectId Request::ReadObjectId(const char* specific_kind) {
ObjectId id = Read8BE();
- VLOG(jdwp) << StringPrintf(" %s id %#" PRIx64, specific_kind, id);
+ VLOG(jdwp) << android::base::StringPrintf(" %s id %#" PRIx64, specific_kind, id);
return id;
}
diff --git a/runtime/jdwp/jdwp_socket.cc b/runtime/jdwp/jdwp_socket.cc
index 3be7fd6428..97662f0727 100644
--- a/runtime/jdwp/jdwp_socket.cc
+++ b/runtime/jdwp/jdwp_socket.cc
@@ -26,8 +26,9 @@
#include <sys/types.h>
#include <unistd.h>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "jdwp/jdwp_priv.h"
namespace art {
@@ -500,7 +501,7 @@ bool JdwpSocketState::ProcessIncoming() {
*/
if (IsAwaitingHandshake()) {
if (memcmp(input_buffer_, kMagicHandshake, kMagicHandshakeLen) != 0) {
- LOG(ERROR) << StringPrintf("ERROR: bad handshake '%.14s'", input_buffer_);
+ LOG(ERROR) << android::base::StringPrintf("ERROR: bad handshake '%.14s'", input_buffer_);
goto fail;
}
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 1b0ad8341b..f43e30dd6f 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -217,6 +217,7 @@ uint8_t* JitCodeCache::CommitCode(Thread* self,
size_t fp_spill_mask,
const uint8_t* code,
size_t code_size,
+ size_t data_size,
bool osr,
Handle<mirror::ObjectArray<mirror::Object>> roots,
bool has_should_deoptimize_flag,
@@ -230,6 +231,7 @@ uint8_t* JitCodeCache::CommitCode(Thread* self,
fp_spill_mask,
code,
code_size,
+ data_size,
osr,
roots,
has_should_deoptimize_flag,
@@ -246,6 +248,7 @@ uint8_t* JitCodeCache::CommitCode(Thread* self,
fp_spill_mask,
code,
code_size,
+ data_size,
osr,
roots,
has_should_deoptimize_flag,
@@ -513,6 +516,7 @@ uint8_t* JitCodeCache::CommitCodeInternal(Thread* self,
size_t fp_spill_mask,
const uint8_t* code,
size_t code_size,
+ size_t data_size,
bool osr,
Handle<mirror::ObjectArray<mirror::Object>> roots,
bool has_should_deoptimize_flag,
@@ -547,6 +551,11 @@ uint8_t* JitCodeCache::CommitCodeInternal(Thread* self,
core_spill_mask,
fp_spill_mask,
code_size);
+ DCHECK_EQ(FromStackMapToRoots(stack_map), roots_data);
+ DCHECK_LE(roots_data, stack_map);
+ // Flush data cache, as compiled code references literals in it.
+ FlushDataCache(reinterpret_cast<char*>(roots_data),
+ reinterpret_cast<char*>(roots_data + data_size));
// Flush caches before we remove write permission because on some ARMv8 hardware,
// flushing caches require write permissions.
//
@@ -657,12 +666,12 @@ void JitCodeCache::ClearData(Thread* self,
FreeData(reinterpret_cast<uint8_t*>(roots_data));
}
-void JitCodeCache::ReserveData(Thread* self,
- size_t stack_map_size,
- size_t number_of_roots,
- ArtMethod* method,
- uint8_t** stack_map_data,
- uint8_t** roots_data) {
+size_t JitCodeCache::ReserveData(Thread* self,
+ size_t stack_map_size,
+ size_t number_of_roots,
+ ArtMethod* method,
+ uint8_t** stack_map_data,
+ uint8_t** roots_data) {
size_t table_size = ComputeRootTableSize(number_of_roots);
size_t size = RoundUp(stack_map_size + table_size, sizeof(void*));
uint8_t* result = nullptr;
@@ -695,9 +704,11 @@ void JitCodeCache::ReserveData(Thread* self,
*roots_data = result;
*stack_map_data = result + table_size;
FillRootTableLength(*roots_data, number_of_roots);
+ return size;
} else {
*roots_data = nullptr;
*stack_map_data = nullptr;
+ return 0;
}
}
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index 30e2efbac5..d97742d00b 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -106,6 +106,7 @@ class JitCodeCache {
size_t fp_spill_mask,
const uint8_t* code,
size_t code_size,
+ size_t data_size,
bool osr,
Handle<mirror::ObjectArray<mirror::Object>> roots,
bool has_should_deoptimize_flag,
@@ -121,12 +122,13 @@ class JitCodeCache {
// Allocate a region of data that contain `size` bytes, and potentially space
// for storing `number_of_roots` roots. Returns null if there is no more room.
- void ReserveData(Thread* self,
- size_t size,
- size_t number_of_roots,
- ArtMethod* method,
- uint8_t** stack_map_data,
- uint8_t** roots_data)
+ // Return the number of bytes allocated.
+ size_t ReserveData(Thread* self,
+ size_t size,
+ size_t number_of_roots,
+ ArtMethod* method,
+ uint8_t** stack_map_data,
+ uint8_t** roots_data)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!lock_);
@@ -237,6 +239,7 @@ class JitCodeCache {
size_t fp_spill_mask,
const uint8_t* code,
size_t code_size,
+ size_t data_size,
bool osr,
Handle<mirror::ObjectArray<mirror::Object>> roots,
bool has_should_deoptimize_flag,
diff --git a/runtime/jni_env_ext.cc b/runtime/jni_env_ext.cc
index 342e0d2a53..5a3fafa726 100644
--- a/runtime/jni_env_ext.cc
+++ b/runtime/jni_env_ext.cc
@@ -19,6 +19,8 @@
#include <algorithm>
#include <vector>
+#include "android-base/stringprintf.h"
+
#include "check_jni.h"
#include "indirect_reference_table.h"
#include "java_vm_ext.h"
@@ -30,6 +32,8 @@
namespace art {
+using android::base::StringPrintf;
+
static constexpr size_t kMonitorsInitial = 32; // Arbitrary.
static constexpr size_t kMonitorsMax = 4096; // Arbitrary sanity check.
diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc
index a421c340ae..4da5e23502 100644
--- a/runtime/jni_internal_test.cc
+++ b/runtime/jni_internal_test.cc
@@ -16,6 +16,8 @@
#include "jni_internal.h"
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "common_compiler_test.h"
#include "indirect_reference_table.h"
@@ -27,6 +29,8 @@
namespace art {
+using android::base::StringPrintf;
+
// TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used.
class JniInternalTest : public CommonCompilerTest {
protected:
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 6da72e4625..19a65bb27e 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -24,7 +24,8 @@
#include <memory>
#include <sstream>
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "base/unix_file/fd_file.h"
#include "os.h"
#include "thread-inl.h"
@@ -42,6 +43,8 @@
namespace art {
+using android::base::StringPrintf;
+
static std::ostream& operator<<(
std::ostream& os,
std::pair<BacktraceMap::const_iterator, BacktraceMap::const_iterator> iters) {
diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc
index 3c22d7f656..da510ceb5c 100644
--- a/runtime/method_handles.cc
+++ b/runtime/method_handles.cc
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-#include "method_handles.h"
-
#include "method_handles-inl.h"
+
+#include "android-base/stringprintf.h"
+
#include "jvalue.h"
#include "jvalue-inl.h"
#include "reflection.h"
@@ -25,6 +26,8 @@
namespace art {
+using android::base::StringPrintf;
+
namespace {
#define PRIMITIVES_LIST(V) \
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index 7d7c1d7cfd..a5db0c0a8a 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -19,10 +19,11 @@
#include "array.h"
+#include "android-base/stringprintf.h"
+
#include "base/bit_utils.h"
#include "base/casts.h"
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "class-inl.h"
#include "gc/heap-inl.h"
#include "obj_ptr-inl.h"
@@ -167,9 +168,9 @@ inline Array* Array::Alloc(Thread* self,
#else
// 32-bit.
if (UNLIKELY(size == 0)) {
- self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow",
- array_class->PrettyDescriptor().c_str(),
- component_count).c_str());
+ self->ThrowOutOfMemoryError(android::base::StringPrintf("%s of length %d would overflow",
+ array_class->PrettyDescriptor().c_str(),
+ component_count).c_str());
return nullptr;
}
#endif
diff --git a/runtime/mirror/array.cc b/runtime/mirror/array.cc
index 8afa4aa744..cc548b9cc8 100644
--- a/runtime/mirror/array.cc
+++ b/runtime/mirror/array.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "array.h"
+#include "array-inl.h"
#include "class.h"
#include "class-inl.h"
@@ -23,7 +23,6 @@
#include "dex_file-inl.h"
#include "gc/accounting/card_table-inl.h"
#include "object-inl.h"
-#include "object_array.h"
#include "object_array-inl.h"
#include "handle_scope-inl.h"
#include "thread.h"
@@ -32,6 +31,8 @@
namespace art {
namespace mirror {
+using android::base::StringPrintf;
+
// Create a multi-dimensional array of Objects or primitive types.
//
// We have to generate the names for X[], X[][], X[][][], and so on. The
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 5fdf8f3c3a..2fb8d28de9 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -937,14 +937,6 @@ inline uint32_t Class::NumDirectInterfaces() {
}
}
-inline void Class::SetDexCacheStrings(StringDexCacheType* new_dex_cache_strings) {
- SetFieldPtr<false>(DexCacheStringsOffset(), new_dex_cache_strings);
-}
-
-inline StringDexCacheType* Class::GetDexCacheStrings() {
- return GetFieldPtr64<StringDexCacheType*>(DexCacheStringsOffset());
-}
-
template<ReadBarrierOption kReadBarrierOption, class Visitor>
void Class::VisitNativeRoots(Visitor& visitor, PointerSize pointer_size) {
for (ArtField& field : GetSFieldsUnchecked()) {
@@ -1095,12 +1087,6 @@ inline void Class::FixupNativePointers(Class* dest,
if (methods != new_methods) {
dest->SetMethodsPtrInternal(new_methods);
}
- // Update dex cache strings.
- StringDexCacheType* strings = GetDexCacheStrings();
- StringDexCacheType* new_strings = visitor(strings);
- if (strings != new_strings) {
- dest->SetDexCacheStrings(new_strings);
- }
// Fix up embedded tables.
if (!IsTemp() && ShouldHaveEmbeddedVTable<kVerifyNone, kReadBarrierOption>()) {
for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) {
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index a862c9798a..9964b73c98 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -16,6 +16,8 @@
#include "class.h"
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "class_ext.h"
@@ -40,6 +42,8 @@
namespace art {
namespace mirror {
+using android::base::StringPrintf;
+
GcRoot<Class> Class::java_lang_Class_;
void Class::SetClassClass(ObjPtr<Class> java_lang_Class) {
@@ -187,7 +191,6 @@ void Class::SetStatus(Handle<Class> h_this, Status new_status, Thread* self) {
void Class::SetDexCache(ObjPtr<DexCache> new_dex_cache) {
SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache);
- SetDexCacheStrings(new_dex_cache != nullptr ? new_dex_cache->GetStrings() : nullptr);
}
void Class::SetClassSize(uint32_t new_class_size) {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index d7449c8008..fb2792a316 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -1247,13 +1247,6 @@ class MANAGED Class FINAL : public Object {
bool GetSlowPathEnabled() REQUIRES_SHARED(Locks::mutator_lock_);
void SetSlowPath(bool enabled) REQUIRES_SHARED(Locks::mutator_lock_);
- StringDexCacheType* GetDexCacheStrings() REQUIRES_SHARED(Locks::mutator_lock_);
- void SetDexCacheStrings(StringDexCacheType* new_dex_cache_strings)
- REQUIRES_SHARED(Locks::mutator_lock_);
- static MemberOffset DexCacheStringsOffset() {
- return OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_strings_);
- }
-
// May cause thread suspension due to EqualParameters.
ArtMethod* GetDeclaredConstructor(Thread* self,
Handle<ObjectArray<Class>> args,
@@ -1438,9 +1431,6 @@ class MANAGED Class FINAL : public Object {
// virtual_ methods_ for miranda methods.
HeapReference<PointerArray> vtable_;
- // Short cuts to dex_cache_ member for fast compiled code access.
- uint64_t dex_cache_strings_;
-
// instance fields
//
// These describe the layout of the contents of an Object.
diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h
index 0fdf1323eb..3e04bf6474 100644
--- a/runtime/mirror/object_array-inl.h
+++ b/runtime/mirror/object_array-inl.h
@@ -17,12 +17,13 @@
#ifndef ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_
#define ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_
+#include "object_array.h"
+
#include <string>
-#include "object_array.h"
+#include "android-base/stringprintf.h"
#include "array-inl.h"
-#include "base/stringprintf.h"
#include "gc/heap.h"
#include "mirror/class.h"
#include "obj_ptr-inl.h"
@@ -330,13 +331,15 @@ inline void ObjectArray<T>::AssignableCheckingMemcpy(int32_t dst_pos,
std::string actualSrcType(mirror::Object::PrettyTypeOf(o));
std::string dstType(PrettyTypeOf());
Thread* self = Thread::Current();
+ std::string msg = android::base::StringPrintf(
+ "source[%d] of type %s cannot be stored in destination array of type %s",
+ src_pos + i,
+ actualSrcType.c_str(),
+ dstType.c_str());
if (throw_exception) {
- self->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
- "source[%d] of type %s cannot be stored in destination array of type %s",
- src_pos + i, actualSrcType.c_str(), dstType.c_str());
+ self->ThrowNewException("Ljava/lang/ArrayStoreException;", msg.c_str());
} else {
- LOG(FATAL) << StringPrintf("source[%d] of type %s cannot be stored in destination array of type %s",
- src_pos + i, actualSrcType.c_str(), dstType.c_str());
+ LOG(FATAL) << msg;
}
}
}
diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h
index 95516ace9f..9b8445dc9e 100644
--- a/runtime/mirror/string-inl.h
+++ b/runtime/mirror/string-inl.h
@@ -16,6 +16,10 @@
#ifndef ART_RUNTIME_MIRROR_STRING_INL_H_
#define ART_RUNTIME_MIRROR_STRING_INL_H_
+#include "string.h"
+
+#include "android-base/stringprintf.h"
+
#include "array.h"
#include "base/bit_utils.h"
#include "class.h"
@@ -24,7 +28,6 @@
#include "globals.h"
#include "intern_table.h"
#include "runtime.h"
-#include "string.h"
#include "thread.h"
#include "utf.h"
#include "utils.h"
@@ -228,9 +231,10 @@ inline String* String::Alloc(Thread* self, int32_t utf16_length_with_flag,
"kObjectAlignment must be at least as big as Java char alignment");
const size_t max_length = RoundDown(max_alloc_length, kObjectAlignment / block_size);
if (UNLIKELY(length > max_length)) {
- self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow",
- Class::PrettyDescriptor(string_class).c_str(),
- static_cast<int>(length)).c_str());
+ self->ThrowOutOfMemoryError(
+ android::base::StringPrintf("%s of length %d would overflow",
+ Class::PrettyDescriptor(string_class).c_str(),
+ static_cast<int>(length)).c_str());
return nullptr;
}
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc
index ade4e87afd..e50409f2c5 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -16,6 +16,8 @@
#include "throwable.h"
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "base/enums.h"
#include "class-inl.h"
@@ -31,6 +33,8 @@
namespace art {
namespace mirror {
+using android::base::StringPrintf;
+
GcRoot<Class> Throwable::java_lang_Throwable_;
void Throwable::SetDetailMessage(ObjPtr<String> new_detail_message) {
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index e7de7e64c6..222eb5c556 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -18,6 +18,8 @@
#include <vector>
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "base/mutex.h"
#include "base/stl_util.h"
@@ -38,6 +40,8 @@
namespace art {
+using android::base::StringPrintf;
+
static constexpr uint64_t kLongWaitMs = 100;
/*
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 1a77072921..cd0e55f261 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -18,9 +18,10 @@
#include <sstream>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
#include "base/stl_util.h"
-#include "base/stringprintf.h"
#include "class_linker.h"
#include "common_throws.h"
#include "compiler_filter.h"
@@ -43,6 +44,8 @@
namespace art {
+using android::base::StringPrintf;
+
static bool ConvertJavaArrayToDexFiles(
JNIEnv* env,
jobject arrayObject,
diff --git a/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc b/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc
index db245aa0d8..981be68199 100644
--- a/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc
+++ b/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc
@@ -16,6 +16,8 @@
#include "dalvik_system_InMemoryDexClassLoader_DexData.h"
+#include "android-base/stringprintf.h"
+
#include "class_linker.h"
#include "common_throws.h"
#include "dex_file.h"
@@ -29,6 +31,8 @@
namespace art {
+using android::base::StringPrintf;
+
static std::unique_ptr<MemMap> AllocateDexMemoryMap(JNIEnv* env, jint start, jint end) {
if (end <= start) {
ScopedObjectAccess soa(env);
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 3058df442c..1af861929e 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -27,6 +27,8 @@ extern "C" void android_set_application_target_sdk_version(uint32_t version);
#include "toStringArray.h"
#pragma GCC diagnostic pop
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "arch/instruction_set.h"
#include "base/enums.h"
@@ -54,6 +56,8 @@ extern "C" void android_set_application_target_sdk_version(uint32_t version);
namespace art {
+using android::base::StringPrintf;
+
static jfloat VMRuntime_getTargetHeapUtilization(JNIEnv*, jobject) {
return Runtime::Current()->GetHeap()->GetTargetHeapUtilization();
}
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index a78909b879..10fc90bc27 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -18,6 +18,8 @@
#include <stdlib.h>
+#include "android-base/stringprintf.h"
+
#include "arch/instruction_set.h"
#include "debugger.h"
#include "java_vm_ext.h"
@@ -37,6 +39,8 @@
namespace art {
+using android::base::StringPrintf;
+
static void EnableDebugger() {
#if defined(__linux__)
// To let a non-privileged gdbserver attach to this
diff --git a/runtime/native/java_lang_ref_Reference.cc b/runtime/native/java_lang_ref_Reference.cc
index 3f4573d55b..c778068bc4 100644
--- a/runtime/native/java_lang_ref_Reference.cc
+++ b/runtime/native/java_lang_ref_Reference.cc
@@ -33,7 +33,7 @@ static jobject Reference_getReferent(JNIEnv* env, jobject javaThis) {
return soa.AddLocalReference<jobject>(referent);
}
-static void Reference_clear(JNIEnv* env, jobject javaThis) {
+static void Reference_clearReferent(JNIEnv* env, jobject javaThis) {
ScopedFastNativeObjectAccess soa(env);
ObjPtr<mirror::Reference> ref = soa.Decode<mirror::Reference>(javaThis);
Runtime::Current()->GetHeap()->GetReferenceProcessor()->ClearReferent(ref);
@@ -41,7 +41,7 @@ static void Reference_clear(JNIEnv* env, jobject javaThis) {
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Reference, getReferent, "!()Ljava/lang/Object;"),
- NATIVE_METHOD(Reference, clear, "!()V"),
+ NATIVE_METHOD(Reference, clearReferent, "!()V"),
};
void register_java_lang_ref_Reference(JNIEnv* env) {
diff --git a/runtime/native/java_lang_reflect_Executable.cc b/runtime/native/java_lang_reflect_Executable.cc
index 73b81a71f8..ee59c4a9e2 100644
--- a/runtime/native/java_lang_reflect_Executable.cc
+++ b/runtime/native/java_lang_reflect_Executable.cc
@@ -16,6 +16,8 @@
#include "java_lang_reflect_Executable.h"
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "dex_file_annotations.h"
#include "handle.h"
@@ -30,6 +32,8 @@
namespace art {
+using android::base::StringPrintf;
+
static jobjectArray Executable_getDeclaredAnnotationsNative(JNIEnv* env, jobject javaMethod) {
ScopedFastNativeObjectAccess soa(env);
ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 6206948225..374eeb5806 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -16,6 +16,8 @@
#include "java_lang_reflect_Field.h"
+#include "android-base/stringprintf.h"
+
#include "class_linker.h"
#include "class_linker-inl.h"
#include "common_throws.h"
@@ -30,6 +32,8 @@
namespace art {
+using android::base::StringPrintf;
+
template<bool kIsSet>
ALWAYS_INLINE inline static bool VerifyFieldAccess(Thread* self,
ObjPtr<mirror::Field> field,
diff --git a/runtime/native/java_lang_reflect_Parameter.cc b/runtime/native/java_lang_reflect_Parameter.cc
index 16164d2f9b..0bb9e382d3 100644
--- a/runtime/native/java_lang_reflect_Parameter.cc
+++ b/runtime/native/java_lang_reflect_Parameter.cc
@@ -16,6 +16,8 @@
#include "java_lang_reflect_Parameter.h"
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "common_throws.h"
#include "dex_file-inl.h"
@@ -26,6 +28,8 @@
namespace art {
+using android::base::StringPrintf;
+
static jobject Parameter_getAnnotationNative(JNIEnv* env,
jclass,
jobject javaMethod,
diff --git a/runtime/native_stack_dump.cc b/runtime/native_stack_dump.cc
index 5565565c7b..7460d622b5 100644
--- a/runtime/native_stack_dump.cc
+++ b/runtime/native_stack_dump.cc
@@ -37,10 +37,11 @@
#include <sys/time.h>
#include <sys/types.h>
+#include "android-base/stringprintf.h"
+
#include "arch/instruction_set.h"
#include "base/memory_tool.h"
#include "base/mutex.h"
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
#include "oat_quick_method_header.h"
#include "os.h"
@@ -53,6 +54,8 @@ namespace art {
#if defined(__linux__)
+using android::base::StringPrintf;
+
static constexpr bool kUseAddr2line = !kIsTargetBuild;
ALWAYS_INLINE
diff --git a/runtime/oat.cc b/runtime/oat.cc
index aab0e81047..cebe765369 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -19,12 +19,15 @@
#include <string.h>
#include <zlib.h>
+#include "android-base/stringprintf.h"
+
#include "arch/instruction_set_features.h"
#include "base/bit_utils.h"
-#include "base/stringprintf.h"
namespace art {
+using android::base::StringPrintf;
+
constexpr uint8_t OatHeader::kOatMagic[4];
constexpr uint8_t OatHeader::kOatVersion[4];
constexpr const char OatHeader::kTrueValue[];
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index bdf8b0e65d..0bf713679b 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -32,6 +32,8 @@
#include "android/dlext.h"
#endif
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "base/bit_vector.h"
#include "base/enums.h"
@@ -58,6 +60,8 @@
namespace art {
+using android::base::StringPrintf;
+
// Whether OatFile::Open will try dlopen. Fallback is our own ELF loader.
static constexpr bool kUseDlopen = true;
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index 7f7b1b5b06..ee7cf9deef 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -23,7 +23,6 @@
#include "android-base/strings.h"
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "compiler_filter.h"
#include "class_linker.h"
#include "gc/heap.h"
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index 5641459f41..33bd0f311d 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -20,6 +20,8 @@
#include <queue>
#include <vector>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/systrace.h"
@@ -38,6 +40,8 @@
namespace art {
+using android::base::StringPrintf;
+
// If true, then we attempt to load the application image if it exists.
static constexpr bool kEnableAppImage = true;
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index 1ad3f0814f..5f97b60079 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -700,7 +700,7 @@ class JvmtiFunctions {
jmethodID method,
jint* entry_count_ptr,
jvmtiLineNumberEntry** table_ptr) {
- return ERR(NOT_IMPLEMENTED);
+ return MethodUtil::GetLineNumberTable(env, method, entry_count_ptr, table_ptr);
}
static jvmtiError GetMethodLocation(jvmtiEnv* env,
diff --git a/runtime/openjdkjvmti/ti_method.cc b/runtime/openjdkjvmti/ti_method.cc
index ffa5ac7e32..a0a09239fa 100644
--- a/runtime/openjdkjvmti/ti_method.cc
+++ b/runtime/openjdkjvmti/ti_method.cc
@@ -130,4 +130,63 @@ jvmtiError MethodUtil::GetMethodModifiers(jvmtiEnv* env ATTRIBUTE_UNUSED,
return ERR(NONE);
}
+using LineNumberContext = std::vector<jvmtiLineNumberEntry>;
+
+static bool CollectLineNumbers(void* void_context, const art::DexFile::PositionInfo& entry) {
+ LineNumberContext* context = reinterpret_cast<LineNumberContext*>(void_context);
+ jvmtiLineNumberEntry jvmti_entry = { static_cast<jlocation>(entry.address_),
+ static_cast<jint>(entry.line_) };
+ context->push_back(jvmti_entry);
+ return false; // Collect all, no early exit.
+}
+
+jvmtiError MethodUtil::GetLineNumberTable(jvmtiEnv* env,
+ jmethodID method,
+ jint* entry_count_ptr,
+ jvmtiLineNumberEntry** table_ptr) {
+ if (method == nullptr) {
+ return ERR(NULL_POINTER);
+ }
+ art::ArtMethod* art_method = art::jni::DecodeArtMethod(method);
+ DCHECK(!art_method->IsRuntimeMethod());
+
+ const art::DexFile::CodeItem* code_item;
+ const art::DexFile* dex_file;
+ {
+ art::ScopedObjectAccess soa(art::Thread::Current());
+
+ if (art_method->IsProxyMethod()) {
+ return ERR(ABSENT_INFORMATION);
+ }
+ if (art_method->IsNative()) {
+ return ERR(NATIVE_METHOD);
+ }
+ if (entry_count_ptr == nullptr || table_ptr == nullptr) {
+ return ERR(NULL_POINTER);
+ }
+
+ code_item = art_method->GetCodeItem();
+ dex_file = art_method->GetDexFile();
+ DCHECK(code_item != nullptr) << art_method->PrettyMethod() << " " << dex_file->GetLocation();
+ }
+
+ LineNumberContext context;
+ bool success = dex_file->DecodeDebugPositionInfo(code_item, CollectLineNumbers, &context);
+ if (!success) {
+ return ERR(ABSENT_INFORMATION);
+ }
+
+ unsigned char* data;
+ jlong mem_size = context.size() * sizeof(jvmtiLineNumberEntry);
+ jvmtiError alloc_error = env->Allocate(mem_size, &data);
+ if (alloc_error != ERR(NONE)) {
+ return alloc_error;
+ }
+ *table_ptr = reinterpret_cast<jvmtiLineNumberEntry*>(data);
+ memcpy(*table_ptr, context.data(), mem_size);
+ *entry_count_ptr = static_cast<jint>(context.size());
+
+ return ERR(NONE);
+}
+
} // namespace openjdkjvmti
diff --git a/runtime/openjdkjvmti/ti_method.h b/runtime/openjdkjvmti/ti_method.h
index 43f11f97ec..fb2fbb2b27 100644
--- a/runtime/openjdkjvmti/ti_method.h
+++ b/runtime/openjdkjvmti/ti_method.h
@@ -52,6 +52,11 @@ class MethodUtil {
static jvmtiError GetMethodModifiers(jvmtiEnv* env,
jmethodID method,
jint* modifiers_ptr);
+
+ static jvmtiError GetLineNumberTable(jvmtiEnv* env,
+ jmethodID method,
+ jint* entry_count_ptr,
+ jvmtiLineNumberEntry** table_ptr);
};
} // namespace openjdkjvmti
diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc
index d0349b987f..e70547dc6a 100644
--- a/runtime/openjdkjvmti/ti_redefine.cc
+++ b/runtime/openjdkjvmti/ti_redefine.cc
@@ -33,6 +33,8 @@
#include <limits>
+#include "android-base/stringprintf.h"
+
#include "art_jvmti.h"
#include "base/logging.h"
#include "events-inl.h"
@@ -49,13 +51,15 @@
namespace openjdkjvmti {
+using android::base::StringPrintf;
+
// Moves dex data to an anonymous, read-only mmap'd region.
std::unique_ptr<art::MemMap> Redefiner::MoveDataToMemMap(const std::string& original_location,
jint data_len,
unsigned char* dex_data,
std::string* error_msg) {
std::unique_ptr<art::MemMap> map(art::MemMap::MapAnonymous(
- art::StringPrintf("%s-transformed", original_location.c_str()).c_str(),
+ StringPrintf("%s-transformed", original_location.c_str()).c_str(),
nullptr,
data_len,
PROT_READ|PROT_WRITE,
@@ -246,9 +250,9 @@ art::mirror::LongArray* Redefiner::AllocateDexFileCookie(
}
void Redefiner::RecordFailure(jvmtiError result, const std::string& error_msg) {
- *error_msg_ = art::StringPrintf("Unable to perform redefinition of '%s': %s",
- class_sig_,
- error_msg.c_str());
+ *error_msg_ = StringPrintf("Unable to perform redefinition of '%s': %s",
+ class_sig_,
+ error_msg.c_str());
result_ = result;
}
@@ -439,7 +443,6 @@ bool Redefiner::UpdateClass(art::ObjPtr<art::mirror::Class> mclass,
// Need to update class last since the ArtMethod gets its DexFile from the class (which is needed
// to call GetReturnTypeDescriptor and GetParameterTypeList above).
mclass->SetDexCache(new_dex_cache.Ptr());
- mclass->SetDexCacheStrings(new_dex_cache->GetStrings());
mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(*class_def));
mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_)));
return true;
diff --git a/runtime/parsed_options_test.cc b/runtime/parsed_options_test.cc
index 5b90c6adad..8948c710db 100644
--- a/runtime/parsed_options_test.cc
+++ b/runtime/parsed_options_test.cc
@@ -19,7 +19,6 @@
#include <memory>
#include "arch/instruction_set.h"
-#include "base/stringprintf.h"
#include "common_runtime_test.h"
namespace art {
diff --git a/runtime/plugin.cc b/runtime/plugin.cc
index 481b1caa15..731967c738 100644
--- a/runtime/plugin.cc
+++ b/runtime/plugin.cc
@@ -17,11 +17,15 @@
#include "plugin.h"
#include <dlfcn.h>
-#include "base/stringprintf.h"
+
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
namespace art {
+using android::base::StringPrintf;
+
const char* PLUGIN_INITIALIZATION_FUNCTION_NAME = "ArtPlugin_Initialize";
const char* PLUGIN_DEINITIALIZATION_FUNCTION_NAME = "ArtPlugin_Deinitialize";
diff --git a/runtime/reference_table.cc b/runtime/reference_table.cc
index 1c975a453a..d8b9dcc016 100644
--- a/runtime/reference_table.cc
+++ b/runtime/reference_table.cc
@@ -16,6 +16,8 @@
#include "reference_table.h"
+#include "android-base/stringprintf.h"
+
#include "base/mutex.h"
#include "indirect_reference_table.h"
#include "mirror/array.h"
@@ -30,6 +32,9 @@
namespace art {
+using android::base::StringAppendF;
+using android::base::StringPrintf;
+
ReferenceTable::ReferenceTable(const char* name, size_t initial_size, size_t max_size)
: name_(name), max_size_(max_size) {
CHECK_LE(initial_size, max_size);
diff --git a/runtime/reference_table_test.cc b/runtime/reference_table_test.cc
index d80a9b3dd1..9523e92d7c 100644
--- a/runtime/reference_table_test.cc
+++ b/runtime/reference_table_test.cc
@@ -16,6 +16,8 @@
#include "reference_table.h"
+#include "android-base/stringprintf.h"
+
#include "class_linker.h"
#include "common_runtime_test.h"
#include "handle_scope-inl.h"
@@ -30,6 +32,8 @@
namespace art {
+using android::base::StringPrintf;
+
class ReferenceTableTest : public CommonRuntimeTest {};
static mirror::Object* CreateWeakReference(mirror::Object* referent)
diff --git a/runtime/reflection-inl.h b/runtime/reflection-inl.h
index 68e7a10e01..62ce9e9509 100644
--- a/runtime/reflection-inl.h
+++ b/runtime/reflection-inl.h
@@ -19,7 +19,8 @@
#include "reflection.h"
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "common_throws.h"
#include "jvalue-inl.h"
#include "mirror/object-inl.h"
@@ -103,13 +104,14 @@ inline bool ConvertPrimitiveValue(bool unbox_for_result,
}
if (!unbox_for_result) {
- ThrowIllegalArgumentException(StringPrintf("Invalid primitive conversion from %s to %s",
- PrettyDescriptor(srcType).c_str(),
- PrettyDescriptor(dstType).c_str()).c_str());
+ ThrowIllegalArgumentException(
+ android::base::StringPrintf("Invalid primitive conversion from %s to %s",
+ PrettyDescriptor(srcType).c_str(),
+ PrettyDescriptor(dstType).c_str()).c_str());
} else {
- ThrowClassCastException(StringPrintf("Couldn't convert result of type %s to %s",
- PrettyDescriptor(srcType).c_str(),
- PrettyDescriptor(dstType).c_str()).c_str());
+ ThrowClassCastException(android::base::StringPrintf("Couldn't convert result of type %s to %s",
+ PrettyDescriptor(srcType).c_str(),
+ PrettyDescriptor(dstType).c_str()).c_str());
}
return false;
}
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 8446b525ad..4d2450135e 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -34,6 +34,8 @@
namespace art {
+using android::base::StringPrintf;
+
class ArgArray {
public:
ArgArray(const char* shorty, uint32_t shorty_len)
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 59c596170d..0977093ed6 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1721,7 +1721,7 @@ void Runtime::VisitImageRoots(RootVisitor* visitor) {
if (space->IsImageSpace()) {
auto* image_space = space->AsImageSpace();
const auto& image_header = image_space->GetImageHeader();
- for (size_t i = 0; i < ImageHeader::kImageRootsMax; ++i) {
+ for (int32_t i = 0, size = image_header.GetImageRoots()->GetLength(); i != size; ++i) {
auto* obj = image_header.GetImageRoot(static_cast<ImageHeader::ImageRoot>(i));
if (obj != nullptr) {
auto* after_obj = obj;
diff --git a/runtime/runtime_android.cc b/runtime/runtime_android.cc
index be9786024a..0a996a9e55 100644
--- a/runtime/runtime_android.cc
+++ b/runtime/runtime_android.cc
@@ -21,7 +21,6 @@
#include "base/logging.h"
#include "base/mutex.h"
-#include "base/stringprintf.h"
#include "thread-inl.h"
#include "utils.h"
diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc
index 93704a971c..b8894d2569 100644
--- a/runtime/runtime_linux.cc
+++ b/runtime/runtime_linux.cc
@@ -24,11 +24,12 @@
#include <iostream>
#include <sstream>
+#include "android-base/stringprintf.h"
+
#include "base/dumpable.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/mutex.h"
-#include "base/stringprintf.h"
#include "native_stack_dump.h"
#include "thread-inl.h"
#include "thread_list.h"
@@ -36,6 +37,8 @@
namespace art {
+using android::base::StringPrintf;
+
static constexpr bool kUseSigRTTimeout = true;
static constexpr bool kDumpNativeStackOnTimeout = true;
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 792da88a63..3fed7c9458 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -16,6 +16,8 @@
#include "stack.h"
+#include "android-base/stringprintf.h"
+
#include "arch/context.h"
#include "art_method-inl.h"
#include "base/enums.h"
@@ -39,6 +41,8 @@
namespace art {
+using android::base::StringPrintf;
+
static constexpr bool kDebugStackWalk = false;
mirror::Object* ShadowFrame::GetThisObject() const {
diff --git a/runtime/thread.cc b/runtime/thread.cc
index d79bf36380..9c93a5f962 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -28,6 +28,8 @@
#include <list>
#include <sstream>
+#include "android-base/stringprintf.h"
+
#include "arch/context.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
@@ -88,6 +90,9 @@
namespace art {
+using android::base::StringAppendV;
+using android::base::StringPrintf;
+
extern "C" NO_RETURN void artDeoptimize(Thread* self);
bool Thread::is_started_ = false;
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 664eeb4b94..bf9eef8370 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -25,6 +25,8 @@
#include <sstream>
+#include "android-base/stringprintf.h"
+
#include "base/histogram-inl.h"
#include "base/mutex-inl.h"
#include "base/systrace.h"
@@ -52,6 +54,8 @@
namespace art {
+using android::base::StringPrintf;
+
static constexpr uint64_t kLongThreadSuspendThreshold = MsToNs(5);
static constexpr uint64_t kThreadSuspendTimeoutMs = 30 * 1000; // 30s.
// Use 0 since we want to yield to prevent blocking for an unpredictable amount of time.
diff --git a/runtime/thread_pool.cc b/runtime/thread_pool.cc
index d9d2ea31a2..6abdca176d 100644
--- a/runtime/thread_pool.cc
+++ b/runtime/thread_pool.cc
@@ -21,6 +21,8 @@
#include <sys/time.h>
#include <sys/resource.h>
+#include "android-base/stringprintf.h"
+
#include "base/bit_utils.h"
#include "base/casts.h"
#include "base/logging.h"
@@ -31,6 +33,8 @@
namespace art {
+using android::base::StringPrintf;
+
static constexpr bool kMeasureWaitTime = false;
ThreadPoolWorker::ThreadPoolWorker(ThreadPool* thread_pool, const std::string& name,
diff --git a/runtime/ti/agent.cc b/runtime/ti/agent.cc
index d21ff77849..0bba44c988 100644
--- a/runtime/ti/agent.cc
+++ b/runtime/ti/agent.cc
@@ -15,12 +15,17 @@
*/
#include "agent.h"
+
+#include "android-base/stringprintf.h"
+
#include "java_vm_ext.h"
#include "runtime.h"
namespace art {
namespace ti {
+using android::base::StringPrintf;
+
const char* AGENT_ON_LOAD_FUNCTION_NAME = "Agent_OnLoad";
const char* AGENT_ON_ATTACH_FUNCTION_NAME = "Agent_OnAttach";
const char* AGENT_ON_UNLOAD_FUNCTION_NAME = "Agent_OnUnload";
diff --git a/runtime/ti/agent.h b/runtime/ti/agent.h
index 6561756edd..7408aeec35 100644
--- a/runtime/ti/agent.h
+++ b/runtime/ti/agent.h
@@ -20,7 +20,6 @@
#include <dlfcn.h>
#include <jni.h> // for jint, JavaVM* etc declarations
-#include "base/stringprintf.h"
#include "runtime.h"
#include "utils.h"
diff --git a/runtime/trace.cc b/runtime/trace.cc
index f564de4952..9d9360e9cb 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -19,6 +19,8 @@
#include <sys/uio.h>
#include <unistd.h>
+#include "android-base/stringprintf.h"
+
#include "art_method-inl.h"
#include "base/casts.h"
#include "base/enums.h"
@@ -46,6 +48,8 @@
namespace art {
+using android::base::StringPrintf;
+
static constexpr size_t TraceActionBits = MinimumBitsToStore(
static_cast<size_t>(kTraceMethodActionMask));
static constexpr uint8_t kOpNewMethod = 1U;
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 4732f59ae1..8867743ec1 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <memory>
+#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "base/stl_util.h"
@@ -48,6 +49,9 @@
namespace art {
+using android::base::StringAppendF;
+using android::base::StringPrintf;
+
static const uint8_t kBase64Map[256] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
diff --git a/runtime/utils.h b/runtime/utils.h
index 04e0dded27..16ef706159 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -284,6 +284,12 @@ inline void FlushInstructionCache(char* begin, char* end) {
__builtin___clear_cache(begin, end);
}
+inline void FlushDataCache(char* begin, char* end) {
+ // Same as FlushInstructionCache for lack of other builtin. __builtin___clear_cache
+ // flushes both caches.
+ __builtin___clear_cache(begin, end);
+}
+
template <typename T>
constexpr PointerSize ConvertToPointerSize(T any) {
if (any == 4 || any == 8) {
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index ebecc85a3c..7e23c8b4bc 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -18,6 +18,8 @@
#include <iostream>
+#include "android-base/stringprintf.h"
+
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/enums.h"
@@ -55,6 +57,8 @@
namespace art {
namespace verifier {
+using android::base::StringPrintf;
+
static constexpr bool kTimeVerifyMethod = !kIsDebugBuild;
static constexpr bool kDebugVerify = false;
// TODO: Add a constant to method_verifier to turn on verbose logging?
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index ab23773bc4..52f7e348ce 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -16,6 +16,8 @@
#include "reg_type-inl.h"
+#include "android-base/stringprintf.h"
+
#include "base/arena_bit_vector.h"
#include "base/bit_vector-inl.h"
#include "base/casts.h"
@@ -35,6 +37,8 @@
namespace art {
namespace verifier {
+using android::base::StringPrintf;
+
const UndefinedType* UndefinedType::instance_ = nullptr;
const ConflictType* ConflictType::instance_ = nullptr;
const BooleanType* BooleanType::instance_ = nullptr;
diff --git a/runtime/verifier/register_line.cc b/runtime/verifier/register_line.cc
index a6088aa036..383d890702 100644
--- a/runtime/verifier/register_line.cc
+++ b/runtime/verifier/register_line.cc
@@ -16,7 +16,8 @@
#include "register_line.h"
-#include "base/stringprintf.h"
+#include "android-base/stringprintf.h"
+
#include "dex_instruction-inl.h"
#include "method_verifier-inl.h"
#include "register_line-inl.h"
@@ -25,6 +26,8 @@
namespace art {
namespace verifier {
+using android::base::StringPrintf;
+
bool RegisterLine::CheckConstructorReturn(MethodVerifier* verifier) const {
if (kIsDebugBuild && this_initialized_) {
// Ensure that there is no UninitializedThisReference type anymore if this_initialized_ is true.
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 35495867c7..009170cb1c 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -20,6 +20,8 @@
#include <sstream>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
#include "entrypoints/quick/quick_entrypoints_enum.h"
#include "jni_internal.h"
@@ -189,7 +191,7 @@ jmethodID CacheMethod(JNIEnv* env, jclass c, bool is_static,
static jmethodID CachePrimitiveBoxingMethod(JNIEnv* env, char prim_name, const char* boxed_name) {
ScopedLocalRef<jclass> boxed_class(env, env->FindClass(boxed_name));
return CacheMethod(env, boxed_class.get(), true, "valueOf",
- StringPrintf("(%c)L%s;", prim_name, boxed_name).c_str());
+ android::base::StringPrintf("(%c)L%s;", prim_name, boxed_name).c_str());
}
#define STRING_INIT_LIST(V) \
diff --git a/runtime/zip_archive.cc b/runtime/zip_archive.cc
index d96fb429e5..cd79bb61f3 100644
--- a/runtime/zip_archive.cc
+++ b/runtime/zip_archive.cc
@@ -23,7 +23,6 @@
#include <unistd.h>
#include <vector>
-#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
namespace art {
diff --git a/test/137-cfi/cfi.cc b/test/137-cfi/cfi.cc
index 113b35f98d..3b237f40ff 100644
--- a/test/137-cfi/cfi.cc
+++ b/test/137-cfi/cfi.cc
@@ -25,11 +25,11 @@
#include "jni.h"
+#include "android-base/stringprintf.h"
#include <backtrace/Backtrace.h>
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stringprintf.h"
#include "gc/heap.h"
#include "gc/space/image_space.h"
#include "oat_file.h"
@@ -91,7 +91,7 @@ static bool CheckStack(Backtrace* bt, const std::vector<std::string>& seq) {
static void MoreErrorInfo(pid_t pid, bool sig_quit_on_fail) {
printf("Secondary pid is %d\n", pid);
- PrintFileToLog(StringPrintf("/proc/%d/maps", pid), ::android::base::ERROR);
+ PrintFileToLog(android::base::StringPrintf("/proc/%d/maps", pid), ::android::base::ERROR);
if (sig_quit_on_fail) {
int res = kill(pid, SIGQUIT);
diff --git a/test/530-checker-loops4/src/Main.java b/test/530-checker-loops4/src/Main.java
index 7d3d7d9bfe..91af1f4ee9 100644
--- a/test/530-checker-loops4/src/Main.java
+++ b/test/530-checker-loops4/src/Main.java
@@ -96,7 +96,29 @@ public class Main {
/// CHECK-NOT: Phi
public static int geo4(int a) {
for (int i = 0; i < 10; i++) {
- a %= 7;
+ a %= 7; // a wrap-around induction
+ }
+ return a;
+ }
+
+ /// CHECK-START: int Main.geo5() loop_optimization (before)
+ /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
+ /// CHECK-DAG: Shr loop:<<Loop>>
+ //
+ /// CHECK-START: int Main.geo5() loop_optimization (after)
+ /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 loop:none
+ /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none
+ /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024 loop:none
+ /// CHECK-DAG: <<Div:i\d+>> Div [<<Int1>>,<<Int2>>] loop:none
+ /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zero>>] loop:none
+ /// CHECK-DAG: Return [<<Add>>] loop:none
+ //
+ /// CHECK-START: int Main.geo5() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ public static int geo5() {
+ int a = 0x7fffffff;
+ for (int i = 0; i < 10; i++) {
+ a >>= 1;
}
return a;
}
@@ -186,7 +208,7 @@ public class Main {
int r = 0;
for (int i = 0; i < 100; i++) { // a converges to 0
r += x[a];
- a %= 5;
+ a %= 5; // a wrap-around induction
}
return r;
}
@@ -305,6 +327,8 @@ public class Main {
expectEquals(i % 7, geo4(i));
}
+ expectEquals(0x1fffff, geo5());
+
expectEquals(34, geo1BCE());
expectEquals(36, geo2BCE());
expectEquals(131, geo3BCE());
diff --git a/test/618-checker-induction/src/Main.java b/test/618-checker-induction/src/Main.java
index 87a69b25c4..ecc129a374 100644
--- a/test/618-checker-induction/src/Main.java
+++ b/test/618-checker-induction/src/Main.java
@@ -248,6 +248,33 @@ public class Main {
return closed; // only needs last value
}
+ /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (before)
+ /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
+ /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Select loop:<<Loop>> outer_loop:none
+ /// CHECK-DAG: Return [<<Phi1>>] loop:none
+ //
+ /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (after)
+ /// CHECK-NOT: Phi
+ /// CHECK-NOT: Select
+ //
+ /// CHECK-START: int Main.closedFormInductionTrivialIf() instruction_simplifier$after_bce (after)
+ /// CHECK-DAG: <<Int:i\d+>> IntConstant 81 loop:none
+ /// CHECK-DAG: Return [<<Int>>] loop:none
+ static int closedFormInductionTrivialIf() {
+ int closed = 11;
+ for (int i = 0; i < 10; i++) {
+ // Trivial if becomes trivial select at HIR level.
+ // Make sure this is still recognized as induction.
+ if (i < 5) {
+ closed += 7;
+ } else {
+ closed += 7;
+ }
+ }
+ return closed; // only needs last value
+ }
+
/// CHECK-START: int Main.closedFormNested() loop_optimization (before)
/// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none
@@ -732,6 +759,7 @@ public class Main {
expectEquals(12395, closedFormInductionUp());
expectEquals(12295, closedFormInductionInAndDown(12345));
+ expectEquals(81, closedFormInductionTrivialIf());
expectEquals(10 * 10, closedFormNested());
expectEquals(12345 + 17 * 23 * 7, closedFormNestedAlt());
for (int n = -4; n < 10; n++) {
diff --git a/test/624-checker-stringops/src/Main.java b/test/624-checker-stringops/src/Main.java
index d965e3ffce..75b782e8c0 100644
--- a/test/624-checker-stringops/src/Main.java
+++ b/test/624-checker-stringops/src/Main.java
@@ -258,6 +258,20 @@ public class Main {
return b.length();
}
+ // Regression b/33656359: StringBuffer x is passed to constructor of String
+ // (this caused old code to crash due to missing nullptr check).
+ //
+ /// CHECK-START: void Main.doesNothing() instruction_simplifier (before)
+ /// CHECK-DAG: InvokeVirtual intrinsic:StringBufferToString
+ //
+ /// CHECK-START: void Main.doesNothing() instruction_simplifier (after)
+ /// CHECK-DAG: InvokeVirtual intrinsic:StringBufferToString
+ static void doesNothing() {
+ StringBuffer x = new StringBuffer();
+ String y = new String(x);
+ x.toString();
+ }
+
public static void main(String[] args) {
expectEquals(1865, liveIndexOf());
expectEquals(29, deadIndexOf());
@@ -281,6 +295,8 @@ public class Main {
expectEquals(0, bufferDeadLoop());
expectEquals(0, builderDeadLoop());
+ doesNothing();
+
System.out.println("passed");
}
diff --git a/test/911-get-stack-trace/expected.txt b/test/911-get-stack-trace/expected.txt
index 77c77ca21e..f8c97ce475 100644
--- a/test/911-get-stack-trace/expected.txt
+++ b/test/911-get-stack-trace/expected.txt
@@ -3,206 +3,206 @@
###################
From top
---------
- getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1
- print (Ljava/lang/Thread;II)V 0
- printOrWait (IILMain$ControlData;)V 6
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- doTest ()V 38
- main ([Ljava/lang/String;)V 6
----------
- print (Ljava/lang/Thread;II)V 0
- printOrWait (IILMain$ControlData;)V 6
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- doTest ()V 42
- main ([Ljava/lang/String;)V 6
----------
- getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1
- print (Ljava/lang/Thread;II)V 0
- printOrWait (IILMain$ControlData;)V 6
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
----------
- printOrWait (IILMain$ControlData;)V 6
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
+ getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 -2
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 38 34
+ main ([Ljava/lang/String;)V 6 24
+---------
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 42 35
+ main ([Ljava/lang/String;)V 6 24
+---------
+ getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 -2
+ print (Ljava/lang/Thread;II)V 0 124
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+---------
+ printOrWait (IILMain$ControlData;)V 6 151
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
From bottom
---------
- main ([Ljava/lang/String;)V 6
+ main ([Ljava/lang/String;)V 6 24
---------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- doTest ()V 65
- main ([Ljava/lang/String;)V 6
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ doTest ()V 65 41
+ main ([Ljava/lang/String;)V 6 24
---------
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
################################
### Other thread (suspended) ###
################################
From top
---------
- wait ()V -1
- printOrWait (IILMain$ControlData;)V 24
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
----------
- printOrWait (IILMain$ControlData;)V 24
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
----------
- wait ()V -1
- printOrWait (IILMain$ControlData;)V 24
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
----------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
+ wait ()V -1 -2
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
+---------
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
+---------
+ wait ()V -1 -2
+ printOrWait (IILMain$ControlData;)V 24 157
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+---------
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
From bottom
---------
- run ()V 4
+ run ()V 4 54
---------
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 54
---------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
###########################
### Other thread (live) ###
###########################
From top
---------
- printOrWait (IILMain$ControlData;)V 44
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
----------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
----------
- printOrWait (IILMain$ControlData;)V 44
- baz (IIILMain$ControlData;)Ljava/lang/Object; 2
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
----------
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
+ printOrWait (IILMain$ControlData;)V 44 164
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
+---------
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
+---------
+ printOrWait (IILMain$ControlData;)V 44 164
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+---------
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
From bottom
---------
- run ()V 4
+ run ()V 4 88
---------
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- run ()V 4
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ run ()V 4 88
---------
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
- foo (IIILMain$ControlData;)I 0
- baz (IIILMain$ControlData;)Ljava/lang/Object; 9
- bar (IIILMain$ControlData;)J 0
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
+ foo (IIILMain$ControlData;)I 0 131
+ baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144
+ bar (IIILMain$ControlData;)J 0 136
diff --git a/test/911-get-stack-trace/stack_trace.cc b/test/911-get-stack-trace/stack_trace.cc
index b5b5678f54..57f6a927ea 100644
--- a/test/911-get-stack-trace/stack_trace.cc
+++ b/test/911-get-stack-trace/stack_trace.cc
@@ -20,9 +20,10 @@
#include <memory>
#include <stdio.h>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stringprintf.h"
#include "jni.h"
#include "openjdkjvmti/jvmti.h"
#include "ScopedLocalRef.h"
@@ -32,6 +33,25 @@
namespace art {
namespace Test911GetStackTrace {
+using android::base::StringPrintf;
+
+static jint FindLineNumber(jint line_number_count,
+ jvmtiLineNumberEntry* line_number_table,
+ jlocation location) {
+ if (line_number_table == nullptr) {
+ return -2;
+ }
+
+ jint line_number = -1;
+ for (jint i = 0; i != line_number_count; ++i) {
+ if (line_number_table[i].start_location > location) {
+ return line_number;
+ }
+ line_number = line_number_table[i].line_number;
+ }
+ return line_number;
+}
+
extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jthread thread, jint start, jint max) {
std::unique_ptr<jvmtiFrameInfo[]> frames(new jvmtiFrameInfo[max]);
@@ -61,6 +81,26 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
}
}
+ jint line_number_count;
+ jvmtiLineNumberEntry* line_number_table;
+ {
+ jvmtiError line_result = jvmti_env->GetLineNumberTable(frames[method_index].method,
+ &line_number_count,
+ &line_number_table);
+ if (line_result != JVMTI_ERROR_NONE) {
+ // Accept absent info and native method errors.
+ if (line_result != JVMTI_ERROR_ABSENT_INFORMATION &&
+ line_result != JVMTI_ERROR_NATIVE_METHOD) {
+ char* err;
+ jvmti_env->GetErrorName(line_result, &err);
+ printf("Failure running GetLineNumberTable: %s\n", err);
+ return nullptr;
+ }
+ line_number_table = nullptr;
+ line_number_count = 0;
+ }
+ }
+
auto inner_callback = [&](jint component_index) -> jstring {
switch (component_index) {
case 0:
@@ -69,11 +109,17 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
return (sig == nullptr) ? nullptr : env->NewStringUTF(sig);
case 2:
return env->NewStringUTF(StringPrintf("%" PRId64, frames[method_index].location).c_str());
+ case 3: {
+ jint line_number = FindLineNumber(line_number_count,
+ line_number_table,
+ frames[method_index].location);
+ return env->NewStringUTF(StringPrintf("%d", line_number).c_str());
+ }
}
LOG(FATAL) << "Unreachable";
UNREACHABLE();
};
- jobjectArray inner_array = CreateObjectArray(env, 3, "java/lang/String", inner_callback);
+ jobjectArray inner_array = CreateObjectArray(env, 4, "java/lang/String", inner_callback);
if (name != nullptr) {
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(name));
@@ -84,6 +130,9 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace(
if (gen != nullptr) {
jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(gen));
}
+ if (line_number_table != nullptr) {
+ jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(line_number_table));
+ }
return inner_array;
};
diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt
index e5fa53f207..7522a659f2 100644
--- a/test/913-heaps/expected.txt
+++ b/test/913-heaps/expected.txt
@@ -5,12 +5,12 @@ root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vre
root@root --(thread)--> 3000@0 [size=132, length=-1]
0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
-1002@0 --(interface)--> 2001@0 [size=132, length=-1]
+1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
1@1000 --(class)--> 1000@0 [size=123, length=-1]
1@1000 --(field@12)--> 3@1001 [size=24, length=-1]
1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
-2001@0 --(interface)--> 2000@0 [size=132, length=-1]
+2001@0 --(interface)--> 2000@0 [size=124, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
@@ -22,12 +22,12 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
-1002@0 --(interface)--> 2001@0 [size=132, length=-1]
+1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
1@1000 --(class)--> 1000@0 [size=123, length=-1]
1@1000 --(field@12)--> 3@1001 [size=24, length=-1]
1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
-2001@0 --(interface)--> 2000@0 [size=132, length=-1]
+2001@0 --(interface)--> 2000@0 [size=124, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
@@ -46,12 +46,12 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot
root@root --(thread)--> 1@1000 [size=16, length=-1]
root@root --(thread)--> 3000@0 [size=132, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
-1002@0 --(interface)--> 2001@0 [size=132, length=-1]
+1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
1@1000 --(class)--> 1000@0 [size=123, length=-1]
1@1000 --(field@12)--> 3@1001 [size=24, length=-1]
1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
-2001@0 --(interface)--> 2000@0 [size=132, length=-1]
+2001@0 --(interface)--> 2000@0 [size=124, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
@@ -63,12 +63,12 @@ root@root --(thread)--> 3000@0 [size=132, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
-1002@0 --(interface)--> 2001@0 [size=132, length=-1]
+1002@0 --(interface)--> 2001@0 [size=124, length=-1]
1002@0 --(superclass)--> 1001@0 [size=123, length=-1]
1@1000 --(class)--> 1000@0 [size=123, length=-1]
1@1000 --(field@12)--> 3@1001 [size=24, length=-1]
1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
-2001@0 --(interface)--> 2000@0 [size=132, length=-1]
+2001@0 --(interface)--> 2000@0 [size=124, length=-1]
2@1000 --(class)--> 1000@0 [size=123, length=-1]
3@1001 --(class)--> 1001@0 [size=123, length=-1]
3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
diff --git a/test/913-heaps/heaps.cc b/test/913-heaps/heaps.cc
index 7b00fcdcc1..49ab7dd83e 100644
--- a/test/913-heaps/heaps.cc
+++ b/test/913-heaps/heaps.cc
@@ -22,9 +22,10 @@
#include <vector>
+#include "android-base/stringprintf.h"
+
#include "base/logging.h"
#include "base/macros.h"
-#include "base/stringprintf.h"
#include "jit/jit.h"
#include "jni.h"
#include "native_stack_dump.h"
@@ -39,6 +40,8 @@
namespace art {
namespace Test913Heaps {
+using android::base::StringPrintf;
+
extern "C" JNIEXPORT void JNICALL Java_Main_forceGarbageCollection(JNIEnv* env ATTRIBUTE_UNUSED,
jclass klass ATTRIBUTE_UNUSED) {
jvmtiError ret = jvmti_env->ForceGarbageCollection();
@@ -180,7 +183,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_followReferences(JNIEnv* env
if (*tag_ptr >= 1000) {
// This is a class or interface, the size of which will be dependent on the architecture.
// Do not print the size, but detect known values and "normalize" for the golden file.
- if ((sizeof(void*) == 4 && size == 180) || (sizeof(void*) == 8 && size == 232)) {
+ if ((sizeof(void*) == 4 && size == 172) || (sizeof(void*) == 8 && size == 224)) {
adapted_size = 123;
}
}
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index b515130a49..c02999bb07 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -492,6 +492,24 @@ ifneq (,$(filter trace stream,$(TRACE_TYPES)))
$(PICTEST_TYPES),$(DEBUGGABLE_TYPES), $(TEST_ART_BROKEN_TRACING_RUN_TESTS),$(ALL_ADDRESS_SIZES))
endif
+TEST_ART_BROKEN_TRACING_RUN_TESTS :=
+
+# These tests expect JIT compilation, which is suppressed when tracing.
+TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS := \
+ 604-hot-static-interface \
+ 612-jit-dex-cache \
+ 613-inlining-dex-cache \
+ 616-cha \
+ 626-set-resolved-string \
+
+ifneq (,$(filter trace stream,$(TRACE_TYPES)))
+ ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
+ jit,$(RELOCATE_TYPES),trace stream,$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \
+ $(PICTEST_TYPES),$(DEBUGGABLE_TYPES), $(TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS),$(ALL_ADDRESS_SIZES))
+endif
+
+TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS :=
+
# Known broken tests for the interpreter.
# CFI unwinding expects managed frames.
# 629 requires compilation.
diff --git a/test/ErroneousA/ErroneousA.java b/test/ErroneousA/ErroneousA.java
new file mode 100644
index 0000000000..49da54452a
--- /dev/null
+++ b/test/ErroneousA/ErroneousA.java
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+final class FinalSuper {}
diff --git a/runtime/base/stringprintf_test.cc b/test/ErroneousB/ErroneousB.java
index 0bfde33a3f..6c2902ab7d 100644
--- a/runtime/base/stringprintf_test.cc
+++ b/test/ErroneousB/ErroneousB.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -14,16 +14,7 @@
* limitations under the License.
*/
-#include "stringprintf.h"
+// Only final in first dex.
+class FinalSuper {}
-#include "gtest/gtest.h"
-
-namespace art {
-
-TEST(StringPrintfTest, HexSizeT) {
- size_t size = 0x00107e59;
- EXPECT_STREQ("00107e59", StringPrintf("%08zx", size).c_str());
- EXPECT_STREQ("0x00107e59", StringPrintf("0x%08zx", size).c_str());
-}
-
-} // namespace art
+class Erroneous extends FinalSuper {}
diff --git a/tools/cpp-define-generator/offset_dexcache.def b/tools/cpp-define-generator/offset_dexcache.def
index 4b9d481eb1..abb5e1ecac 100644
--- a/tools/cpp-define-generator/offset_dexcache.def
+++ b/tools/cpp-define-generator/offset_dexcache.def
@@ -38,7 +38,6 @@ DEFINE_ART_METHOD_OFFSET_SIZED(DEX_CACHE_TYPES, DexCacheResolvedTypes)
DEFINE_ART_METHOD_OFFSET_SIZED(JNI, EntryPointFromJni)
DEFINE_ART_METHOD_OFFSET_SIZED(QUICK_CODE, EntryPointFromQuickCompiledCode)
DEFINE_ART_METHOD_OFFSET(DECLARING_CLASS, DeclaringClass)
-DEFINE_DECLARING_CLASS_OFFSET(DEX_CACHE_STRINGS, DexCacheStrings)
#undef DEFINE_ART_METHOD_OFFSET
#undef DEFINE_ART_METHOD_OFFSET_32
diff --git a/tools/jfuzz/run_jfuzz_test.py b/tools/jfuzz/run_jfuzz_test.py
index fd8415d3a9..42745d247a 100755
--- a/tools/jfuzz/run_jfuzz_test.py
+++ b/tools/jfuzz/run_jfuzz_test.py
@@ -414,14 +414,16 @@ class JFuzzTester(object):
retc2: int, normalized return code of second runner
"""
if retc1 == retc2:
- # Non-divergent in return code.
+ # No divergence in return code.
if retc1 == RetCode.SUCCESS:
# Both compilations and runs were successful, inspect generated output.
runner1_out = self._runner1.output_file
runner2_out = self._runner2.output_file
if not filecmp.cmp(runner1_out, runner2_out, shallow=False):
+ # Divergence in output.
self.ReportDivergence(retc1, retc2, is_output_divergence=True)
else:
+ # No divergence in output.
self._num_success += 1
elif retc1 == RetCode.TIMEOUT:
self._num_timed_out += 1
@@ -429,8 +431,12 @@ class JFuzzTester(object):
self._num_not_compiled += 1
else:
self._num_not_run += 1
+ elif self._true_divergence_only and RetCode.TIMEOUT in (retc1, retc2):
+ # When only true divergences are requested, any divergence in return
+ # code where one is a time out is treated as a regular time out.
+ self._num_timed_out += 1
else:
- # Divergent in return code.
+ # Divergence in return code.
self.ReportDivergence(retc1, retc2, is_output_divergence=False)
def GetCurrentDivergenceDir(self):
@@ -450,13 +456,12 @@ class JFuzzTester(object):
os.mkdir(ddir)
for f in glob('*.txt') + ['Test.java']:
shutil.copy(f, ddir)
- if not (self._true_divergence_only and RetCode.TIMEOUT in (retc1, retc2)):
- # Maybe run bisection bug search.
- if retc1 in BISECTABLE_RET_CODES and retc2 in BISECTABLE_RET_CODES:
- self.MaybeBisectDivergence(retc1, retc2, is_output_divergence)
- # Call reporting script.
- if self._report_script:
- self.RunReportScript(retc1, retc2, is_output_divergence)
+ # Maybe run bisection bug search.
+ if retc1 in BISECTABLE_RET_CODES and retc2 in BISECTABLE_RET_CODES:
+ self.MaybeBisectDivergence(retc1, retc2, is_output_divergence)
+ # Call reporting script.
+ if self._report_script:
+ self.RunReportScript(retc1, retc2, is_output_divergence)
def RunReportScript(self, retc1, retc2, is_output_divergence):
"""Runs report script."""