Merge "Add HVariableInputSizeInstruction."
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index d59d8f6..bd7f900 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -26,6 +26,8 @@
AbstractMethod \
AllFields \
DexToDexDecompiler \
+ ErroneousA \
+ ErroneousB \
ExceptionHandle \
GetMethodSignature \
ImageLayoutA \
@@ -85,7 +87,7 @@
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 6e042c3..f4540ff 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 @@
" 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 @@
// 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/compiled_class.h b/compiler/compiled_class.h
index b88d613..06ce946 100644
--- a/compiler/compiled_class.h
+++ b/compiler/compiled_class.h
@@ -28,8 +28,11 @@
mirror::Class::Status GetStatus() const {
return status_;
}
+ void SetStatus(mirror::Class::Status status) {
+ status_ = status;
+ }
private:
- const mirror::Class::Status status_;
+ mirror::Class::Status status_;
};
} // namespace art
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index cf69f46..d4f6545 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/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 1b1de78..d1a5c4d 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -423,7 +423,7 @@
// Compile:
// 1) Compile all classes and methods enabled for compilation. May fall back to dex-to-dex
// compilation.
- if (!GetCompilerOptions().VerifyAtRuntime()) {
+ if (!GetCompilerOptions().VerifyAtRuntime() && !GetCompilerOptions().VerifyOnlyProfile()) {
Compile(class_loader, dex_files, timings);
}
if (dump_stats_) {
@@ -492,6 +492,7 @@
// TODO: we unquicken unconditionnally, as we don't know
// if the boot image has changed. How exactly we'll know is under
// experimentation.
+ TimingLogger::ScopedTiming t("Unquicken", timings);
Unquicken(dex_files, vdex_file->GetQuickeningInfo());
Runtime::Current()->GetCompilerCallbacks()->SetVerifierDeps(
new verifier::VerifierDeps(dex_files, vdex_file->GetVerifierDepsData()));
@@ -983,8 +984,10 @@
<< "situations. Please check the log.";
}
- InitializeClasses(class_loader, dex_files, timings);
- VLOG(compiler) << "InitializeClasses: " << GetMemoryUsageString(false);
+ if (!verify_only_profile) {
+ InitializeClasses(class_loader, dex_files, timings);
+ VLOG(compiler) << "InitializeClasses: " << GetMemoryUsageString(false);
+ }
UpdateImageClasses(timings);
VLOG(compiler) << "UpdateImageClasses: " << GetMemoryUsageString(false);
@@ -2060,21 +2063,32 @@
std::set<dex::TypeIndex> set(unverified_classes.begin(), unverified_classes.end());
for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
- const char* descriptor = dex_file->GetClassDescriptor(class_def);
- cls.Assign(class_linker->FindClass(soa.Self(), descriptor, class_loader));
- if (cls.Get() == nullptr) {
- CHECK(soa.Self()->IsExceptionPending());
- soa.Self()->ClearException();
- } else if (set.find(class_def.class_idx_) == set.end()) {
- ObjectLock<mirror::Class> lock(soa.Self(), cls);
- mirror::Class::SetStatus(cls, mirror::Class::kStatusVerified, soa.Self());
- // Create `VerifiedMethod`s for each methods, the compiler expects one for
- // quickening or compiling.
- // Note that this means:
- // - We're only going to compile methods that did verify.
- // - Quickening will not do checkcast ellision.
- // TODO(ngeoffray): Reconsider this once we refactor compiler filters.
- PopulateVerifiedMethods(*dex_file, i, verification_results_);
+ if (set.find(class_def.class_idx_) == set.end()) {
+ if (GetCompilerOptions().VerifyOnlyProfile()) {
+ // Just update the compiled_classes_ map. The compiler doesn't need to resolve
+ // the type.
+ compiled_classes_.Overwrite(
+ ClassReference(dex_file, i), new CompiledClass(mirror::Class::kStatusVerified));
+ } else {
+ // Resolve the type, so later compilation stages know they don't need to verify
+ // the class.
+ const char* descriptor = dex_file->GetClassDescriptor(class_def);
+ cls.Assign(class_linker->FindClass(soa.Self(), descriptor, class_loader));
+ if (cls.Get() != nullptr) {
+ ObjectLock<mirror::Class> lock(soa.Self(), cls);
+ mirror::Class::SetStatus(cls, mirror::Class::kStatusVerified, soa.Self());
+ } else {
+ DCHECK(soa.Self()->IsExceptionPending());
+ soa.Self()->ClearException();
+ }
+ // Create `VerifiedMethod`s for each methods, the compiler expects one for
+ // quickening or compiling.
+ // Note that this means:
+ // - We're only going to compile methods that did verify.
+ // - Quickening will not do checkcast ellision.
+ // TODO(ngeoffray): Reconsider this once we refactor compiler filters.
+ PopulateVerifiedMethods(*dex_file, i, verification_results_);
+ }
}
}
}
@@ -2675,29 +2689,29 @@
}
void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status status) {
+ switch (status) {
+ case mirror::Class::kStatusNotReady:
+ case mirror::Class::kStatusError:
+ case mirror::Class::kStatusRetryVerificationAtRuntime:
+ case mirror::Class::kStatusVerified:
+ case mirror::Class::kStatusInitialized:
+ case mirror::Class::kStatusResolved:
+ break; // Expected states.
+ default:
+ LOG(FATAL) << "Unexpected class status for class "
+ << PrettyDescriptor(ref.first->GetClassDescriptor(ref.first->GetClassDef(ref.second)))
+ << " of " << status;
+ }
+
MutexLock mu(Thread::Current(), compiled_classes_lock_);
auto it = compiled_classes_.find(ref);
- if (it == compiled_classes_.end() || it->second->GetStatus() != status) {
- // An entry doesn't exist or the status is lower than the new status.
- if (it != compiled_classes_.end()) {
- CHECK_GT(status, it->second->GetStatus());
- delete it->second;
- }
- switch (status) {
- case mirror::Class::kStatusNotReady:
- case mirror::Class::kStatusError:
- case mirror::Class::kStatusRetryVerificationAtRuntime:
- case mirror::Class::kStatusVerified:
- case mirror::Class::kStatusInitialized:
- case mirror::Class::kStatusResolved:
- break; // Expected states.
- default:
- LOG(FATAL) << "Unexpected class status for class "
- << PrettyDescriptor(ref.first->GetClassDescriptor(ref.first->GetClassDef(ref.second)))
- << " of " << status;
- }
+ if (it == compiled_classes_.end()) {
CompiledClass* compiled_class = new CompiledClass(status);
compiled_classes_.Overwrite(ref, compiled_class);
+ } else if (status > it->second->GetStatus()) {
+ // Update the status if we now have a greater one. This happens with vdex,
+ // which records a class is verified, but does not resolve it.
+ it->second->SetStatus(status);
}
}
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index cc50197..eb69931 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -440,9 +440,12 @@
TimingLogger* timings)
REQUIRES(!Locks::mutator_lock_);
+ // NO_THREAD_SAFETY_ANALYSIS as the method accesses a guarded value in a
+ // single-threaded way.
void Verify(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
- TimingLogger* timings);
+ TimingLogger* timings)
+ NO_THREAD_SAFETY_ANALYSIS;
void VerifyDexFile(jobject class_loader,
const DexFile& dex_file,
diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc
index 64fd9e7..47b1929 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 6f48779..9669c4a 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 9bbe595..1290379 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 @@
// 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 b22ca47..9c38445 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -1113,11 +1113,15 @@
}
// 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 @@
}
// 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/image_writer.h b/compiler/image_writer.h
index cc7df1c..c537483 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -27,7 +27,6 @@
#include <string>
#include <ostream>
-#include "art_method.h"
#include "base/bit_utils.h"
#include "base/dchecked_vector.h"
#include "base/enums.h"
diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc
index 9dfb434..148ce4f 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 @@
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 0a778b0..edc93ab 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 @@
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 55f3c3c..1c5aec0 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -46,8 +46,10 @@
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::OutputVRegister;
using helpers::RegisterFrom;
using helpers::SRegisterFrom;
+using helpers::Uint64ConstantFrom;
using vixl::ExactAssemblyScope;
using vixl::CodeBufferCheckScope;
@@ -1378,7 +1381,7 @@
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 @@
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 @@
__ 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 @@
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 @@
} 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
__ 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 @@
__ 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 @@
__ 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 @@
// 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 @@
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 @@
// `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 @@
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 @@
// `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 @@
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 @@
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 @@
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 @@
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 @@
// `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 @@
// 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 @@
__ 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 eabdbad..21c3ae6 100644
--- a/compiler/optimizing/common_arm.h
+++ b/compiler/optimizing/common_arm.h
@@ -122,10 +122,16 @@
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 @@
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) {
+ return Int32ConstantFrom(location.GetConstant());
+}
+
inline int64_t Int64ConstantFrom(Location location) {
HConstant* instr = location.GetConstant();
if (instr->IsIntConstant()) {
@@ -167,6 +176,11 @@
}
}
+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 188ee3a..34b52a8 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 d530564..28ee3a5 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 c240c67..b21bc09 100644
--- a/compiler/optimizing/induction_var_analysis.cc
+++ b/compiler/optimizing/induction_var_analysis.cc
@@ -211,7 +211,7 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
}
// 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::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::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 @@
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 @@
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 @@
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 @@
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 4720f2d..293aa70 100644
--- a/compiler/optimizing/induction_var_analysis.h
+++ b/compiler/optimizing/induction_var_analysis.h
@@ -115,7 +115,7 @@
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 @@
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 @@
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 2d182f6..f52a1aa 100644
--- a/compiler/optimizing/induction_var_analysis_test.cc
+++ b/compiler/optimizing/induction_var_analysis_test.cc
@@ -87,6 +87,7 @@
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 @@
HInstruction* constant2_;
HInstruction* constant7_;
HInstruction* constant100_;
+ HInstruction* constantm1_;
HInstruction* float_constant0_;
// Loop specifics.
@@ -612,6 +614,45 @@
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 e665551..7bcc384 100644
--- a/compiler/optimizing/induction_var_range.cc
+++ b/compiler/optimizing/induction_var_range.cc
@@ -983,10 +983,10 @@
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 c615df1..439e3b6 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1897,7 +1897,8 @@
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 95551c8..641a5c9 100644
--- a/compiler/optimizing/intrinsics_arm_vixl.cc
+++ b/compiler/optimizing/intrinsics_arm_vixl.cc
@@ -1509,7 +1509,7 @@
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 13e14c5..3831aa6 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 ba7012a..0d0f62a 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -1193,7 +1193,7 @@
}
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 @@
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 5891350..c6579dc 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 @@
: 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 951cdfb..1af94f3 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 4297634..f69f417 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 @@
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 30e8f4e..0147a76 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 ac54813..c06e9ca 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 @@
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 5a0f0c6..2346635 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 b6b62a8..cdb3b9f 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 @@
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 916984c..d5776fa 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 @@
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 d28ca28..53dda6a 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 cfe4837..cac6090 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 665baa6..46a1c43 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 da1dd7f..1320942 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 a374686..f307cbc 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 9f771ba..3f2afc0 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 @@
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 e4462d8..148ee88 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_roots_descriptions_[] = {
"kDexCaches",
"kClassRoots",
+ "kClassLoader",
};
// Map is so that we don't allocate multiple dex files for the same OatDexFile.
@@ -1506,12 +1510,13 @@
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 a2eba45..e77d03b 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 62d1ddf..7ae13a5 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 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 0b2d172..e538407 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 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 32ebee2..86019bf 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -40,7 +40,6 @@
"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 @@
"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 f264b82..181b2ed 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 @@
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 f7b5a76..52d8b3e 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 0b8e531..d489392 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 5dfc4b4..5aae93a 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 a65c967..5b50573 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 e564d1e..92c44e8 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 cc102ec..c520d63 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-inl.h b/runtime/art_method-inl.h
index c78db3e..ef03bb3 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -134,7 +134,8 @@
// NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here
// without accessing the DexCache and we don't want to do that in release build.
DCHECK_LT(method_index,
- GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods());
+ GetInterfaceMethodIfProxy(pointer_size)->GetDeclaringClass()
+ ->GetDexCache()->NumResolvedMethods());
ArtMethod* method = mirror::DexCache::GetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
method_index,
pointer_size);
@@ -153,7 +154,8 @@
// NOTE: Unchecked, i.e. not throwing AIOOB. We don't even know the length here
// without accessing the DexCache and we don't want to do that in release build.
DCHECK_LT(method_index,
- GetInterfaceMethodIfProxy(pointer_size)->GetDexCache()->NumResolvedMethods());
+ GetInterfaceMethodIfProxy(pointer_size)->GetDeclaringClass()
+ ->GetDexCache()->NumResolvedMethods());
DCHECK(new_method == nullptr || new_method->GetDeclaringClass() != nullptr);
mirror::DexCache::SetElementPtrSize(GetDexCacheResolvedMethods(pointer_size),
method_index,
@@ -184,7 +186,8 @@
inline mirror::Class* ArtMethod::GetDexCacheResolvedType(dex::TypeIndex type_index,
PointerSize pointer_size) {
if (kWithCheck) {
- mirror::DexCache* dex_cache = GetInterfaceMethodIfProxy(pointer_size)->GetDexCache();
+ mirror::DexCache* dex_cache =
+ GetInterfaceMethodIfProxy(pointer_size)->GetDeclaringClass()->GetDexCache();
if (UNLIKELY(type_index.index_ >= dex_cache->NumResolvedTypes())) {
ThrowArrayIndexOutOfBoundsException(type_index.index_, dex_cache->NumResolvedTypes());
return nullptr;
@@ -330,7 +333,7 @@
}
inline const DexFile::CodeItem* ArtMethod::GetCodeItem() {
- return GetDexFile()->GetCodeItem(GetCodeItemOffset());
+ return GetDeclaringClass()->GetDexFile().GetCodeItem(GetCodeItemOffset());
}
inline bool ArtMethod::IsResolvedTypeIdx(dex::TypeIndex type_idx, PointerSize pointer_size) {
@@ -395,20 +398,11 @@
}
inline mirror::DexCache* ArtMethod::GetDexCache() {
- if (LIKELY(!IsObsolete())) {
- return GetDeclaringClass()->GetDexCache();
- } else {
- DCHECK(!IsProxyMethod());
+ DCHECK(!IsProxyMethod());
+ if (UNLIKELY(IsObsolete())) {
return GetObsoleteDexCache();
- }
-}
-
-inline mirror::StringDexCacheType* ArtMethod::GetDexCacheStrings() {
- if (LIKELY(!IsObsolete())) {
- return GetDeclaringClass()->GetDexCacheStrings();
} else {
- DCHECK(!IsProxyMethod());
- return GetObsoleteDexCache()->GetStrings();
+ return GetDeclaringClass()->GetDexCache();
}
}
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 96b6f18..dfc7837 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/art_method.h b/runtime/art_method.h
index 83ed1db..3bc6f5d 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -27,7 +27,6 @@
#include "invoke_type.h"
#include "method_reference.h"
#include "modifiers.h"
-#include "mirror/dex_cache.h"
#include "mirror/object.h"
#include "obj_ptr.h"
#include "read_barrier_option.h"
@@ -221,12 +220,6 @@
return !IsIntrinsic() && (GetAccessFlags() & kAccObsoleteMethod) != 0;
}
- void SetIsObsolete() {
- // TODO We should really support redefining intrinsic if possible.
- DCHECK(!IsIntrinsic());
- SetAccessFlags(GetAccessFlags() | kAccObsoleteMethod);
- }
-
template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
bool IsNative() {
return (GetAccessFlags<kReadBarrierOption>() & kAccNative) != 0;
@@ -333,10 +326,6 @@
ALWAYS_INLINE ArtMethod* GetDexCacheResolvedMethod(uint16_t method_index,
PointerSize pointer_size)
REQUIRES_SHARED(Locks::mutator_lock_);
-
- ALWAYS_INLINE mirror::StringDexCacheType* GetDexCacheStrings()
- REQUIRES_SHARED(Locks::mutator_lock_);
-
ALWAYS_INLINE void SetDexCacheResolvedMethod(uint16_t method_index,
ArtMethod* new_method,
PointerSize pointer_size)
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index 5ef1f06..e4972da 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -175,19 +175,19 @@
#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 de6f423..568a7ae 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 92b7c65..44a84c8 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 ce452cb..9116097 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 0e8031f..d4bb56b 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 8fd9257..0000000
--- 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 4767a75..0000000
--- 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 57f198d..3c09d5a 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 6c27bc6..1c3328e 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 213986a..a11257f 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -73,7 +73,7 @@
// 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 f3a5be2..20aaa42 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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
// 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;
+ 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));
}
- 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;
+ }
+ // 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);
}
- 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 (!equal) {
+ VLOG(image) << "Image dex files " << image_dex_file_names.size();
+ for (ObjPtr<mirror::String> name : image_dex_file_names) {
+ VLOG(image) << name->ToModifiedUtf8();
}
- // 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));
- }
+ VLOG(image) << "Loader dex files " << loader_dex_file_names.size();
+ for (ObjPtr<mirror::String> name : loader_dex_file_names) {
+ VLOG(image) << name->ToModifiedUtf8();
}
- // 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();
- }
- 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.
- }
+ *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 @@
}
// 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 @@
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 @@
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 685677b..42108d8 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -278,8 +278,6 @@
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 @@
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 @@
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 8226e60..743fcc8 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 @@
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 9f0dbbb..c30272e 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 e339666..df4413d 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 aa8fb38..7d704ad 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 52b9f11..9504e8b 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 07f0fca..a3ab9fa 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 9902389..7b8974f 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 ee0f340..59b734f 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/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 14c9c21..f6eeffc 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -563,7 +563,7 @@
HandleWrapperObjPtr<mirror::Object> h_this(hs2.NewHandleWrapper(this_object));
Handle<mirror::Class> h_referring_class(hs2.NewHandle(referrer->GetDeclaringClass()));
const dex::TypeIndex method_type_idx =
- referrer->GetDexFile()->GetMethodId(method_idx).class_idx_;
+ h_referring_class->GetDexFile().GetMethodId(method_idx).class_idx_;
mirror::Class* method_reference_class = class_linker->ResolveType(method_type_idx, referrer);
if (UNLIKELY(method_reference_class == nullptr)) {
// Bad type idx.
@@ -673,7 +673,8 @@
size_t expected_size) {
ScopedAssertNoThreadSuspension ants(__FUNCTION__);
ArtField* resolved_field =
- referrer->GetDexCache()->GetResolvedField(field_idx, kRuntimePointerSize);
+ referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx,
+ kRuntimePointerSize);
if (UNLIKELY(resolved_field == nullptr)) {
return nullptr;
}
@@ -732,7 +733,7 @@
}
mirror::Class* referring_class = referrer->GetDeclaringClass();
ArtMethod* resolved_method =
- referrer->GetDexCache()->GetResolvedMethod(method_idx, kRuntimePointerSize);
+ referring_class->GetDexCache()->GetResolvedMethod(method_idx, kRuntimePointerSize);
if (UNLIKELY(resolved_method == nullptr)) {
return nullptr;
}
@@ -758,9 +759,9 @@
} else if (type == kSuper) {
// TODO This lookup is rather slow.
dex::TypeIndex method_type_idx =
- referrer->GetDexFile()->GetMethodId(method_idx).class_idx_;
+ referring_class->GetDexFile().GetMethodId(method_idx).class_idx_;
mirror::Class* method_reference_class =
- referrer->GetDexCache()->GetResolvedType(method_type_idx);
+ referring_class->GetDexCache()->GetResolvedType(method_type_idx);
if (method_reference_class == nullptr) {
// Need to do full type resolution...
return nullptr;
diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc
index f4d0bc7..eb9f039 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 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 2e4475f..35a251f 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 ed16854..01bcb7d 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::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 3ed138c..34d8284 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 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 @@
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 76f3692..e03958d 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 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 fa941c0..5999548 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 @@
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 b1572cc..a186f4c 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 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 f13ff8c..bebcd71 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_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 8cbe491..fe6a6e9 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 @@
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 52c9f4e..2ef60c3 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 da9976a..6c76f49 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -189,6 +189,7 @@
enum ImageRoot {
kDexCaches,
kClassRoots,
+ kClassLoader, // App image only.
kImageRootsMax,
};
@@ -206,6 +207,10 @@
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 9c634fa..0e66ae9 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 @@
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 @@
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 @@
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 722b411..bf4cab2 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 3956af4..03ef962 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -557,10 +557,8 @@
}
Instrumentation::InstrumentationLevel Instrumentation::GetCurrentInstrumentationLevel() const {
- if (interpreter_stubs_installed_ && interpret_only_) {
+ if (interpreter_stubs_installed_) {
return InstrumentationLevel::kInstrumentWithInterpreter;
- } else if (interpreter_stubs_installed_) {
- return InstrumentationLevel::kInstrumentWithInterpreterAndJit;
} else if (entry_exit_stubs_installed_) {
return InstrumentationLevel::kInstrumentWithInstrumentationStubs;
} else {
@@ -568,14 +566,6 @@
}
}
-bool Instrumentation::RequiresInstrumentationInstallation(InstrumentationLevel new_level) const {
- // We need to reinstall instrumentation if we go to a different level or if the current level is
- // kInstrumentWithInterpreterAndJit since that level does not force all code to always use the
- // interpreter and so we might have started running optimized code again.
- return new_level == InstrumentationLevel::kInstrumentWithInterpreterAndJit ||
- GetCurrentInstrumentationLevel() != new_level;
-}
-
void Instrumentation::ConfigureStubs(const char* key, InstrumentationLevel desired_level) {
// Store the instrumentation level for this key or remove it.
if (desired_level == InstrumentationLevel::kInstrumentNothing) {
@@ -595,7 +585,8 @@
interpret_only_ = (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) ||
forced_interpret_only_;
- if (!RequiresInstrumentationInstallation(requested_level)) {
+ InstrumentationLevel current_level = GetCurrentInstrumentationLevel();
+ if (requested_level == current_level) {
// We're already set.
return;
}
@@ -604,7 +595,7 @@
Locks::mutator_lock_->AssertExclusiveHeld(self);
Locks::thread_list_lock_->AssertNotHeld(self);
if (requested_level > InstrumentationLevel::kInstrumentNothing) {
- if (requested_level >= InstrumentationLevel::kInstrumentWithInterpreterAndJit) {
+ if (requested_level == InstrumentationLevel::kInstrumentWithInterpreter) {
interpreter_stubs_installed_ = true;
entry_exit_stubs_installed_ = true;
} else {
@@ -851,8 +842,7 @@
void Instrumentation::DisableDeoptimization(const char* key) {
CHECK_EQ(deoptimization_enabled_, true);
// If we deoptimized everything, undo it.
- InstrumentationLevel level = GetCurrentInstrumentationLevel();
- if (level == InstrumentationLevel::kInstrumentWithInterpreter) {
+ if (interpreter_stubs_installed_) {
UndeoptimizeEverything(key);
}
// Undeoptimized selected methods.
@@ -879,14 +869,6 @@
return !deoptimization_enabled_ && !interpreter_stubs_installed_;
}
-// TODO we don't check deoptimization_enabled_ because currently there isn't really any support for
-// multiple users of instrumentation. Since this is just a temporary state anyway pending work to
-// ensure that the current_method doesn't get kept across suspend points this should be okay.
-// TODO Remove once b/33630159 is resolved.
-void Instrumentation::ReJitEverything(const char* key) {
- ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInterpreterAndJit);
-}
-
void Instrumentation::DeoptimizeEverything(const char* key) {
CHECK(deoptimization_enabled_);
ConfigureStubs(key, InstrumentationLevel::kInstrumentWithInterpreter);
@@ -1116,10 +1098,14 @@
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/instrumentation.h b/runtime/instrumentation.h
index 872efac..1e5fcf2 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -133,9 +133,6 @@
enum class InstrumentationLevel {
kInstrumentNothing, // execute without instrumentation
kInstrumentWithInstrumentationStubs, // execute with instrumentation entry/exit stubs
- kInstrumentWithInterpreterAndJit, // execute with interpreter initially and later the JIT
- // (if it is enabled). This level is special in that it
- // always requires re-instrumentation.
kInstrumentWithInterpreter // execute with interpreter
};
@@ -166,13 +163,6 @@
}
bool ShouldNotifyMethodEnterExitEvents() const REQUIRES_SHARED(Locks::mutator_lock_);
- // Executes everything with the interpreter/jit (if available).
- void ReJitEverything(const char* key)
- REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
- REQUIRES(!Locks::thread_list_lock_,
- !Locks::classlinker_classes_lock_,
- !deoptimized_methods_lock_);
-
// Executes everything with interpreter.
void DeoptimizeEverything(const char* key)
REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
@@ -445,10 +435,6 @@
private:
InstrumentationLevel GetCurrentInstrumentationLevel() const;
- // Returns true if moving to the given instrumentation level requires the installation of stubs.
- // False otherwise.
- bool RequiresInstrumentationInstallation(InstrumentationLevel new_level) const;
-
// Does the job of installing or removing instrumentation code within methods.
// In order to support multiple clients using instrumentation at the same time,
// the caller must pass a unique key (a string) identifying it so we remind which
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 22da07d..a09e71b 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -676,7 +676,7 @@
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 02a99e7..423f054 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"
@@ -249,16 +251,17 @@
}
}
ArtMethod* method = shadow_frame.GetMethod();
+ ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass();
// MethodVerifier refuses methods with string_idx out of bounds.
DCHECK_LT(string_idx.index_ % mirror::DexCache::kDexCacheStringCacheSize,
- method->GetDexFile()->NumStringIds());
+ declaring_class->GetDexFile().NumStringIds());
ObjPtr<mirror::String> string_ptr =
- mirror::StringDexCachePair::Lookup(method->GetDexCacheStrings(),
+ mirror::StringDexCachePair::Lookup(declaring_class->GetDexCache()->GetStrings(),
string_idx.index_,
mirror::DexCache::kDexCacheStringCacheSize).Read();
if (UNLIKELY(string_ptr == nullptr)) {
StackHandleScope<1> hs(self);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
string_ptr = Runtime::Current()->GetClassLinker()->ResolveString(*method->GetDexFile(),
string_idx,
dex_cache);
@@ -429,12 +432,12 @@
#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 a5b1038..7dd3d3d 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 caf705a..f80c43d 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 e9d6d07..0eff2ab 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 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 5574a11..172f52a 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 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 0f2d188..964c567 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 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 e3bf3e5..7707ba4 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 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 18f40a1..6af267e 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 @@
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 3be7fd6..97662f0 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 @@
*/
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 d7827ef..f43e30d 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -217,6 +217,7 @@
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 @@
fp_spill_mask,
code,
code_size,
+ data_size,
osr,
roots,
has_should_deoptimize_flag,
@@ -246,6 +248,7 @@
fp_spill_mask,
code,
code_size,
+ data_size,
osr,
roots,
has_should_deoptimize_flag,
@@ -513,6 +516,7 @@
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 @@
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.
//
@@ -636,38 +645,6 @@
return CodeCacheSizeLocked();
}
-// This invalidates old_method. Once this function returns one can no longer use old_method to
-// execute code unless it is fixed up. This fixup will happen later in the process of installing a
-// class redefinition.
-// TODO We should add some info to ArtMethod to note that 'old_method' has been invalidated and
-// shouldn't be used since it is no longer logically in the jit code cache.
-// TODO We should add DCHECKS that validate that the JIT is paused when this method is entered.
-void JitCodeCache::MoveObsoleteMethod(ArtMethod* old_method, ArtMethod* new_method) {
- MutexLock mu(Thread::Current(), lock_);
- // Update ProfilingInfo to the new one.
- if (old_method->GetProfilingInfo(kRuntimePointerSize) != nullptr) {
- DCHECK_EQ(old_method->GetProfilingInfo(kRuntimePointerSize)->GetMethod(), old_method);
- ProfilingInfo* info = old_method->GetProfilingInfo(kRuntimePointerSize);
- // Since the JIT should be paused and all threads suspended by the time this is called these
- // checks should always pass.
- DCHECK(!info->IsInUseByCompiler());
- new_method->SetProfilingInfo(info);
- info->method_ = new_method;
- }
- // Update method_code_map_ to point to the new method.
- for (auto& it : method_code_map_) {
- if (it.second == old_method) {
- it.second = new_method;
- }
- }
- // Update osr_code_map_ to point to the new method.
- auto code_map = osr_code_map_.find(old_method);
- if (code_map != osr_code_map_.end()) {
- osr_code_map_.Put(new_method, code_map->second);
- osr_code_map_.erase(old_method);
- }
-}
-
size_t JitCodeCache::CodeCacheSizeLocked() {
return used_memory_for_code_;
}
@@ -689,12 +666,12 @@
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;
@@ -727,9 +704,11 @@
*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 5bfe661..d97742d 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -106,6 +106,7 @@
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 @@
// 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_);
@@ -217,11 +219,6 @@
void DisallowInlineCacheAccess() REQUIRES(!lock_);
void BroadcastForInlineCacheAccess() REQUIRES(!lock_);
- // Notify the code cache that the method at the pointer 'old_method' is being moved to the pointer
- // 'new_method' since it is being made obsolete.
- void MoveObsoleteMethod(ArtMethod* old_method, ArtMethod* new_method)
- REQUIRES(!lock_) REQUIRES(Locks::mutator_lock_);
-
private:
// Take ownership of maps.
JitCodeCache(MemMap* code_map,
@@ -242,6 +239,7 @@
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/jit/profiling_info.h b/runtime/jit/profiling_info.h
index 9fbf2e3..9902bb5 100644
--- a/runtime/jit/profiling_info.h
+++ b/runtime/jit/profiling_info.h
@@ -128,9 +128,7 @@
const uint32_t number_of_inline_caches_;
// Method this profiling info is for.
- // Not 'const' as JVMTI introduces obsolete methods that we implement by creating new ArtMethods.
- // See JitCodeCache::MoveObsoleteMethod.
- ArtMethod* method_;
+ ArtMethod* const method_;
// Whether the ArtMethod is currently being compiled. This flag
// is implicitly guarded by the JIT code cache lock.
diff --git a/runtime/jni_env_ext.cc b/runtime/jni_env_ext.cc
index 342e0d2..5a3fafa 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 a421c34..4da5e23 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 6da72e4..19a65bb 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 3c22d7f..da510ce 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 7d7c1d7..a5db0c0 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 @@
#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 8afa4aa..cc548b9 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 5fdf8f3..2fb8d28 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -937,14 +937,6 @@
}
}
-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 @@
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 a862c97..9964b73 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::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 d7449c8..fb2792a 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -1247,13 +1247,6 @@
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 @@
// 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/dex_cache.h b/runtime/mirror/dex_cache.h
index 6f88cc5..ec265e5 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -19,6 +19,7 @@
#include "array.h"
#include "art_field.h"
+#include "art_method.h"
#include "class.h"
#include "dex_file_types.h"
#include "object.h"
@@ -26,7 +27,6 @@
namespace art {
-class ArtMethod;
struct DexCacheOffsets;
class DexFile;
class ImageWriter;
diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h
index 0fdf132..3e04bf6 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 <string>
-
#include "object_array.h"
+#include <string>
+
+#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 @@
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 95516ac..9b8445d 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 @@
"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 ade4e87..e50409f 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 e7de7e6..222eb5c 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 1a77072..cd0e55f 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 db245aa..981be68 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 3058df4..1af8619 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -27,6 +27,8 @@
#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 @@
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 a78909b..10fc90b 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_reflect_Executable.cc b/runtime/native/java_lang_reflect_Executable.cc
index 73b81a7..ee59c4a 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 6206948..374eeb5 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 16164d2..0bb9e38 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 5565565..7460d62 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 @@
#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 aab0e81..cebe765 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 bdf8b0e..0bf7136 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 7f7b1b5..ee7cf9d 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 5641459..33bd0f3 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/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc
index 429409a..e70547d 100644
--- a/runtime/openjdkjvmti/ti_redefine.cc
+++ b/runtime/openjdkjvmti/ti_redefine.cc
@@ -33,13 +33,13 @@
#include <limits>
+#include "android-base/stringprintf.h"
+
#include "art_jvmti.h"
#include "base/logging.h"
#include "events-inl.h"
#include "gc/allocation_listener.h"
#include "instrumentation.h"
-#include "jit/jit.h"
-#include "jit/jit_code_cache.h"
#include "jni_env_ext-inl.h"
#include "jvmti_allocator.h"
#include "mirror/class.h"
@@ -51,141 +51,7 @@
namespace openjdkjvmti {
-// This visitor walks thread stacks and allocates and sets up the obsolete methods. It also does
-// some basic sanity checks that the obsolete method is sane.
-class ObsoleteMethodStackVisitor : public art::StackVisitor {
- protected:
- ObsoleteMethodStackVisitor(
- art::Thread* thread,
- art::LinearAlloc* allocator,
- const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
- /*out*/std::unordered_map<art::ArtMethod*, art::ArtMethod*>* obsolete_maps,
- /*out*/bool* success,
- /*out*/std::string* error_msg)
- : StackVisitor(thread,
- /*context*/nullptr,
- StackVisitor::StackWalkKind::kIncludeInlinedFrames),
- allocator_(allocator),
- obsoleted_methods_(obsoleted_methods),
- obsolete_maps_(obsolete_maps),
- success_(success),
- is_runtime_frame_(false),
- error_msg_(error_msg) {}
-
- ~ObsoleteMethodStackVisitor() OVERRIDE {}
-
- public:
- // Returns true if we successfully installed obsolete methods on this thread, filling
- // obsolete_maps_ with the translations if needed. Returns false and fills error_msg_ if we fail.
- // The stack is cleaned up when we fail.
- static bool UpdateObsoleteFrames(
- art::Thread* thread,
- art::LinearAlloc* allocator,
- const std::unordered_set<art::ArtMethod*>& obsoleted_methods,
- /*out*/std::unordered_map<art::ArtMethod*, art::ArtMethod*>* obsolete_maps,
- /*out*/std::string* error_msg) REQUIRES(art::Locks::mutator_lock_) {
- bool success = true;
- ObsoleteMethodStackVisitor visitor(thread,
- allocator,
- obsoleted_methods,
- obsolete_maps,
- &success,
- error_msg);
- visitor.WalkStack();
- if (!success) {
- RestoreFrames(thread, *obsolete_maps);
- return false;
- } else {
- return true;
- }
- }
-
- static void RestoreFrames(
- art::Thread* thread ATTRIBUTE_UNUSED,
- const std::unordered_map<art::ArtMethod*, art::ArtMethod*>& obsolete_maps ATTRIBUTE_UNUSED)
- REQUIRES(art::Locks::mutator_lock_) {
- LOG(FATAL) << "Restoring stack frames is not yet supported.";
- }
-
- bool VisitFrame() OVERRIDE REQUIRES(art::Locks::mutator_lock_) {
- art::ArtMethod* old_method = GetMethod();
- // TODO REMOVE once either current_method doesn't stick around through suspend points or deopt
- // works through runtime methods.
- bool prev_was_runtime_frame_ = is_runtime_frame_;
- is_runtime_frame_ = old_method->IsRuntimeMethod();
- if (obsoleted_methods_.find(old_method) != obsoleted_methods_.end()) {
- // This works since when we deoptimize we set shadow frames for all frames until a
- // native/runtime transition and for those set the return PC to a function that will complete
- // the deoptimization. This does leave us with the unfortunate side-effect that frames just
- // below runtime frames cannot be deoptimized at the moment.
- // TODO REMOVE once either current_method doesn't stick around through suspend points or deopt
- // works through runtime methods.
- // TODO b/33616143
- if (!IsShadowFrame() && prev_was_runtime_frame_) {
- *error_msg_ = art::StringPrintf("Deoptimization failed due to runtime method in stack.");
- *success_ = false;
- return false;
- }
- // We cannot ensure that the right dex file is used in inlined frames so we don't support
- // redefining them.
- DCHECK(!IsInInlinedFrame()) << "Inlined frames are not supported when using redefinition";
- // TODO We should really support intrinsic obsolete methods.
- // TODO We should really support redefining intrinsics.
- // We don't support intrinsics so check for them here.
- DCHECK(!old_method->IsIntrinsic());
- art::ArtMethod* new_obsolete_method = nullptr;
- auto obsolete_method_pair = obsolete_maps_->find(old_method);
- if (obsolete_method_pair == obsolete_maps_->end()) {
- // Create a new Obsolete Method and put it in the list.
- art::Runtime* runtime = art::Runtime::Current();
- art::ClassLinker* cl = runtime->GetClassLinker();
- auto ptr_size = cl->GetImagePointerSize();
- const size_t method_size = art::ArtMethod::Size(ptr_size);
- auto* method_storage = allocator_->Alloc(GetThread(), method_size);
- if (method_storage == nullptr) {
- *success_ = false;
- *error_msg_ = art::StringPrintf("Unable to allocate storage for obsolete version of '%s'",
- old_method->PrettyMethod().c_str());
- return false;
- }
- new_obsolete_method = new (method_storage) art::ArtMethod();
- new_obsolete_method->CopyFrom(old_method, ptr_size);
- new_obsolete_method->SetIsObsolete();
- obsolete_maps_->insert({old_method, new_obsolete_method});
- // Update JIT Data structures to point to the new method.
- art::jit::Jit* jit = art::Runtime::Current()->GetJit();
- if (jit != nullptr && jit->GetCodeCache()->ContainsMethod(old_method)) {
- // Notify the JIT we are making this obsolete method. It will update it's maps and change
- // entrypoint etc over.
- jit->GetCodeCache()->MoveObsoleteMethod(old_method, new_obsolete_method);
- }
- DCHECK_EQ(new_obsolete_method->GetDeclaringClass(), old_method->GetDeclaringClass());
- } else {
- new_obsolete_method = obsolete_method_pair->second;
- }
- DCHECK(new_obsolete_method != nullptr);
- SetMethod(new_obsolete_method);
- }
- *success_ = true;
- return true;
- }
-
- private:
- // The linear allocator we should use to make new methods.
- art::LinearAlloc* allocator_;
- // The set of all methods which could be obsoleted.
- const std::unordered_set<art::ArtMethod*>& obsoleted_methods_;
- // A map from the original to the newly allocated obsolete method for frames on this thread. The
- // values in this map must be added to the obsolete_methods_ (and obsolete_dex_caches_) fields of
- // the redefined classes ClassExt by the caller.
- std::unordered_map<art::ArtMethod*, art::ArtMethod*>* obsolete_maps_;
- bool* success_;
- // TODO REMOVE once either current_method doesn't stick around through suspend points or deopt
- // works through runtime methods.
- bool is_runtime_frame_;
- std::string* error_msg_;
-};
-
+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,
@@ -193,7 +59,7 @@
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,
@@ -210,8 +76,6 @@
return map;
}
-// TODO This should handle doing multiple classes at once so we need to do less cleanup when things
-// go wrong.
jvmtiError Redefiner::RedefineClass(ArtJvmTiEnv* env,
art::Runtime* runtime,
art::Thread* self,
@@ -252,8 +116,6 @@
*error_msg = os.str();
return ERR(INVALID_CLASS_FORMAT);
}
- // Stop JIT for the duration of this redefine.
- art::jit::ScopedJitSuspend suspend_jit;
// Get shared mutator lock.
art::ScopedObjectAccess soa(self);
art::StackHandleScope<1> hs(self);
@@ -388,9 +250,9 @@
}
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;
}
@@ -434,109 +296,6 @@
return true;
}
-struct CallbackCtx {
- Redefiner* const r;
- art::LinearAlloc* allocator;
- std::unordered_map<art::ArtMethod*, art::ArtMethod*> obsolete_map;
- std::unordered_set<art::ArtMethod*> obsolete_methods;
- bool success;
- std::string* error_msg;
-
- CallbackCtx(Redefiner* self, art::LinearAlloc* alloc, std::string* error)
- : r(self), allocator(alloc), success(true), error_msg(error) {}
-};
-
-void DoRestoreObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS {
- CallbackCtx* data = reinterpret_cast<CallbackCtx*>(vdata);
- ObsoleteMethodStackVisitor::RestoreFrames(t, data->obsolete_map);
-}
-
-void DoAllocateObsoleteMethodsCallback(art::Thread* t, void* vdata) NO_THREAD_SAFETY_ANALYSIS {
- CallbackCtx* data = reinterpret_cast<CallbackCtx*>(vdata);
- if (data->success) {
- // Don't do anything if we already failed once.
- data->success = ObsoleteMethodStackVisitor::UpdateObsoleteFrames(t,
- data->allocator,
- data->obsolete_methods,
- &data->obsolete_map,
- data->error_msg);
- }
-}
-
-void Redefiner::AddAllDeclaredMethods(
- art::mirror::Class* art_klass,
- art::PointerSize ptr_size,
- /*out*/std::unordered_set<art::ArtMethod*>* declared_methods) {
- for (auto& m : art_klass->GetDeclaredMethods(ptr_size)) {
- declared_methods->insert(&m);
- }
-}
-
-bool Redefiner::AllocateObsoleteMethods(art::mirror::Class* art_klass) {
- art::ScopedAssertNoThreadSuspension ns("No thread suspension during thread stack walking");
- art::mirror::ClassExt* ext = art_klass->GetExtData();
- CHECK(ext->GetObsoleteMethods() != nullptr);
- CallbackCtx ctx(this, art_klass->GetClassLoader()->GetAllocator(), error_msg_);
- AddAllDeclaredMethods(art_klass, art::kRuntimePointerSize, &ctx.obsolete_methods);
- for (art::ArtMethod* old_method : ctx.obsolete_methods) {
- if (old_method->IsIntrinsic()) {
- *error_msg_ = art::StringPrintf("Method '%s' is intrinsic and cannot be made obsolete!",
- old_method->PrettyMethod().c_str());
- return false;
- }
- }
- {
- art::MutexLock mu(self_, *art::Locks::thread_list_lock_);
- art::ThreadList* list = art::Runtime::Current()->GetThreadList();
- list->ForEach(DoAllocateObsoleteMethodsCallback, static_cast<void*>(&ctx));
- if (!ctx.success) {
- list->ForEach(DoRestoreObsoleteMethodsCallback, static_cast<void*>(&ctx));
- return false;
- }
- }
- FillObsoleteMethodMap(art_klass, ctx.obsolete_map);
- return true;
-}
-
-void Redefiner::FillObsoleteMethodMap(
- art::mirror::Class* art_klass,
- const std::unordered_map<art::ArtMethod*, art::ArtMethod*>& obsoletes) {
- int32_t index = 0;
- art::mirror::ClassExt* ext_data = art_klass->GetExtData();
- art::mirror::PointerArray* obsolete_methods = ext_data->GetObsoleteMethods();
- art::mirror::ObjectArray<art::mirror::DexCache>* obsolete_dex_caches =
- ext_data->GetObsoleteDexCaches();
- int32_t num_method_slots = obsolete_methods->GetLength();
- // Find the first empty index.
- for (; index < num_method_slots; index++) {
- if (obsolete_methods->GetElementPtrSize<art::ArtMethod*>(
- index, art::kRuntimePointerSize) == nullptr) {
- break;
- }
- }
- // Make sure we have enough space.
- CHECK_GT(num_method_slots, static_cast<int32_t>(obsoletes.size() + index));
- CHECK(obsolete_dex_caches->Get(index) == nullptr);
- // Fill in the map.
- for (auto& obs : obsoletes) {
- obsolete_methods->SetElementPtrSize(index, obs.second, art::kRuntimePointerSize);
- obsolete_dex_caches->Set(index, art_klass->GetDexCache());
- index++;
- }
-}
-
-// TODO It should be possible to only deoptimize the specific obsolete methods.
-// TODO ReJitEverything can (sort of) fail. In certain cases it will skip deoptimizing some frames.
-// If one of these frames is an obsolete method we have a problem. b/33616143
-// TODO This shouldn't be necessary once we can ensure that the current method is not kept in
-// registers across suspend points.
-// TODO Pending b/33630159
-void Redefiner::EnsureObsoleteMethodsAreDeoptimized() {
- art::ScopedAssertNoThreadSuspension nts("Deoptimizing everything!");
- art::instrumentation::Instrumentation* i = runtime_->GetInstrumentation();
- i->ReJitEverything("libOpenJkdJvmti - Class Redefinition");
-}
-
jvmtiError Redefiner::Run() {
art::StackHandleScope<5> hs(self_);
// TODO We might want to have a global lock (or one based on the class being redefined at least)
@@ -586,8 +345,7 @@
art::ObjPtr<art::mirror::LongArray> original_dex_file_cookie(nullptr);
if (!UpdateJavaDexFile(java_dex_file.Get(),
new_dex_file_cookie.Get(),
- &original_dex_file_cookie) ||
- !AllocateObsoleteMethods(art_class.Get())) {
+ &original_dex_file_cookie)) {
// Release suspendAll
runtime_->GetThreadList()->ResumeAll();
// Get back shared mutator lock as expected for return.
@@ -603,20 +361,18 @@
self_->TransitionFromSuspendedToRunnable();
return result_;
}
- // Ensure that obsolete methods are deoptimized. This is needed since optimized methods may have
- // pointers to their ArtMethod's stashed in registers that they then use to attempt to hit the
- // DexCache.
- // TODO This can fail (leave some methods optimized) near runtime methods (including
- // quick-to-interpreter transition function).
- // TODO Mingyao@ suggested we could maybe just do a retry loop instead of fixing the above.
- // TODO We probably don't need this at all once we have a way to ensure that the
- // current_art_method is never stashed in a (physical) register by the JIT and lost to the
- // stack-walker.
- EnsureObsoleteMethodsAreDeoptimized();
- // TODO Verify the new Class.
- // TODO Failure then undo updates to class
- // TODO Shrink the obsolete method maps if possible?
- // TODO find appropriate class loader.
+ // Update the ClassObjects Keep the old DexCache (and other stuff) around so we can restore
+ // functions/fields.
+ // Verify the new Class.
+ // Failure then undo updates to class
+ // Do stack walks and allocate obsolete methods
+ // Shrink the obsolete method maps if possible?
+ // TODO find appropriate class loader. Allocate new dex files array. Pause all java treads.
+ // Replace dex files array. Do stack scan + allocate obsoletes. Remove array if possible.
+ // TODO We might want to ensure that all threads are stopped for this!
+ // AddDexToClassPath();
+ // TODO
+ // Release suspendAll
// TODO Put this into a scoped thing.
runtime_->GetThreadList()->ResumeAll();
// Get back shared mutator lock as expected for return.
@@ -669,29 +425,24 @@
}
const art::DexFile::ProtoId* proto_id = dex_file_->FindProtoId(method_return_idx,
new_type_list);
- // TODO Return false, cleanup.
CHECK(proto_id != nullptr || old_type_list == nullptr);
+ // TODO Return false, cleanup.
const art::DexFile::MethodId* method_id = dex_file_->FindMethodId(declaring_class_id,
*new_name_id,
*proto_id);
- // TODO Return false, cleanup.
CHECK(method_id != nullptr);
+ // TODO Return false, cleanup.
uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
method.SetDexMethodIndex(dex_method_idx);
linker->SetEntryPointsToInterpreter(&method);
method.SetCodeItemOffset(dex_file_->FindCodeItemOffset(*class_def, dex_method_idx));
method.SetDexCacheResolvedMethods(new_dex_cache->GetResolvedMethods(), image_pointer_size);
method.SetDexCacheResolvedTypes(new_dex_cache->GetResolvedTypes(), image_pointer_size);
- if (!method.IsNative()) {
- // Reset profiling info.
- method.SetProfilingInfo(nullptr);
- }
}
// Update the class fields.
// 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/openjdkjvmti/ti_redefine.h b/runtime/openjdkjvmti/ti_redefine.h
index 2e3df0c..c819acd 100644
--- a/runtime/openjdkjvmti/ti_redefine.h
+++ b/runtime/openjdkjvmti/ti_redefine.h
@@ -64,8 +64,6 @@
namespace openjdkjvmti {
// Class that can redefine a single class's methods.
-// TODO We should really make this be driven by an outside class so we can do multiple classes at
-// the same time and have less required cleanup.
class Redefiner {
public:
// Redefine the given class with the given dex data. Note this function does not take ownership of
@@ -126,15 +124,6 @@
// in the future. For now we will just take the memory hit.
bool EnsureClassAllocationsFinished() REQUIRES_SHARED(art::Locks::mutator_lock_);
- // Ensure that obsolete methods are deoptimized. This is needed since optimized methods may have
- // pointers to their ArtMethods stashed in registers that they then use to attempt to hit the
- // DexCache.
- // TODO Make this fallible
- void EnsureObsoleteMethodsAreDeoptimized()
- REQUIRES(art::Locks::mutator_lock_)
- REQUIRES(!art::Locks::thread_list_lock_,
- !art::Locks::classlinker_classes_lock_);
-
art::mirror::ClassLoader* GetClassLoader() REQUIRES_SHARED(art::Locks::mutator_lock_);
// This finds the java.lang.DexFile we will add the native DexFile to as part of the classpath.
@@ -173,17 +162,6 @@
bool UpdateClass(art::ObjPtr<art::mirror::Class> mclass,
art::ObjPtr<art::mirror::DexCache> new_dex_cache)
REQUIRES(art::Locks::mutator_lock_);
-
- bool AllocateObsoleteMethods(art::mirror::Class* art_klass) REQUIRES(art::Locks::mutator_lock_);
-
- void AddAllDeclaredMethods(art::mirror::Class* art_klass,
- art::PointerSize ptr_size,
- /*out*/std::unordered_set<art::ArtMethod*>* declared_methods)
- REQUIRES_SHARED(art::Locks::mutator_lock_);
-
- void FillObsoleteMethodMap(art::mirror::Class* art_klass,
- const std::unordered_map<art::ArtMethod*, art::ArtMethod*>& obsoletes)
- REQUIRES(art::Locks::mutator_lock_);
};
} // namespace openjdkjvmti
diff --git a/runtime/parsed_options_test.cc b/runtime/parsed_options_test.cc
index 5b90c6a..8948c71 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 481b1ca..731967c 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 1c975a4..d8b9dcc 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 d80a9b3..9523e92 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 68e7a10..62ce9e9 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 @@
}
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 8446b52..4d24501 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 59c5961..0977093 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1721,7 +1721,7 @@
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 be97860..0a996a9 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 93704a9..b8894d2 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 726ca2f..3fed7c9 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 {
@@ -614,23 +618,6 @@
return result;
}
-static instrumentation::InstrumentationStackFrame& GetInstrumentationStackFrame(Thread* thread,
- uint32_t depth) {
- CHECK_LT(depth, thread->GetInstrumentationStack()->size());
- return thread->GetInstrumentationStack()->at(depth);
-}
-
-void StackVisitor::SetMethod(ArtMethod* method) {
- DCHECK(GetMethod() != nullptr);
- if (cur_shadow_frame_ != nullptr) {
- cur_shadow_frame_->SetMethod(method);
- } else {
- DCHECK(cur_quick_frame_ != nullptr);
- CHECK(!IsInInlinedFrame()) << "We do not support setting inlined method's ArtMethod!";
- *cur_quick_frame_ = method;
- }
-}
-
static void AssertPcIsWithinQuickCode(ArtMethod* method, uintptr_t pc)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (method->IsNative() || method->IsRuntimeMethod() || method->IsProxyMethod()) {
@@ -792,8 +779,8 @@
void StackVisitor::WalkStack(bool include_transitions) {
DCHECK(thread_ == Thread::Current() || thread_->IsSuspended());
CHECK_EQ(cur_depth_, 0U);
- size_t instrumentation_stack_depth = 0;
bool exit_stubs_installed = Runtime::Current()->GetInstrumentation()->AreExitStubsInstalled();
+ uint32_t instrumentation_stack_depth = 0;
size_t inlined_frames_count = 0;
for (const ManagedStack* current_fragment = thread_->GetManagedStack();
@@ -856,7 +843,7 @@
if (reinterpret_cast<uintptr_t>(GetQuickInstrumentationExitPc()) == return_pc) {
CHECK_LT(instrumentation_stack_depth, thread_->GetInstrumentationStack()->size());
const instrumentation::InstrumentationStackFrame& instrumentation_frame =
- GetInstrumentationStackFrame(thread_, instrumentation_stack_depth);
+ thread_->GetInstrumentationStack()->at(instrumentation_stack_depth);
instrumentation_stack_depth++;
if (GetMethod() ==
Runtime::Current()->GetCalleeSaveMethod(Runtime::kSaveAllCalleeSaves)) {
diff --git a/runtime/stack.h b/runtime/stack.h
index 9dceb29..b1e99e5 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -327,12 +327,6 @@
}
}
- void SetMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_) {
- DCHECK(method != nullptr);
- DCHECK(method_ != nullptr);
- method_ = method;
- }
-
ArtMethod* GetMethod() const REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(method_ != nullptr);
return method_;
@@ -616,10 +610,6 @@
ArtMethod* GetMethod() const REQUIRES_SHARED(Locks::mutator_lock_);
- // Sets this stack frame's method pointer. This requires a full lock of the MutatorLock. This
- // doesn't work with inlined methods.
- void SetMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_);
-
ArtMethod* GetOuterMethod() const {
return *GetCurrentQuickFrame();
}
diff --git a/runtime/thread.cc b/runtime/thread.cc
index d79bf36..9c93a5f 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 664eeb4..bf9eef8 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 d9d2ea3..6abdca1 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 d21ff77..0bba44c 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 6561756..7408aee 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 f564de4..9d9360e 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 4732f59..8867743 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 04e0dde..16ef706 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -284,6 +284,12 @@
__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 ebecc85..7e23c8b 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 ab23773..52f7e34 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 a6088aa..383d890 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 3549586..009170c 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 @@
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 d96fb42..cd79bb6 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 113b35f..3b237f4 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 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 7d3d7d9..91af1f4 100644
--- a/test/530-checker-loops4/src/Main.java
+++ b/test/530-checker-loops4/src/Main.java
@@ -96,7 +96,29 @@
/// 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 @@
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 @@
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 87a69b2..ecc129a 100644
--- a/test/618-checker-induction/src/Main.java
+++ b/test/618-checker-induction/src/Main.java
@@ -248,6 +248,33 @@
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 @@
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 d965e3f..75b782e 100644
--- a/test/624-checker-stringops/src/Main.java
+++ b/test/624-checker-stringops/src/Main.java
@@ -258,6 +258,20 @@
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 @@
expectEquals(0, bufferDeadLoop());
expectEquals(0, builderDeadLoop());
+ doesNothing();
+
System.out.println("passed");
}
diff --git a/test/911-get-stack-trace/stack_trace.cc b/test/911-get-stack-trace/stack_trace.cc
index 9092f2f..57f6a92 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,8 @@
namespace art {
namespace Test911GetStackTrace {
+using android::base::StringPrintf;
+
static jint FindLineNumber(jint line_number_count,
jvmtiLineNumberEntry* line_number_table,
jlocation location) {
diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt
index e5fa53f..7522a65 100644
--- a/test/913-heaps/expected.txt
+++ b/test/913-heaps/expected.txt
@@ -5,12 +5,12 @@
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 @@
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 --(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 @@
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 7b00fcd..49ab7dd 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 @@
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/914-hello-obsolescence/build b/test/914-hello-obsolescence/build
deleted file mode 100755
index 898e2e5..0000000
--- a/test/914-hello-obsolescence/build
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-./default-build "$@" --experimental agents
diff --git a/test/914-hello-obsolescence/expected.txt b/test/914-hello-obsolescence/expected.txt
deleted file mode 100644
index 83efda1..0000000
--- a/test/914-hello-obsolescence/expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-hello
-Not doing anything here
-goodbye
-hello
-transforming calling function
-goodbye
-Hello - Transformed
-Not doing anything here
-Goodbye - Transformed
diff --git a/test/914-hello-obsolescence/info.txt b/test/914-hello-obsolescence/info.txt
deleted file mode 100644
index c8b892c..0000000
--- a/test/914-hello-obsolescence/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests basic obsolete method support
diff --git a/test/914-hello-obsolescence/run b/test/914-hello-obsolescence/run
deleted file mode 100755
index b2f0b04..0000000
--- a/test/914-hello-obsolescence/run
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-plugin=libopenjdkjvmtid.so
-agent=libtiagentd.so
-lib=tiagentd
-if [[ "$@" == *"-O"* ]]; then
- agent=libtiagent.so
- plugin=libopenjdkjvmti.so
- lib=tiagent
-fi
-
-if [[ "$@" == *"--jvm"* ]]; then
- arg="jvm"
-else
- arg="art"
- if [[ "$@" != *"--debuggable"* ]]; then
- other_args=" -Xcompiler-option --debuggable "
- else
- other_args=""
- fi
-fi
-
-
-./default-run "$@" --experimental agents \
- --experimental runtime-plugins \
- --runtime-option -agentpath:${agent}=914-hello-obsolescence,${arg} \
- --android-runtime-option -Xplugin:${plugin} \
- --android-runtime-option -Xfully-deoptable \
- ${other_args} \
- --args ${lib}
diff --git a/test/914-hello-obsolescence/src/Main.java b/test/914-hello-obsolescence/src/Main.java
deleted file mode 100644
index 46266ef..0000000
--- a/test/914-hello-obsolescence/src/Main.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.
- */
-
-import java.util.Base64;
-
-public class Main {
- // class Transform {
- // public void sayHi(Runnable r) {
- // System.out.println("Hello - Transformed");
- // r.run();
- // System.out.println("Goodbye - Transformed");
- // }
- // }
- private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
- "yv66vgAAADQAJAoACAARCQASABMIABQKABUAFgsAFwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW" +
- "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7" +
- "KVYBAApTb3VyY2VGaWxlAQAOVHJhbnNmb3JtLmphdmEMAAkACgcAHAwAHQAeAQATSGVsbG8gLSBU" +
- "cmFuc2Zvcm1lZAcAHwwAIAAhBwAiDAAjAAoBABVHb29kYnllIC0gVHJhbnNmb3JtZWQBAAlUcmFu" +
- "c2Zvcm0BABBqYXZhL2xhbmcvT2JqZWN0AQAQamF2YS9sYW5nL1N5c3RlbQEAA291dAEAFUxqYXZh" +
- "L2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmludGxuAQAVKExqYXZh" +
- "L2xhbmcvU3RyaW5nOylWAQASamF2YS9sYW5nL1J1bm5hYmxlAQADcnVuACAABwAIAAAAAAACAAAA" +
- "CQAKAAEACwAAAB0AAQABAAAABSq3AAGxAAAAAQAMAAAABgABAAAAAQABAA0ADgABAAsAAAA7AAIA" +
- "AgAAABeyAAISA7YABCu5AAUBALIAAhIGtgAEsQAAAAEADAAAABIABAAAAAMACAAEAA4ABQAWAAYA" +
- "AQAPAAAAAgAQ");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQAYeAMMXgYWxoeSHAS9EWKCCtVRSAGpqZVQAwAAcAAAAHhWNBIAAAAAAAAAALACAAAR" +
- "AAAAcAAAAAcAAAC0AAAAAwAAANAAAAABAAAA9AAAAAUAAAD8AAAAAQAAACQBAAAMAgAARAEAAKIB" +
- "AACqAQAAwQEAANYBAADjAQAA+gEAAA4CAAAkAgAAOAIAAEwCAABcAgAAXwIAAGMCAAB3AgAAfAIA" +
- "AIUCAACKAgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA" +
- "lAEAAAsAAAAGAAAAnAEAAAUAAQANAAAAAAAAAAAAAAAAAAEAEAAAAAEAAgAOAAAAAgAAAAAAAAAD" +
- "AAAADwAAAAAAAAAAAAAAAgAAAAAAAAAJAAAAAAAAAJ8CAAAAAAAAAQABAAEAAACRAgAABAAAAHAQ" +
- "AwAAAA4ABAACAAIAAACWAgAAFAAAAGIAAAAbAQIAAABuIAIAEAByEAQAAwBiAAAAGwEBAAAAbiAC" +
- "ABAADgABAAAAAwAAAAEAAAAEAAY8aW5pdD4AFUdvb2RieWUgLSBUcmFuc2Zvcm1lZAATSGVsbG8g" +
- "LSBUcmFuc2Zvcm1lZAALTFRyYW5zZm9ybTsAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwASTGphdmEv" +
- "bGFuZy9PYmplY3Q7ABRMamF2YS9sYW5nL1J1bm5hYmxlOwASTGphdmEvbGFuZy9TdHJpbmc7ABJM" +
- "amF2YS9sYW5nL1N5c3RlbTsADlRyYW5zZm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00" +
- "LjEzAANvdXQAB3ByaW50bG4AA3J1bgAFc2F5SGkAAQAHDgADAQAHDoc8hwAAAAEBAICABMQCAQHc" +
- "AgAAAA0AAAAAAAAAAQAAAAAAAAABAAAAEQAAAHAAAAACAAAABwAAALQAAAADAAAAAwAAANAAAAAE" +
- "AAAAAQAAAPQAAAAFAAAABQAAAPwAAAAGAAAAAQAAACQBAAABIAAAAgAAAEQBAAABEAAAAgAAAJQB" +
- "AAACIAAAEQAAAKIBAAADIAAAAgAAAJECAAAAIAAAAQAAAJ8CAAAAEAAAAQAAALACAAA=");
-
- public static void main(String[] args) {
- System.loadLibrary(args[1]);
- doTest(new Transform());
- }
-
- public static void doTest(Transform t) {
- t.sayHi(() -> { System.out.println("Not doing anything here"); });
- t.sayHi(() -> {
- System.out.println("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- });
- t.sayHi(() -> { System.out.println("Not doing anything here"); });
- }
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
-}
diff --git a/test/914-hello-obsolescence/src/Transform.java b/test/914-hello-obsolescence/src/Transform.java
deleted file mode 100644
index 8cda6cd..0000000
--- a/test/914-hello-obsolescence/src/Transform.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.
- */
-
-class Transform {
- public void sayHi(Runnable r) {
- // Use lower 'h' to make sure the string will have a different string id
- // than the transformation (the transformation code is the same except
- // the actual printed String, which was making the test inacurately passing
- // in JIT mode when loading the string from the dex cache, as the string ids
- // of the two different strings were the same).
- // We know the string ids will be different because lexicographically:
- // "Hello" < "LTransform;" < "hello".
- System.out.println("hello");
- r.run();
- System.out.println("goodbye");
- }
-}
diff --git a/test/915-obsolete-2/build b/test/915-obsolete-2/build
deleted file mode 100755
index 898e2e5..0000000
--- a/test/915-obsolete-2/build
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-./default-build "$@" --experimental agents
diff --git a/test/915-obsolete-2/expected.txt b/test/915-obsolete-2/expected.txt
deleted file mode 100644
index 04aff3a..0000000
--- a/test/915-obsolete-2/expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Pre Start private method call
-hello - private
-Post Start private method call
-Not doing anything here
-Pre Finish private method call
-goodbye - private
-Post Finish private method call
-Pre Start private method call
-hello - private
-Post Start private method call
-transforming calling function
-Pre Finish private method call
-Goodbye - private - Transformed
-Post Finish private method call
-Pre Start private method call - Transformed
-Hello - private - Transformed
-Post Start private method call - Transformed
-Not doing anything here
-Pre Finish private method call - Transformed
-Goodbye - private - Transformed
-Post Finish private method call - Transformed
diff --git a/test/915-obsolete-2/info.txt b/test/915-obsolete-2/info.txt
deleted file mode 100644
index c8b892c..0000000
--- a/test/915-obsolete-2/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests basic obsolete method support
diff --git a/test/915-obsolete-2/run b/test/915-obsolete-2/run
deleted file mode 100755
index bfe227f..0000000
--- a/test/915-obsolete-2/run
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-plugin=libopenjdkjvmtid.so
-agent=libtiagentd.so
-lib=tiagentd
-if [[ "$@" == *"-O"* ]]; then
- agent=libtiagent.so
- plugin=libopenjdkjvmti.so
- lib=tiagent
-fi
-
-if [[ "$@" == *"--jvm"* ]]; then
- arg="jvm"
-else
- arg="art"
- if [[ "$@" != *"--debuggable"* ]]; then
- other_args=" -Xcompiler-option --debuggable "
- else
- other_args=""
- fi
-fi
-
-
-./default-run "$@" --experimental agents \
- --experimental runtime-plugins \
- --runtime-option -agentpath:${agent}=915-obsolete-2,${arg} \
- --android-runtime-option -Xplugin:${plugin} \
- --android-runtime-option -Xfully-deoptable \
- ${other_args} \
- --args ${lib}
diff --git a/test/915-obsolete-2/src/Main.java b/test/915-obsolete-2/src/Main.java
deleted file mode 100644
index bbeb726..0000000
--- a/test/915-obsolete-2/src/Main.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.
- */
-
-import java.util.Base64;
-
-public class Main {
- // class Transform {
- // private void Start() {
- // System.out.println("Hello - private - Transformed");
- // }
- //
- // private void Finish() {
- // System.out.println("Goodbye - private - Transformed");
- // }
- //
- // public void sayHi(Runnable r) {
- // System.out.println("Pre Start private method call - Transformed");
- // Start();
- // System.out.println("Post Start private method call - Transformed");
- // r.run();
- // System.out.println("Pre Finish private method call - Transformed");
- // Finish();
- // System.out.println("Post Finish private method call - Transformed");
- // }
- // }
- private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
- "yv66vgAAADQAMgoADgAZCQAaABsIABwKAB0AHggAHwgAIAoADQAhCAAiCwAjACQIACUKAA0AJggA" +
- "JwcAKAcAKQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVTdGFydAEA" +
- "BkZpbmlzaAEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7KVYBAApTb3VyY2VGaWxlAQAO" +
- "VHJhbnNmb3JtLmphdmEMAA8AEAcAKgwAKwAsAQAdSGVsbG8gLSBwcml2YXRlIC0gVHJhbnNmb3Jt" +
- "ZWQHAC0MAC4ALwEAH0dvb2RieWUgLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQBACtQcmUgU3RhcnQg" +
- "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAATABABACxQb3N0IFN0YXJ0IHByaXZh" +
- "dGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAcAMAwAMQAQAQAsUHJlIEZpbmlzaCBwcml2YXRl" +
- "IG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQMABQAEAEALVBvc3QgRmluaXNoIHByaXZhdGUgbWV0" +
- "aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAEACVRyYW5zZm9ybQEAEGphdmEvbGFuZy9PYmplY3QBABBq" +
- "YXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9Q" +
- "cmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABJqYXZhL2xhbmcv" +
- "UnVubmFibGUBAANydW4AIAANAA4AAAAAAAQAAAAPABAAAQARAAAAHQABAAEAAAAFKrcAAbEAAAAB" +
- "ABIAAAAGAAEAAAABAAIAEwAQAAEAEQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEAEgAAAAoAAgAA" +
- "AAMACAAEAAIAFAAQAAEAEQAAACUAAgABAAAACbIAAhIFtgAEsQAAAAEAEgAAAAoAAgAAAAcACAAI" +
- "AAEAFQAWAAEAEQAAAGMAAgACAAAAL7IAAhIGtgAEKrcAB7IAAhIItgAEK7kACQEAsgACEgq2AAQq" +
- "twALsgACEgy2AASxAAAAAQASAAAAIgAIAAAACwAIAAwADAANABQADgAaAA8AIgAQACYAEQAuABIA" +
- "AQAXAAAAAgAY");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQCM0QYTJmX+NsZXkImojgSkJtXyuew3oaXcBAAAcAAAAHhWNBIAAAAAAAAAADwEAAAX" +
- "AAAAcAAAAAcAAADMAAAAAwAAAOgAAAABAAAADAEAAAcAAAAUAQAAAQAAAEwBAABwAwAAbAEAAD4C" +
- "AABGAgAATgIAAG8CAACOAgAAmwIAALICAADGAgAA3AIAAPACAAAEAwAAMwMAAGEDAACPAwAAvAMA" +
- "AMMDAADTAwAA1gMAANoDAADuAwAA8wMAAPwDAAABBAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAA" +
- "EAAAABAAAAAGAAAAAAAAABEAAAAGAAAAMAIAABEAAAAGAAAAOAIAAAUAAQATAAAAAAAAAAAAAAAA" +
- "AAAAAQAAAAAAAAAOAAAAAAABABYAAAABAAIAFAAAAAIAAAAAAAAAAwAAABUAAAAAAAAAAAAAAAIA" +
- "AAAAAAAADwAAAAAAAAAmBAAAAAAAAAEAAQABAAAACAQAAAQAAABwEAUAAAAOAAMAAQACAAAADQQA" +
- "AAkAAABiAAAAGwECAAAAbiAEABAADgAAAAMAAQACAAAAEwQAAAkAAABiAAAAGwEDAAAAbiAEABAA" +
- "DgAAAAQAAgACAAAAGQQAACoAAABiAAAAGwENAAAAbiAEABAAcBACAAIAYgAAABsBCwAAAG4gBAAQ" +
- "AHIQBgADAGIAAAAbAQwAAABuIAQAEABwEAEAAgBiAAAAGwEKAAAAbiAEABAADgABAAAAAwAAAAEA" +
- "AAAEAAY8aW5pdD4ABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAAdSGVs" +
- "bG8gLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAC0xUcmFuc2Zvcm07ABVMamF2YS9pby9QcmludFN0" +
- "cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEvbGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xh" +
- "bmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AC1Qb3N0IEZpbmlzaCBwcml2YXRlIG1ldGhv" +
- "ZCBjYWxsIC0gVHJhbnNmb3JtZWQALFBvc3QgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRy" +
- "YW5zZm9ybWVkACxQcmUgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAr" +
- "UHJlIFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAFU3RhcnQADlRyYW5z" +
- "Zm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00LjEzAANvdXQAB3ByaW50bG4AA3J1bgAF" +
- "c2F5SGkAAQAHDgAHAAcOhwADAAcOhwALAQAHDoc8hzyHPIcAAAADAQCAgATsAgEChAMBAqgDAwHM" +
- "Aw0AAAAAAAAAAQAAAAAAAAABAAAAFwAAAHAAAAACAAAABwAAAMwAAAADAAAAAwAAAOgAAAAEAAAA" +
- "AQAAAAwBAAAFAAAABwAAABQBAAAGAAAAAQAAAEwBAAABIAAABAAAAGwBAAABEAAAAgAAADACAAAC" +
- "IAAAFwAAAD4CAAADIAAABAAAAAgEAAAAIAAAAQAAACYEAAAAEAAAAQAAADwEAAA=");
-
- public static void main(String[] args) {
- System.loadLibrary(args[1]);
- doTest(new Transform());
- }
-
- public static void doTest(Transform t) {
- t.sayHi(() -> { System.out.println("Not doing anything here"); });
- t.sayHi(() -> {
- System.out.println("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- });
- t.sayHi(() -> { System.out.println("Not doing anything here"); });
- }
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
-}
diff --git a/test/915-obsolete-2/src/Transform.java b/test/915-obsolete-2/src/Transform.java
deleted file mode 100644
index e914e29..0000000
--- a/test/915-obsolete-2/src/Transform.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-class Transform {
- private void Start() {
- System.out.println("hello - private");
- }
-
- private void Finish() {
- System.out.println("goodbye - private");
- }
-
- public void sayHi(Runnable r) {
- System.out.println("Pre Start private method call");
- Start();
- System.out.println("Post Start private method call");
- r.run();
- System.out.println("Pre Finish private method call");
- Finish();
- System.out.println("Post Finish private method call");
- }
-}
diff --git a/test/916-obsolete-jit/build b/test/916-obsolete-jit/build
deleted file mode 100755
index 898e2e5..0000000
--- a/test/916-obsolete-jit/build
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-./default-build "$@" --experimental agents
diff --git a/test/916-obsolete-jit/expected.txt b/test/916-obsolete-jit/expected.txt
deleted file mode 100644
index 04aff3a..0000000
--- a/test/916-obsolete-jit/expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Pre Start private method call
-hello - private
-Post Start private method call
-Not doing anything here
-Pre Finish private method call
-goodbye - private
-Post Finish private method call
-Pre Start private method call
-hello - private
-Post Start private method call
-transforming calling function
-Pre Finish private method call
-Goodbye - private - Transformed
-Post Finish private method call
-Pre Start private method call - Transformed
-Hello - private - Transformed
-Post Start private method call - Transformed
-Not doing anything here
-Pre Finish private method call - Transformed
-Goodbye - private - Transformed
-Post Finish private method call - Transformed
diff --git a/test/916-obsolete-jit/info.txt b/test/916-obsolete-jit/info.txt
deleted file mode 100644
index c8b892c..0000000
--- a/test/916-obsolete-jit/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Tests basic obsolete method support
diff --git a/test/916-obsolete-jit/run b/test/916-obsolete-jit/run
deleted file mode 100755
index 25c2c07..0000000
--- a/test/916-obsolete-jit/run
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-plugin=libopenjdkjvmtid.so
-agent=libtiagentd.so
-lib=tiagentd
-if [[ "$@" == *"-O"* ]]; then
- agent=libtiagent.so
- plugin=libopenjdkjvmti.so
- lib=tiagent
-fi
-
-if [[ "$@" == *"--jit"* ]]; then
- other_args=""
-else
- other_args="--jit"
-fi
-if [[ "$@" == *"--jvm"* ]]; then
- arg="jvm"
-else
- arg="art"
- if [[ "$@" != *"--debuggable"* ]]; then
- other_args="$other_args -Xcompiler-option --debuggable "
- fi
-fi
-
-
-./default-run "$@" --experimental agents \
- --experimental runtime-plugins \
- --runtime-option -agentpath:${agent}=915-obsolete-2,${arg} \
- --android-runtime-option -Xplugin:${plugin} \
- --android-runtime-option -Xfully-deoptable \
- ${other_args} \
- --args ${lib}
diff --git a/test/916-obsolete-jit/src/Main.java b/test/916-obsolete-jit/src/Main.java
deleted file mode 100644
index d4fa667..0000000
--- a/test/916-obsolete-jit/src/Main.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.
- */
-
-import java.util.Base64;
-
-public class Main {
- private static boolean do_print = false;
-
- public static boolean doPrint() {
- return do_print;
- }
-
- // Since the transformed code isn't really an issue this is the same as test 915.
- // class Transform {
- // private void Start() {
- // System.out.println("Hello - private - Transformed");
- // }
- //
- // private void Finish() {
- // System.out.println("Goodbye - private - Transformed");
- // }
- //
- // public void sayHi(Runnable r) {
- // System.out.println("Pre Start private method call - Transformed");
- // Start();
- // System.out.println("Post Start private method call - Transformed");
- // r.run();
- // System.out.println("Pre Finish private method call - Transformed");
- // Finish();
- // System.out.println("Post Finish private method call - Transformed");
- // }
- // }
- private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
- "yv66vgAAADQAMgoADgAZCQAaABsIABwKAB0AHggAHwgAIAoADQAhCAAiCwAjACQIACUKAA0AJggA" +
- "JwcAKAcAKQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVTdGFydAEA" +
- "BkZpbmlzaAEABXNheUhpAQAXKExqYXZhL2xhbmcvUnVubmFibGU7KVYBAApTb3VyY2VGaWxlAQAO" +
- "VHJhbnNmb3JtLmphdmEMAA8AEAcAKgwAKwAsAQAdSGVsbG8gLSBwcml2YXRlIC0gVHJhbnNmb3Jt" +
- "ZWQHAC0MAC4ALwEAH0dvb2RieWUgLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQBACtQcmUgU3RhcnQg" +
- "cHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRyYW5zZm9ybWVkDAATABABACxQb3N0IFN0YXJ0IHByaXZh" +
- "dGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAcAMAwAMQAQAQAsUHJlIEZpbmlzaCBwcml2YXRl" +
- "IG1ldGhvZCBjYWxsIC0gVHJhbnNmb3JtZWQMABQAEAEALVBvc3QgRmluaXNoIHByaXZhdGUgbWV0" +
- "aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAEACVRyYW5zZm9ybQEAEGphdmEvbGFuZy9PYmplY3QBABBq" +
- "YXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9Q" +
- "cmludFN0cmVhbQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABJqYXZhL2xhbmcv" +
- "UnVubmFibGUBAANydW4AIAANAA4AAAAAAAQAAAAPABAAAQARAAAAHQABAAEAAAAFKrcAAbEAAAAB" +
- "ABIAAAAGAAEAAAABAAIAEwAQAAEAEQAAACUAAgABAAAACbIAAhIDtgAEsQAAAAEAEgAAAAoAAgAA" +
- "AAMACAAEAAIAFAAQAAEAEQAAACUAAgABAAAACbIAAhIFtgAEsQAAAAEAEgAAAAoAAgAAAAcACAAI" +
- "AAEAFQAWAAEAEQAAAGMAAgACAAAAL7IAAhIGtgAEKrcAB7IAAhIItgAEK7kACQEAsgACEgq2AAQq" +
- "twALsgACEgy2AASxAAAAAQASAAAAIgAIAAAACwAIAAwADAANABQADgAaAA8AIgAQACYAEQAuABIA" +
- "AQAXAAAAAgAY");
- private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
- "ZGV4CjAzNQCM0QYTJmX+NsZXkImojgSkJtXyuew3oaXcBAAAcAAAAHhWNBIAAAAAAAAAADwEAAAX" +
- "AAAAcAAAAAcAAADMAAAAAwAAAOgAAAABAAAADAEAAAcAAAAUAQAAAQAAAEwBAABwAwAAbAEAAD4C" +
- "AABGAgAATgIAAG8CAACOAgAAmwIAALICAADGAgAA3AIAAPACAAAEAwAAMwMAAGEDAACPAwAAvAMA" +
- "AMMDAADTAwAA1gMAANoDAADuAwAA8wMAAPwDAAABBAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAA" +
- "EAAAABAAAAAGAAAAAAAAABEAAAAGAAAAMAIAABEAAAAGAAAAOAIAAAUAAQATAAAAAAAAAAAAAAAA" +
- "AAAAAQAAAAAAAAAOAAAAAAABABYAAAABAAIAFAAAAAIAAAAAAAAAAwAAABUAAAAAAAAAAAAAAAIA" +
- "AAAAAAAADwAAAAAAAAAmBAAAAAAAAAEAAQABAAAACAQAAAQAAABwEAUAAAAOAAMAAQACAAAADQQA" +
- "AAkAAABiAAAAGwECAAAAbiAEABAADgAAAAMAAQACAAAAEwQAAAkAAABiAAAAGwEDAAAAbiAEABAA" +
- "DgAAAAQAAgACAAAAGQQAACoAAABiAAAAGwENAAAAbiAEABAAcBACAAIAYgAAABsBCwAAAG4gBAAQ" +
- "AHIQBgADAGIAAAAbAQwAAABuIAQAEABwEAEAAgBiAAAAGwEKAAAAbiAEABAADgABAAAAAwAAAAEA" +
- "AAAEAAY8aW5pdD4ABkZpbmlzaAAfR29vZGJ5ZSAtIHByaXZhdGUgLSBUcmFuc2Zvcm1lZAAdSGVs" +
- "bG8gLSBwcml2YXRlIC0gVHJhbnNmb3JtZWQAC0xUcmFuc2Zvcm07ABVMamF2YS9pby9QcmludFN0" +
- "cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwAUTGphdmEvbGFuZy9SdW5uYWJsZTsAEkxqYXZhL2xh" +
- "bmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AC1Qb3N0IEZpbmlzaCBwcml2YXRlIG1ldGhv" +
- "ZCBjYWxsIC0gVHJhbnNmb3JtZWQALFBvc3QgU3RhcnQgcHJpdmF0ZSBtZXRob2QgY2FsbCAtIFRy" +
- "YW5zZm9ybWVkACxQcmUgRmluaXNoIHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAr" +
- "UHJlIFN0YXJ0IHByaXZhdGUgbWV0aG9kIGNhbGwgLSBUcmFuc2Zvcm1lZAAFU3RhcnQADlRyYW5z" +
- "Zm9ybS5qYXZhAAFWAAJWTAASZW1pdHRlcjogamFjay00LjEzAANvdXQAB3ByaW50bG4AA3J1bgAF" +
- "c2F5SGkAAQAHDgAHAAcOhwADAAcOhwALAQAHDoc8hzyHPIcAAAADAQCAgATsAgEChAMBAqgDAwHM" +
- "Aw0AAAAAAAAAAQAAAAAAAAABAAAAFwAAAHAAAAACAAAABwAAAMwAAAADAAAAAwAAAOgAAAAEAAAA" +
- "AQAAAAwBAAAFAAAABwAAABQBAAAGAAAAAQAAAEwBAAABIAAABAAAAGwBAAABEAAAAgAAADACAAAC" +
- "IAAAFwAAAD4CAAADIAAABAAAAAgEAAAAIAAAAQAAACYEAAAAEAAAAQAAADwEAAA=");
-
- public static void main(String[] args) {
- System.loadLibrary(args[1]);
- doTest(new Transform());
- }
-
- // TODO Workaround to (1) inability to ensure that current_method is not put into a register by
- // the JIT and/or (2) inability to deoptimize frames near runtime functions.
- // TODO Fix one/both of these issues.
- public static void doCall(Runnable r) {
- r.run();
- }
-
- private static boolean interpreting = true;
- public static void doTest(Transform t) {
- do_print = false;
- Runnable noop = () -> {};
- long j = 0;
- do {
- for (int i = 0; i < 10000; i++) {
- t.sayHi(noop);
- j++;
- }
- t.sayHi(() -> {
- // TODO 2 is wrong It is checking a piece of this lambda method but should be fine due to
- // how we implement lambdas. Be sure to fix before really submitting.
- interpreting = Main.isInterpretedFunction("LTransform;->sayHi()V");
- });
- if (j >= 1000000) {
- System.out.println("FAIL: Could not make sayHi be Jitted!");
- return;
- }
- j++;
- } while(interpreting);
- // Start printing.
- do_print = true;
- t.sayHi(() -> {
- System.out.println("Not doing anything here");
- });
- t.sayHi(() -> {
- if (Main.isInterpretedFunction("LTransform;->sayHi()V")) {
- System.out.println("FAIL: sayHi is being interpreted!");
- }
- System.out.println("transforming calling function");
- doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
- });
- t.sayHi(() -> { System.out.println("Not doing anything here"); });
- }
-
- private static native boolean isInterpretedFunction(String name);
-
- // Transforms the class
- private static native void doCommonClassRedefinition(Class<?> target,
- byte[] classfile,
- byte[] dexfile);
-}
diff --git a/test/916-obsolete-jit/src/Transform.java b/test/916-obsolete-jit/src/Transform.java
deleted file mode 100644
index a22f389..0000000
--- a/test/916-obsolete-jit/src/Transform.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.
- */
-
-class Transform {
- private void Start() {
- if (Main.doPrint()) {
- System.out.println("hello - private");
- }
- }
-
- private void Finish() {
- if (Main.doPrint()) {
- System.out.println("goodbye - private");
- }
- }
-
- public void sayHi(Runnable r) {
- if (Main.doPrint()) {
- System.out.println("Pre Start private method call");
- }
- Start();
- if (Main.doPrint()) {
- System.out.println("Post Start private method call");
- }
- // TODO Revist with b/33616143
- // TODO Uncomment this
- // r.run();
- // TODO This is a very temporary fix until we get either deoptimization near runtime frames
- // working, forcing current method to be always read from the stack or both working.
- Main.doCall(r);
- if (Main.doPrint()) {
- System.out.println("Pre Finish private method call");
- }
- Finish();
- if (Main.doPrint()) {
- System.out.println("Post Finish private method call");
- }
- }
-}
diff --git a/test/Android.bp b/test/Android.bp
index c42ffc9..2625f56 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -243,8 +243,6 @@
name: "libtiagent-defaults",
defaults: ["libartagent-defaults"],
srcs: [
- // This is to get the IsInterpreted native method.
- "common/stack_inspect.cc",
"ti-agent/common_load.cc",
"ti-agent/common_helper.cc",
"901-hello-ti-agent/basics.cc",
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 2b620b5..c02999b 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -280,9 +280,6 @@
911-get-stack-trace \
912-classes \
913-heaps \
- 914-hello-obsolescence \
- 915-obsolete-2 \
- 916-obsolete-jit \
ifneq (,$(filter target,$(TARGET_TYPES)))
ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \
@@ -495,6 +492,24 @@
$(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/runtime/base/stringprintf_test.cc b/test/ErroneousA/ErroneousA.java
similarity index 61%
copy from runtime/base/stringprintf_test.cc
copy to test/ErroneousA/ErroneousA.java
index 0bfde33..49da544 100644
--- a/runtime/base/stringprintf_test.cc
+++ b/test/ErroneousA/ErroneousA.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,4 @@
* limitations under the License.
*/
-#include "stringprintf.h"
-
-#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
+final class FinalSuper {}
diff --git a/runtime/base/stringprintf_test.cc b/test/ErroneousB/ErroneousB.java
similarity index 61%
rename from runtime/base/stringprintf_test.cc
rename to test/ErroneousB/ErroneousB.java
index 0bfde33..6c2902a 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/test/common/stack_inspect.cc b/test/common/stack_inspect.cc
index eefaabc..4df2d47 100644
--- a/test/common/stack_inspect.cc
+++ b/test/common/stack_inspect.cc
@@ -52,53 +52,6 @@
return IsInterpreted(env, klass, 1);
}
-// public static native boolean isInterpreted(int depth);
-
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpretedAt(JNIEnv* env,
- jclass klass,
- jint depth) {
- return IsInterpreted(env, klass, depth);
-}
-
-
-// public static native boolean isInterpretedFunction(String smali);
-
-struct MethodIsInterpretedVisitor : public StackVisitor {
- public:
- MethodIsInterpretedVisitor(Thread* thread, std::string shorty)
- : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
- shorty_(shorty),
- method_is_interpreted_(false) {}
-
- virtual bool VisitFrame() OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {
- if (!GetMethod()->IsRuntimeMethod() && shorty_ == GetMethod()->GetShorty()) {
- method_is_interpreted_ = IsShadowFrame();
- return false;
- }
- return true;
- }
-
- bool IsInterpreted() {
- return method_is_interpreted_;
- }
-
- private:
- const std::string shorty_;
- bool method_is_interpreted_;
-};
-
-extern "C" JNIEXPORT jboolean JNICALL Java_Main_isInterpretedFunction(JNIEnv* env,
- jclass klass ATTRIBUTE_UNUSED,
- jstring name) {
- if (Runtime::Current() == nullptr) {
- return JNI_TRUE;
- }
- ScopedObjectAccess soa(env);
- MethodIsInterpretedVisitor v(soa.Self(), soa.Decode<mirror::String>(name)->ToModifiedUtf8());
- v.WalkStack();
- return v.IsInterpreted();
-}
-
// public static native void assertIsInterpreted();
extern "C" JNIEXPORT void JNICALL Java_Main_assertIsInterpreted(JNIEnv* env, jclass klass) {
diff --git a/test/etc/default-build b/test/etc/default-build
index faa0813..51ae175 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -69,7 +69,6 @@
# Setup experimental flag mappings in a bash associative array.
declare -A JACK_EXPERIMENTAL_ARGS
-JACK_EXPERIMENTAL_ARGS["agents"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
JACK_EXPERIMENTAL_ARGS["method-handles"]="-D jack.java.source.version=1.7 -D jack.android.min-api-level=o-b1"
@@ -77,14 +76,12 @@
declare -A SMALI_EXPERIMENTAL_ARGS
SMALI_EXPERIMENTAL_ARGS["default-methods"]="--api-level 24"
SMALI_EXPERIMENTAL_ARGS["method-handles"]="--api-level 26"
-SMALI_EXPERIMENTAL_ARGS["agents"]="--api-level 26"
declare -A JAVAC_EXPERIMENTAL_ARGS
JAVAC_EXPERIMENTAL_ARGS["default-methods"]="-source 1.8 -target 1.8"
JAVAC_EXPERIMENTAL_ARGS["lambdas"]="-source 1.8 -target 1.8"
JAVAC_EXPERIMENTAL_ARGS["method-handles"]="-source 1.8 -target 1.8"
JAVAC_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-source 1.7 -target 1.7"
-JAVAC_EXPERIMENTAL_ARGS["agents"]="-source 1.8 -target 1.8"
while true; do
if [ "x$1" = "x--dx-option" ]; then
diff --git a/test/ti-agent/common_helper.cc b/test/ti-agent/common_helper.cc
index ebf1e46..3e2b168 100644
--- a/test/ti-agent/common_helper.cc
+++ b/test/ti-agent/common_helper.cc
@@ -18,11 +18,8 @@
#include <stdio.h>
-#include "art_method.h"
#include "jni.h"
#include "openjdkjvmti/jvmti.h"
-#include "scoped_thread_state_change-inl.h"
-#include "stack.h"
#include "ti-agent/common_load.h"
#include "utils.h"
diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc
index 826c5ad..2795cbc 100644
--- a/test/ti-agent/common_load.cc
+++ b/test/ti-agent/common_load.cc
@@ -66,8 +66,6 @@
{ "911-get-stack-trace", Test911GetStackTrace::OnLoad, nullptr },
{ "912-classes", Test912Classes::OnLoad, nullptr },
{ "913-heaps", Test913Heaps::OnLoad, nullptr },
- { "914-hello-obsolescence", common_redefine::OnLoad, nullptr },
- { "915-obsolete-2", common_redefine::OnLoad, nullptr },
};
static AgentLib* FindAgent(char* name) {
diff --git a/tools/cpp-define-generator/offset_dexcache.def b/tools/cpp-define-generator/offset_dexcache.def
index 4b9d481..abb5e1e 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(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 fd8415d..42745d2 100755
--- a/tools/jfuzz/run_jfuzz_test.py
+++ b/tools/jfuzz/run_jfuzz_test.py
@@ -414,14 +414,16 @@
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 @@
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 @@
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."""