Merge "Revert "Revert^4 "Make class redefinition work with native methods on stack."""
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index e525808..5c49f19 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -93,7 +93,7 @@
ART_GTEST_compiler_driver_test_DEX_DEPS := AbstractMethod StaticLeafMethods ProfileTestMultiDex
ART_GTEST_dex_cache_test_DEX_DEPS := Main Packages MethodTypes
ART_GTEST_dex_file_test_DEX_DEPS := GetMethodSignature Main Nested
-ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) Statics
+ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) Statics VerifierDeps
ART_GTEST_exception_test_DEX_DEPS := ExceptionHandle
ART_GTEST_image_test_DEX_DEPS := ImageLayoutA ImageLayoutB
ART_GTEST_imtable_test_DEX_DEPS := IMTA IMTB
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index 27b4253..e6032d2 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -34,6 +34,9 @@
#include "utils/stack_checks.h"
using namespace vixl::aarch64; // NOLINT(build/namespaces)
+using vixl::ExactAssemblyScope;
+using vixl::CodeBufferCheckScope;
+using vixl::EmissionCheckScope;
#ifdef __
#error "ARM64 Codegen VIXL macro-assembler macro already defined."
@@ -613,10 +616,9 @@
// We are about to use the assembler to place literals directly. Make sure we have enough
// underlying code buffer and we have generated the jump table with right size.
- vixl::CodeBufferCheckScope scope(codegen->GetVIXLAssembler(),
- num_entries * sizeof(int32_t),
- vixl::CodeBufferCheckScope::kReserveBufferSpace,
- vixl::CodeBufferCheckScope::kExactSize);
+ EmissionCheckScope scope(codegen->GetVIXLAssembler(),
+ num_entries * sizeof(int32_t),
+ CodeBufferCheckScope::kExactSize);
__ Bind(&table_start_);
const ArenaVector<HBasicBlock*>& successors = switch_instr_->GetBlock()->GetSuccessors();
@@ -1279,7 +1281,6 @@
void CodeGeneratorARM64::GenerateFrameEntry() {
MacroAssembler* masm = GetVIXLAssembler();
- BlockPoolsScope block_pools(masm);
__ Bind(&frame_entry_label_);
bool do_overflow_check = FrameNeedsStackCheck(GetFrameSize(), kArm64) || !IsLeafMethod();
@@ -1288,8 +1289,14 @@
Register temp = temps.AcquireX();
DCHECK(GetCompilerOptions().GetImplicitStackOverflowChecks());
__ Sub(temp, sp, static_cast<int32_t>(GetStackOverflowReservedBytes(kArm64)));
- __ Ldr(wzr, MemOperand(temp, 0));
- RecordPcInfo(nullptr, 0);
+ {
+ // Ensure that between load and RecordPcInfo there are no pools emitted.
+ ExactAssemblyScope eas(GetVIXLAssembler(),
+ kInstructionSize,
+ CodeBufferCheckScope::kExactSize);
+ __ ldr(wzr, MemOperand(temp, 0));
+ RecordPcInfo(nullptr, 0);
+ }
}
if (!HasEmptyFrame()) {
@@ -1324,7 +1331,6 @@
}
void CodeGeneratorARM64::GenerateFrameExit() {
- BlockPoolsScope block_pools(GetVIXLAssembler());
GetAssembler()->cfi().RememberState();
if (!HasEmptyFrame()) {
int frame_size = GetFrameSize();
@@ -1651,7 +1657,6 @@
const MemOperand& src,
bool needs_null_check) {
MacroAssembler* masm = GetVIXLAssembler();
- BlockPoolsScope block_pools(masm);
UseScratchRegisterScope temps(masm);
Register temp_base = temps.AcquireX();
Primitive::Type type = instruction->GetType();
@@ -1661,58 +1666,79 @@
// TODO(vixl): Let the MacroAssembler handle MemOperand.
__ Add(temp_base, src.GetBaseRegister(), OperandFromMemOperand(src));
- MemOperand base = MemOperand(temp_base);
- switch (type) {
- case Primitive::kPrimBoolean:
- __ Ldarb(Register(dst), base);
- if (needs_null_check) {
- MaybeRecordImplicitNullCheck(instruction);
- }
- break;
- case Primitive::kPrimByte:
- __ Ldarb(Register(dst), base);
- if (needs_null_check) {
- MaybeRecordImplicitNullCheck(instruction);
- }
- __ Sbfx(Register(dst), Register(dst), 0, Primitive::ComponentSize(type) * kBitsPerByte);
- break;
- case Primitive::kPrimChar:
- __ Ldarh(Register(dst), base);
- if (needs_null_check) {
- MaybeRecordImplicitNullCheck(instruction);
- }
- break;
- case Primitive::kPrimShort:
- __ Ldarh(Register(dst), base);
- if (needs_null_check) {
- MaybeRecordImplicitNullCheck(instruction);
- }
- __ Sbfx(Register(dst), Register(dst), 0, Primitive::ComponentSize(type) * kBitsPerByte);
- break;
- case Primitive::kPrimInt:
- case Primitive::kPrimNot:
- case Primitive::kPrimLong:
- DCHECK_EQ(dst.Is64Bits(), Primitive::Is64BitType(type));
- __ Ldar(Register(dst), base);
- if (needs_null_check) {
- MaybeRecordImplicitNullCheck(instruction);
- }
- break;
- case Primitive::kPrimFloat:
- case Primitive::kPrimDouble: {
- DCHECK(dst.IsFPRegister());
- DCHECK_EQ(dst.Is64Bits(), Primitive::Is64BitType(type));
+ {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ MemOperand base = MemOperand(temp_base);
+ switch (type) {
+ case Primitive::kPrimBoolean:
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ ldarb(Register(dst), base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
+ break;
+ case Primitive::kPrimByte:
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ ldarb(Register(dst), base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
+ __ Sbfx(Register(dst), Register(dst), 0, Primitive::ComponentSize(type) * kBitsPerByte);
+ break;
+ case Primitive::kPrimChar:
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ ldarh(Register(dst), base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
+ break;
+ case Primitive::kPrimShort:
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ ldarh(Register(dst), base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
+ __ Sbfx(Register(dst), Register(dst), 0, Primitive::ComponentSize(type) * kBitsPerByte);
+ break;
+ case Primitive::kPrimInt:
+ case Primitive::kPrimNot:
+ case Primitive::kPrimLong:
+ DCHECK_EQ(dst.Is64Bits(), Primitive::Is64BitType(type));
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ ldar(Register(dst), base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
+ break;
+ case Primitive::kPrimFloat:
+ case Primitive::kPrimDouble: {
+ DCHECK(dst.IsFPRegister());
+ DCHECK_EQ(dst.Is64Bits(), Primitive::Is64BitType(type));
- Register temp = dst.Is64Bits() ? temps.AcquireX() : temps.AcquireW();
- __ Ldar(temp, base);
- if (needs_null_check) {
- MaybeRecordImplicitNullCheck(instruction);
+ Register temp = dst.Is64Bits() ? temps.AcquireX() : temps.AcquireW();
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ ldar(temp, base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
+ __ Fmov(FPRegister(dst), temp);
+ break;
}
- __ Fmov(FPRegister(dst), temp);
- break;
+ case Primitive::kPrimVoid:
+ LOG(FATAL) << "Unreachable type " << type;
}
- case Primitive::kPrimVoid:
- LOG(FATAL) << "Unreachable type " << type;
}
}
@@ -1741,9 +1767,12 @@
}
}
-void CodeGeneratorARM64::StoreRelease(Primitive::Type type,
+void CodeGeneratorARM64::StoreRelease(HInstruction* instruction,
+ Primitive::Type type,
CPURegister src,
- const MemOperand& dst) {
+ const MemOperand& dst,
+ bool needs_null_check) {
+ MacroAssembler* masm = GetVIXLAssembler();
UseScratchRegisterScope temps(GetVIXLAssembler());
Register temp_base = temps.AcquireX();
@@ -1754,20 +1783,39 @@
Operand op = OperandFromMemOperand(dst);
__ Add(temp_base, dst.GetBaseRegister(), op);
MemOperand base = MemOperand(temp_base);
+ // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted.
switch (type) {
case Primitive::kPrimBoolean:
case Primitive::kPrimByte:
- __ Stlrb(Register(src), base);
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ stlrb(Register(src), base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
break;
case Primitive::kPrimChar:
case Primitive::kPrimShort:
- __ Stlrh(Register(src), base);
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ stlrh(Register(src), base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
break;
case Primitive::kPrimInt:
case Primitive::kPrimNot:
case Primitive::kPrimLong:
DCHECK_EQ(src.Is64Bits(), Primitive::Is64BitType(type));
- __ Stlr(Register(src), base);
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ stlr(Register(src), base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
break;
case Primitive::kPrimFloat:
case Primitive::kPrimDouble: {
@@ -1781,8 +1829,13 @@
temp_src = src.Is64Bits() ? temps.AcquireX() : temps.AcquireW();
__ Fmov(temp_src, FPRegister(src));
}
-
- __ Stlr(temp_src, base);
+ {
+ ExactAssemblyScope eas(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ stlr(temp_src, base);
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
+ }
break;
}
case Primitive::kPrimVoid:
@@ -1795,9 +1848,15 @@
uint32_t dex_pc,
SlowPathCode* slow_path) {
ValidateInvokeRuntime(entrypoint, instruction, slow_path);
- GenerateInvokeRuntime(GetThreadOffset<kArm64PointerSize>(entrypoint).Int32Value());
- if (EntrypointRequiresStackMap(entrypoint)) {
- RecordPcInfo(instruction, dex_pc, slow_path);
+
+ __ Ldr(lr, MemOperand(tr, GetThreadOffset<kArm64PointerSize>(entrypoint).Int32Value()));
+ {
+ // Ensure the pc position is recorded immediately after the `blr` instruction.
+ ExactAssemblyScope eas(GetVIXLAssembler(), kInstructionSize, CodeBufferCheckScope::kExactSize);
+ __ blr(lr);
+ if (EntrypointRequiresStackMap(entrypoint)) {
+ RecordPcInfo(instruction, dex_pc, slow_path);
+ }
}
}
@@ -1805,11 +1864,6 @@
HInstruction* instruction,
SlowPathCode* slow_path) {
ValidateInvokeRuntimeWithoutRecordingPcInfo(instruction, slow_path);
- GenerateInvokeRuntime(entry_point_offset);
-}
-
-void CodeGeneratorARM64::GenerateInvokeRuntime(int32_t entry_point_offset) {
- BlockPoolsScope block_pools(GetVIXLAssembler());
__ Ldr(lr, MemOperand(tr, entry_point_offset));
__ Blr(lr);
}
@@ -1976,7 +2030,6 @@
Location out = locations->Out();
uint32_t offset = field_info.GetFieldOffset().Uint32Value();
Primitive::Type field_type = field_info.GetFieldType();
- BlockPoolsScope block_pools(GetVIXLAssembler());
MemOperand field = HeapOperand(InputRegisterAt(instruction, 0), field_info.GetFieldOffset());
if (field_type == Primitive::kPrimNot && kEmitCompilerReadBarrier && kUseBakerReadBarrier) {
@@ -2003,6 +2056,8 @@
codegen_->LoadAcquire(
instruction, OutputCPURegister(instruction), field, /* needs_null_check */ true);
} else {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
codegen_->Load(field_type, OutputCPURegister(instruction), field);
codegen_->MaybeRecordImplicitNullCheck(instruction);
}
@@ -2032,7 +2087,6 @@
const FieldInfo& field_info,
bool value_can_be_null) {
DCHECK(instruction->IsInstanceFieldSet() || instruction->IsStaticFieldSet());
- BlockPoolsScope block_pools(GetVIXLAssembler());
Register obj = InputRegisterAt(instruction, 0);
CPURegister value = InputCPURegisterOrZeroRegAt(instruction, 1);
@@ -2054,9 +2108,11 @@
}
if (field_info.IsVolatile()) {
- codegen_->StoreRelease(field_type, source, HeapOperand(obj, offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
+ codegen_->StoreRelease(
+ instruction, field_type, source, HeapOperand(obj, offset), /* needs_null_check */ true);
} else {
+ // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
codegen_->Store(field_type, source, HeapOperand(obj, offset));
codegen_->MaybeRecordImplicitNullCheck(instruction);
}
@@ -2342,10 +2398,7 @@
masm->GetCursorAddress<vixl::aarch64::Instruction*>() - kInstructionSize;
if (prev->IsLoadOrStore()) {
// Make sure we emit only exactly one nop.
- vixl::CodeBufferCheckScope scope(masm,
- kInstructionSize,
- vixl::CodeBufferCheckScope::kReserveBufferSpace,
- vixl::CodeBufferCheckScope::kExactSize);
+ ExactAssemblyScope scope(masm, kInstructionSize, CodeBufferCheckScope::kExactSize);
__ nop();
}
}
@@ -2401,8 +2454,6 @@
instruction->IsStringCharAt();
MacroAssembler* masm = GetVIXLAssembler();
UseScratchRegisterScope temps(masm);
- // Block pools between `Load` and `MaybeRecordImplicitNullCheck`.
- BlockPoolsScope block_pools(masm);
// The read barrier instrumentation of object ArrayGet instructions
// does not support the HIntermediateAddress instruction.
@@ -2424,15 +2475,21 @@
if (maybe_compressed_char_at) {
uint32_t count_offset = mirror::String::CountOffset().Uint32Value();
length = temps.AcquireW();
- if (instruction->GetArray()->IsIntermediateAddress()) {
- DCHECK_LT(count_offset, offset);
- int64_t adjusted_offset = static_cast<int64_t>(count_offset) - static_cast<int64_t>(offset);
- // Note that `adjusted_offset` is negative, so this will be a LDUR.
- __ Ldr(length, MemOperand(obj.X(), adjusted_offset));
- } else {
- __ Ldr(length, HeapOperand(obj, count_offset));
+ {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+
+ if (instruction->GetArray()->IsIntermediateAddress()) {
+ DCHECK_LT(count_offset, offset);
+ int64_t adjusted_offset =
+ static_cast<int64_t>(count_offset) - static_cast<int64_t>(offset);
+ // Note that `adjusted_offset` is negative, so this will be a LDUR.
+ __ Ldr(length, MemOperand(obj.X(), adjusted_offset));
+ } else {
+ __ Ldr(length, HeapOperand(obj, count_offset));
+ }
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
}
- codegen_->MaybeRecordImplicitNullCheck(instruction);
}
if (index.IsConstant()) {
if (maybe_compressed_char_at) {
@@ -2482,6 +2539,8 @@
}
}
if (!maybe_compressed_char_at) {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
codegen_->Load(type, OutputCPURegister(instruction), source);
codegen_->MaybeRecordImplicitNullCheck(instruction);
}
@@ -2509,9 +2568,12 @@
void InstructionCodeGeneratorARM64::VisitArrayLength(HArrayLength* instruction) {
uint32_t offset = CodeGenerator::GetArrayLengthOffset(instruction);
vixl::aarch64::Register out = OutputRegister(instruction);
- BlockPoolsScope block_pools(GetVIXLAssembler());
- __ Ldr(out, HeapOperand(InputRegisterAt(instruction, 0), offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
+ {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ __ Ldr(out, HeapOperand(InputRegisterAt(instruction, 0), offset));
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ }
// Mask out compression flag from String's array length.
if (mirror::kUseStringCompression && instruction->IsStringLength()) {
__ Lsr(out.W(), out.W(), 1u);
@@ -2552,7 +2614,6 @@
size_t offset = mirror::Array::DataOffset(Primitive::ComponentSize(value_type)).Uint32Value();
MemOperand destination = HeapOperand(array);
MacroAssembler* masm = GetVIXLAssembler();
- BlockPoolsScope block_pools(masm);
if (!needs_write_barrier) {
DCHECK(!may_need_runtime_call_for_type_check);
@@ -2579,8 +2640,12 @@
LSL,
Primitive::ComponentSizeShift(value_type));
}
- codegen_->Store(value_type, value, destination);
- codegen_->MaybeRecordImplicitNullCheck(instruction);
+ {
+ // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ codegen_->Store(value_type, value, destination);
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ }
} else {
DCHECK(!instruction->GetArray()->IsIntermediateAddress());
vixl::aarch64::Label done;
@@ -2613,8 +2678,13 @@
if (!index.IsConstant()) {
__ Add(temp, array, offset);
}
- __ Str(wzr, destination);
- codegen_->MaybeRecordImplicitNullCheck(instruction);
+ {
+ // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools
+ // emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ __ Str(wzr, destination);
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ }
__ B(&done);
__ Bind(&non_zero);
}
@@ -2629,8 +2699,12 @@
Register temp2 = temps.AcquireSameSizeAs(array);
// /* HeapReference<Class> */ temp = array->klass_
- __ Ldr(temp, HeapOperand(array, class_offset));
- codegen_->MaybeRecordImplicitNullCheck(instruction);
+ {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ __ Ldr(temp, HeapOperand(array, class_offset));
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ }
GetAssembler()->MaybeUnpoisonHeapReference(temp);
// /* HeapReference<Class> */ temp = temp->component_type_
@@ -2671,10 +2745,14 @@
if (!index.IsConstant()) {
__ Add(temp, array, offset);
}
- __ Str(source, destination);
+ {
+ // Ensure that between store and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ __ Str(source, destination);
- if (!may_need_runtime_call_for_type_check) {
- codegen_->MaybeRecordImplicitNullCheck(instruction);
+ if (!may_need_runtime_call_for_type_check) {
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ }
}
}
@@ -3969,19 +4047,25 @@
// art_quick_imt_conflict_trampoline, so prevent VIXL from using it.
MacroAssembler* masm = GetVIXLAssembler();
UseScratchRegisterScope scratch_scope(masm);
- BlockPoolsScope block_pools(masm);
scratch_scope.Exclude(ip1);
__ Mov(ip1, invoke->GetDexMethodIndex());
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
if (receiver.IsStackSlot()) {
__ Ldr(temp.W(), StackOperandFrom(receiver));
- // /* HeapReference<Class> */ temp = temp->klass_
- __ Ldr(temp.W(), HeapOperand(temp.W(), class_offset));
+ {
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ // /* HeapReference<Class> */ temp = temp->klass_
+ __ Ldr(temp.W(), HeapOperand(temp.W(), class_offset));
+ codegen_->MaybeRecordImplicitNullCheck(invoke);
+ }
} else {
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
// /* HeapReference<Class> */ temp = receiver->klass_
__ Ldr(temp.W(), HeapOperandFrom(receiver, class_offset));
+ codegen_->MaybeRecordImplicitNullCheck(invoke);
}
- codegen_->MaybeRecordImplicitNullCheck(invoke);
+
// Instead of simply (possibly) unpoisoning `temp` here, we should
// emit a read barrier for the previous class reference load.
// However this is not required in practice, as this is an
@@ -3998,10 +4082,16 @@
__ Ldr(temp, MemOperand(temp, method_offset));
// lr = temp->GetEntryPoint();
__ Ldr(lr, MemOperand(temp, entry_point.Int32Value()));
- // lr();
- __ Blr(lr);
- DCHECK(!codegen_->IsLeafMethod());
- codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
+
+ {
+ // Ensure the pc position is recorded immediately after the `blr` instruction.
+ ExactAssemblyScope eas(GetVIXLAssembler(), kInstructionSize, CodeBufferCheckScope::kExactSize);
+
+ // lr();
+ __ blr(lr);
+ DCHECK(!codegen_->IsLeafMethod());
+ codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
+ }
}
void LocationsBuilderARM64::VisitInvokeVirtual(HInvokeVirtual* invoke) {
@@ -4113,8 +4203,16 @@
__ Ldr(lr, MemOperand(
XRegisterFrom(callee_method),
ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArm64PointerSize).Int32Value()));
- // lr()
- __ Blr(lr);
+ {
+ // To ensure that the pc position is recorded immediately after the `blr` instruction
+ // BLR must be the last instruction emitted in this function.
+ // Recording the pc will occur right after returning from this function.
+ ExactAssemblyScope eas(GetVIXLAssembler(),
+ kInstructionSize,
+ CodeBufferCheckScope::kExactSize);
+ // lr()
+ __ blr(lr);
+ }
break;
}
@@ -4134,12 +4232,15 @@
Offset class_offset = mirror::Object::ClassOffset();
Offset entry_point = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArm64PointerSize);
- BlockPoolsScope block_pools(GetVIXLAssembler());
-
DCHECK(receiver.IsRegister());
- // /* HeapReference<Class> */ temp = receiver->klass_
- __ Ldr(temp.W(), HeapOperandFrom(LocationFrom(receiver), class_offset));
- MaybeRecordImplicitNullCheck(invoke);
+
+ {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ // /* HeapReference<Class> */ temp = receiver->klass_
+ __ Ldr(temp.W(), HeapOperandFrom(LocationFrom(receiver), class_offset));
+ MaybeRecordImplicitNullCheck(invoke);
+ }
// Instead of simply (possibly) unpoisoning `temp` here, we should
// emit a read barrier for the previous class reference load.
// intermediate/temporary reference and because the current
@@ -4151,8 +4252,14 @@
__ Ldr(temp, MemOperand(temp, method_offset));
// lr = temp->GetEntryPoint();
__ Ldr(lr, MemOperand(temp, entry_point.SizeValue()));
- // lr();
- __ Blr(lr);
+ {
+ // To ensure that the pc position is recorded immediately after the `blr` instruction
+ // BLR should be the last instruction emitted in this function.
+ // Recording the pc will occur right after returning from this function.
+ ExactAssemblyScope eas(GetVIXLAssembler(), kInstructionSize, CodeBufferCheckScope::kExactSize);
+ // lr();
+ __ blr(lr);
+ }
}
void LocationsBuilderARM64::VisitInvokePolymorphic(HInvokePolymorphic* invoke) {
@@ -4365,7 +4472,9 @@
return;
}
- BlockPoolsScope block_pools(GetVIXLAssembler());
+ // Ensure that between the BLR (emitted by GenerateStaticOrDirectCall) and RecordPcInfo there
+ // are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kInvokeCodeMarginSizeInBytes);
LocationSummary* locations = invoke->GetLocations();
codegen_->GenerateStaticOrDirectCall(
invoke, locations->HasTemps() ? locations->GetTemp(0) : Location::NoLocation());
@@ -4377,6 +4486,9 @@
return;
}
+ // Ensure that between the BLR (emitted by GenerateVirtualCall) and RecordPcInfo there
+ // are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kInvokeCodeMarginSizeInBytes);
codegen_->GenerateVirtualCall(invoke, invoke->GetLocations()->GetTemp(0));
DCHECK(!codegen_->IsLeafMethod());
codegen_->RecordPcInfo(invoke, invoke->GetDexPc());
@@ -4872,8 +4984,15 @@
MemberOffset code_offset = ArtMethod::EntryPointFromQuickCompiledCodeOffset(kArm64PointerSize);
__ Ldr(XRegisterFrom(temp), MemOperand(tr, QUICK_ENTRY_POINT(pNewEmptyString)));
__ Ldr(lr, MemOperand(XRegisterFrom(temp), code_offset.Int32Value()));
- __ Blr(lr);
- codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+
+ {
+ // Ensure the pc position is recorded immediately after the `blr` instruction.
+ ExactAssemblyScope eas(GetVIXLAssembler(),
+ kInstructionSize,
+ CodeBufferCheckScope::kExactSize);
+ __ blr(lr);
+ codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+ }
} else {
codegen_->InvokeRuntime(instruction->GetEntrypoint(), instruction, instruction->GetDexPc());
CheckEntrypointTypes<kQuickAllocObjectWithChecks, void*, mirror::Class*>();
@@ -4917,11 +5036,13 @@
if (CanMoveNullCheckToUser(instruction)) {
return;
}
-
- BlockPoolsScope block_pools(GetVIXLAssembler());
- Location obj = instruction->GetLocations()->InAt(0);
- __ Ldr(wzr, HeapOperandFrom(obj, Offset(0)));
- RecordPcInfo(instruction, instruction->GetDexPc());
+ {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ Location obj = instruction->GetLocations()->InAt(0);
+ __ Ldr(wzr, HeapOperandFrom(obj, Offset(0)));
+ RecordPcInfo(instruction, instruction->GetDexPc());
+ }
}
void CodeGeneratorARM64::GenerateExplicitNullCheck(HNullCheck* instruction) {
@@ -5658,10 +5779,14 @@
DCHECK(obj.IsW());
uint32_t monitor_offset = mirror::Object::MonitorOffset().Int32Value();
- // /* int32_t */ monitor = obj->monitor_
- __ Ldr(temp, HeapOperand(obj, monitor_offset));
- if (needs_null_check) {
- MaybeRecordImplicitNullCheck(instruction);
+ {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ EmissionCheckScope guard(GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ // /* int32_t */ monitor = obj->monitor_
+ __ Ldr(temp, HeapOperand(obj, monitor_offset));
+ if (needs_null_check) {
+ MaybeRecordImplicitNullCheck(instruction);
+ }
}
// /* LockWord */ lock_word = LockWord(monitor)
static_assert(sizeof(LockWord) == sizeof(int32_t),
diff --git a/compiler/optimizing/code_generator_arm64.h b/compiler/optimizing/code_generator_arm64.h
index f6cb90a..5faf29a 100644
--- a/compiler/optimizing/code_generator_arm64.h
+++ b/compiler/optimizing/code_generator_arm64.h
@@ -43,6 +43,11 @@
// Use a local definition to prevent copying mistakes.
static constexpr size_t kArm64WordSize = static_cast<size_t>(kArm64PointerSize);
+// These constants are used as an approximate margin when emission of veneer and literal pools
+// must be blocked.
+static constexpr int kMaxMacroInstructionSizeInBytes = 15 * vixl::aarch64::kInstructionSize;
+static constexpr int kInvokeCodeMarginSizeInBytes = 6 * kMaxMacroInstructionSizeInBytes;
+
static const vixl::aarch64::Register kParameterCoreRegisters[] = {
vixl::aarch64::x1,
vixl::aarch64::x2,
@@ -486,9 +491,11 @@
vixl::aarch64::CPURegister dst,
const vixl::aarch64::MemOperand& src,
bool needs_null_check);
- void StoreRelease(Primitive::Type type,
+ void StoreRelease(HInstruction* instruction,
+ Primitive::Type type,
vixl::aarch64::CPURegister src,
- const vixl::aarch64::MemOperand& dst);
+ const vixl::aarch64::MemOperand& dst,
+ bool needs_null_check);
// Generate code to invoke a runtime entry point.
void InvokeRuntime(QuickEntrypointEnum entrypoint,
@@ -502,8 +509,6 @@
HInstruction* instruction,
SlowPathCode* slow_path);
- void GenerateInvokeRuntime(int32_t entry_point_offset);
-
ParallelMoveResolverARM64* GetMoveResolver() OVERRIDE { return &move_resolver_; }
bool NeedsTwoRegisters(Primitive::Type type ATTRIBUTE_UNUSED) const OVERRIDE {
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index 0677dad..c9dde7c 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -1914,6 +1914,8 @@
auto null_checker = GetImplicitNullChecker(instruction);
Primitive::Type type = instruction->GetType();
+ const bool maybe_compressed_char_at = mirror::kUseStringCompression &&
+ instruction->IsStringCharAt();
switch (type) {
case Primitive::kPrimBoolean: {
Register out = locations->Out().AsRegister<Register>();
@@ -1957,14 +1959,54 @@
case Primitive::kPrimChar: {
Register out = locations->Out().AsRegister<Register>();
+ if (maybe_compressed_char_at) {
+ uint32_t count_offset = mirror::String::CountOffset().Uint32Value();
+ __ LoadFromOffset(kLoadWord, TMP, obj, count_offset, null_checker);
+ __ Sll(TMP, TMP, 31); // Extract compression flag into the most significant bit of TMP.
+ static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u,
+ "Expecting 0=compressed, 1=uncompressed");
+ }
if (index.IsConstant()) {
- size_t offset =
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset;
- __ LoadFromOffset(kLoadUnsignedHalfword, out, obj, offset, null_checker);
+ int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue();
+ if (maybe_compressed_char_at) {
+ MipsLabel uncompressed_load, done;
+ __ Bnez(TMP, &uncompressed_load);
+ __ LoadFromOffset(kLoadUnsignedByte,
+ out,
+ obj,
+ data_offset + (const_index << TIMES_1));
+ __ B(&done);
+ __ Bind(&uncompressed_load);
+ __ LoadFromOffset(kLoadUnsignedHalfword,
+ out,
+ obj,
+ data_offset + (const_index << TIMES_2));
+ __ Bind(&done);
+ } else {
+ __ LoadFromOffset(kLoadUnsignedHalfword,
+ out,
+ obj,
+ data_offset + (const_index << TIMES_2),
+ null_checker);
+ }
} else {
- __ Sll(TMP, index.AsRegister<Register>(), TIMES_2);
- __ Addu(TMP, obj, TMP);
- __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset, null_checker);
+ Register index_reg = index.AsRegister<Register>();
+ if (maybe_compressed_char_at) {
+ MipsLabel uncompressed_load, done;
+ __ Bnez(TMP, &uncompressed_load);
+ __ Addu(TMP, obj, index_reg);
+ __ LoadFromOffset(kLoadUnsignedByte, out, TMP, data_offset);
+ __ B(&done);
+ __ Bind(&uncompressed_load);
+ __ Sll(TMP, index_reg, TIMES_2);
+ __ Addu(TMP, obj, TMP);
+ __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset);
+ __ Bind(&done);
+ } else {
+ __ Sll(TMP, index_reg, TIMES_2);
+ __ Addu(TMP, obj, TMP);
+ __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset, null_checker);
+ }
}
break;
}
@@ -2046,6 +2088,10 @@
Register out = locations->Out().AsRegister<Register>();
__ LoadFromOffset(kLoadWord, out, obj, offset);
codegen_->MaybeRecordImplicitNullCheck(instruction);
+ // Mask out compression flag from String's array length.
+ if (mirror::kUseStringCompression && instruction->IsStringLength()) {
+ __ Srl(out, out, 1u);
+ }
}
Location LocationsBuilderMIPS::RegisterOrZeroConstant(HInstruction* instruction) {
diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc
index 4c8dabf..5be0da4 100644
--- a/compiler/optimizing/code_generator_mips64.cc
+++ b/compiler/optimizing/code_generator_mips64.cc
@@ -1490,6 +1490,8 @@
uint32_t data_offset = CodeGenerator::GetArrayDataOffset(instruction);
Primitive::Type type = instruction->GetType();
+ const bool maybe_compressed_char_at = mirror::kUseStringCompression &&
+ instruction->IsStringCharAt();
switch (type) {
case Primitive::kPrimBoolean: {
GpuRegister out = locations->Out().AsRegister<GpuRegister>();
@@ -1533,14 +1535,54 @@
case Primitive::kPrimChar: {
GpuRegister out = locations->Out().AsRegister<GpuRegister>();
+ if (maybe_compressed_char_at) {
+ uint32_t count_offset = mirror::String::CountOffset().Uint32Value();
+ __ LoadFromOffset(kLoadWord, TMP, obj, count_offset);
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ __ Dext(TMP, TMP, 0, 1);
+ static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u,
+ "Expecting 0=compressed, 1=uncompressed");
+ }
if (index.IsConstant()) {
- size_t offset =
- (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_2) + data_offset;
- __ LoadFromOffset(kLoadUnsignedHalfword, out, obj, offset);
+ int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue();
+ if (maybe_compressed_char_at) {
+ Mips64Label uncompressed_load, done;
+ __ Bnezc(TMP, &uncompressed_load);
+ __ LoadFromOffset(kLoadUnsignedByte,
+ out,
+ obj,
+ data_offset + (const_index << TIMES_1));
+ __ Bc(&done);
+ __ Bind(&uncompressed_load);
+ __ LoadFromOffset(kLoadUnsignedHalfword,
+ out,
+ obj,
+ data_offset + (const_index << TIMES_2));
+ __ Bind(&done);
+ } else {
+ __ LoadFromOffset(kLoadUnsignedHalfword,
+ out,
+ obj,
+ data_offset + (const_index << TIMES_2));
+ }
} else {
- __ Dsll(TMP, index.AsRegister<GpuRegister>(), TIMES_2);
- __ Daddu(TMP, obj, TMP);
- __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset);
+ GpuRegister index_reg = index.AsRegister<GpuRegister>();
+ if (maybe_compressed_char_at) {
+ Mips64Label uncompressed_load, done;
+ __ Bnezc(TMP, &uncompressed_load);
+ __ Daddu(TMP, obj, index_reg);
+ __ LoadFromOffset(kLoadUnsignedByte, out, TMP, data_offset);
+ __ Bc(&done);
+ __ Bind(&uncompressed_load);
+ __ Dsll(TMP, index_reg, TIMES_2);
+ __ Daddu(TMP, obj, TMP);
+ __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset);
+ __ Bind(&done);
+ } else {
+ __ Dsll(TMP, index_reg, TIMES_2);
+ __ Daddu(TMP, obj, TMP);
+ __ LoadFromOffset(kLoadUnsignedHalfword, out, TMP, data_offset);
+ }
}
break;
}
@@ -1608,7 +1650,9 @@
LOG(FATAL) << "Unreachable type " << instruction->GetType();
UNREACHABLE();
}
- codegen_->MaybeRecordImplicitNullCheck(instruction);
+ if (!maybe_compressed_char_at) {
+ codegen_->MaybeRecordImplicitNullCheck(instruction);
+ }
}
void LocationsBuilderMIPS64::VisitArrayLength(HArrayLength* instruction) {
@@ -1624,6 +1668,10 @@
GpuRegister out = locations->Out().AsRegister<GpuRegister>();
__ LoadFromOffset(kLoadWord, out, obj, offset);
codegen_->MaybeRecordImplicitNullCheck(instruction);
+ // Mask out compression flag from String's array length.
+ if (mirror::kUseStringCompression && instruction->IsStringLength()) {
+ __ Srl(out, out, 1u);
+ }
}
void LocationsBuilderMIPS64::VisitArraySet(HArraySet* instruction) {
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc
index bbf826c..1047d3b 100644
--- a/compiler/optimizing/intrinsics_arm64.cc
+++ b/compiler/optimizing/intrinsics_arm64.cc
@@ -115,13 +115,18 @@
MoveArguments(invoke_, codegen);
- if (invoke_->IsInvokeStaticOrDirect()) {
- codegen->GenerateStaticOrDirectCall(invoke_->AsInvokeStaticOrDirect(),
- LocationFrom(kArtMethodRegister));
- } else {
- codegen->GenerateVirtualCall(invoke_->AsInvokeVirtual(), LocationFrom(kArtMethodRegister));
+ {
+ // Ensure that between the BLR (emitted by Generate*Call) and RecordPcInfo there
+ // are no pools emitted.
+ vixl::EmissionCheckScope guard(codegen->GetVIXLAssembler(), kInvokeCodeMarginSizeInBytes);
+ if (invoke_->IsInvokeStaticOrDirect()) {
+ codegen->GenerateStaticOrDirectCall(invoke_->AsInvokeStaticOrDirect(),
+ LocationFrom(kArtMethodRegister));
+ } else {
+ codegen->GenerateVirtualCall(invoke_->AsInvokeVirtual(), LocationFrom(kArtMethodRegister));
+ }
+ codegen->RecordPcInfo(invoke_, invoke_->GetDexPc(), this);
}
- codegen->RecordPcInfo(invoke_, invoke_->GetDexPc(), this);
// Copy the result back to the expected output.
Location out = invoke_->GetLocations()->Out();
@@ -980,11 +985,12 @@
CreateIntIntIntIntToVoid(arena_, invoke);
}
-static void GenUnsafePut(LocationSummary* locations,
+static void GenUnsafePut(HInvoke* invoke,
Primitive::Type type,
bool is_volatile,
bool is_ordered,
CodeGeneratorARM64* codegen) {
+ LocationSummary* locations = invoke->GetLocations();
MacroAssembler* masm = codegen->GetVIXLAssembler();
Register base = WRegisterFrom(locations->InAt(1)); // Object pointer.
@@ -1007,7 +1013,7 @@
}
if (is_volatile || is_ordered) {
- codegen->StoreRelease(type, source, mem_op);
+ codegen->StoreRelease(invoke, type, source, mem_op, /* needs_null_check */ false);
} else {
codegen->Store(type, source, mem_op);
}
@@ -1020,63 +1026,63 @@
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePut(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimInt,
/* is_volatile */ false,
/* is_ordered */ false,
codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePutOrdered(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimInt,
/* is_volatile */ false,
/* is_ordered */ true,
codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePutVolatile(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimInt,
/* is_volatile */ true,
/* is_ordered */ false,
codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePutObject(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimNot,
/* is_volatile */ false,
/* is_ordered */ false,
codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePutObjectOrdered(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimNot,
/* is_volatile */ false,
/* is_ordered */ true,
codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePutObjectVolatile(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimNot,
/* is_volatile */ true,
/* is_ordered */ false,
codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePutLong(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimLong,
/* is_volatile */ false,
/* is_ordered */ false,
codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePutLongOrdered(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimLong,
/* is_volatile */ false,
/* is_ordered */ true,
codegen_);
}
void IntrinsicCodeGeneratorARM64::VisitUnsafePutLongVolatile(HInvoke* invoke) {
- GenUnsafePut(invoke->GetLocations(),
+ GenUnsafePut(invoke,
Primitive::kPrimLong,
/* is_volatile */ true,
/* is_ordered */ false,
@@ -2825,9 +2831,13 @@
}
__ Cbnz(temp0, slow_path->GetEntryLabel());
- // Fast path.
- __ Ldr(out, HeapOperand(obj, mirror::Reference::ReferentOffset().Int32Value()));
- codegen_->MaybeRecordImplicitNullCheck(invoke);
+ {
+ // Ensure that between load and MaybeRecordImplicitNullCheck there are no pools emitted.
+ vixl::EmissionCheckScope guard(codegen_->GetVIXLAssembler(), kMaxMacroInstructionSizeInBytes);
+ // Fast path.
+ __ Ldr(out, HeapOperand(obj, mirror::Reference::ReferentOffset().Int32Value()));
+ codegen_->MaybeRecordImplicitNullCheck(invoke);
+ }
codegen_->GetAssembler()->MaybeUnpoisonHeapReference(out);
__ Bind(slow_path->GetExitLabel());
}
diff --git a/compiler/optimizing/intrinsics_mips.cc b/compiler/optimizing/intrinsics_mips.cc
index 6cf9b83..64a6840 100644
--- a/compiler/optimizing/intrinsics_mips.cc
+++ b/compiler/optimizing/intrinsics_mips.cc
@@ -2004,31 +2004,48 @@
__ Lw(temp2, arg, class_offset);
__ Bne(temp1, temp2, &return_false);
- // Load lengths of this and argument strings.
+ // Load `count` fields of this and argument strings.
__ Lw(temp1, str, count_offset);
__ Lw(temp2, arg, count_offset);
- // Check if lengths are equal, return false if they're not.
+ // Check if `count` fields are equal, return false if they're not.
+ // Also compares the compression style, if differs return false.
__ Bne(temp1, temp2, &return_false);
- // Return true if both strings are empty.
+ // Return true if both strings are empty. Even with string compression `count == 0` means empty.
+ static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u,
+ "Expecting 0=compressed, 1=uncompressed");
__ Beqz(temp1, &return_true);
// Don't overwrite input registers
__ Move(TMP, str);
__ Move(temp3, arg);
- // Assertions that must hold in order to compare strings 2 characters at a time.
+ // Assertions that must hold in order to compare strings 4 bytes at a time.
DCHECK_ALIGNED(value_offset, 4);
static_assert(IsAligned<4>(kObjectAlignment), "String of odd length is not zero padded");
- // Loop to compare strings 2 characters at a time starting at the beginning of the string.
- // Ok to do this because strings are zero-padded.
+ // For string compression, calculate the number of bytes to compare (not chars).
+ if (mirror::kUseStringCompression) {
+ // Extract compression flag.
+ if (IsR2OrNewer()) {
+ __ Ext(temp2, temp1, 0, 1);
+ } else {
+ __ Sll(temp2, temp1, 31);
+ __ Srl(temp2, temp2, 31);
+ }
+ __ Srl(temp1, temp1, 1); // Extract length.
+ __ Sllv(temp1, temp1, temp2); // Double the byte count if uncompressed.
+ }
+
+ // Loop to compare strings 4 bytes at a time starting at the beginning of the string.
+ // Ok to do this because strings are zero-padded to kObjectAlignment.
__ Bind(&loop);
__ Lw(out, TMP, value_offset);
__ Lw(temp2, temp3, value_offset);
__ Bne(out, temp2, &return_false);
__ Addiu(TMP, TMP, 4);
__ Addiu(temp3, temp3, 4);
- __ Addiu(temp1, temp1, -2);
+ // With string compression, we have compared 4 bytes, otherwise 2 chars.
+ __ Addiu(temp1, temp1, mirror::kUseStringCompression ? -4 : -2);
__ Bgtz(temp1, &loop);
// Return true and exit the function.
@@ -2578,6 +2595,30 @@
__ Addu(dstPtr, dstPtr, AT);
}
+ if (mirror::kUseStringCompression) {
+ MipsLabel uncompressed_copy, compressed_loop;
+ const uint32_t count_offset = mirror::String::CountOffset().Uint32Value();
+ // Load count field and extract compression flag.
+ __ LoadFromOffset(kLoadWord, TMP, srcObj, count_offset);
+ __ Sll(TMP, TMP, 31);
+
+ // If string is uncompressed, use memcpy() path.
+ __ Bnez(TMP, &uncompressed_copy);
+
+ // Copy loop for compressed src, copying 1 character (8-bit) to (16-bit) at a time.
+ __ Addu(srcPtr, srcObj, srcBegin);
+ __ Bind(&compressed_loop);
+ __ LoadFromOffset(kLoadUnsignedByte, TMP, srcPtr, value_offset);
+ __ StoreToOffset(kStoreHalfword, TMP, dstPtr, 0);
+ __ Addiu(numChrs, numChrs, -1);
+ __ Addiu(srcPtr, srcPtr, 1);
+ __ Addiu(dstPtr, dstPtr, 2);
+ __ Bnez(numChrs, &compressed_loop);
+
+ __ B(&done);
+ __ Bind(&uncompressed_copy);
+ }
+
// Calculate source address.
__ Addiu(srcPtr, srcObj, value_offset);
if (IsR6()) {
diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc
index 00a1fa1..3888828 100644
--- a/compiler/optimizing/intrinsics_mips64.cc
+++ b/compiler/optimizing/intrinsics_mips64.cc
@@ -1607,31 +1607,42 @@
__ Lw(temp2, arg, class_offset);
__ Bnec(temp1, temp2, &return_false);
- // Load lengths of this and argument strings.
+ // Load `count` fields of this and argument strings.
__ Lw(temp1, str, count_offset);
__ Lw(temp2, arg, count_offset);
- // Check if lengths are equal, return false if they're not.
+ // Check if `count` fields are equal, return false if they're not.
+ // Also compares the compression style, if differs return false.
__ Bnec(temp1, temp2, &return_false);
- // Return true if both strings are empty.
+ // Return true if both strings are empty. Even with string compression `count == 0` means empty.
+ static_assert(static_cast<uint32_t>(mirror::StringCompressionFlag::kCompressed) == 0u,
+ "Expecting 0=compressed, 1=uncompressed");
__ Beqzc(temp1, &return_true);
// Don't overwrite input registers
__ Move(TMP, str);
__ Move(temp3, arg);
- // Assertions that must hold in order to compare strings 4 characters at a time.
+ // Assertions that must hold in order to compare strings 8 bytes at a time.
DCHECK_ALIGNED(value_offset, 8);
static_assert(IsAligned<8>(kObjectAlignment), "String of odd length is not zero padded");
- // Loop to compare strings 4 characters at a time starting at the beginning of the string.
- // Ok to do this because strings are zero-padded to be 8-byte aligned.
+ if (mirror::kUseStringCompression) {
+ // For string compression, calculate the number of bytes to compare (not chars).
+ __ Dext(temp2, temp1, 0, 1); // Extract compression flag.
+ __ Srl(temp1, temp1, 1); // Extract length.
+ __ Sllv(temp1, temp1, temp2); // Double the byte count if uncompressed.
+ }
+
+ // Loop to compare strings 8 bytes at a time starting at the beginning of the string.
+ // Ok to do this because strings are zero-padded to kObjectAlignment.
__ Bind(&loop);
__ Ld(out, TMP, value_offset);
__ Ld(temp2, temp3, value_offset);
__ Bnec(out, temp2, &return_false);
__ Daddiu(TMP, TMP, 8);
__ Daddiu(temp3, temp3, 8);
- __ Addiu(temp1, temp1, -4);
+ // With string compression, we have compared 8 bytes, otherwise 4 chars.
+ __ Addiu(temp1, temp1, mirror::kUseStringCompression ? -8 : -4);
__ Bgtzc(temp1, &loop);
// Return true and exit the function.
@@ -1912,6 +1923,30 @@
__ Daddiu(dstPtr, dstObj, data_offset);
__ Dlsa(dstPtr, dstBegin, dstPtr, char_shift);
+ if (mirror::kUseStringCompression) {
+ Mips64Label uncompressed_copy, compressed_loop;
+ const uint32_t count_offset = mirror::String::CountOffset().Uint32Value();
+ // Load count field and extract compression flag.
+ __ LoadFromOffset(kLoadWord, TMP, srcObj, count_offset);
+ __ Dext(TMP, TMP, 0, 1);
+
+ // If string is uncompressed, use memcpy() path.
+ __ Bnezc(TMP, &uncompressed_copy);
+
+ // Copy loop for compressed src, copying 1 character (8-bit) to (16-bit) at a time.
+ __ Daddu(srcPtr, srcObj, srcBegin);
+ __ Bind(&compressed_loop);
+ __ LoadFromOffset(kLoadUnsignedByte, TMP, srcPtr, value_offset);
+ __ StoreToOffset(kStoreHalfword, TMP, dstPtr, 0);
+ __ Daddiu(numChrs, numChrs, -1);
+ __ Daddiu(srcPtr, srcPtr, 1);
+ __ Daddiu(dstPtr, dstPtr, 2);
+ __ Bnezc(numChrs, &compressed_loop);
+
+ __ Bc(&done);
+ __ Bind(&uncompressed_copy);
+ }
+
// Calculate source address.
__ Daddiu(srcPtr, srcObj, value_offset);
__ Dlsa(srcPtr, srcBegin, srcPtr, char_shift);
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index f8e01b7..1bcc8e1 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -38,19 +38,14 @@
current_entry_.native_pc_code_offset = CodeOffset::FromOffset(native_pc_offset, instruction_set_);
current_entry_.register_mask = register_mask;
current_entry_.sp_mask = sp_mask;
- current_entry_.num_dex_registers = num_dex_registers;
current_entry_.inlining_depth = inlining_depth;
- current_entry_.dex_register_locations_start_index = dex_register_locations_.size();
current_entry_.inline_infos_start_index = inline_infos_.size();
- current_entry_.dex_register_map_hash = 0;
- current_entry_.same_dex_register_map_as_ = kNoSameDexMapFound;
current_entry_.stack_mask_index = 0;
- if (num_dex_registers != 0) {
- current_entry_.live_dex_registers_mask =
- ArenaBitVector::Create(allocator_, num_dex_registers, true, kArenaAllocStackMapStream);
- } else {
- current_entry_.live_dex_registers_mask = nullptr;
- }
+ current_entry_.dex_register_entry.num_dex_registers = num_dex_registers;
+ current_entry_.dex_register_entry.locations_start_index = dex_register_locations_.size();
+ current_entry_.dex_register_entry.live_dex_registers_mask = (num_dex_registers != 0)
+ ? ArenaBitVector::Create(allocator_, num_dex_registers, true, kArenaAllocStackMapStream)
+ : nullptr;
if (sp_mask != nullptr) {
stack_mask_max_ = std::max(stack_mask_max_, sp_mask->GetHighestBitSet());
@@ -65,7 +60,7 @@
}
void StackMapStream::EndStackMapEntry() {
- current_entry_.same_dex_register_map_as_ = FindEntryWithTheSameDexMap();
+ current_entry_.dex_register_map_index = AddDexRegisterMapEntry(current_entry_.dex_register_entry);
stack_maps_.push_back(current_entry_);
current_entry_ = StackMapEntry();
}
@@ -91,19 +86,15 @@
dex_register_locations_.push_back(index);
location_catalog_entries_indices_.Insert(std::make_pair(location, index));
}
-
- if (in_inline_frame_) {
- // TODO: Support sharing DexRegisterMap across InlineInfo.
- DCHECK_LT(current_dex_register_, current_inline_info_.num_dex_registers);
- current_inline_info_.live_dex_registers_mask->SetBit(current_dex_register_);
- } else {
- DCHECK_LT(current_dex_register_, current_entry_.num_dex_registers);
- current_entry_.live_dex_registers_mask->SetBit(current_dex_register_);
- current_entry_.dex_register_map_hash += (1 <<
- (current_dex_register_ % (sizeof(current_entry_.dex_register_map_hash) * kBitsPerByte)));
- current_entry_.dex_register_map_hash += static_cast<uint32_t>(value);
- current_entry_.dex_register_map_hash += static_cast<uint32_t>(kind);
- }
+ DexRegisterMapEntry* const entry = in_inline_frame_
+ ? ¤t_inline_info_.dex_register_entry
+ : ¤t_entry_.dex_register_entry;
+ DCHECK_LT(current_dex_register_, entry->num_dex_registers);
+ entry->live_dex_registers_mask->SetBit(current_dex_register_);
+ entry->hash += (1 <<
+ (current_dex_register_ % (sizeof(DexRegisterMapEntry::hash) * kBitsPerByte)));
+ entry->hash += static_cast<uint32_t>(value);
+ entry->hash += static_cast<uint32_t>(kind);
}
current_dex_register_++;
}
@@ -124,20 +115,19 @@
current_inline_info_.method_index = method->GetDexMethodIndexUnchecked();
}
current_inline_info_.dex_pc = dex_pc;
- current_inline_info_.num_dex_registers = num_dex_registers;
- current_inline_info_.dex_register_locations_start_index = dex_register_locations_.size();
- if (num_dex_registers != 0) {
- current_inline_info_.live_dex_registers_mask =
- ArenaBitVector::Create(allocator_, num_dex_registers, true, kArenaAllocStackMapStream);
- } else {
- current_inline_info_.live_dex_registers_mask = nullptr;
- }
+ current_inline_info_.dex_register_entry.num_dex_registers = num_dex_registers;
+ current_inline_info_.dex_register_entry.locations_start_index = dex_register_locations_.size();
+ current_inline_info_.dex_register_entry.live_dex_registers_mask = (num_dex_registers != 0)
+ ? ArenaBitVector::Create(allocator_, num_dex_registers, true, kArenaAllocStackMapStream)
+ : nullptr;
current_dex_register_ = 0;
}
void StackMapStream::EndInlineInfoEntry() {
+ current_inline_info_.dex_register_map_index =
+ AddDexRegisterMapEntry(current_inline_info_.dex_register_entry);
DCHECK(in_inline_frame_);
- DCHECK_EQ(current_dex_register_, current_inline_info_.num_dex_registers)
+ DCHECK_EQ(current_dex_register_, current_inline_info_.dex_register_entry.num_dex_registers)
<< "Inline information contains less registers than expected";
in_inline_frame_ = false;
inline_infos_.push_back(current_inline_info_);
@@ -193,8 +183,7 @@
return size;
}
-size_t StackMapStream::ComputeDexRegisterMapSize(uint32_t num_dex_registers,
- const BitVector* live_dex_registers_mask) const {
+size_t StackMapStream::DexRegisterMapEntry::ComputeSize(size_t catalog_size) const {
// For num_dex_registers == 0u live_dex_registers_mask may be null.
if (num_dex_registers == 0u) {
return 0u; // No register map will be emitted.
@@ -208,8 +197,7 @@
// Compute the size of the set of live Dex register entries.
size_t number_of_live_dex_registers = live_dex_registers_mask->NumSetBits();
size_t map_entries_size_in_bits =
- DexRegisterMap::SingleEntrySizeInBits(location_catalog_entries_.size())
- * number_of_live_dex_registers;
+ DexRegisterMap::SingleEntrySizeInBits(catalog_size) * number_of_live_dex_registers;
size_t map_entries_size_in_bytes =
RoundUp(map_entries_size_in_bits, kBitsPerByte) / kBitsPerByte;
size += map_entries_size_in_bytes;
@@ -218,18 +206,8 @@
size_t StackMapStream::ComputeDexRegisterMapsSize() const {
size_t size = 0;
- size_t inline_info_index = 0;
- for (const StackMapEntry& entry : stack_maps_) {
- if (entry.same_dex_register_map_as_ == kNoSameDexMapFound) {
- size += ComputeDexRegisterMapSize(entry.num_dex_registers, entry.live_dex_registers_mask);
- } else {
- // Entries with the same dex map will have the same offset.
- }
- for (size_t j = 0; j < entry.inlining_depth; ++j) {
- InlineInfoEntry inline_entry = inline_infos_[inline_info_index++];
- size += ComputeDexRegisterMapSize(inline_entry.num_dex_registers,
- inline_entry.live_dex_registers_mask);
- }
+ for (const DexRegisterMapEntry& entry : dex_register_entries_) {
+ size += entry.ComputeSize(location_catalog_entries_.size());
}
return size;
}
@@ -264,6 +242,30 @@
encoding->SetFromSizes(method_index_max, dex_pc_max, extra_data_max, dex_register_maps_bytes);
}
+size_t StackMapStream::MaybeCopyDexRegisterMap(DexRegisterMapEntry& entry,
+ size_t* current_offset,
+ MemoryRegion dex_register_locations_region) {
+ DCHECK(current_offset != nullptr);
+ if ((entry.num_dex_registers == 0) || (entry.live_dex_registers_mask->NumSetBits() == 0)) {
+ // No dex register map needed.
+ return StackMap::kNoDexRegisterMap;
+ }
+ if (entry.offset == DexRegisterMapEntry::kOffsetUnassigned) {
+ // Not already copied, need to copy and and assign an offset.
+ entry.offset = *current_offset;
+ const size_t entry_size = entry.ComputeSize(location_catalog_entries_.size());
+ DexRegisterMap dex_register_map(
+ dex_register_locations_region.Subregion(entry.offset, entry_size));
+ *current_offset += entry_size;
+ // Fill in the map since it was just added.
+ FillInDexRegisterMap(dex_register_map,
+ entry.num_dex_registers,
+ *entry.live_dex_registers_mask,
+ entry.locations_start_index);
+ }
+ return entry.offset;
+}
+
void StackMapStream::FillIn(MemoryRegion region) {
DCHECK_EQ(0u, current_entry_.dex_pc) << "EndStackMapEntry not called after BeginStackMapEntry";
DCHECK_NE(0u, needed_size_) << "PrepareForFillIn not called before FillIn";
@@ -311,35 +313,10 @@
stack_map.SetRegisterMaskIndex(encoding.stack_map.encoding, entry.register_mask_index);
stack_map.SetStackMaskIndex(encoding.stack_map.encoding, entry.stack_mask_index);
- if (entry.num_dex_registers == 0 || (entry.live_dex_registers_mask->NumSetBits() == 0)) {
- // No dex map available.
- stack_map.SetDexRegisterMapOffset(encoding.stack_map.encoding, StackMap::kNoDexRegisterMap);
- } else {
- // Search for an entry with the same dex map.
- if (entry.same_dex_register_map_as_ != kNoSameDexMapFound) {
- // If we have a hit reuse the offset.
- stack_map.SetDexRegisterMapOffset(
- encoding.stack_map.encoding,
- code_info.GetStackMapAt(entry.same_dex_register_map_as_, encoding)
- .GetDexRegisterMapOffset(encoding.stack_map.encoding));
- } else {
- // New dex registers maps should be added to the stack map.
- MemoryRegion register_region = dex_register_locations_region.Subregion(
- next_dex_register_map_offset,
- ComputeDexRegisterMapSize(entry.num_dex_registers, entry.live_dex_registers_mask));
- next_dex_register_map_offset += register_region.size();
- DexRegisterMap dex_register_map(register_region);
- stack_map.SetDexRegisterMapOffset(
- encoding.stack_map.encoding,
- register_region.begin() - dex_register_locations_region.begin());
-
- // Set the dex register location.
- FillInDexRegisterMap(dex_register_map,
- entry.num_dex_registers,
- *entry.live_dex_registers_mask,
- entry.dex_register_locations_start_index);
- }
- }
+ size_t offset = MaybeCopyDexRegisterMap(dex_register_entries_[entry.dex_register_map_index],
+ &next_dex_register_map_offset,
+ dex_register_locations_region);
+ stack_map.SetDexRegisterMapOffset(encoding.stack_map.encoding, offset);
// Set the inlining info.
if (entry.inlining_depth != 0) {
@@ -371,29 +348,13 @@
inline_info.SetExtraDataAtDepth(encoding.inline_info.encoding, depth, 1);
}
inline_info.SetDexPcAtDepth(encoding.inline_info.encoding, depth, inline_entry.dex_pc);
- if (inline_entry.num_dex_registers == 0) {
- // No dex map available.
- inline_info.SetDexRegisterMapOffsetAtDepth(encoding.inline_info.encoding,
- depth,
- StackMap::kNoDexRegisterMap);
- DCHECK(inline_entry.live_dex_registers_mask == nullptr);
- } else {
- MemoryRegion register_region = dex_register_locations_region.Subregion(
- next_dex_register_map_offset,
- ComputeDexRegisterMapSize(inline_entry.num_dex_registers,
- inline_entry.live_dex_registers_mask));
- next_dex_register_map_offset += register_region.size();
- DexRegisterMap dex_register_map(register_region);
- inline_info.SetDexRegisterMapOffsetAtDepth(
- encoding.inline_info.encoding,
- depth,
- register_region.begin() - dex_register_locations_region.begin());
-
- FillInDexRegisterMap(dex_register_map,
- inline_entry.num_dex_registers,
- *inline_entry.live_dex_registers_mask,
- inline_entry.dex_register_locations_start_index);
- }
+ size_t dex_register_map_offset = MaybeCopyDexRegisterMap(
+ dex_register_entries_[inline_entry.dex_register_map_index],
+ &next_dex_register_map_offset,
+ dex_register_locations_region);
+ inline_info.SetDexRegisterMapOffsetAtDepth(encoding.inline_info.encoding,
+ depth,
+ dex_register_map_offset);
}
} else if (encoding.stack_map.encoding.GetInlineInfoEncoding().BitSize() > 0) {
stack_map.SetInlineInfoIndex(encoding.stack_map.encoding, StackMap::kNoInlineInfo);
@@ -448,34 +409,31 @@
}
}
-size_t StackMapStream::FindEntryWithTheSameDexMap() {
- size_t current_entry_index = stack_maps_.size();
- auto entries_it = dex_map_hash_to_stack_map_indices_.find(current_entry_.dex_register_map_hash);
+size_t StackMapStream::AddDexRegisterMapEntry(const DexRegisterMapEntry& entry) {
+ const size_t current_entry_index = dex_register_entries_.size();
+ auto entries_it = dex_map_hash_to_stack_map_indices_.find(entry.hash);
if (entries_it == dex_map_hash_to_stack_map_indices_.end()) {
// We don't have a perfect hash functions so we need a list to collect all stack maps
// which might have the same dex register map.
ArenaVector<uint32_t> stack_map_indices(allocator_->Adapter(kArenaAllocStackMapStream));
stack_map_indices.push_back(current_entry_index);
- dex_map_hash_to_stack_map_indices_.Put(current_entry_.dex_register_map_hash,
- std::move(stack_map_indices));
- return kNoSameDexMapFound;
- }
-
- // We might have collisions, so we need to check whether or not we really have a match.
- for (uint32_t test_entry_index : entries_it->second) {
- if (HaveTheSameDexMaps(GetStackMap(test_entry_index), current_entry_)) {
- return test_entry_index;
+ dex_map_hash_to_stack_map_indices_.Put(entry.hash, std::move(stack_map_indices));
+ } else {
+ // We might have collisions, so we need to check whether or not we really have a match.
+ for (uint32_t test_entry_index : entries_it->second) {
+ if (DexRegisterMapEntryEquals(dex_register_entries_[test_entry_index], entry)) {
+ return test_entry_index;
+ }
}
+ entries_it->second.push_back(current_entry_index);
}
- entries_it->second.push_back(current_entry_index);
- return kNoSameDexMapFound;
+ dex_register_entries_.push_back(entry);
+ return current_entry_index;
}
-bool StackMapStream::HaveTheSameDexMaps(const StackMapEntry& a, const StackMapEntry& b) const {
- if (a.live_dex_registers_mask == nullptr && b.live_dex_registers_mask == nullptr) {
- return true;
- }
- if (a.live_dex_registers_mask == nullptr || b.live_dex_registers_mask == nullptr) {
+bool StackMapStream::DexRegisterMapEntryEquals(const DexRegisterMapEntry& a,
+ const DexRegisterMapEntry& b) const {
+ if ((a.live_dex_registers_mask == nullptr) != (b.live_dex_registers_mask == nullptr)) {
return false;
}
if (a.num_dex_registers != b.num_dex_registers) {
@@ -489,12 +447,12 @@
}
size_t number_of_live_dex_registers = a.live_dex_registers_mask->NumSetBits();
DCHECK_LE(number_of_live_dex_registers, dex_register_locations_.size());
- DCHECK_LE(a.dex_register_locations_start_index,
+ DCHECK_LE(a.locations_start_index,
dex_register_locations_.size() - number_of_live_dex_registers);
- DCHECK_LE(b.dex_register_locations_start_index,
+ DCHECK_LE(b.locations_start_index,
dex_register_locations_.size() - number_of_live_dex_registers);
- auto a_begin = dex_register_locations_.begin() + a.dex_register_locations_start_index;
- auto b_begin = dex_register_locations_.begin() + b.dex_register_locations_start_index;
+ auto a_begin = dex_register_locations_.begin() + a.locations_start_index;
+ auto b_begin = dex_register_locations_.begin() + b.locations_start_index;
if (!std::equal(a_begin, a_begin + number_of_live_dex_registers, b_begin)) {
return false;
}
@@ -597,10 +555,10 @@
CheckDexRegisterMap(code_info,
code_info.GetDexRegisterMapOf(
- stack_map, encoding, entry.num_dex_registers),
- entry.num_dex_registers,
- entry.live_dex_registers_mask,
- entry.dex_register_locations_start_index);
+ stack_map, encoding, entry.dex_register_entry.num_dex_registers),
+ entry.dex_register_entry.num_dex_registers,
+ entry.dex_register_entry.live_dex_registers_mask,
+ entry.dex_register_entry.locations_start_index);
// Check inline info.
DCHECK_EQ(stack_map.HasInlineInfo(stack_map_encoding), (entry.inlining_depth != 0));
@@ -623,10 +581,13 @@
CheckDexRegisterMap(code_info,
code_info.GetDexRegisterMapAtDepth(
- d, inline_info, encoding, inline_entry.num_dex_registers),
- inline_entry.num_dex_registers,
- inline_entry.live_dex_registers_mask,
- inline_entry.dex_register_locations_start_index);
+ d,
+ inline_info,
+ encoding,
+ inline_entry.dex_register_entry.num_dex_registers),
+ inline_entry.dex_register_entry.num_dex_registers,
+ inline_entry.dex_register_entry.live_dex_registers_mask,
+ inline_entry.dex_register_entry.locations_start_index);
}
}
}
diff --git a/compiler/optimizing/stack_map_stream.h b/compiler/optimizing/stack_map_stream.h
index 08c1d3e..bba3d51 100644
--- a/compiler/optimizing/stack_map_stream.h
+++ b/compiler/optimizing/stack_map_stream.h
@@ -70,6 +70,7 @@
inline_infos_(allocator->Adapter(kArenaAllocStackMapStream)),
stack_masks_(allocator->Adapter(kArenaAllocStackMapStream)),
register_masks_(allocator->Adapter(kArenaAllocStackMapStream)),
+ dex_register_entries_(allocator->Adapter(kArenaAllocStackMapStream)),
stack_mask_max_(-1),
dex_pc_max_(0),
register_mask_max_(0),
@@ -89,30 +90,42 @@
code_info_encoding_.reserve(16);
}
+ // A dex register map entry for a single stack map entry, contains what registers are live as
+ // well as indices into the location catalog.
+ class DexRegisterMapEntry {
+ public:
+ static const size_t kOffsetUnassigned = -1;
+
+ BitVector* live_dex_registers_mask;
+ uint32_t num_dex_registers;
+ size_t locations_start_index;
+ // Computed fields
+ size_t hash = 0;
+ size_t offset = kOffsetUnassigned;
+
+ size_t ComputeSize(size_t catalog_size) const;
+ };
+
// See runtime/stack_map.h to know what these fields contain.
struct StackMapEntry {
uint32_t dex_pc;
CodeOffset native_pc_code_offset;
uint32_t register_mask;
BitVector* sp_mask;
- uint32_t num_dex_registers;
uint8_t inlining_depth;
- size_t dex_register_locations_start_index;
size_t inline_infos_start_index;
- BitVector* live_dex_registers_mask;
- uint32_t dex_register_map_hash;
- size_t same_dex_register_map_as_;
uint32_t stack_mask_index;
uint32_t register_mask_index;
+ DexRegisterMapEntry dex_register_entry;
+ size_t dex_register_map_index;
};
struct InlineInfoEntry {
uint32_t dex_pc; // DexFile::kDexNoIndex for intrinsified native methods.
ArtMethod* method;
uint32_t method_index;
- uint32_t num_dex_registers;
- BitVector* live_dex_registers_mask;
- size_t dex_register_locations_start_index;
+ DexRegisterMapEntry dex_register_entry;
+ size_t dex_register_map_index;
};
void BeginStackMapEntry(uint32_t dex_pc,
@@ -140,7 +153,8 @@
}
void SetStackMapNativePcOffset(size_t i, uint32_t native_pc_offset) {
- stack_maps_[i].native_pc_code_offset = CodeOffset::FromOffset(native_pc_offset, instruction_set_);
+ stack_maps_[i].native_pc_code_offset =
+ CodeOffset::FromOffset(native_pc_offset, instruction_set_);
}
// Prepares the stream to fill in a memory region. Must be called before FillIn.
@@ -150,8 +164,6 @@
private:
size_t ComputeDexRegisterLocationCatalogSize() const;
- size_t ComputeDexRegisterMapSize(uint32_t num_dex_registers,
- const BitVector* live_dex_registers_mask) const;
size_t ComputeDexRegisterMapsSize() const;
void ComputeInlineInfoEncoding(InlineInfoEncoding* encoding,
size_t dex_register_maps_bytes);
@@ -164,15 +176,24 @@
// Returns the number of unique register masks.
size_t PrepareRegisterMasks();
- // Returns the index of an entry with the same dex register map as the current_entry,
- // or kNoSameDexMapFound if no such entry exists.
- size_t FindEntryWithTheSameDexMap();
- bool HaveTheSameDexMaps(const StackMapEntry& a, const StackMapEntry& b) const;
+ // Deduplicate entry if possible and return the corresponding index into dex_register_entries_
+ // array. If entry is not a duplicate, a new entry is added to dex_register_entries_.
+ size_t AddDexRegisterMapEntry(const DexRegisterMapEntry& entry);
+
+ // Return true if the two dex register map entries are equal.
+ bool DexRegisterMapEntryEquals(const DexRegisterMapEntry& a, const DexRegisterMapEntry& b) const;
+
+ // Fill in the corresponding entries of a register map.
void FillInDexRegisterMap(DexRegisterMap dex_register_map,
uint32_t num_dex_registers,
const BitVector& live_dex_registers_mask,
uint32_t start_index_in_dex_register_locations) const;
+ // Returns the offset for the dex register inside of the dex register location region. See FillIn.
+ // Only copies the dex register map if the offset for the entry is not already assigned.
+ size_t MaybeCopyDexRegisterMap(DexRegisterMapEntry& entry,
+ size_t* current_offset,
+ MemoryRegion dex_register_locations_region);
void CheckDexRegisterMap(const CodeInfo& code_info,
const DexRegisterMap& dex_register_map,
size_t num_dex_registers,
@@ -199,6 +220,7 @@
ArenaVector<InlineInfoEntry> inline_infos_;
ArenaVector<uint8_t> stack_masks_;
ArenaVector<uint32_t> register_masks_;
+ ArenaVector<DexRegisterMapEntry> dex_register_entries_;
int stack_mask_max_;
uint32_t dex_pc_max_;
uint32_t register_mask_max_;
diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc
index bd0aa6d..0416951 100644
--- a/compiler/optimizing/stack_map_test.cc
+++ b/compiler/optimizing/stack_map_test.cc
@@ -410,6 +410,100 @@
}
}
+TEST(StackMapTest, TestDeduplicateInlineInfoDexRegisterMap) {
+ ArenaPool pool;
+ ArenaAllocator arena(&pool);
+ StackMapStream stream(&arena, kRuntimeISA);
+ ArtMethod art_method;
+
+ ArenaBitVector sp_mask1(&arena, 0, true);
+ sp_mask1.SetBit(2);
+ sp_mask1.SetBit(4);
+ const size_t number_of_dex_registers = 2;
+ const size_t number_of_dex_registers_in_inline_info = 2;
+ stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 1);
+ stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
+ stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
+ stream.BeginInlineInfoEntry(&art_method, 3, number_of_dex_registers_in_inline_info);
+ stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location.
+ stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location.
+ stream.EndInlineInfoEntry();
+ stream.EndStackMapEntry();
+
+ size_t size = stream.PrepareForFillIn();
+ void* memory = arena.Alloc(size, kArenaAllocMisc);
+ MemoryRegion region(memory, size);
+ stream.FillIn(region);
+
+ CodeInfo code_info(region);
+ CodeInfoEncoding encoding = code_info.ExtractEncoding();
+ ASSERT_EQ(1u, code_info.GetNumberOfStackMaps(encoding));
+
+ uint32_t number_of_catalog_entries = code_info.GetNumberOfLocationCatalogEntries(encoding);
+ ASSERT_EQ(2u, number_of_catalog_entries);
+ DexRegisterLocationCatalog location_catalog = code_info.GetDexRegisterLocationCatalog(encoding);
+ // The Dex register location catalog contains:
+ // - one 1-byte short Dex register locations, and
+ // - one 5-byte large Dex register location.
+ const size_t expected_location_catalog_size = 1u + 5u;
+ ASSERT_EQ(expected_location_catalog_size, location_catalog.Size());
+
+ // First stack map.
+ {
+ StackMap stack_map = code_info.GetStackMapAt(0, encoding);
+ ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0, encoding)));
+ ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64, encoding)));
+ ASSERT_EQ(0u, stack_map.GetDexPc(encoding.stack_map.encoding));
+ ASSERT_EQ(64u, stack_map.GetNativePcOffset(encoding.stack_map.encoding, kRuntimeISA));
+ ASSERT_EQ(0x3u, code_info.GetRegisterMaskOf(encoding, stack_map));
+
+ ASSERT_TRUE(CheckStackMask(code_info, encoding, stack_map, sp_mask1));
+
+ ASSERT_TRUE(stack_map.HasDexRegisterMap(encoding.stack_map.encoding));
+ DexRegisterMap map(code_info.GetDexRegisterMapOf(stack_map, encoding, number_of_dex_registers));
+ ASSERT_TRUE(map.IsDexRegisterLive(0));
+ ASSERT_TRUE(map.IsDexRegisterLive(1));
+ ASSERT_EQ(2u, map.GetNumberOfLiveDexRegisters(number_of_dex_registers));
+ // The Dex register map contains:
+ // - one 1-byte live bit mask, and
+ // - one 1-byte set of location catalog entry indices composed of two 2-bit values.
+ size_t expected_map_size = 1u + 1u;
+ ASSERT_EQ(expected_map_size, map.Size());
+
+ ASSERT_EQ(Kind::kInStack, map.GetLocationKind(0, number_of_dex_registers, code_info, encoding));
+ ASSERT_EQ(Kind::kConstant,
+ map.GetLocationKind(1, number_of_dex_registers, code_info, encoding));
+ ASSERT_EQ(Kind::kInStack,
+ map.GetLocationInternalKind(0, number_of_dex_registers, code_info, encoding));
+ ASSERT_EQ(Kind::kConstantLargeValue,
+ map.GetLocationInternalKind(1, number_of_dex_registers, code_info, encoding));
+ ASSERT_EQ(0, map.GetStackOffsetInBytes(0, number_of_dex_registers, code_info, encoding));
+ ASSERT_EQ(-2, map.GetConstant(1, number_of_dex_registers, code_info, encoding));
+
+ const size_t index0 =
+ map.GetLocationCatalogEntryIndex(0, number_of_dex_registers, number_of_catalog_entries);
+ const size_t index1 =
+ map.GetLocationCatalogEntryIndex(1, number_of_dex_registers, number_of_catalog_entries);
+ ASSERT_EQ(0u, index0);
+ ASSERT_EQ(1u, index1);
+ DexRegisterLocation location0 = location_catalog.GetDexRegisterLocation(index0);
+ DexRegisterLocation location1 = location_catalog.GetDexRegisterLocation(index1);
+ ASSERT_EQ(Kind::kInStack, location0.GetKind());
+ ASSERT_EQ(Kind::kConstant, location1.GetKind());
+ ASSERT_EQ(Kind::kInStack, location0.GetInternalKind());
+ ASSERT_EQ(Kind::kConstantLargeValue, location1.GetInternalKind());
+ ASSERT_EQ(0, location0.GetValue());
+ ASSERT_EQ(-2, location1.GetValue());
+
+ // Test that the inline info dex register map deduplicated to the same offset as the stack map
+ // one.
+ ASSERT_TRUE(stack_map.HasInlineInfo(encoding.stack_map.encoding));
+ InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map, encoding);
+ EXPECT_EQ(inline_info.GetDexRegisterMapOffsetAtDepth(encoding.inline_info.encoding, 0),
+ stack_map.GetDexRegisterMapOffset(encoding.stack_map.encoding));
+ }
+}
+
TEST(StackMapTest, TestNonLiveDexRegisters) {
ArenaPool pool;
ArenaAllocator arena(&pool);
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index c2275ac..e208337 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -231,7 +231,7 @@
}
virtual std::string GetTestDexFileName() {
- return GetDexSrc1();
+ return Dex2oatEnvironmentTest::GetTestDexFileName("VerifierDeps");
}
virtual void CheckResult(bool expect_use) {
@@ -399,11 +399,6 @@
};
TEST_F(Dex2oatSwapUseTest, CheckSwapUsage) {
- // The `native_alloc_2_ >= native_alloc_1_` assertion below may not
- // hold true on some x86 systems when read barriers are enabled;
- // disable this test while we investigate (b/29259363).
- TEST_DISABLED_FOR_READ_BARRIER_ON_X86();
-
RunTest(false /* use_fd */,
false /* expect_use */);
GrabResult1();
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index a6c3cf0..d395c17 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -94,6 +94,54 @@
std::string error;
return ExecAndReturnCode(argv_str, &error);
}
+
+ bool CreateProfile(std::string class_file_contents, const std::string& filename) {
+ ScratchFile class_names_file;
+ File* file = class_names_file.GetFile();
+ EXPECT_TRUE(file->WriteFully(class_file_contents.c_str(), class_file_contents.length()));
+ EXPECT_EQ(0, file->Flush());
+ EXPECT_TRUE(file->ResetOffset());
+ std::string profman_cmd = GetProfmanCmd();
+ std::vector<std::string> argv_str;
+ argv_str.push_back(profman_cmd);
+ argv_str.push_back("--create-profile-from=" + class_names_file.GetFilename());
+ argv_str.push_back("--reference-profile-file=" + filename);
+ argv_str.push_back("--apk=" + GetLibCoreDexFileNames()[0]);
+ argv_str.push_back("--dex-location=classes.dex");
+ std::string error;
+ EXPECT_EQ(ExecAndReturnCode(argv_str, &error), 0);
+ return true;
+ }
+
+ bool DumpClasses(const std::string& filename, std::string* file_contents) {
+ ScratchFile class_names_file;
+ std::string profman_cmd = GetProfmanCmd();
+ std::vector<std::string> argv_str;
+ argv_str.push_back(profman_cmd);
+ argv_str.push_back("--dump-classes");
+ argv_str.push_back("--profile-file=" + filename);
+ argv_str.push_back("--apk=" + GetLibCoreDexFileNames()[0]);
+ argv_str.push_back("--dex-location=classes.dex");
+ argv_str.push_back("--dump-output-to-fd=" + std::to_string(GetFd(class_names_file)));
+ std::string error;
+ EXPECT_EQ(ExecAndReturnCode(argv_str, &error), 0);
+ File* file = class_names_file.GetFile();
+ EXPECT_EQ(0, file->Flush());
+ EXPECT_TRUE(file->ResetOffset());
+ int64_t length = file->GetLength();
+ std::unique_ptr<char[]> buf(new char[length]);
+ EXPECT_EQ(file->Read(buf.get(), length, 0), length);
+ *file_contents = std::string(buf.get(), length);
+ return true;
+ }
+
+ bool CreateAndDump(const std::string& input_file_contents, std::string* output_file_contents) {
+ ScratchFile profile_file;
+ EXPECT_TRUE(CreateProfile(input_file_contents, profile_file.GetFilename()));
+ profile_file.GetFile()->ResetOffset();
+ EXPECT_TRUE(DumpClasses(profile_file.GetFilename(), output_file_contents));
+ return true;
+ }
};
TEST_F(ProfileAssistantTest, AdviseCompilationEmptyReferences) {
@@ -307,4 +355,55 @@
ASSERT_TRUE(info.Load(GetFd(profile)));
}
+TEST_F(ProfileAssistantTest, TestProfileCreationAllMatch) {
+ // Class names put here need to be in sorted order.
+ std::vector<std::string> class_names = {
+ "java.lang.Comparable",
+ "java.lang.Math",
+ "java.lang.Object"
+ };
+ std::string input_file_contents;
+ for (std::string& class_name : class_names) {
+ input_file_contents += class_name + std::string("\n");
+ }
+ std::string output_file_contents;
+ ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents));
+ ASSERT_EQ(output_file_contents, input_file_contents);
+}
+
+TEST_F(ProfileAssistantTest, TestProfileCreationOneNotMatched) {
+ // Class names put here need to be in sorted order.
+ std::vector<std::string> class_names = {
+ "doesnt.match.this.one",
+ "java.lang.Comparable",
+ "java.lang.Object"
+ };
+ std::string input_file_contents;
+ for (std::string& class_name : class_names) {
+ input_file_contents += class_name + std::string("\n");
+ }
+ std::string output_file_contents;
+ ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents));
+ std::string expected_contents =
+ class_names[1] + std::string("\n") + class_names[2] + std::string("\n");
+ ASSERT_EQ(output_file_contents, expected_contents);
+}
+
+TEST_F(ProfileAssistantTest, TestProfileCreationNoneMatched) {
+ // Class names put here need to be in sorted order.
+ std::vector<std::string> class_names = {
+ "doesnt.match.this.one",
+ "doesnt.match.this.one.either",
+ "nor.this.one"
+ };
+ std::string input_file_contents;
+ for (std::string& class_name : class_names) {
+ input_file_contents += class_name + std::string("\n");
+ }
+ std::string output_file_contents;
+ ASSERT_TRUE(CreateAndDump(input_file_contents, &output_file_contents));
+ std::string expected_contents("");
+ ASSERT_EQ(output_file_contents, expected_contents);
+}
+
} // namespace art
diff --git a/profman/profman.cc b/profman/profman.cc
index b0cbed1..f6b145a 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -21,8 +21,11 @@
#include <sys/stat.h>
#include <unistd.h>
+#include <fstream>
#include <iostream>
+#include <set>
#include <string>
+#include <unordered_set>
#include <vector>
#include "android-base/stringprintf.h"
@@ -84,8 +87,10 @@
UsageError(" --dump-only: dumps the content of the specified profile files");
UsageError(" to standard output (default) in a human readable form.");
UsageError("");
- UsageError(" --dump-output-to-fd=<number>: redirects --dump-info-for output to a file");
- UsageError(" descriptor.");
+ UsageError(" --dump-output-to-fd=<number>: redirects --dump-only output to a file descriptor.");
+ UsageError("");
+ UsageError(" --dump-classes: dumps a sorted list of classes that are in the specified profile");
+ UsageError(" file to standard output (default) in a human readable form.");
UsageError("");
UsageError(" --profile-file=<filename>: specify profiler output file to use for compilation.");
UsageError(" Can be specified multiple time, in which case the data from the different");
@@ -103,6 +108,7 @@
UsageError(" --reference-profile-file-fd=<number>: same as --reference-profile-file but");
UsageError(" accepts a file descriptor. Cannot be used together with");
UsageError(" --reference-profile-file.");
+ UsageError("");
UsageError(" --generate-test-profile=<filename>: generates a random profile file for testing.");
UsageError(" --generate-test-profile-num-dex=<number>: number of dex files that should be");
UsageError(" included in the generated profile. Defaults to 20.");
@@ -111,12 +117,15 @@
UsageError(" --generate-test-profile-class-ratio=<number>: the percentage from the maximum");
UsageError(" number of classes that should be generated. Defaults to 5.");
UsageError("");
+ UsageError(" --create-profile-from=<filename>: creates a profile from a list of classes.");
+ UsageError("");
UsageError("");
UsageError(" --dex-location=<string>: location string to use with corresponding");
UsageError(" apk-fd to find dex files");
UsageError("");
UsageError(" --apk-fd=<number>: file descriptor containing an open APK to");
UsageError(" search for dex files");
+ UsageError(" --apk-=<filename>: an APK to search for dex files");
UsageError("");
exit(EXIT_FAILURE);
@@ -132,6 +141,7 @@
ProfMan() :
reference_profile_file_fd_(kInvalidFd),
dump_only_(false),
+ dump_classes_(false),
dump_output_to_fd_(kInvalidFd),
test_profile_num_dex_(kDefaultTestProfileNumDex),
test_profile_method_ratio_(kDefaultTestProfileMethodRatio),
@@ -164,6 +174,10 @@
}
if (option == "--dump-only") {
dump_only_ = true;
+ } else if (option == "--dump-classes") {
+ dump_classes_ = true;
+ } else if (option.starts_with("--create-profile-from=")) {
+ create_profile_from_file_ = option.substr(strlen("--create-profile-from=")).ToString();
} else if (option.starts_with("--dump-output-to-fd=")) {
ParseUintOption(option, "--dump-output-to-fd", &dump_output_to_fd_, Usage);
} else if (option.starts_with("--profile-file=")) {
@@ -178,6 +192,8 @@
dex_locations_.push_back(option.substr(strlen("--dex-location=")).ToString());
} else if (option.starts_with("--apk-fd=")) {
ParseFdForCollection(option, "--apk-fd", &apks_fd_);
+ } else if (option.starts_with("--apk=")) {
+ apk_files_.push_back(option.substr(strlen("--apk=")).ToString());
} else if (option.starts_with("--generate-test-profile=")) {
test_profile_ = option.substr(strlen("--generate-test-profile=")).ToString();
} else if (option.starts_with("--generate-test-profile-num-dex=")) {
@@ -213,14 +229,34 @@
}
return;
}
- // --dump-only may be specified with only --reference-profiles present.
- if (!dump_only_ && !has_profiles) {
+ if (!apk_files_.empty() && !apks_fd_.empty()) {
+ Usage("APK files should not be specified with both --apk-fd and --apk");
+ }
+ if (!create_profile_from_file_.empty()) {
+ if (apk_files_.empty() && apks_fd_.empty()) {
+ Usage("APK files must be specified");
+ }
+ if (dex_locations_.empty()) {
+ Usage("DEX locations must be specified");
+ }
+ if (reference_profile_file_.empty() && !FdIsValid(reference_profile_file_fd_)) {
+ Usage("Reference profile must be specified with --reference-profile-file or "
+ "--reference-profile-file-fd");
+ }
+ if (has_profiles) {
+ Usage("Profile must be specified with --reference-profile-file or "
+ "--reference-profile-file-fd");
+ }
+ return;
+ }
+ // --dump-only and --dump-classes may be specified with only --reference-profiles present.
+ if (!dump_only_ && !dump_classes_ && !has_profiles) {
Usage("No profile files specified.");
}
if (!profile_files_.empty() && !profile_files_fd_.empty()) {
Usage("Profile files should not be specified with both --profile-file-fd and --profile-file");
}
- if (!dump_only_ && !has_reference_profile) {
+ if (!dump_only_ && !dump_classes_ && !has_reference_profile) {
Usage("No reference profile file specified.");
}
if (!reference_profile_file_.empty() && FdIsValid(reference_profile_file_fd_)) {
@@ -248,6 +284,46 @@
return result;
}
+ void OpenApkFilesFromLocations(std::vector<std::unique_ptr<const DexFile>>* dex_files) {
+ bool use_apk_fd_list = !apks_fd_.empty();
+ if (use_apk_fd_list) {
+ CHECK(apk_files_.empty());
+ CHECK_EQ(dex_locations_.size(), apks_fd_.size());
+ } else {
+ CHECK_EQ(dex_locations_.size(), apk_files_.size());
+ CHECK(!apk_files_.empty());
+ }
+ static constexpr bool kVerifyChecksum = true;
+ for (size_t i = 0; i < dex_locations_.size(); ++i) {
+ std::string error_msg;
+ std::vector<std::unique_ptr<const DexFile>> dex_files_for_location;
+ if (use_apk_fd_list) {
+ if (DexFile::OpenZip(apks_fd_[i],
+ dex_locations_[i],
+ kVerifyChecksum,
+ &error_msg,
+ &dex_files_for_location)) {
+ } else {
+ LOG(WARNING) << "OpenZip failed for '" << dex_locations_[i] << "' " << error_msg;
+ continue;
+ }
+ } else {
+ if (DexFile::Open(apk_files_[i].c_str(),
+ dex_locations_[i],
+ kVerifyChecksum,
+ &error_msg,
+ &dex_files_for_location)) {
+ } else {
+ LOG(WARNING) << "Open failed for '" << dex_locations_[i] << "' " << error_msg;
+ continue;
+ }
+ }
+ for (std::unique_ptr<const DexFile>& dex_file : dex_files_for_location) {
+ dex_files->emplace_back(std::move(dex_file));
+ }
+ }
+ }
+
int DumpOneProfile(const std::string& banner,
const std::string& filename,
int fd,
@@ -256,13 +332,13 @@
if (!filename.empty()) {
fd = open(filename.c_str(), O_RDWR);
if (fd < 0) {
- std::cerr << "Cannot open " << filename << strerror(errno);
+ LOG(ERROR) << "Cannot open " << filename << strerror(errno);
return -1;
}
}
ProfileCompilationInfo info;
if (!info.Load(fd)) {
- std::cerr << "Cannot load profile info from fd=" << fd << "\n";
+ LOG(ERROR) << "Cannot load profile info from fd=" << fd << "\n";
return -1;
}
std::string this_dump = banner + "\n" + info.DumpInfo(dex_files) + "\n";
@@ -281,25 +357,7 @@
// Open apk/zip files and and read dex files.
MemMap::Init(); // for ZipArchive::OpenFromFd
std::vector<std::unique_ptr<const DexFile>> dex_files;
- assert(dex_locations_.size() == apks_fd_.size());
- static constexpr bool kVerifyChecksum = true;
- for (size_t i = 0; i < dex_locations_.size(); ++i) {
- std::string error_msg;
- std::vector<std::unique_ptr<const DexFile>> dex_files_for_location;
- if (DexFile::OpenZip(apks_fd_[i],
- dex_locations_[i],
- kVerifyChecksum,
- &error_msg,
- &dex_files_for_location)) {
- } else {
- LOG(WARNING) << "OpenFromZip failed for '" << dex_locations_[i] << "' " << error_msg;
- continue;
- }
- for (std::unique_ptr<const DexFile>& dex_file : dex_files_for_location) {
- dex_files.emplace_back(std::move(dex_file));
- }
- }
-
+ OpenApkFilesFromLocations(&dex_files);
std::string dump;
// Dump individual profile files.
if (!profile_files_fd_.empty()) {
@@ -358,17 +416,207 @@
return dump_only_;
}
+ bool GetClassNames(int fd,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files,
+ std::set<std::string>* class_names) {
+ ProfileCompilationInfo profile_info;
+ if (!profile_info.Load(fd)) {
+ LOG(ERROR) << "Cannot load profile info";
+ return false;
+ }
+ profile_info.GetClassNames(dex_files, class_names);
+ return true;
+ }
+
+ bool GetClassNames(std::string profile_file,
+ std::vector<std::unique_ptr<const DexFile>>* dex_files,
+ std::set<std::string>* class_names) {
+ int fd = open(profile_file.c_str(), O_RDONLY);
+ if (!FdIsValid(fd)) {
+ LOG(ERROR) << "Cannot open " << profile_file << strerror(errno);
+ return false;
+ }
+ if (!GetClassNames(fd, dex_files, class_names)) {
+ return false;
+ }
+ if (close(fd) < 0) {
+ PLOG(WARNING) << "Failed to close descriptor";
+ }
+ return true;
+ }
+
+ int DumpClasses() {
+ // Open apk/zip files and and read dex files.
+ MemMap::Init(); // for ZipArchive::OpenFromFd
+ // Open the dex files to get the names for classes.
+ std::vector<std::unique_ptr<const DexFile>> dex_files;
+ OpenApkFilesFromLocations(&dex_files);
+ // Build a vector of class names from individual profile files.
+ std::set<std::string> class_names;
+ if (!profile_files_fd_.empty()) {
+ for (int profile_file_fd : profile_files_fd_) {
+ if (!GetClassNames(profile_file_fd, &dex_files, &class_names)) {
+ return -1;
+ }
+ }
+ }
+ if (!profile_files_.empty()) {
+ for (const std::string& profile_file : profile_files_) {
+ if (!GetClassNames(profile_file, &dex_files, &class_names)) {
+ return -1;
+ }
+ }
+ }
+ // Concatenate class names from reference profile file.
+ if (FdIsValid(reference_profile_file_fd_)) {
+ if (!GetClassNames(reference_profile_file_fd_, &dex_files, &class_names)) {
+ return -1;
+ }
+ }
+ if (!reference_profile_file_.empty()) {
+ if (!GetClassNames(reference_profile_file_, &dex_files, &class_names)) {
+ return -1;
+ }
+ }
+ // Dump the class names.
+ std::string dump;
+ for (const std::string& class_name : class_names) {
+ dump += class_name + std::string("\n");
+ }
+ if (!FdIsValid(dump_output_to_fd_)) {
+ std::cout << dump;
+ } else {
+ unix_file::FdFile out_fd(dump_output_to_fd_, false /*check_usage*/);
+ if (!out_fd.WriteFully(dump.c_str(), dump.length())) {
+ return -1;
+ }
+ }
+ return 0;
+ }
+
+ bool ShouldOnlyDumpClasses() {
+ return dump_classes_;
+ }
+
+ // Read lines from the given file, dropping comments and empty lines. Post-process each line with
+ // the given function.
+ template <typename T>
+ static T* ReadCommentedInputFromFile(
+ const char* input_filename, std::function<std::string(const char*)>* process) {
+ std::unique_ptr<std::ifstream> input_file(new std::ifstream(input_filename, std::ifstream::in));
+ if (input_file.get() == nullptr) {
+ LOG(ERROR) << "Failed to open input file " << input_filename;
+ return nullptr;
+ }
+ std::unique_ptr<T> result(
+ ReadCommentedInputStream<T>(*input_file, process));
+ input_file->close();
+ return result.release();
+ }
+
+ // Read lines from the given stream, dropping comments and empty lines. Post-process each line
+ // with the given function.
+ template <typename T>
+ static T* ReadCommentedInputStream(
+ std::istream& in_stream,
+ std::function<std::string(const char*)>* process) {
+ std::unique_ptr<T> output(new T());
+ while (in_stream.good()) {
+ std::string dot;
+ std::getline(in_stream, dot);
+ if (android::base::StartsWith(dot, "#") || dot.empty()) {
+ continue;
+ }
+ if (process != nullptr) {
+ std::string descriptor((*process)(dot.c_str()));
+ output->insert(output->end(), descriptor);
+ } else {
+ output->insert(output->end(), dot);
+ }
+ }
+ return output.release();
+ }
+
+ int CreateProfile() {
+ MemMap::Init(); // for ZipArchive::OpenFromFd
+ // Open the profile output file if needed.
+ int fd = reference_profile_file_fd_;
+ if (!FdIsValid(fd)) {
+ CHECK(!reference_profile_file_.empty());
+ fd = open(reference_profile_file_.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
+ if (fd < 0) {
+ LOG(ERROR) << "Cannot open " << reference_profile_file_ << strerror(errno);
+ return -1;
+ }
+ }
+ // Read the user-specified list of classes (dot notation rather than descriptors).
+ std::unique_ptr<std::unordered_set<std::string>>
+ user_class_list(ReadCommentedInputFromFile<std::unordered_set<std::string>>(
+ create_profile_from_file_.c_str(), nullptr)); // No post-processing.
+ std::unordered_set<std::string> matched_user_classes;
+ // Open the dex files to look up class names.
+ std::vector<std::unique_ptr<const DexFile>> dex_files;
+ OpenApkFilesFromLocations(&dex_files);
+ // Iterate over the dex files looking for class names in the input stream.
+ std::set<DexCacheResolvedClasses> resolved_class_set;
+ for (auto& dex_file : dex_files) {
+ // Compute the set of classes to be added for this dex file first. This
+ // avoids creating an entry in the profile information for dex files that
+ // contribute no classes.
+ std::unordered_set<dex::TypeIndex> classes_to_be_added;
+ for (const auto& klass : *user_class_list) {
+ std::string descriptor = DotToDescriptor(klass.c_str());
+ const DexFile::TypeId* type_id = dex_file->FindTypeId(descriptor.c_str());
+ if (type_id == nullptr) {
+ continue;
+ }
+ classes_to_be_added.insert(dex_file->GetIndexForTypeId(*type_id));
+ matched_user_classes.insert(klass);
+ }
+ if (classes_to_be_added.empty()) {
+ continue;
+ }
+ // Insert the DexCacheResolved Classes into the set expected for
+ // AddMethodsAndClasses.
+ std::set<DexCacheResolvedClasses>::iterator dex_resolved_classes =
+ resolved_class_set.emplace(dex_file->GetLocation(),
+ dex_file->GetBaseLocation(),
+ dex_file->GetLocationChecksum()).first;
+ dex_resolved_classes->AddClasses(classes_to_be_added.begin(), classes_to_be_added.end());
+ }
+ // Warn the user if we didn't find matches for every class.
+ for (const auto& klass : *user_class_list) {
+ if (matched_user_classes.find(klass) == matched_user_classes.end()) {
+ LOG(WARNING) << "requested class '" << klass << "' was not matched in any dex file";
+ }
+ }
+ // Generate the profile data structure.
+ ProfileCompilationInfo info;
+ std::vector<MethodReference> methods; // No methods for now.
+ info.AddMethodsAndClasses(methods, resolved_class_set);
+ // Write the profile file.
+ CHECK(info.Save(fd));
+ if (close(fd) < 0) {
+ PLOG(WARNING) << "Failed to close descriptor";
+ }
+ return 0;
+ }
+
+ bool ShouldCreateProfile() {
+ return !create_profile_from_file_.empty();
+ }
+
int GenerateTestProfile() {
int profile_test_fd = open(test_profile_.c_str(), O_CREAT | O_TRUNC | O_WRONLY, 0644);
if (profile_test_fd < 0) {
- std::cerr << "Cannot open " << test_profile_ << strerror(errno);
+ LOG(ERROR) << "Cannot open " << test_profile_ << strerror(errno);
return -1;
}
bool result = ProfileCompilationInfo::GenerateTestProfile(profile_test_fd,
- test_profile_num_dex_,
- test_profile_method_ratio_,
- test_profile_class_ratio_);
+ test_profile_num_dex_,
+ test_profile_method_ratio_,
+ test_profile_class_ratio_);
close(profile_test_fd); // ignore close result.
return result ? 0 : -1;
}
@@ -405,12 +653,15 @@
std::vector<std::string> profile_files_;
std::vector<int> profile_files_fd_;
std::vector<std::string> dex_locations_;
+ std::vector<std::string> apk_files_;
std::vector<int> apks_fd_;
std::string reference_profile_file_;
int reference_profile_file_fd_;
bool dump_only_;
+ bool dump_classes_;
int dump_output_to_fd_;
std::string test_profile_;
+ std::string create_profile_from_file_;
uint16_t test_profile_num_dex_;
uint16_t test_profile_method_ratio_;
uint16_t test_profile_class_ratio_;
@@ -430,6 +681,12 @@
if (profman.ShouldOnlyDumpProfile()) {
return profman.DumpProfileInfo();
}
+ if (profman.ShouldOnlyDumpClasses()) {
+ return profman.DumpClasses();
+ }
+ if (profman.ShouldCreateProfile()) {
+ return profman.CreateProfile();
+ }
// Process profile information and assess if we need to do a profile guided compilation.
// This operation involves I/O.
return profman.ProcessProfiles();
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index 10b690a..ec8ae85 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -2042,67 +2042,158 @@
/* $a0 holds address of "this" */
/* $a1 holds "ch" */
/* $a2 holds "fromIndex" */
- lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # this.length()
- slt $t1, $a2, $zero # if fromIndex < 0
-#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
- seleqz $a2, $a2, $t1 # fromIndex = 0;
+#if (STRING_COMPRESSION_FEATURE)
+ lw $a3, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this
#else
- movn $a2, $zero, $t1 # fromIndex = 0;
+ lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # this.length()
#endif
- subu $t0, $t0, $a2 # this.length() - fromIndex
- blez $t0, 6f # if this.length()-fromIndex <= 0
- li $v0, -1 # return -1;
+ slt $t1, $a2, $zero # if fromIndex < 0
+#if defined(_MIPS_ARCH_MIPS32R6) || defined(_MIPS_ARCH_MIPS64R6)
+ seleqz $a2, $a2, $t1 # fromIndex = 0;
+#else
+ movn $a2, $zero, $t1 # fromIndex = 0;
+#endif
+#if (STRING_COMPRESSION_FEATURE)
+ srl $t0, $a3, 1 # $a3 holds count (with flag) and $t0 holds actual length
+#endif
+ subu $t0, $t0, $a2 # this.length() - fromIndex
+ blez $t0, 6f # if this.length()-fromIndex <= 0
+ li $v0, -1 # return -1;
- sll $v0, $a2, 1 # $a0 += $a2 * 2
- addu $a0, $a0, $v0 # " ditto "
- move $v0, $a2 # Set i to fromIndex.
+#if (STRING_COMPRESSION_FEATURE)
+ sll $a3, $a3, 31 # Extract compression flag.
+ beqz $a3, .Lstring_indexof_compressed
+ move $t2, $a0 # Save a copy in $t2 to later compute result (in branch delay slot).
+#endif
+ sll $v0, $a2, 1 # $a0 += $a2 * 2
+ addu $a0, $a0, $v0 # " ditto "
+ move $v0, $a2 # Set i to fromIndex.
1:
- lhu $t3, MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch
- beq $t3, $a1, 6f # return i;
- addu $a0, $a0, 2 # i++
- subu $t0, $t0, 1 # this.length() - i
- bnez $t0, 1b # while this.length() - i > 0
- addu $v0, $v0, 1 # i++
+ lhu $t3, MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch
+ beq $t3, $a1, 6f # return i;
+ addu $a0, $a0, 2 # i++
+ subu $t0, $t0, 1 # this.length() - i
+ bnez $t0, 1b # while this.length() - i > 0
+ addu $v0, $v0, 1 # i++
- li $v0, -1 # if this.length() - i <= 0
- # return -1;
+ li $v0, -1 # if this.length() - i <= 0
+ # return -1;
6:
- j $ra
- nop
+ j $ra
+ nop
+
+#if (STRING_COMPRESSION_FEATURE)
+.Lstring_indexof_compressed:
+ addu $a0, $a0, $a2 # $a0 += $a2
+
+.Lstring_indexof_compressed_loop:
+ lbu $t3, MIRROR_STRING_VALUE_OFFSET($a0)
+ beq $t3, $a1, .Lstring_indexof_compressed_matched
+ subu $t0, $t0, 1
+ bgtz $t0, .Lstring_indexof_compressed_loop
+ addu $a0, $a0, 1
+
+.Lstring_indexof_nomatch:
+ jalr $zero, $ra
+ li $v0, -1 # return -1;
+
+.Lstring_indexof_compressed_matched:
+ jalr $zero, $ra
+ subu $v0, $a0, $t2 # return (current - start);
+#endif
END art_quick_indexof
/* java.lang.String.compareTo(String anotherString) */
ENTRY_NO_GP art_quick_string_compareto
/* $a0 holds address of "this" */
/* $a1 holds address of "anotherString" */
- beq $a0, $a1, 9f # this and anotherString are the same object
- move $v0, $zero
+ beq $a0, $a1, .Lstring_compareto_length_diff # this and anotherString are the same object
+ move $a3, $a2 # trick to return 0 (it returns a2 - a3)
- lw $a2, MIRROR_STRING_COUNT_OFFSET($a0) # this.length()
- lw $a3, MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length()
- MINu $t2, $a2, $a3
-# $t2 now holds min(this.length(),anotherString.length())
+#if (STRING_COMPRESSION_FEATURE)
+ lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this
+ lw $t1, MIRROR_STRING_COUNT_OFFSET($a1) # 'count' field of anotherString
+ sra $a2, $t0, 1 # this.length()
+ sra $a3, $t1, 1 # anotherString.length()
+#else
+ lw $a2, MIRROR_STRING_COUNT_OFFSET($a0) # this.length()
+ lw $a3, MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length()
+#endif
- beqz $t2, 9f # while min(this.length(),anotherString.length())-i != 0
- subu $v0, $a2, $a3 # if $t2==0 return
- # (this.length() - anotherString.length())
-1:
- lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i)
- lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
- bne $t0, $t1, 9f # if this.charAt(i) != anotherString.charAt(i)
- subu $v0, $t0, $t1 # return (this.charAt(i) - anotherString.charAt(i))
- addiu $a0, $a0, 2 # point at this.charAt(i++)
- subu $t2, $t2, 1 # new value of
- # min(this.length(),anotherString.length())-i
- bnez $t2, 1b
- addiu $a1, $a1, 2 # point at anotherString.charAt(i++)
- subu $v0, $a2, $a3
+ MINu $t2, $a2, $a3
+ # $t2 now holds min(this.length(),anotherString.length())
-9:
- j $ra
- nop
+ # while min(this.length(),anotherString.length())-i != 0
+ beqz $t2, .Lstring_compareto_length_diff # if $t2==0
+ nop # return (this.length() - anotherString.length())
+
+#if (STRING_COMPRESSION_FEATURE)
+ # Differ cases:
+ sll $t3, $t0, 31
+ beqz $t3, .Lstring_compareto_this_is_compressed
+ sll $t3, $t1, 31 # In branch delay slot.
+ beqz $t3, .Lstring_compareto_that_is_compressed
+ nop
+ b .Lstring_compareto_both_not_compressed
+ nop
+
+.Lstring_compareto_this_is_compressed:
+ beqz $t3, .Lstring_compareto_both_compressed
+ nop
+ /* If (this->IsCompressed() && that->IsCompressed() == false) */
+.Lstring_compareto_loop_comparison_this_compressed:
+ lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0)
+ lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
+ bne $t0, $t1, .Lstring_compareto_char_diff
+ addiu $a0, $a0, 1 # point at this.charAt(i++) - compressed
+ subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i
+ bnez $t2, .Lstring_compareto_loop_comparison_this_compressed
+ addiu $a1, $a1, 2 # point at anotherString.charAt(i++) - uncompressed
+ jalr $zero, $ra
+ subu $v0, $a2, $a3 # return (this.length() - anotherString.length())
+
+.Lstring_compareto_that_is_compressed:
+ lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0)
+ lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
+ bne $t0, $t1, .Lstring_compareto_char_diff
+ addiu $a0, $a0, 2 # point at this.charAt(i++) - uncompressed
+ subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i
+ bnez $t2, .Lstring_compareto_that_is_compressed
+ addiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed
+ jalr $zero, $ra
+ subu $v0, $a2, $a3 # return (this.length() - anotherString.length())
+
+.Lstring_compareto_both_compressed:
+ lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0)
+ lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
+ bne $t0, $t1, .Lstring_compareto_char_diff
+ addiu $a0, $a0, 1 # point at this.charAt(i++) - compressed
+ subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i
+ bnez $t2, .Lstring_compareto_both_compressed
+ addiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed
+ jalr $zero, $ra
+ subu $v0, $a2, $a3 # return (this.length() - anotherString.length())
+#endif
+
+.Lstring_compareto_both_not_compressed:
+ lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i)
+ lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
+ bne $t0, $t1, .Lstring_compareto_char_diff # if this.charAt(i) != anotherString.charAt(i)
+ # return (this.charAt(i) - anotherString.charAt(i))
+ addiu $a0, $a0, 2 # point at this.charAt(i++)
+ subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i
+ bnez $t2, .Lstring_compareto_both_not_compressed
+ addiu $a1, $a1, 2 # point at anotherString.charAt(i++)
+
+.Lstring_compareto_length_diff:
+ jalr $zero, $ra
+ subu $v0, $a2, $a3 # return (this.length() - anotherString.length())
+
+.Lstring_compareto_char_diff:
+ jalr $zero, $ra
+ subu $v0, $t0, $t1 # return (this.charAt(i) - anotherString.charAt(i))
END art_quick_string_compareto
.extern artInvokePolymorphic
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index fff6d25..28d7c77 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -1900,32 +1900,91 @@
ENTRY_NO_GP art_quick_string_compareto
/* $a0 holds address of "this" */
/* $a1 holds address of "anotherString" */
- beq $a0,$a1,9f # this and anotherString are the same object
- move $v0,$zero
+ move $a2, $zero
+ beq $a0, $a1, .Lstring_compareto_length_diff # this and anotherString are the same object
+ move $a3, $zero # return 0 (it returns a2 - a3)
- lw $a2,MIRROR_STRING_COUNT_OFFSET($a0) # this.length()
- lw $a3,MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length()
- MINu $t2, $a2, $a3
-# $t2 now holds min(this.length(),anotherString.length())
+#if (STRING_COMPRESSION_FEATURE)
+ lw $a4, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this
+ lw $a5, MIRROR_STRING_COUNT_OFFSET($a1) # 'count' field of anotherString
+ sra $a2, $a4, 1 # this.length()
+ sra $a3, $a5, 1 # anotherString.length()
+#else
+ lw $a2, MIRROR_STRING_COUNT_OFFSET($a0) # this.length()
+ lw $a3, MIRROR_STRING_COUNT_OFFSET($a1) # anotherString.length()
+#endif
- beqz $t2,9f # while min(this.length(),anotherString.length())-i != 0
- subu $v0,$a2,$a3 # if $t2==0 return
- # (this.length() - anotherString.length())
-1:
- lhu $t0,MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i)
- lhu $t1,MIRROR_STRING_VALUE_OFFSET($a1)
- bne $t0,$t1,9f # if this.charAt(i) != anotherString.charAt(i)
- subu $v0,$t0,$t1 # return (this.charAt(i) - anotherString.charAt(i))
- daddiu $a0,$a0,2 # point at this.charAt(i++)
- subu $t2,$t2,1 # new value of
- # min(this.length(),anotherString.length())-i
- bnez $t2,1b
- daddiu $a1,$a1,2 # point at anotherString.charAt(i++)
- subu $v0,$a2,$a3
+ MINu $t2, $a2, $a3
+ # $t2 now holds min(this.length(),anotherString.length())
-9:
- j $ra
- nop
+ # while min(this.length(),anotherString.length())-i != 0
+ beqzc $t2, .Lstring_compareto_length_diff # if $t2==0
+ # return (this.length() - anotherString.length())
+
+#if (STRING_COMPRESSION_FEATURE)
+ # Differ cases:
+ dext $a6, $a4, 0, 1
+ beqz $a6, .Lstring_compareto_this_is_compressed
+ dext $a6, $a5, 0, 1 # In branch delay slot.
+ beqz $a6, .Lstring_compareto_that_is_compressed
+ nop
+ b .Lstring_compareto_both_not_compressed
+ nop
+
+.Lstring_compareto_this_is_compressed:
+ beqzc $a6, .Lstring_compareto_both_compressed
+ /* If (this->IsCompressed() && that->IsCompressed() == false) */
+.Lstring_compareto_loop_comparison_this_compressed:
+ lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0)
+ lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
+ bnec $t0, $t1, .Lstring_compareto_char_diff
+ daddiu $a0, $a0, 1 # point at this.charAt(i++) - compressed
+ subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i
+ bnez $t2, .Lstring_compareto_loop_comparison_this_compressed
+ daddiu $a1, $a1, 2 # point at anotherString.charAt(i++) - uncompressed
+ jalr $zero, $ra
+ subu $v0, $a2, $a3 # return (this.length() - anotherString.length())
+
+.Lstring_compareto_that_is_compressed:
+ lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0)
+ lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
+ bnec $t0, $t1, .Lstring_compareto_char_diff
+ daddiu $a0, $a0, 2 # point at this.charAt(i++) - uncompressed
+ subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i
+ bnez $t2, .Lstring_compareto_that_is_compressed
+ daddiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed
+ jalr $zero, $ra
+ subu $v0, $a2, $a3 # return (this.length() - anotherString.length())
+
+.Lstring_compareto_both_compressed:
+ lbu $t0, MIRROR_STRING_VALUE_OFFSET($a0)
+ lbu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
+ bnec $t0, $t1, .Lstring_compareto_char_diff
+ daddiu $a0, $a0, 1 # point at this.charAt(i++) - compressed
+ subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i
+ bnez $t2, .Lstring_compareto_both_compressed
+ daddiu $a1, $a1, 1 # point at anotherString.charAt(i++) - compressed
+ jalr $zero, $ra
+ subu $v0, $a2, $a3 # return (this.length() - anotherString.length())
+#endif
+
+.Lstring_compareto_both_not_compressed:
+ lhu $t0, MIRROR_STRING_VALUE_OFFSET($a0) # while this.charAt(i) == anotherString.charAt(i)
+ lhu $t1, MIRROR_STRING_VALUE_OFFSET($a1)
+ bnec $t0, $t1, .Lstring_compareto_char_diff # if this.charAt(i) != anotherString.charAt(i)
+ # return (this.charAt(i) - anotherString.charAt(i))
+ daddiu $a0, $a0, 2 # point at this.charAt(i++)
+ subu $t2, $t2, 1 # new value of min(this.length(),anotherString.length())-i
+ bnez $t2, .Lstring_compareto_both_not_compressed
+ daddiu $a1, $a1, 2 # point at anotherString.charAt(i++)
+
+.Lstring_compareto_length_diff:
+ jalr $zero, $ra
+ subu $v0, $a2, $a3 # return (this.length() - anotherString.length())
+
+.Lstring_compareto_char_diff:
+ jalr $zero, $ra
+ subu $v0, $t0, $t1 # return (this.charAt(i) - anotherString.charAt(i))
END art_quick_string_compareto
/* java.lang.String.indexOf(int ch, int fromIndex=0) */
@@ -1933,31 +1992,64 @@
/* $a0 holds address of "this" */
/* $a1 holds "ch" */
/* $a2 holds "fromIndex" */
- lw $t0,MIRROR_STRING_COUNT_OFFSET($a0) # this.length()
- slt $at, $a2, $zero # if fromIndex < 0
- seleqz $a2, $a2, $at # fromIndex = 0;
- subu $t0,$t0,$a2 # this.length() - fromIndex
- blez $t0,6f # if this.length()-fromIndex <= 0
- li $v0,-1 # return -1;
+#if (STRING_COMPRESSION_FEATURE)
+ lw $a3, MIRROR_STRING_COUNT_OFFSET($a0) # 'count' field of this
+#else
+ lw $t0, MIRROR_STRING_COUNT_OFFSET($a0) # this.length()
+#endif
+ slt $at, $a2, $zero # if fromIndex < 0
+ seleqz $a2, $a2, $at # fromIndex = 0;
+#if (STRING_COMPRESSION_FEATURE)
+ srl $t0, $a3, 1 # $a3 holds count (with flag) and $t0 holds actual length
+#endif
+ subu $t0, $t0, $a2 # this.length() - fromIndex
+ blez $t0, 6f # if this.length()-fromIndex <= 0
+ li $v0, -1 # return -1;
- sll $v0,$a2,1 # $a0 += $a2 * 2
- daddu $a0,$a0,$v0 # " ditto "
- move $v0,$a2 # Set i to fromIndex.
+#if (STRING_COMPRESSION_FEATURE)
+ dext $a3, $a3, 0, 1 # Extract compression flag.
+ beqzc $a3, .Lstring_indexof_compressed
+#endif
+
+ sll $v0, $a2, 1 # $a0 += $a2 * 2
+ daddu $a0, $a0, $v0 # " ditto "
+ move $v0, $a2 # Set i to fromIndex.
1:
- lhu $t3,MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch
- beq $t3,$a1,6f # return i;
- daddu $a0,$a0,2 # i++
- subu $t0,$t0,1 # this.length() - i
- bnez $t0,1b # while this.length() - i > 0
- addu $v0,$v0,1 # i++
+ lhu $t3, MIRROR_STRING_VALUE_OFFSET($a0) # if this.charAt(i) == ch
+ beq $t3, $a1, 6f # return i;
+ daddu $a0, $a0, 2 # i++
+ subu $t0, $t0, 1 # this.length() - i
+ bnez $t0, 1b # while this.length() - i > 0
+ addu $v0, $v0, 1 # i++
- li $v0,-1 # if this.length() - i <= 0
- # return -1;
+ li $v0, -1 # if this.length() - i <= 0
+ # return -1;
6:
- j $ra
- nop
+ j $ra
+ nop
+
+#if (STRING_COMPRESSION_FEATURE)
+.Lstring_indexof_compressed:
+ move $a4, $a0 # Save a copy in $a4 to later compute result.
+ daddu $a0, $a0, $a2 # $a0 += $a2
+
+.Lstring_indexof_compressed_loop:
+ lbu $t3, MIRROR_STRING_VALUE_OFFSET($a0)
+ beq $t3, $a1, .Lstring_indexof_compressed_matched
+ subu $t0, $t0, 1
+ bgtz $t0, .Lstring_indexof_compressed_loop
+ daddu $a0, $a0, 1
+
+.Lstring_indexof_nomatch:
+ jalr $zero, $ra
+ li $v0, -1 # return -1;
+
+.Lstring_indexof_compressed_matched:
+ jalr $zero, $ra
+ dsubu $v0, $a0, $a4 # return (current - start);
+#endif
END art_quick_indexof
.extern artInvokePolymorphic
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 6cb8544..4902ad4 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -67,7 +67,6 @@
}
ArtMethod* ArtMethod::GetSingleImplementation(PointerSize pointer_size) {
- DCHECK(!IsNative());
if (!IsAbstract()) {
// A non-abstract's single implementation is itself.
return this;
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index 6e102be..7bba944 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -72,6 +72,7 @@
ReaderWriterMutex* Locks::jni_globals_lock_ = nullptr;
Mutex* Locks::jni_weak_globals_lock_ = nullptr;
ReaderWriterMutex* Locks::dex_lock_ = nullptr;
+std::vector<BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_;
struct AllMutexData {
// A guard for all_mutexes_ that's not a mutex (Mutexes must CAS to acquire and busy wait).
@@ -146,7 +147,10 @@
const uint64_t start_nano_time_;
};
-BaseMutex::BaseMutex(const char* name, LockLevel level) : level_(level), name_(name) {
+BaseMutex::BaseMutex(const char* name, LockLevel level)
+ : level_(level),
+ name_(name),
+ should_respond_to_empty_checkpoint_request_(false) {
if (kLogLockContentions) {
ScopedAllMutexesLock mu(this);
std::set<BaseMutex*>** all_mutexes_ptr = &gAllMutexData->all_mutexes;
@@ -377,6 +381,9 @@
// Failed to acquire, hang up.
ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid());
num_contenders_++;
+ if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) {
+ self->CheckEmptyCheckpointFromMutex();
+ }
if (futex(state_.Address(), FUTEX_WAIT, 1, nullptr, nullptr, 0) != 0) {
// EAGAIN and EINTR both indicate a spurious failure, try again from the beginning.
// We don't use TEMP_FAILURE_RETRY so we can intentionally retry to acquire the lock.
@@ -519,6 +526,18 @@
return os;
}
+void Mutex::WakeupToRespondToEmptyCheckpoint() {
+#if ART_USE_FUTEXES
+ // Wake up all the waiters so they will respond to the emtpy checkpoint.
+ DCHECK(should_respond_to_empty_checkpoint_request_);
+ if (UNLIKELY(num_contenders_.LoadRelaxed() > 0)) {
+ futex(state_.Address(), FUTEX_WAKE, -1, nullptr, nullptr, 0);
+ }
+#else
+ LOG(FATAL) << "Non futex case isn't supported.";
+#endif
+}
+
ReaderWriterMutex::ReaderWriterMutex(const char* name, LockLevel level)
: BaseMutex(name, level)
#if ART_USE_FUTEXES
@@ -563,6 +582,9 @@
// Failed to acquire, hang up.
ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid());
++num_pending_writers_;
+ if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) {
+ self->CheckEmptyCheckpointFromMutex();
+ }
if (futex(state_.Address(), FUTEX_WAIT, cur_state, nullptr, nullptr, 0) != 0) {
// EAGAIN and EINTR both indicate a spurious failure, try again from the beginning.
// We don't use TEMP_FAILURE_RETRY so we can intentionally retry to acquire the lock.
@@ -639,6 +661,9 @@
}
ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid());
++num_pending_writers_;
+ if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) {
+ self->CheckEmptyCheckpointFromMutex();
+ }
if (futex(state_.Address(), FUTEX_WAIT, cur_state, &rel_ts, nullptr, 0) != 0) {
if (errno == ETIMEDOUT) {
--num_pending_writers_;
@@ -677,6 +702,9 @@
// Owner holds it exclusively, hang up.
ScopedContentionRecorder scr(this, GetExclusiveOwnerTid(), SafeGetTid(self));
++num_pending_readers_;
+ if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) {
+ self->CheckEmptyCheckpointFromMutex();
+ }
if (futex(state_.Address(), FUTEX_WAIT, cur_state, nullptr, nullptr, 0) != 0) {
if (errno != EAGAIN && errno != EINTR) {
PLOG(FATAL) << "futex wait failed for " << name_;
@@ -749,6 +777,19 @@
return os;
}
+void ReaderWriterMutex::WakeupToRespondToEmptyCheckpoint() {
+#if ART_USE_FUTEXES
+ // Wake up all the waiters so they will respond to the emtpy checkpoint.
+ DCHECK(should_respond_to_empty_checkpoint_request_);
+ if (UNLIKELY(num_pending_readers_.LoadRelaxed() > 0 ||
+ num_pending_writers_.LoadRelaxed() > 0)) {
+ futex(state_.Address(), FUTEX_WAKE, -1, nullptr, nullptr, 0);
+ }
+#else
+ LOG(FATAL) << "Non futex case isn't supported.";
+#endif
+}
+
ConditionVariable::ConditionVariable(const char* name, Mutex& guard)
: name_(name), guard_(guard) {
#if ART_USE_FUTEXES
@@ -1121,6 +1162,12 @@
#undef UPDATE_CURRENT_LOCK_LEVEL
+ // List of mutexes that we may hold when accessing a weak ref.
+ dex_lock_->SetShouldRespondToEmptyCheckpointRequest(true);
+ expected_mutexes_on_weak_ref_access_.push_back(dex_lock_);
+ classlinker_classes_lock_->SetShouldRespondToEmptyCheckpointRequest(true);
+ expected_mutexes_on_weak_ref_access_.push_back(classlinker_classes_lock_);
+
InitConditions();
}
}
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index ffe18c6..9b6938f 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -152,6 +152,16 @@
static void DumpAll(std::ostream& os);
+ bool ShouldRespondToEmptyCheckpointRequest() const {
+ return should_respond_to_empty_checkpoint_request_;
+ }
+
+ void SetShouldRespondToEmptyCheckpointRequest(bool value) {
+ should_respond_to_empty_checkpoint_request_ = value;
+ }
+
+ virtual void WakeupToRespondToEmptyCheckpoint() = 0;
+
protected:
friend class ConditionVariable;
@@ -168,6 +178,7 @@
const LockLevel level_; // Support for lock hierarchy.
const char* const name_;
+ bool should_respond_to_empty_checkpoint_request_;
// A log entry that records contention but makes no guarantee that either tid will be held live.
struct ContentionLogEntry {
@@ -266,6 +277,8 @@
// For negative capabilities in clang annotations.
const Mutex& operator!() const { return *this; }
+ void WakeupToRespondToEmptyCheckpoint() OVERRIDE;
+
private:
#if ART_USE_FUTEXES
// 0 is unheld, 1 is held.
@@ -386,6 +399,8 @@
// For negative capabilities in clang annotations.
const ReaderWriterMutex& operator!() const { return *this; }
+ void WakeupToRespondToEmptyCheckpoint() OVERRIDE;
+
private:
#if ART_USE_FUTEXES
// Out-of-inline path for handling contention for a SharedLock.
@@ -713,6 +728,12 @@
// Have an exclusive logging thread.
static Mutex* logging_lock_ ACQUIRED_AFTER(unexpected_signal_lock_);
+
+ // List of mutexes that we expect a thread may hold when accessing weak refs. This is used to
+ // avoid a deadlock in the empty checkpoint while weak ref access is disabled (b/34964016). If we
+ // encounter an unexpected mutex on accessing weak refs,
+ // Thread::CheckEmptyCheckpointFromWeakRefAccess will detect it.
+ static std::vector<BaseMutex*> expected_mutexes_on_weak_ref_access_;
};
class Roles {
diff --git a/runtime/cha.cc b/runtime/cha.cc
index d11b12f..eaba01b 100644
--- a/runtime/cha.cc
+++ b/runtime/cha.cc
@@ -200,7 +200,8 @@
if (verify_method != excluded_method) {
DCHECK(!verify_method->HasSingleImplementation())
<< "class: " << verify_class->PrettyClass()
- << " verify_method: " << verify_method->PrettyMethod(true);
+ << " verify_method: " << verify_method->PrettyMethod(true)
+ << " excluded_method: " << excluded_method->PrettyMethod(true);
if (verify_method->IsAbstract()) {
DCHECK(verify_method->GetSingleImplementation(image_pointer_size) == nullptr);
}
@@ -257,9 +258,6 @@
return;
}
- // Native methods don't have single-implementation flag set.
- DCHECK(!method_in_super->IsNative());
-
uint16_t method_index = method_in_super->GetMethodIndex();
if (method_in_super->IsAbstract()) {
if (kIsDebugBuild) {
@@ -374,12 +372,12 @@
// used for static methods or methods of final classes.
return;
}
- if (method->IsNative()) {
- // Native method's invocation overhead is already high and it
- // cannot be inlined. It's not worthwhile to devirtualize the
- // call which can add a deoptimization point.
- DCHECK(!method->HasSingleImplementation());
- } else if (method->IsAbstract()) {
+ if (method->IsAbstract()) {
+ // single-implementation of abstract method shares the same field
+ // that's used for JNI function of native method. It's fine since a method
+ // cannot be both abstract and native.
+ DCHECK(!method->IsNative()) << "Abstract method cannot be native";
+
if (method->GetDeclaringClass()->IsInstantiable()) {
// Rare case, but we do accept it (such as 800-smali/smali/b_26143249.smali).
// Do not attempt to devirtualize it.
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 17e3729..26ec364 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -223,12 +223,6 @@
return; \
}
-#define TEST_DISABLED_FOR_READ_BARRIER_ON_X86() \
- if (kUseReadBarrier && kRuntimeISA == kX86) { \
- printf("WARNING: TEST DISABLED FOR READ BARRIER ON X86\n"); \
- return; \
- }
-
#define TEST_DISABLED_FOR_STRING_COMPRESSION() \
if (mirror::kUseStringCompression) { \
printf("WARNING: TEST DISABLED FOR STRING COMPRESSION\n"); \
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index f59420d..02ba33c 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -497,9 +497,14 @@
method_ids_(reinterpret_cast<const MethodId*>(base + header_->method_ids_off_)),
proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)),
class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)),
+ method_handles_(nullptr),
+ num_method_handles_(0),
+ call_site_ids_(nullptr),
+ num_call_site_ids_(0),
oat_dex_file_(oat_dex_file) {
CHECK(begin_ != nullptr) << GetLocation();
CHECK_GT(size_, 0U) << GetLocation();
+ InitializeSectionsFromMapList();
}
DexFile::~DexFile() {
@@ -540,6 +545,29 @@
return true;
}
+void DexFile::InitializeSectionsFromMapList() {
+ const MapList* map_list = reinterpret_cast<const MapList*>(begin_ + header_->map_off_);
+ const size_t count = map_list->size_;
+
+ size_t map_limit = header_->map_off_ + count * sizeof(MapItem);
+ if (header_->map_off_ >= map_limit || map_limit > size_) {
+ // Overflow or out out of bounds. The dex file verifier runs after
+ // this method and will reject the file as it is malformed.
+ return;
+ }
+
+ for (size_t i = 0; i < count; ++i) {
+ const MapItem& map_item = map_list->list_[i];
+ if (map_item.type_ == kDexTypeMethodHandleItem) {
+ method_handles_ = reinterpret_cast<const MethodHandleItem*>(begin_ + map_item.offset_);
+ num_method_handles_ = map_item.size_;
+ } else if (map_item.type_ == kDexTypeCallSiteIdItem) {
+ call_site_ids_ = reinterpret_cast<const CallSiteIdItem*>(begin_ + map_item.offset_);
+ num_call_site_ids_ = map_item.size_;
+ }
+ }
+}
+
bool DexFile::IsMagicValid(const uint8_t* magic) {
return (memcmp(magic, kDexMagic, sizeof(kDexMagic)) == 0);
}
@@ -1339,24 +1367,20 @@
}
}
-EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(const DexFile& dex_file,
- const DexFile::ClassDef& class_def)
+EncodedArrayValueIterator::EncodedArrayValueIterator(const DexFile& dex_file,
+ const uint8_t* array_data)
: dex_file_(dex_file),
array_size_(),
pos_(-1),
+ ptr_(array_data),
type_(kByte) {
- ptr_ = dex_file_.GetEncodedStaticFieldValuesArray(class_def);
- if (ptr_ == nullptr) {
- array_size_ = 0;
- } else {
- array_size_ = DecodeUnsignedLeb128(&ptr_);
- }
+ array_size_ = (ptr_ != nullptr) ? DecodeUnsignedLeb128(&ptr_) : 0;
if (array_size_ > 0) {
Next();
}
}
-void EncodedStaticFieldValueIterator::Next() {
+void EncodedArrayValueIterator::Next() {
pos_++;
if (pos_ >= array_size_) {
return;
@@ -1396,6 +1420,8 @@
break;
case kString:
case kType:
+ case kMethodType:
+ case kMethodHandle:
jval_.i = DexFile::ReadUnsignedInt(ptr_, value_arg, false);
break;
case kField:
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index cb7f174..cf90bca 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -103,7 +103,7 @@
};
// Map item type codes.
- enum {
+ enum MapItemType : uint16_t { // private
kDexTypeHeaderItem = 0x0000,
kDexTypeStringIdItem = 0x0001,
kDexTypeTypeIdItem = 0x0002,
@@ -111,6 +111,8 @@
kDexTypeFieldIdItem = 0x0004,
kDexTypeMethodIdItem = 0x0005,
kDexTypeClassDefItem = 0x0006,
+ kDexTypeCallSiteIdItem = 0x0007,
+ kDexTypeMethodHandleItem = 0x0008,
kDexTypeMapList = 0x1000,
kDexTypeTypeList = 0x1001,
kDexTypeAnnotationSetRefList = 0x1002,
@@ -260,6 +262,37 @@
DISALLOW_COPY_AND_ASSIGN(TypeList);
};
+ // MethodHandle Types
+ enum class MethodHandleType : uint16_t { // private
+ kPutStatic = 0x0000, // a setter for a given static field.
+ kGetStatic = 0x0001, // a getter for a given static field.
+ kPutInstance = 0x0002, // a setter for a given instance field.
+ kGetInstance = 0x0003, // a getter for a given instance field.
+ kInvokeStatic = 0x0004, // an invoker for a given static method
+ kInvokeInstance = 0x0005, // invoke_instance : an invoker for a given instance method. This
+ // can be any non-static method on any class (or interface) except
+ // for “<init>”.
+ kInvokeConstructor = 0x0006, // an invoker for a given constructor.
+ kLast = kInvokeConstructor
+ };
+
+ // raw method_handle_item
+ struct MethodHandleItem {
+ uint16_t method_handle_type_;
+ uint16_t reserved1_; // Reserved for future use.
+ uint16_t field_or_method_idx_;
+ uint16_t reserved2_; // Reserved for future use.
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
+ };
+
+ // raw call_site_id_item
+ struct CallSiteIdItem {
+ uint32_t data_off_; // Offset into data section pointing to encoded array items.
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CallSiteIdItem);
+ };
+
// Raw code_item.
struct CodeItem {
uint16_t registers_size_; // the number of registers used by this code
@@ -302,6 +335,8 @@
kDexAnnotationLong = 0x06,
kDexAnnotationFloat = 0x10,
kDexAnnotationDouble = 0x11,
+ kDexAnnotationMethodType = 0x15,
+ kDexAnnotationMethodHandle = 0x16,
kDexAnnotationString = 0x17,
kDexAnnotationType = 0x18,
kDexAnnotationField = 0x19,
@@ -683,6 +718,10 @@
}
}
+ uint32_t NumMethodHandles() const {
+ return num_method_handles_;
+ }
+
// Returns a pointer to the raw memory mapped class_data_item
const uint8_t* GetClassData(const ClassDef& class_def) const {
if (class_def.class_data_off_ == 0) {
@@ -761,6 +800,10 @@
}
}
+ const uint8_t* GetCallSiteEncodedValuesArray(const CallSiteIdItem& call_site_id) const {
+ return begin_ + call_site_id.data_off_;
+ }
+
static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset);
// Get the base of the encoded data for the given DexCode.
@@ -1101,6 +1144,9 @@
// Returns true if the header magic and version numbers are of the expected values.
bool CheckMagicAndVersion(std::string* error_msg) const;
+ // Initialize section info for sections only found in map. Returns true on success.
+ void InitializeSectionsFromMapList();
+
// Check whether a location denotes a multidex dex file. This is a very simple check: returns
// whether the string contains the separator character.
static bool IsMultiDexLocation(const char* location);
@@ -1143,6 +1189,18 @@
// Points to the base of the class definition list.
const ClassDef* const class_defs_;
+ // Points to the base of the method handles list.
+ const MethodHandleItem* method_handles_;
+
+ // Number of elements in the method handles list.
+ size_t num_method_handles_;
+
+ // Points to the base of the call sites id list.
+ const CallSiteIdItem* call_site_ids_;
+
+ // Number of elements in the call sites list.
+ size_t num_call_site_ids_;
+
// If this dex file was loaded from an oat file, oat_dex_file_ contains a
// pointer to the OatDexFile it was loaded from. Otherwise oat_dex_file_ is
// null.
@@ -1409,32 +1467,33 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
};
-class EncodedStaticFieldValueIterator {
+class EncodedArrayValueIterator {
public:
- EncodedStaticFieldValueIterator(const DexFile& dex_file,
- const DexFile::ClassDef& class_def);
+ EncodedArrayValueIterator(const DexFile& dex_file, const uint8_t* array_data);
bool HasNext() const { return pos_ < array_size_; }
void Next();
enum ValueType {
- kByte = 0x00,
- kShort = 0x02,
- kChar = 0x03,
- kInt = 0x04,
- kLong = 0x06,
- kFloat = 0x10,
- kDouble = 0x11,
- kString = 0x17,
- kType = 0x18,
- kField = 0x19,
- kMethod = 0x1a,
- kEnum = 0x1b,
- kArray = 0x1c,
- kAnnotation = 0x1d,
- kNull = 0x1e,
- kBoolean = 0x1f
+ kByte = 0x00,
+ kShort = 0x02,
+ kChar = 0x03,
+ kInt = 0x04,
+ kLong = 0x06,
+ kFloat = 0x10,
+ kDouble = 0x11,
+ kMethodType = 0x15,
+ kMethodHandle = 0x16,
+ kString = 0x17,
+ kType = 0x18,
+ kField = 0x19,
+ kMethod = 0x1a,
+ kEnum = 0x1b,
+ kArray = 0x1c,
+ kAnnotation = 0x1d,
+ kNull = 0x1e,
+ kBoolean = 0x1f,
};
ValueType GetValueType() const { return type_; }
@@ -1452,10 +1511,38 @@
jvalue jval_; // Value of current encoded value.
private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedArrayValueIterator);
+};
+std::ostream& operator<<(std::ostream& os, const EncodedArrayValueIterator::ValueType& code);
+
+class EncodedStaticFieldValueIterator : public EncodedArrayValueIterator {
+ public:
+ EncodedStaticFieldValueIterator(const DexFile& dex_file,
+ const DexFile::ClassDef& class_def)
+ : EncodedArrayValueIterator(dex_file,
+ dex_file.GetEncodedStaticFieldValuesArray(class_def))
+ {}
+
+ private:
DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
};
std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
+class CallSiteArrayValueIterator : public EncodedArrayValueIterator {
+ public:
+ CallSiteArrayValueIterator(const DexFile& dex_file,
+ const DexFile::CallSiteIdItem& call_site_id)
+ : EncodedArrayValueIterator(dex_file,
+ dex_file.GetCallSiteEncodedValuesArray(call_site_id))
+ {}
+
+ uint32_t Size() const { return array_size_; }
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(CallSiteArrayValueIterator);
+};
+std::ostream& operator<<(std::ostream& os, const CallSiteArrayValueIterator::ValueType& code);
+
class CatchHandlerIterator {
public:
CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 318123e..d870e52 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -46,8 +46,8 @@
return (high == 0);
}
-static uint32_t MapTypeToBitMask(uint32_t map_type) {
- switch (map_type) {
+static uint32_t MapTypeToBitMask(DexFile::MapItemType map_item_type) {
+ switch (map_item_type) {
case DexFile::kDexTypeHeaderItem: return 1 << 0;
case DexFile::kDexTypeStringIdItem: return 1 << 1;
case DexFile::kDexTypeTypeIdItem: return 1 << 2;
@@ -55,23 +55,25 @@
case DexFile::kDexTypeFieldIdItem: return 1 << 4;
case DexFile::kDexTypeMethodIdItem: return 1 << 5;
case DexFile::kDexTypeClassDefItem: return 1 << 6;
- case DexFile::kDexTypeMapList: return 1 << 7;
- case DexFile::kDexTypeTypeList: return 1 << 8;
- case DexFile::kDexTypeAnnotationSetRefList: return 1 << 9;
- case DexFile::kDexTypeAnnotationSetItem: return 1 << 10;
- case DexFile::kDexTypeClassDataItem: return 1 << 11;
- case DexFile::kDexTypeCodeItem: return 1 << 12;
- case DexFile::kDexTypeStringDataItem: return 1 << 13;
- case DexFile::kDexTypeDebugInfoItem: return 1 << 14;
- case DexFile::kDexTypeAnnotationItem: return 1 << 15;
- case DexFile::kDexTypeEncodedArrayItem: return 1 << 16;
- case DexFile::kDexTypeAnnotationsDirectoryItem: return 1 << 17;
+ case DexFile::kDexTypeCallSiteIdItem: return 1 << 7;
+ case DexFile::kDexTypeMethodHandleItem: return 1 << 8;
+ case DexFile::kDexTypeMapList: return 1 << 9;
+ case DexFile::kDexTypeTypeList: return 1 << 10;
+ case DexFile::kDexTypeAnnotationSetRefList: return 1 << 11;
+ case DexFile::kDexTypeAnnotationSetItem: return 1 << 12;
+ case DexFile::kDexTypeClassDataItem: return 1 << 13;
+ case DexFile::kDexTypeCodeItem: return 1 << 14;
+ case DexFile::kDexTypeStringDataItem: return 1 << 15;
+ case DexFile::kDexTypeDebugInfoItem: return 1 << 16;
+ case DexFile::kDexTypeAnnotationItem: return 1 << 17;
+ case DexFile::kDexTypeEncodedArrayItem: return 1 << 18;
+ case DexFile::kDexTypeAnnotationsDirectoryItem: return 1 << 19;
}
return 0;
}
-static bool IsDataSectionType(uint32_t map_type) {
- switch (map_type) {
+static bool IsDataSectionType(DexFile::MapItemType map_item_type) {
+ switch (map_item_type) {
case DexFile::kDexTypeHeaderItem:
case DexFile::kDexTypeStringIdItem:
case DexFile::kDexTypeTypeIdItem:
@@ -80,6 +82,20 @@
case DexFile::kDexTypeMethodIdItem:
case DexFile::kDexTypeClassDefItem:
return false;
+ case DexFile::kDexTypeCallSiteIdItem:
+ case DexFile::kDexTypeMethodHandleItem:
+ case DexFile::kDexTypeMapList:
+ case DexFile::kDexTypeTypeList:
+ case DexFile::kDexTypeAnnotationSetRefList:
+ case DexFile::kDexTypeAnnotationSetItem:
+ case DexFile::kDexTypeClassDataItem:
+ case DexFile::kDexTypeCodeItem:
+ case DexFile::kDexTypeStringDataItem:
+ case DexFile::kDexTypeDebugInfoItem:
+ case DexFile::kDexTypeAnnotationItem:
+ case DexFile::kDexTypeEncodedArrayItem:
+ case DexFile::kDexTypeAnnotationsDirectoryItem:
+ return true;
}
return true;
}
@@ -455,7 +471,8 @@
return false;
}
- if (IsDataSectionType(item->type_)) {
+ DexFile::MapItemType item_type = static_cast<DexFile::MapItemType>(item->type_);
+ if (IsDataSectionType(item_type)) {
uint32_t icount = item->size_;
if (UNLIKELY(icount > data_items_left)) {
ErrorStringPrintf("Too many items in data section: %ud", data_item_count + icount);
@@ -465,7 +482,7 @@
data_item_count += icount;
}
- uint32_t bit = MapTypeToBitMask(item->type_);
+ uint32_t bit = MapTypeToBitMask(item_type);
if (UNLIKELY(bit == 0)) {
ErrorStringPrintf("Unknown map section type %x", item->type_);
@@ -837,6 +854,28 @@
return false;
}
break;
+ case DexFile::kDexAnnotationMethodType: {
+ if (UNLIKELY(value_arg > 3)) {
+ ErrorStringPrintf("Bad encoded_value method type size %x", value_arg);
+ return false;
+ }
+ uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
+ if (!CheckIndex(idx, header_->proto_ids_size_, "method_type value")) {
+ return false;
+ }
+ break;
+ }
+ case DexFile::kDexAnnotationMethodHandle: {
+ if (UNLIKELY(value_arg > 3)) {
+ ErrorStringPrintf("Bad encoded_value method handle size %x", value_arg);
+ return false;
+ }
+ uint32_t idx = ReadUnsignedLittleEndian(value_arg + 1);
+ if (!CheckIndex(idx, dex_file_->NumMethodHandles(), "method_handle value")) {
+ return false;
+ }
+ break;
+ }
default:
ErrorStringPrintf("Bogus encoded_value value_type %x", value_type);
return false;
@@ -1455,7 +1494,7 @@
}
bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count,
- uint16_t type) {
+ DexFile::MapItemType type) {
// Get the right alignment mask for the type of section.
size_t alignment_mask;
switch (type) {
@@ -1481,6 +1520,7 @@
}
// Check depending on the section type.
+ const uint8_t* start_ptr = ptr_;
switch (type) {
case DexFile::kDexTypeStringIdItem: {
if (!CheckListSize(ptr_, 1, sizeof(DexFile::StringId), "string_ids")) {
@@ -1524,6 +1564,20 @@
ptr_ += sizeof(DexFile::ClassDef);
break;
}
+ case DexFile::kDexTypeCallSiteIdItem: {
+ if (!CheckListSize(ptr_, 1, sizeof(DexFile::CallSiteIdItem), "call_site_ids")) {
+ return false;
+ }
+ ptr_ += sizeof(DexFile::CallSiteIdItem);
+ break;
+ }
+ case DexFile::kDexTypeMethodHandleItem: {
+ if (!CheckListSize(ptr_, 1, sizeof(DexFile::MethodHandleItem), "method_handles")) {
+ return false;
+ }
+ ptr_ += sizeof(DexFile::MethodHandleItem);
+ break;
+ }
case DexFile::kDexTypeTypeList: {
if (!CheckList(sizeof(DexFile::TypeItem), "type_list", &ptr_)) {
return false;
@@ -1584,9 +1638,14 @@
}
break;
}
- default:
- ErrorStringPrintf("Unknown map item type %x", type);
- return false;
+ case DexFile::kDexTypeHeaderItem:
+ case DexFile::kDexTypeMapList:
+ break;
+ }
+
+ if (start_ptr == ptr_) {
+ ErrorStringPrintf("Unknown map item type %x", type);
+ return false;
}
if (IsDataSectionType(type)) {
@@ -1610,7 +1669,9 @@
return true;
}
-bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type) {
+bool DexFileVerifier::CheckIntraIdSection(size_t offset,
+ uint32_t count,
+ DexFile::MapItemType type) {
uint32_t expected_offset;
uint32_t expected_size;
@@ -1658,7 +1719,9 @@
return CheckIntraSectionIterate(offset, count, type);
}
-bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type) {
+bool DexFileVerifier::CheckIntraDataSection(size_t offset,
+ uint32_t count,
+ DexFile::MapItemType type) {
size_t data_start = header_->data_off_;
size_t data_end = data_start + header_->data_size_;
@@ -1684,16 +1747,16 @@
bool DexFileVerifier::CheckIntraSection() {
const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
const DexFile::MapItem* item = map->list_;
-
- uint32_t count = map->size_;
size_t offset = 0;
+ uint32_t count = map->size_;
ptr_ = begin_;
// Check the items listed in the map.
while (count--) {
+ const size_t current_offset = offset;
uint32_t section_offset = item->offset_;
uint32_t section_count = item->size_;
- uint16_t type = item->type_;
+ DexFile::MapItemType type = static_cast<DexFile::MapItemType>(item->type_);
// Check for padding and overlap between items.
if (!CheckPadding(offset, section_offset)) {
@@ -1741,6 +1804,11 @@
ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
break;
+ case DexFile::kDexTypeMethodHandleItem:
+ case DexFile::kDexTypeCallSiteIdItem:
+ CheckIntraSectionIterate(section_offset, section_count, type);
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeTypeList:
case DexFile::kDexTypeAnnotationSetRefList:
case DexFile::kDexTypeAnnotationSetItem:
@@ -1756,7 +1824,9 @@
}
offset = ptr_ - begin_;
break;
- default:
+ }
+
+ if (offset == current_offset) {
ErrorStringPrintf("Unknown map item type %x", type);
return false;
}
@@ -2237,6 +2307,92 @@
return true;
}
+bool DexFileVerifier::CheckInterCallSiteIdItem() {
+ const DexFile::CallSiteIdItem* item = reinterpret_cast<const DexFile::CallSiteIdItem*>(ptr_);
+
+ // Check call site referenced by item is in encoded array section.
+ if (!CheckOffsetToTypeMap(item->data_off_, DexFile::kDexTypeEncodedArrayItem)) {
+ ErrorStringPrintf("Invalid offset in CallSideIdItem");
+ return false;
+ }
+
+ CallSiteArrayValueIterator it(*dex_file_, *item);
+
+ // Check Method Handle
+ if (!it.HasNext() || it.GetValueType() != EncodedArrayValueIterator::ValueType::kMethodHandle) {
+ ErrorStringPrintf("CallSiteArray missing method handle");
+ return false;
+ }
+
+ uint32_t handle_index = static_cast<uint32_t>(it.GetJavaValue().i);
+ if (handle_index >= dex_file_->NumMethodHandles()) {
+ ErrorStringPrintf("CallSite has bad method handle id: %x", handle_index);
+ return false;
+ }
+
+ // Check target method name.
+ it.Next();
+ if (!it.HasNext() ||
+ it.GetValueType() != EncodedArrayValueIterator::ValueType::kString) {
+ ErrorStringPrintf("CallSiteArray missing target method name");
+ return false;
+ }
+
+ uint32_t name_index = static_cast<uint32_t>(it.GetJavaValue().i);
+ if (name_index >= dex_file_->NumStringIds()) {
+ ErrorStringPrintf("CallSite has bad method name id: %x", name_index);
+ return false;
+ }
+
+ // Check method type.
+ it.Next();
+ if (!it.HasNext() ||
+ it.GetValueType() != EncodedArrayValueIterator::ValueType::kMethodType) {
+ ErrorStringPrintf("CallSiteArray missing method type");
+ return false;
+ }
+
+ uint32_t proto_index = static_cast<uint32_t>(it.GetJavaValue().i);
+ if (proto_index >= dex_file_->NumProtoIds()) {
+ ErrorStringPrintf("CallSite has bad method type: %x", proto_index);
+ return false;
+ }
+
+ ptr_ += sizeof(DexFile::CallSiteIdItem);
+ return true;
+}
+
+bool DexFileVerifier::CheckInterMethodHandleItem() {
+ const DexFile::MethodHandleItem* item = reinterpret_cast<const DexFile::MethodHandleItem*>(ptr_);
+
+ DexFile::MethodHandleType method_handle_type =
+ static_cast<DexFile::MethodHandleType>(item->method_handle_type_);
+ if (method_handle_type > DexFile::MethodHandleType::kLast) {
+ ErrorStringPrintf("Bad method handle type %x", item->method_handle_type_);
+ return false;
+ }
+
+ uint32_t index = item->field_or_method_idx_;
+ switch (method_handle_type) {
+ case DexFile::MethodHandleType::kPutStatic:
+ case DexFile::MethodHandleType::kGetStatic:
+ case DexFile::MethodHandleType::kPutInstance:
+ case DexFile::MethodHandleType::kGetInstance: {
+ LOAD_FIELD(field, index, "method_handle_item field_idx", return false);
+ break;
+ }
+ case DexFile::MethodHandleType::kInvokeStatic:
+ case DexFile::MethodHandleType::kInvokeInstance:
+ case DexFile::MethodHandleType::kInvokeConstructor: {
+ LOAD_METHOD(method, index, "method_handle_item method_idx", return false);
+ break;
+ }
+ }
+
+ ptr_ += sizeof(DexFile::MethodHandleItem);
+ return true;
+}
+
bool DexFileVerifier::CheckInterAnnotationSetRefList() {
const DexFile::AnnotationSetRefList* list =
reinterpret_cast<const DexFile::AnnotationSetRefList*>(ptr_);
@@ -2386,7 +2542,9 @@
return true;
}
-bool DexFileVerifier::CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type) {
+bool DexFileVerifier::CheckInterSectionIterate(size_t offset,
+ uint32_t count,
+ DexFile::MapItemType type) {
// Get the right alignment mask for the type of section.
size_t alignment_mask;
switch (type) {
@@ -2405,8 +2563,22 @@
ptr_ = begin_ + new_offset;
const uint8_t* prev_ptr = ptr_;
+ if (MapTypeToBitMask(type) == 0) {
+ ErrorStringPrintf("Unknown map item type %x", type);
+ return false;
+ }
+
// Check depending on the section type.
switch (type) {
+ case DexFile::kDexTypeHeaderItem:
+ case DexFile::kDexTypeMapList:
+ case DexFile::kDexTypeTypeList:
+ case DexFile::kDexTypeCodeItem:
+ case DexFile::kDexTypeStringDataItem:
+ case DexFile::kDexTypeDebugInfoItem:
+ case DexFile::kDexTypeAnnotationItem:
+ case DexFile::kDexTypeEncodedArrayItem:
+ break;
case DexFile::kDexTypeStringIdItem: {
if (!CheckInterStringIdItem()) {
return false;
@@ -2451,6 +2623,18 @@
}
break;
}
+ case DexFile::kDexTypeCallSiteIdItem: {
+ if (!CheckInterCallSiteIdItem()) {
+ return false;
+ }
+ break;
+ }
+ case DexFile::kDexTypeMethodHandleItem: {
+ if (!CheckInterMethodHandleItem()) {
+ return false;
+ }
+ break;
+ }
case DexFile::kDexTypeAnnotationSetRefList: {
if (!CheckInterAnnotationSetRefList()) {
return false;
@@ -2483,9 +2667,6 @@
}
break;
}
- default:
- ErrorStringPrintf("Unknown map item type %x", type);
- return false;
}
previous_item_ = prev_ptr;
@@ -2504,7 +2685,8 @@
while (count--) {
uint32_t section_offset = item->offset_;
uint32_t section_count = item->size_;
- uint16_t type = item->type_;
+ DexFile::MapItemType type = static_cast<DexFile::MapItemType>(item->type_);
+ bool found = false;
switch (type) {
case DexFile::kDexTypeHeaderItem:
@@ -2515,6 +2697,7 @@
case DexFile::kDexTypeDebugInfoItem:
case DexFile::kDexTypeAnnotationItem:
case DexFile::kDexTypeEncodedArrayItem:
+ found = true;
break;
case DexFile::kDexTypeStringIdItem:
case DexFile::kDexTypeTypeIdItem:
@@ -2522,6 +2705,8 @@
case DexFile::kDexTypeFieldIdItem:
case DexFile::kDexTypeMethodIdItem:
case DexFile::kDexTypeClassDefItem:
+ case DexFile::kDexTypeCallSiteIdItem:
+ case DexFile::kDexTypeMethodHandleItem:
case DexFile::kDexTypeAnnotationSetRefList:
case DexFile::kDexTypeAnnotationSetItem:
case DexFile::kDexTypeClassDataItem:
@@ -2529,11 +2714,14 @@
if (!CheckInterSectionIterate(section_offset, section_count, type)) {
return false;
}
+ found = true;
break;
}
- default:
- ErrorStringPrintf("Unknown map item type %x", type);
- return false;
+ }
+
+ if (!found) {
+ ErrorStringPrintf("Unknown map item type %x", item->type_);
+ return false;
}
item++;
diff --git a/runtime/dex_file_verifier.h b/runtime/dex_file_verifier.h
index ae20613..71b316c 100644
--- a/runtime/dex_file_verifier.h
+++ b/runtime/dex_file_verifier.h
@@ -122,9 +122,9 @@
bool CheckIntraAnnotationItem();
bool CheckIntraAnnotationsDirectoryItem();
- bool CheckIntraSectionIterate(size_t offset, uint32_t count, uint16_t type);
- bool CheckIntraIdSection(size_t offset, uint32_t count, uint16_t type);
- bool CheckIntraDataSection(size_t offset, uint32_t count, uint16_t type);
+ bool CheckIntraSectionIterate(size_t offset, uint32_t count, DexFile::MapItemType type);
+ bool CheckIntraIdSection(size_t offset, uint32_t count, DexFile::MapItemType type);
+ bool CheckIntraDataSection(size_t offset, uint32_t count, DexFile::MapItemType type);
bool CheckIntraSection();
bool CheckOffsetToTypeMap(size_t offset, uint16_t type);
@@ -140,12 +140,14 @@
bool CheckInterFieldIdItem();
bool CheckInterMethodIdItem();
bool CheckInterClassDefItem();
+ bool CheckInterCallSiteIdItem();
+ bool CheckInterMethodHandleItem();
bool CheckInterAnnotationSetRefList();
bool CheckInterAnnotationSetItem();
bool CheckInterClassDataItem();
bool CheckInterAnnotationsDirectoryItem();
- bool CheckInterSectionIterate(size_t offset, uint32_t count, uint16_t type);
+ bool CheckInterSectionIterate(size_t offset, uint32_t count, DexFile::MapItemType type);
bool CheckInterSection();
// Load a string by (type) index. Checks whether the index is in bounds, printing the error if
diff --git a/runtime/dex_file_verifier_test.cc b/runtime/dex_file_verifier_test.cc
index c56b200..7736f3d 100644
--- a/runtime/dex_file_verifier_test.cc
+++ b/runtime/dex_file_verifier_test.cc
@@ -1885,4 +1885,209 @@
&error_msg));
}
+static const char* kInvokeCustomDexFiles[] = {
+ // TODO(oth): Revisit this test when we have smali / dx support.
+ // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test001/Tests.java
+ "ZGV4CjAzOAAEj12s/acmmdGuDL92SWSBh6iLBjxgomWkCAAAcAAAAHhWNBIAAAAAAAAAALwHAAAx"
+ "AAAAcAAAABYAAAA0AQAACQAAAIwBAAADAAAA+AEAAAsAAAAQAgAAAQAAAHACAAAMBgAAmAIAAMID"
+ "AADKAwAAzQMAANIDAADhAwAA5AMAAOoDAAAfBAAAUgQAAIMEAAC4BAAA1AQAAOsEAAD+BAAAEgUA"
+ "ACYFAAA6BQAAUQUAAG4FAACTBQAAtAUAAN0FAAD/BQAAHgYAADgGAABKBgAAVgYAAFkGAABdBgAA"
+ "YgYAAGYGAAB7BgAAgAYAAI8GAACdBgAAtAYAAMMGAADSBgAA3gYAAPIGAAD4BgAABgcAAA4HAAAU"
+ "BwAAGgcAAB8HAAAoBwAANAcAADoHAAABAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0A"
+ "AAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABoAAAAeAAAAAgAA"
+ "AAAAAACMAwAABQAAAAwAAACUAwAABQAAAA4AAACgAwAABAAAAA8AAAAAAAAAGgAAABQAAAAAAAAA"
+ "GwAAABQAAACsAwAAHAAAABQAAACMAwAAHQAAABQAAAC0AwAAHQAAABQAAAC8AwAAAwADAAMAAAAE"
+ "AAwAJAAAAAoABgAsAAAABAAEAAAAAAAEAAAAHwAAAAQAAQAoAAAABAAIACoAAAAEAAQALwAAAAYA"
+ "BQAtAAAACAAEAAAAAAANAAcAAAAAAA8AAgAlAAAAEAADACkAAAASAAYAIQAAAJYHAACWBwAABAAA"
+ "AAEAAAAIAAAAAAAAABkAAABkAwAAnQcAAAAAAAAEAAAAAgAAAAEAAABjBwAAAQAAAIsHAAACAAAA"
+ "iwcAAJMHAAABAAEAAQAAAEEHAAAEAAAAcBAGAAAADgADAAIAAAAAAEYHAAADAAAAkAABAg8AAAAF"
+ "AAMABAAAAE0HAAAQAAAAcQAJAAAADAAcAQQAbkAIABBDDAAiAQ0AcCAHAAEAEQEEAAEAAgAAAFYH"
+ "AAAMAAAAYgACABIhEjL8IAAAIQAKAW4gBQAQAA4AAwABAAIAAABdBwAACwAAABIgEjH8IAEAEAAK"
+ "ABJRcSAKAAEADgAAAAAAAAAAAAAAAwAAAAAAAAABAAAAmAIAAAIAAACgAgAABAAAAKgCAAACAAAA"
+ "AAAAAAMAAAAPAAkAEQAAAAMAAAAHAAkAEQAAAAEAAAAAAAAAAQAAAA4AAAABAAAAFQAGPGluaXQ+"
+ "AAFJAANJSUkADUlOVk9LRV9TVEFUSUMAAUwABExMTEwAM0xjb20vYW5kcm9pZC9qYWNrL2Fubm90"
+ "YXRpb25zL0NhbGxlZEJ5SW52b2tlQ3VzdG9tOwAxTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlv"
+ "bnMvTGlua2VyTWV0aG9kSGFuZGxlOwAvTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMvTWV0"
+ "aG9kSGFuZGxlS2luZDsAM0xjb20vYW5kcm9pZC9qYWNrL2phdmE3L2ludm9rZWN1c3RvbS90ZXN0"
+ "MDAxL1Rlc3RzOwAaTGRhbHZpay9hbm5vdGF0aW9uL1Rocm93czsAFUxqYXZhL2lvL1ByaW50U3Ry"
+ "ZWFtOwARTGphdmEvbGFuZy9DbGFzczsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9T"
+ "dHJpbmc7ABJMamF2YS9sYW5nL1N5c3RlbTsAFUxqYXZhL2xhbmcvVGhyb3dhYmxlOwAbTGphdmEv"
+ "bGFuZy9pbnZva2UvQ2FsbFNpdGU7ACNMamF2YS9sYW5nL2ludm9rZS9Db25zdGFudENhbGxTaXRl"
+ "OwAfTGphdmEvbGFuZy9pbnZva2UvTWV0aG9kSGFuZGxlOwAnTGphdmEvbGFuZy9pbnZva2UvTWV0"
+ "aG9kSGFuZGxlcyRMb29rdXA7ACBMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzOwAdTGph"
+ "dmEvbGFuZy9pbnZva2UvTWV0aG9kVHlwZTsAGExqdW5pdC9mcmFtZXdvcmsvQXNzZXJ0OwAQTG9y"
+ "Zy9qdW5pdC9UZXN0OwAKVGVzdHMuamF2YQABVgACVkkAA1ZJSQACVkwAE1tMamF2YS9sYW5nL1N0"
+ "cmluZzsAA2FkZAANYXJndW1lbnRUeXBlcwAMYXNzZXJ0RXF1YWxzABVlbWl0dGVyOiBqYWNrLTQu"
+ "MC1lbmcADWVuY2xvc2luZ1R5cGUADWZpZWxkQ2FsbFNpdGUACmZpbmRTdGF0aWMAEmludm9rZU1l"
+ "dGhvZEhhbmRsZQAEa2luZAAMbGlua2VyTWV0aG9kAAZsb29rdXAABG1haW4ABG5hbWUAA291dAAH"
+ "cHJpbnRsbgAKcmV0dXJuVHlwZQAEdGVzdAAFdmFsdWUAIgAHDgAvAgAABw4ANQMAAAAHDqUAPwEA"
+ "Bw60ADsABw6lAAABBCAcAhgAGAAmHAEdAgQgHAMYDxgJGBEjGAQnGwArFygrFx8uGAACBQEwHAEY"
+ "CwETAAMWABcfFQABAAQBAQkAgYAEtAUBCswFAQrkBQEJlAYEAbwGAAAAEwAAAAAAAAABAAAAAAAA"
+ "AAEAAAAxAAAAcAAAAAIAAAAWAAAANAEAAAMAAAAJAAAAjAEAAAQAAAADAAAA+AEAAAUAAAALAAAA"
+ "EAIAAAcAAAACAAAAaAIAAAYAAAABAAAAcAIAAAgAAAABAAAAkAIAAAMQAAADAAAAmAIAAAEgAAAF"
+ "AAAAtAIAAAYgAAABAAAAZAMAAAEQAAAGAAAAjAMAAAIgAAAxAAAAwgMAAAMgAAAFAAAAQQcAAAQg"
+ "AAADAAAAYwcAAAUgAAABAAAAlgcAAAAgAAABAAAAnQcAAAAQAAABAAAAvAcAAA==",
+ // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test002/Tests.java
+ "ZGV4CjAzOAAzq3aGAwKhT4QQj4lqNfZJAO8Tm24uTyNICQAAcAAAAHhWNBIAAAAAAAAAAGAIAAA2"
+ "AAAAcAAAABgAAABIAQAACQAAAKgBAAAEAAAAFAIAAA0AAAA0AgAAAQAAAKQCAAB8BgAAzAIAACYE"
+ "AAAwBAAAOAQAAEQEAABHBAAATAQAAE8EAABVBAAAigQAALwEAADtBAAAIgUAAD4FAABVBQAAaAUA"
+ "AH0FAACRBQAApQUAALkFAADQBQAA7QUAABIGAAAzBgAAXAYAAH4GAACdBgAAtwYAAMkGAADPBgAA"
+ "2wYAAN4GAADiBgAA5wYAAOsGAAD/BgAAFAcAABkHAAAoBwAANgcAAE0HAABcBwAAawcAAH4HAACK"
+ "BwAAkAcAAJgHAACeBwAAqgcAALAHAAC1BwAAxgcAAM8HAADbBwAA4QcAAAMAAAAHAAAACAAAAAkA"
+ "AAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAA"
+ "ABgAAAAZAAAAGgAAAB0AAAAhAAAAIgAAAAQAAAAAAAAA8AMAAAYAAAAPAAAA+AMAAAUAAAAQAAAA"
+ "AAAAAAYAAAASAAAABAQAAB0AAAAVAAAAAAAAAB4AAAAVAAAAEAQAAB8AAAAVAAAA8AMAACAAAAAV"
+ "AAAAGAQAACAAAAAVAAAAIAQAAAMAAwACAAAABAANACgAAAAIAAcAGwAAAAsABgAwAAAABAAEAAAA"
+ "AAAEAAQAAQAAAAQAAAAjAAAABAAIAC0AAAAEAAQANAAAAAYABQAyAAAACQAEAAEAAAAMAAQAMQAA"
+ "AA4ABwABAAAAEAABACoAAAARAAIALAAAABIAAwAuAAAAEwAGACUAAAA4CAAAOAgAAAQAAAABAAAA"
+ "CQAAAAAAAAAcAAAA0AMAAD8IAAAAAAAAAQAAAAEAAAABAAAADggAAAIAAAAtCAAANQgAAAgAAAAE"
+ "AAEA6AcAACoAAABxAAoAAAAMABwBBAAbAiMAAABiAwIAYgQCABIVI1UWAGIGAgASB00GBQdxMAsA"
+ "QwUMA25ACQAQMgwAIgEOAHAgCAABAGkBAQAOAA0AbhAHAAAAKPsAAAAAJAABAAEBDCUBAAEAAQAA"
+ "APUHAAAEAAAAcBAGAAAADgADAAIAAAAAAPoHAAADAAAAkAABAg8AAAAEAAEAAgAAAAEIAAAMAAAA"
+ "YgADABIhEjL8IAAAIQAKAW4gBQAQAA4AAwABAAIAAAAICAAACwAAABIgEjH8IAEAEAAKABJRcSAM"
+ "AAEADgAAAAAAAAAAAAAAAgAAAAAAAAACAAAAzAIAAAQAAADUAgAAAgAAAAAAAAADAAAABwAKABIA"
+ "AAADAAAABwAHABYAAAABAAAAAAAAAAEAAAAPAAAAAQAAABcACDxjbGluaXQ+AAY8aW5pdD4ACkdF"
+ "VF9TVEFUSUMAAUkAA0lJSQABTAAETExMTAAzTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMv"
+ "Q2FsbGVkQnlJbnZva2VDdXN0b207ADBMY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9MaW5r"
+ "ZXJGaWVsZEhhbmRsZTsAL0xjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL01ldGhvZEhhbmRs"
+ "ZUtpbmQ7ADNMY29tL2FuZHJvaWQvamFjay9qYXZhNy9pbnZva2VjdXN0b20vdGVzdDAwMi9UZXN0"
+ "czsAGkxkYWx2aWsvYW5ub3RhdGlvbi9UaHJvd3M7ABVMamF2YS9pby9QcmludFN0cmVhbTsAEUxq"
+ "YXZhL2xhbmcvQ2xhc3M7ABNMamF2YS9sYW5nL0ludGVnZXI7ABJMamF2YS9sYW5nL09iamVjdDsA"
+ "EkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07ABVMamF2YS9sYW5nL1Rocm93"
+ "YWJsZTsAG0xqYXZhL2xhbmcvaW52b2tlL0NhbGxTaXRlOwAjTGphdmEvbGFuZy9pbnZva2UvQ29u"
+ "c3RhbnRDYWxsU2l0ZTsAH0xqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZTsAJ0xqYXZhL2xh"
+ "bmcvaW52b2tlL01ldGhvZEhhbmRsZXMkTG9va3VwOwAgTGphdmEvbGFuZy9pbnZva2UvTWV0aG9k"
+ "SGFuZGxlczsAHUxqYXZhL2xhbmcvaW52b2tlL01ldGhvZFR5cGU7ABhManVuaXQvZnJhbWV3b3Jr"
+ "L0Fzc2VydDsAEExvcmcvanVuaXQvVGVzdDsABFRZUEUAClRlc3RzLmphdmEAAVYAAlZJAANWSUkA"
+ "AlZMABJbTGphdmEvbGFuZy9DbGFzczsAE1tMamF2YS9sYW5nL1N0cmluZzsAA2FkZAANYXJndW1l"
+ "bnRUeXBlcwAMYXNzZXJ0RXF1YWxzABVlbWl0dGVyOiBqYWNrLTQuMC1lbmcADWVuY2xvc2luZ1R5"
+ "cGUADWZpZWxkQ2FsbFNpdGUAEWZpZWxkTWV0aG9kSGFuZGxlAApmaW5kU3RhdGljAARraW5kAAZs"
+ "b29rdXAABG1haW4ACm1ldGhvZFR5cGUABG5hbWUAA291dAAPcHJpbnRTdGFja1RyYWNlAAdwcmlu"
+ "dGxuAApyZXR1cm5UeXBlAAR0ZXN0AAV2YWx1ZQAoAAcOAR0PAnh3Jh4AIQAHDgA2AgAABw4APwEA"
+ "Bw60ADsABw6lAAABBCQcAhgAGAApHAEdAgMnGAQrGwAvFygvFyMzGAACBQE1HAEYDAEUAAMWABcj"
+ "FQABAAQBAQkAiIAE4AUBgYAE0AYBCugGAQmABwQBqAcAAAATAAAAAAAAAAEAAAAAAAAAAQAAADYA"
+ "AABwAAAAAgAAABgAAABIAQAAAwAAAAkAAACoAQAABAAAAAQAAAAUAgAABQAAAA0AAAA0AgAABwAA"
+ "AAIAAACcAgAABgAAAAEAAACkAgAACAAAAAEAAADEAgAAAxAAAAIAAADMAgAAASAAAAUAAADgAgAA"
+ "BiAAAAEAAADQAwAAARAAAAYAAADwAwAAAiAAADYAAAAmBAAAAyAAAAUAAADoBwAABCAAAAMAAAAO"
+ "CAAABSAAAAEAAAA4CAAAACAAAAEAAAA/CAAAABAAAAEAAABgCAAA",
+ // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test003/Tests.java
+ "ZGV4CjAzOABjnhkFatj30/7cHTCJsfr7vAjz9/p+Y+TcCAAAcAAAAHhWNBIAAAAAAAAAAPQHAAAx"
+ "AAAAcAAAABYAAAA0AQAACQAAAIwBAAADAAAA+AEAAAsAAAAQAgAAAQAAAHACAABEBgAAmAIAAOoD"
+ "AADyAwAA9QMAAP4DAAANBAAAEAQAABYEAABLBAAAfgQAAK8EAADkBAAAAAUAABcFAAAqBQAAPgUA"
+ "AFIFAABmBQAAfQUAAJoFAAC/BQAA4AUAAAkGAAArBgAASgYAAGQGAAB2BgAAggYAAIUGAACJBgAA"
+ "jgYAAJIGAACnBgAArAYAALsGAADJBgAA4AYAAO8GAAD+BgAACgcAAB4HAAAkBwAAMgcAADoHAABA"
+ "BwAARgcAAEsHAABUBwAAYAcAAGYHAAABAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0A"
+ "AAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABoAAAAeAAAAAgAA"
+ "AAAAAACkAwAABQAAAAwAAAC0AwAABQAAAA4AAADAAwAABAAAAA8AAAAAAAAAGgAAABQAAAAAAAAA"
+ "GwAAABQAAADMAwAAHAAAABQAAADUAwAAHQAAABQAAADcAwAAHQAAABQAAADkAwAAAwADAAMAAAAE"
+ "AAwAJAAAAAoABgAsAAAABAAEAAAAAAAEAAAAHwAAAAQAAQAoAAAABAAIACoAAAAEAAQALwAAAAYA"
+ "BQAtAAAACAAEAAAAAAANAAcAAAAAAA8AAgAlAAAAEAADACkAAAASAAYAIQAAAM4HAADOBwAABAAA"
+ "AAEAAAAIAAAAAAAAABkAAAB8AwAA1QcAAAAAAAAEAAAAAgAAAAEAAACTBwAAAQAAAMMHAAACAAAA"
+ "wwcAAMsHAAABAAEAAQAAAG0HAAAEAAAAcBAGAAAADgAHAAYAAAAAAHIHAAAHAAAAkAABArAwsECw"
+ "ULBgDwAAAAUAAwAEAAAAfQcAABAAAABxAAkAAAAMABwBBABuQAgAEEMMACIBDQBwIAcAAQARAQgA"
+ "AQACAAAAhgcAABAAAABiBgIAEhASIRIyEkMSVBJl/QYAAAAACgBuIAUABgAOAAcAAQACAAAAjQcA"
+ "ABAAAAASEBIhEjISQxJUEmX9BgEAAAAKABMBFQBxIAoAAQAOAAAAAAAAAAAAAwAAAAAAAAABAAAA"
+ "mAIAAAIAAACgAgAABAAAAKgCAAAGAAAAAAAAAAAAAAAAAAAAAwAAAA8ACQARAAAAAwAAAAcACQAR"
+ "AAAAAQAAAAAAAAACAAAAAAAAAAEAAAAOAAAAAQAAABUABjxpbml0PgABSQAHSUlJSUlJSQANSU5W"
+ "T0tFX1NUQVRJQwABTAAETExMTAAzTGNvbS9hbmRyb2lkL2phY2svYW5ub3RhdGlvbnMvQ2FsbGVk"
+ "QnlJbnZva2VDdXN0b207ADFMY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9MaW5rZXJNZXRo"
+ "b2RIYW5kbGU7AC9MY29tL2FuZHJvaWQvamFjay9hbm5vdGF0aW9ucy9NZXRob2RIYW5kbGVLaW5k"
+ "OwAzTGNvbS9hbmRyb2lkL2phY2svamF2YTcvaW52b2tlY3VzdG9tL3Rlc3QwMDMvVGVzdHM7ABpM"
+ "ZGFsdmlrL2Fubm90YXRpb24vVGhyb3dzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABFMamF2YS9s"
+ "YW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZh"
+ "L2xhbmcvU3lzdGVtOwAVTGphdmEvbGFuZy9UaHJvd2FibGU7ABtMamF2YS9sYW5nL2ludm9rZS9D"
+ "YWxsU2l0ZTsAI0xqYXZhL2xhbmcvaW52b2tlL0NvbnN0YW50Q2FsbFNpdGU7AB9MamF2YS9sYW5n"
+ "L2ludm9rZS9NZXRob2RIYW5kbGU7ACdMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzJExv"
+ "b2t1cDsAIExqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXM7AB1MamF2YS9sYW5nL2ludm9r"
+ "ZS9NZXRob2RUeXBlOwAYTGp1bml0L2ZyYW1ld29yay9Bc3NlcnQ7ABBMb3JnL2p1bml0L1Rlc3Q7"
+ "AApUZXN0cy5qYXZhAAFWAAJWSQADVklJAAJWTAATW0xqYXZhL2xhbmcvU3RyaW5nOwADYWRkAA1h"
+ "cmd1bWVudFR5cGVzAAxhc3NlcnRFcXVhbHMAFWVtaXR0ZXI6IGphY2stNC4wLWVuZwANZW5jbG9z"
+ "aW5nVHlwZQANZmllbGRDYWxsU2l0ZQAKZmluZFN0YXRpYwASaW52b2tlTWV0aG9kSGFuZGxlAARr"
+ "aW5kAAxsaW5rZXJNZXRob2QABmxvb2t1cAAEbWFpbgAEbmFtZQADb3V0AAdwcmludGxuAApyZXR1"
+ "cm5UeXBlAAR0ZXN0AAV2YWx1ZQAiAAcOAC8GAAAAAAAABw4ANQMAAAAHDqUAPwEABw7wADsABw7w"
+ "AAABBCAcBhgAGAAYABgAGAAYACYcAR0CBCAcAxgPGAkYESMYBCcbACsXKCsXHy4YAAIFATAcARgL"
+ "ARMAAxYAFx8VAAEABAEBCQCBgAS0BQEKzAUBCuwFAQmcBgQBzAYAAAATAAAAAAAAAAEAAAAAAAAA"
+ "AQAAADEAAABwAAAAAgAAABYAAAA0AQAAAwAAAAkAAACMAQAABAAAAAMAAAD4AQAABQAAAAsAAAAQ"
+ "AgAABwAAAAIAAABoAgAABgAAAAEAAABwAgAACAAAAAEAAACQAgAAAxAAAAMAAACYAgAAASAAAAUA"
+ "AAC0AgAABiAAAAEAAAB8AwAAARAAAAcAAACkAwAAAiAAADEAAADqAwAAAyAAAAUAAABtBwAABCAA"
+ "AAMAAACTBwAABSAAAAEAAADOBwAAACAAAAEAAADVBwAAABAAAAEAAAD0BwAA",
+ // https://cs.corp.google.com/android/toolchain/jack/jack-tests/tests/com/android/jack/java7/invokecustom/test004/Tests.java
+ "ZGV4CjAzOABvUVfbV74qWbSOEsgKP+EzahlNQLW2/8TMDAAAcAAAAHhWNBIAAAAAAAAAAOQLAABS"
+ "AAAAcAAAAB8AAAC4AQAAEAAAADQCAAADAAAA9AIAABIAAAAMAwAAAQAAAKQDAAAACQAAzAMAANYF"
+ "AADZBQAA4QUAAOkFAADsBQAA7wUAAPIFAAD1BQAA/AUAAP8FAAAEBgAAEwYAABYGAAAZBgAAHwYA"
+ "AC8GAABkBgAAjQYAAMAGAADxBgAAJgcAAEUHAABhBwAAeAcAAIoHAACdBwAAsQcAAMUHAADZBwAA"
+ "8AcAAA0IAAAyCAAAUwgAAHwIAACeCAAAvQgAANcIAADpCAAA7AgAAPgIAAD7CAAAAAkAAAYJAAAM"
+ "CQAAEAkAABUJAAAaCQAAHgkAACMJAAAnCQAAKgkAADMJAABICQAATQkAAFwJAABqCQAAdgkAAIQJ"
+ "AACPCQAAmgkAAKYJAACzCQAAygkAANkJAADoCQAA9AkAAAAKAAAKCgAAHgoAACQKAAAyCgAAPQoA"
+ "AEUKAABLCgAAYgoAAGgKAABtCgAAdgoAAIIKAACOCgAAmwoAAKEKAAADAAAABAAAAAUAAAAGAAAA"
+ "CAAAAAsAAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABgAAAAZAAAAGgAAABsAAAAc"
+ "AAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJwAAADEAAAAzAAAACQAAAAQA"
+ "AABMBQAADgAAABMAAABUBQAADQAAABUAAAB0BQAADAAAABYAAAAAAAAAJwAAABwAAAAAAAAAKAAA"
+ "ABwAAACABQAAKQAAABwAAACIBQAAKgAAABwAAACUBQAAKwAAABwAAACgBQAALAAAABwAAABMBQAA"
+ "LQAAABwAAACoBQAALwAAABwAAACwBQAALwAAABwAAAC4BQAALgAAABwAAADABQAAMAAAABwAAADI"
+ "BQAALgAAABwAAADQBQAACQAJAAoAAAAKABMAPwAAABEADQBLAAAACgAEAAIAAAAKAAAANAAAAAoA"
+ "AQBFAAAACgAPAEgAAAAKAAQAUAAAAA0ACABMAAAADwAEAAIAAAAUAA0AAgAAABYAAgBAAAAAFwAD"
+ "AEcAAAAZAAUANgAAABkABgA2AAAAGQAHADYAAAAZAAkANgAAABkACgA2AAAAGQALADYAAAAZAAwA"
+ "NgAAABkADgA3AAAAnQsAAJ0LAAAKAAAAAQAAAA8AAAAAAAAAJgAAACQFAADGCwAAAAAAAAQAAAAC"
+ "AAAAAQAAAN4KAAACAAAAegsAAJILAAACAAAAkgsAAJoLAAABAAEAAQAAAKgKAAAEAAAAcBAGAAAA"
+ "DgADAAIAAAAAAK0KAAADAAAAkAABAg8AAAAYAA8ABgAAALQKAABTAAAAcRARAAwAEhJxIA0A0gAT"
+ "AmEAcSAKAOIAEwIABHEgDQDyABISAgAQAHEgDQACABICFAOamTFBAgARAHEwDAADAhYGAAAYApqZ"
+ "mZmZmQFABQQSAHcGCwACABsCBwAAAAgAFABxIBAAAgAcAgoACAAVAHEgDwACABcCFc1bBwUAFgBx"
+ "QA4AMhBxAAkAAAAMAhwDCgBuQAgAMroMAiIDFABwIAcAIwARAwAABAABAAIAAADRCgAADAAAAGIA"
+ "AgASIRIy/CAAACEACgFuIAUAEAAOAAMAAQACAAAA2AoAAAsAAAASIBIx/CABABAACgASUXEgDQAB"
+ "AA4AAAAAAAAAAAAAAAMAAAAAAAAAAQAAAMwDAAACAAAA1AMAAAQAAADgAwAAAgAAAAQABAANAAAA"
+ "FgAQABgAHQAAAAEAGwAEAAMAAgAQAA4ABQAAAAMAAAAOABAAGAAAAAIAAAABAAEAAwAAAAIAAgAC"
+ "AAAAAwAAAAMAAwADAAAAAQAAAAQAAAACAAAABQAFAAIAAAAPAA8AAgAAABAAEAABAAAAFQAAAAEA"
+ "AAAdAAAAAQAAAB4AASgABjwqPjtKKQAGPGluaXQ+AAFCAAFDAAFEAAFGAAVIZWxsbwABSQADSUlJ"
+ "AA1JTlZPS0VfU1RBVElDAAFKAAFMAARMTExMAA5MTExMWkJDU0lGRExMSgAzTGNvbS9hbmRyb2lk"
+ "L2phY2svYW5ub3RhdGlvbnMvQ2FsbGVkQnlJbnZva2VDdXN0b207ACdMY29tL2FuZHJvaWQvamFj"
+ "ay9hbm5vdGF0aW9ucy9Db25zdGFudDsAMUxjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL0xp"
+ "bmtlck1ldGhvZEhhbmRsZTsAL0xjb20vYW5kcm9pZC9qYWNrL2Fubm90YXRpb25zL01ldGhvZEhh"
+ "bmRsZUtpbmQ7ADNMY29tL2FuZHJvaWQvamFjay9qYXZhNy9pbnZva2VjdXN0b20vdGVzdDAwNC9U"
+ "ZXN0czsAHUxkYWx2aWsvYW5ub3RhdGlvbi9TaWduYXR1cmU7ABpMZGFsdmlrL2Fubm90YXRpb24v"
+ "VGhyb3dzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABBMamF2YS9sYW5nL0NsYXNzABFMamF2YS9s"
+ "YW5nL0NsYXNzOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsAEkxqYXZh"
+ "L2xhbmcvU3lzdGVtOwAVTGphdmEvbGFuZy9UaHJvd2FibGU7ABtMamF2YS9sYW5nL2ludm9rZS9D"
+ "YWxsU2l0ZTsAI0xqYXZhL2xhbmcvaW52b2tlL0NvbnN0YW50Q2FsbFNpdGU7AB9MamF2YS9sYW5n"
+ "L2ludm9rZS9NZXRob2RIYW5kbGU7ACdMamF2YS9sYW5nL2ludm9rZS9NZXRob2RIYW5kbGVzJExv"
+ "b2t1cDsAIExqYXZhL2xhbmcvaW52b2tlL01ldGhvZEhhbmRsZXM7AB1MamF2YS9sYW5nL2ludm9r"
+ "ZS9NZXRob2RUeXBlOwAYTGp1bml0L2ZyYW1ld29yay9Bc3NlcnQ7ABBMb3JnL2p1bml0L1Rlc3Q7"
+ "AAFTAApUZXN0cy5qYXZhAAFWAANWQ0MABFZEREQABFZGRkYAAlZJAANWSUkAA1ZKSgACVkwAA1ZM"
+ "TAACVloAAVoAB1pCQ1NJRkQAE1tMamF2YS9sYW5nL1N0cmluZzsAA2FkZAANYXJndW1lbnRUeXBl"
+ "cwAMYXNzZXJ0RXF1YWxzAAphc3NlcnRUcnVlAAxib29sZWFuVmFsdWUACWJ5dGVWYWx1ZQAJY2hh"
+ "clZhbHVlAApjbGFzc1ZhbHVlAAtkb3VibGVWYWx1ZQAVZW1pdHRlcjogamFjay00LjAtZW5nAA1l"
+ "bmNsb3NpbmdUeXBlAA1maWVsZENhbGxTaXRlAApmaW5kU3RhdGljAApmbG9hdFZhbHVlAAhpbnRW"
+ "YWx1ZQASaW52b2tlTWV0aG9kSGFuZGxlAARraW5kAAxsaW5rZXJNZXRob2QACWxvbmdWYWx1ZQAG"
+ "bG9va3VwAARtYWluABVtZXRob2RIYW5kbGVFeHRyYUFyZ3MABG5hbWUAA291dAAHcHJpbnRsbgAK"
+ "cmV0dXJuVHlwZQAKc2hvcnRWYWx1ZQALc3RyaW5nVmFsdWUABHRlc3QABXZhbHVlACMABw4ANwIA"
+ "AAcOAD4NAAAAAAAAAAAAAAAAAAcOPEtaWmmWw4d4h6UAUgEABw60AE4ABw6lAAAGBTUcAhgEGARD"
+ "HAEdCAQ1HA0YFhgQGBgYHRgAGAEYGxgEGAMYAhgQGA4YBT4YCkQbAEoXRUkcCh0HATgcAT8dBwE5"
+ "HAEAAR0HATocAQNhHQcBThwBIgAEHQcBQhwBBAEdBwFBHAFwmpkxQR0HATwcAfGamZmZmZkBQB0H"
+ "AU8cARcHHQcBOxwBGAodBwFGHAFmFc1bB0oXNE0YBAILAVEcCRcAFyAXGhciFzIXGhcXFwEXHQIM"
+ "AVEcARgSARoADRYAFzQVAAQBBAEEYSQABAQBcJqZMUHxmpmZmZmZAUAXBxgKZhXNWwcBAAQBAQkA"
+ "gYAE7AcBCoQIAQqcCAEJ1AkEAfwJAAATAAAAAAAAAAEAAAAAAAAAAQAAAFIAAABwAAAAAgAAAB8A"
+ "AAC4AQAAAwAAABAAAAA0AgAABAAAAAMAAAD0AgAABQAAABIAAAAMAwAABwAAAAIAAACcAwAABgAA"
+ "AAEAAACkAwAACAAAAAEAAADEAwAAAxAAAAMAAADMAwAAASAAAAUAAADsAwAABiAAAAEAAAAkBQAA"
+ "ARAAAA0AAABMBQAAAiAAAFIAAADWBQAAAyAAAAUAAACoCgAABCAAAAQAAADeCgAABSAAAAEAAACd"
+ "CwAAACAAAAEAAADGCwAAABAAAAEAAADkCwAA"
+};
+
+TEST_F(DexFileVerifierTest, InvokeCustomDexSamples) {
+ for (size_t i = 0; i < arraysize(kInvokeCustomDexFiles); ++i) {
+ size_t length;
+ std::unique_ptr<uint8_t[]> dex_bytes(DecodeBase64(kInvokeCustomDexFiles[i], &length));
+ CHECK(dex_bytes != nullptr);
+ // Note: `dex_file` will be destroyed before `dex_bytes`.
+ std::unique_ptr<DexFile> dex_file(GetDexFile(dex_bytes.get(), length));
+ std::string error_msg;
+ EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(),
+ dex_file->Begin(),
+ dex_file->Size(),
+ "good checksum, verify",
+ /*verify_checksum*/ true,
+ &error_msg));
+ // TODO(oth): Test corruptions (b/35308502)
+ }
+}
+
} // namespace art
diff --git a/runtime/gc/allocation_record.cc b/runtime/gc/allocation_record.cc
index e18a955..122f779 100644
--- a/runtime/gc/allocation_record.cc
+++ b/runtime/gc/allocation_record.cc
@@ -292,7 +292,7 @@
(kUseReadBarrier && !self->GetWeakRefAccessEnabled()))) {
// Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
// presence of threads blocking for weak ref access.
- self->CheckEmptyCheckpoint();
+ self->CheckEmptyCheckpointFromWeakRefAccess(Locks::alloc_tracker_lock_);
new_record_condition_.WaitHoldingLocks(self);
}
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index f12ad80..f18ffb4 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -835,65 +835,9 @@
void ConcurrentCopying::IssueEmptyCheckpoint() {
Thread* self = Thread::Current();
ThreadList* thread_list = Runtime::Current()->GetThreadList();
- Barrier* barrier = thread_list->EmptyCheckpointBarrier();
- barrier->Init(self, 0);
- std::vector<uint32_t> runnable_thread_ids; // Used in debug build only
- size_t barrier_count = thread_list->RunEmptyCheckpoint(runnable_thread_ids);
- // If there are no threads to wait which implys that all the checkpoint functions are finished,
- // then no need to release the mutator lock.
- if (barrier_count == 0) {
- return;
- }
// Release locks then wait for all mutator threads to pass the barrier.
Locks::mutator_lock_->SharedUnlock(self);
- {
- ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun);
- if (kIsDebugBuild) {
- static constexpr uint64_t kEmptyCheckpointTimeoutMs = 600 * 1000; // 10 minutes.
- bool timed_out = barrier->Increment(self, barrier_count, kEmptyCheckpointTimeoutMs);
- if (timed_out) {
- std::ostringstream ss;
- ss << "Empty checkpoint timeout\n";
- ss << "Barrier count " << barrier->GetCount(self) << "\n";
- ss << "Runnable thread IDs";
- for (uint32_t tid : runnable_thread_ids) {
- ss << " " << tid;
- }
- ss << "\n";
- Locks::mutator_lock_->Dump(ss);
- ss << "\n";
- LOG(FATAL_WITHOUT_ABORT) << ss.str();
- // Some threads in 'runnable_thread_ids' are probably stuck. Try to dump their stacks.
- // Avoid using ThreadList::Dump() initially because it is likely to get stuck as well.
- {
- ScopedObjectAccess soa(self);
- MutexLock mu1(self, *Locks::thread_list_lock_);
- for (Thread* thread : thread_list->GetList()) {
- uint32_t tid = thread->GetThreadId();
- bool is_in_runnable_thread_ids =
- std::find(runnable_thread_ids.begin(), runnable_thread_ids.end(), tid) !=
- runnable_thread_ids.end();
- if (is_in_runnable_thread_ids &&
- thread->ReadFlag(kEmptyCheckpointRequest)) {
- // Found a runnable thread that hasn't responded to the empty checkpoint request.
- // Assume it's stuck and safe to dump its stack.
- thread->Dump(LOG_STREAM(FATAL_WITHOUT_ABORT),
- /*dump_native_stack*/ true,
- /*backtrace_map*/ nullptr,
- /*force_dump_stack*/ true);
- }
- }
- }
- LOG(FATAL_WITHOUT_ABORT)
- << "Dumped runnable threads that haven't responded to empty checkpoint.";
- // Now use ThreadList::Dump() to dump more threads, noting it may get stuck.
- thread_list->Dump(LOG_STREAM(FATAL_WITHOUT_ABORT));
- LOG(FATAL) << "Dumped all threads.";
- }
- } else {
- barrier->Increment(self, barrier_count);
- }
- }
+ thread_list->RunEmptyCheckpoint();
Locks::mutator_lock_->SharedLock(self);
}
diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc
index c154836..86b1522 100644
--- a/runtime/gc/reference_processor.cc
+++ b/runtime/gc/reference_processor.cc
@@ -104,7 +104,7 @@
}
// Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
// presence of threads blocking for weak ref access.
- self->CheckEmptyCheckpoint();
+ self->CheckEmptyCheckpointFromWeakRefAccess(Locks::reference_processor_lock_);
condition_.WaitHoldingLocks(self);
}
return reference->GetReferent();
@@ -292,7 +292,7 @@
(kUseReadBarrier && !self->GetWeakRefAccessEnabled())) {
// Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
// presence of threads blocking for weak ref access.
- self->CheckEmptyCheckpoint();
+ self->CheckEmptyCheckpointFromWeakRefAccess(Locks::reference_processor_lock_);
condition_.WaitHoldingLocks(self);
}
}
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index ffbca52..442a42e 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -587,15 +587,18 @@
}
std::unique_ptr<MemMap> map;
+
// GetImageBegin is the preferred address to map the image. If we manage to map the
// image at the image begin, the amount of fixup work required is minimized.
+ // If it is pic we will retry with error_msg for the failure case. Pass a null error_msg to
+ // avoid reading proc maps for a mapping failure and slowing everything down.
map.reset(LoadImageFile(image_filename,
image_location,
*image_header,
image_header->GetImageBegin(),
file->Fd(),
logger,
- error_msg));
+ image_header->IsPic() ? nullptr : error_msg));
// If the header specifies PIC mode, we can also map at a random low_4gb address since we can
// relocate in-place.
if (map == nullptr && image_header->IsPic()) {
@@ -765,8 +768,10 @@
if (storage_mode != ImageHeader::kStorageModeLZ4 &&
storage_mode != ImageHeader::kStorageModeLZ4HC) {
- *error_msg = StringPrintf("Invalid storage mode in image header %d",
- static_cast<int>(storage_mode));
+ if (error_msg != nullptr) {
+ *error_msg = StringPrintf("Invalid storage mode in image header %d",
+ static_cast<int>(storage_mode));
+ }
return nullptr;
}
@@ -790,7 +795,7 @@
image_filename,
error_msg));
if (temp_map == nullptr) {
- DCHECK(!error_msg->empty());
+ DCHECK(error_msg == nullptr || !error_msg->empty());
return nullptr;
}
memcpy(map->Begin(), &image_header, sizeof(ImageHeader));
@@ -802,12 +807,18 @@
reinterpret_cast<char*>(map->Begin()) + decompress_offset,
stored_size,
map->Size() - decompress_offset);
- VLOG(image) << "Decompressing image took " << PrettyDuration(NanoTime() - start);
+ const uint64_t time = NanoTime() - start;
+ // Add one 1 ns to prevent possible divide by 0.
+ VLOG(image) << "Decompressing image took " << PrettyDuration(time) << " ("
+ << PrettySize(static_cast<uint64_t>(map->Size()) * MsToNs(1000) / (time + 1))
+ << "/s)";
if (decompressed_size + sizeof(ImageHeader) != image_header.GetImageSize()) {
- *error_msg = StringPrintf(
- "Decompressed size does not match expected image size %zu vs %zu",
- decompressed_size + sizeof(ImageHeader),
- image_header.GetImageSize());
+ if (error_msg != nullptr) {
+ *error_msg = StringPrintf(
+ "Decompressed size does not match expected image size %zu vs %zu",
+ decompressed_size + sizeof(ImageHeader),
+ image_header.GetImageSize());
+ }
return nullptr;
}
}
diff --git a/runtime/gc/system_weak.h b/runtime/gc/system_weak.h
index e5cddfc..60105f4 100644
--- a/runtime/gc/system_weak.h
+++ b/runtime/gc/system_weak.h
@@ -82,7 +82,7 @@
(kUseReadBarrier && !self->GetWeakRefAccessEnabled()))) {
// Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
// presence of threads blocking for weak ref access.
- self->CheckEmptyCheckpoint();
+ self->CheckEmptyCheckpointFromWeakRefAccess(&allow_disallow_lock_);
new_weak_condition_.WaitHoldingLocks(self);
}
}
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index f11e2cb..d862ff2 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -1010,15 +1010,18 @@
void Instrumentation::ExceptionCaughtEvent(Thread* thread,
mirror::Throwable* exception_object) const {
+ Thread* self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object));
if (HasExceptionCaughtListeners()) {
- DCHECK_EQ(thread->GetException(), exception_object);
+ DCHECK_EQ(thread->GetException(), h_exception.Get());
thread->ClearException();
for (InstrumentationListener* listener : exception_caught_listeners_) {
if (listener != nullptr) {
- listener->ExceptionCaught(thread, exception_object);
+ listener->ExceptionCaught(thread, h_exception.Get());
}
}
- thread->SetException(exception_object);
+ thread->SetException(h_exception.Get());
}
}
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index e0f28ad..a341cdb 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -572,7 +572,7 @@
while (!kUseReadBarrier && UNLIKELY(!MayAccessWeakGlobals(self))) {
// Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
// presence of threads blocking for weak ref access.
- self->CheckEmptyCheckpoint();
+ self->CheckEmptyCheckpointFromWeakRefAccess(Locks::jni_weak_globals_lock_);
weak_globals_add_condition_.WaitHoldingLocks(self);
}
IndirectRef ref = weak_globals_.Add(kIRTFirstSegment, obj);
@@ -706,7 +706,7 @@
while (UNLIKELY(!MayAccessWeakGlobals(self))) {
// Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
// presence of threads blocking for weak ref access.
- self->CheckEmptyCheckpoint();
+ self->CheckEmptyCheckpointFromWeakRefAccess(Locks::jni_weak_globals_lock_);
weak_globals_add_condition_.WaitHoldingLocks(self);
}
return weak_globals_.Get(ref);
@@ -731,7 +731,7 @@
while (UNLIKELY(!MayAccessWeakGlobals(self))) {
// Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
// presence of threads blocking for weak ref access.
- self->CheckEmptyCheckpoint();
+ self->CheckEmptyCheckpointFromWeakRefAccess(Locks::jni_weak_globals_lock_);
weak_globals_add_condition_.WaitHoldingLocks(self);
}
// When just checking a weak ref has been cleared, avoid triggering the read barrier in decode
diff --git a/runtime/jdwp/jdwp.h b/runtime/jdwp/jdwp.h
index e5d34e1..86af6d4 100644
--- a/runtime/jdwp/jdwp.h
+++ b/runtime/jdwp/jdwp.h
@@ -22,6 +22,7 @@
#include "jdwp/jdwp_bits.h"
#include "jdwp/jdwp_constants.h"
#include "jdwp/jdwp_expand_buf.h"
+#include "obj_ptr.h"
#include <pthread.h>
#include <stddef.h>
@@ -286,6 +287,10 @@
REQUIRES(!event_list_lock_)
REQUIRES_SHARED(Locks::mutator_lock_);
+ void UnregisterLocationEventsOnClass(ObjPtr<mirror::Class> klass)
+ REQUIRES(!event_list_lock_)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
/*
* Unregister all events.
*/
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index 172f52a..96249f9 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -251,6 +251,43 @@
return ERR_NONE;
}
+void JdwpState::UnregisterLocationEventsOnClass(ObjPtr<mirror::Class> klass) {
+ VLOG(jdwp) << "Removing events within " << klass->PrettyClass();
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<mirror::Class> h_klass(hs.NewHandle(klass));
+ std::vector<JdwpEvent*> to_remove;
+ MutexLock mu(Thread::Current(), event_list_lock_);
+ for (JdwpEvent* cur_event = event_list_; cur_event != nullptr; cur_event = cur_event->next) {
+ // Fill in the to_remove list
+ bool found_event = false;
+ for (int i = 0; i < cur_event->modCount && !found_event; i++) {
+ JdwpEventMod& mod = cur_event->mods[i];
+ switch (mod.modKind) {
+ case MK_LOCATION_ONLY: {
+ JdwpLocation& loc = mod.locationOnly.loc;
+ JdwpError error;
+ ObjPtr<mirror::Class> breakpoint_class(
+ Dbg::GetObjectRegistry()->Get<art::mirror::Class*>(loc.class_id, &error));
+ DCHECK_EQ(error, ERR_NONE);
+ if (breakpoint_class == h_klass.Get()) {
+ to_remove.push_back(cur_event);
+ found_event = true;
+ }
+ break;
+ }
+ default:
+ // TODO Investigate how we should handle non-locationOnly events.
+ break;
+ }
+ }
+ }
+
+ for (JdwpEvent* event : to_remove) {
+ UnregisterEvent(event);
+ EventFree(event);
+ }
+}
+
/*
* Remove an event from the list. This will also remove the event from
* any optimization tables, e.g. breakpoints.
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index f5151b5..0ac388a 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -556,12 +556,13 @@
// 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.
+ // Flush caches before we remove write permission because some ARMv8 Qualcomm kernels may
+ // trigger a segfault if a page fault occurs when requesting a cache maintenance operation.
+ // This is a kernel bug that we need to work around until affected devices (e.g. Nexus 5X and
+ // 6P) stop being supported or their kernels are fixed.
//
- // For reference, here are kernel patches discussing about this issue:
- // https://android.googlesource.com/kernel/msm/%2B/0e7f7bcc3fc87489cda5aa6aff8ce40eed912279
- // https://patchwork.kernel.org/patch/9047921/
+ // For reference, this behavior is caused by this commit:
+ // https://android.googlesource.com/kernel/msm/+/3fbe6bc28a6b9939d0650f2f17eb5216c719950c
FlushInstructionCache(reinterpret_cast<char*>(code_ptr),
reinterpret_cast<char*>(code_ptr + code_size));
DCHECK(!Runtime::Current()->IsAotCompiler());
diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc
index 9ba2d1a..54fc038 100644
--- a/runtime/jit/profile_compilation_info.cc
+++ b/runtime/jit/profile_compilation_info.cc
@@ -664,6 +664,38 @@
return os.str();
}
+void ProfileCompilationInfo::GetClassNames(
+ const std::vector<std::unique_ptr<const DexFile>>* dex_files,
+ std::set<std::string>* class_names) const {
+ std::unique_ptr<const std::vector<const DexFile*>> non_owning_dex_files(
+ MakeNonOwningVector(dex_files));
+ GetClassNames(non_owning_dex_files.get(), class_names);
+}
+
+void ProfileCompilationInfo::GetClassNames(const std::vector<const DexFile*>* dex_files,
+ std::set<std::string>* class_names) const {
+ if (info_.empty()) {
+ return;
+ }
+ for (const auto& it : info_) {
+ const std::string& location = it.first;
+ const DexFileData& dex_data = it.second;
+ const DexFile* dex_file = nullptr;
+ if (dex_files != nullptr) {
+ for (size_t i = 0; i < dex_files->size(); i++) {
+ if (location == (*dex_files)[i]->GetLocation()) {
+ dex_file = (*dex_files)[i];
+ }
+ }
+ }
+ for (const auto class_it : dex_data.class_set) {
+ if (dex_file != nullptr) {
+ class_names->insert(std::string(dex_file->PrettyType(class_it)));
+ }
+ }
+ }
+}
+
bool ProfileCompilationInfo::Equals(const ProfileCompilationInfo& other) {
return info_.Equals(other.info_);
}
diff --git a/runtime/jit/profile_compilation_info.h b/runtime/jit/profile_compilation_info.h
index b1587c0..758b46d 100644
--- a/runtime/jit/profile_compilation_info.h
+++ b/runtime/jit/profile_compilation_info.h
@@ -78,6 +78,11 @@
std::string DumpInfo(const std::vector<const DexFile*>* dex_files,
bool print_full_dex_location = true) const;
+ void GetClassNames(const std::vector<std::unique_ptr<const DexFile>>* dex_files,
+ std::set<std::string>* class_names) const;
+ void GetClassNames(const std::vector<const DexFile*>* dex_files,
+ std::set<std::string>* class_names) const;
+
bool Equals(const ProfileCompilationInfo& other);
static std::string GetProfileDexFileKey(const std::string& dex_location);
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index dce56b3..93c212b 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -400,7 +400,7 @@
// reuse means it is okay that it overlaps an existing page mapping.
// Only use this if you actually made the page reservation yourself.
CHECK(expected_ptr != nullptr);
-
+ DCHECK(error_msg != nullptr);
DCHECK(ContainedWithinExistingMap(expected_ptr, byte_count, error_msg))
<< ((error_msg != nullptr) ? *error_msg : std::string());
flags |= MAP_FIXED;
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index a32003e..f3cb0df 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -1380,7 +1380,7 @@
while (!kUseReadBarrier && UNLIKELY(!allow_new_monitors_)) {
// Check and run the empty checkpoint before blocking so the empty checkpoint will work in the
// presence of threads blocking for weak ref access.
- self->CheckEmptyCheckpoint();
+ self->CheckEmptyCheckpointFromWeakRefAccess(&monitor_list_lock_);
monitor_add_condition_.WaitHoldingLocks(self);
}
list_.push_front(m);
diff --git a/runtime/oat.h b/runtime/oat.h
index e7e8328..a764e0e 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
class PACKED(4) OatHeader {
public:
static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
- static constexpr uint8_t kOatVersion[] = { '1', '1', '0', '\0' }; // Clean up code info change.
+ static constexpr uint8_t kOatVersion[] = { '1', '1', '1', '\0' }; // Revert^3 hash-based DexCache types.
static constexpr const char* kImageLocationKey = "image-location";
static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
diff --git a/runtime/openjdkjvmti/ti_class.cc b/runtime/openjdkjvmti/ti_class.cc
index c14fd84..7ca233f 100644
--- a/runtime/openjdkjvmti/ti_class.cc
+++ b/runtime/openjdkjvmti/ti_class.cc
@@ -42,12 +42,17 @@
#include "class_linker.h"
#include "common_throws.h"
#include "events-inl.h"
+#include "gc/heap.h"
+#include "gc_root.h"
#include "handle.h"
#include "jni_env_ext-inl.h"
#include "jni_internal.h"
#include "mirror/array-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_ext.h"
+#include "mirror/object_reference.h"
+#include "mirror/object-inl.h"
+#include "mirror/reference.h"
#include "runtime.h"
#include "runtime_callbacks.h"
#include "ScopedLocalRef.h"
@@ -261,15 +266,22 @@
thread_jni.get(),
jklass.get());
}
- AddTempClass(thread, jklass.get());
+ if (klass->IsTemp()) {
+ AddTempClass(thread, jklass.get());
+ }
}
}
- void ClassPrepare(art::Handle<art::mirror::Class> temp_klass ATTRIBUTE_UNUSED,
+ void ClassPrepare(art::Handle<art::mirror::Class> temp_klass,
art::Handle<art::mirror::Class> klass)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
if (event_handler->IsEventEnabledAnywhere(ArtJvmtiEvent::kClassPrepare)) {
art::Thread* thread = art::Thread::Current();
+ if (temp_klass.Get() != klass.Get()) {
+ DCHECK(temp_klass->IsTemp());
+ DCHECK(temp_klass->IsRetired());
+ HandleTempClass(thread, temp_klass, klass);
+ }
ScopedLocalRef<jclass> jklass(thread->GetJniEnv(),
thread->GetJniEnv()->AddLocalReference<jclass>(klass.Get()));
ScopedLocalRef<jthread> thread_jni(
@@ -283,32 +295,209 @@
}
}
+ // To support parallel class-loading, we need to perform some locking dances here. Namely,
+ // the fixup stage must not be holding the temp_classes lock when it fixes up the system
+ // (as that requires suspending all mutators).
+
void AddTempClass(art::Thread* self, jclass klass) {
std::unique_lock<std::mutex> mu(temp_classes_lock);
- temp_classes.push_back(reinterpret_cast<jclass>(self->GetJniEnv()->NewGlobalRef(klass)));
+ jclass global_klass = reinterpret_cast<jclass>(self->GetJniEnv()->NewGlobalRef(klass));
+ temp_classes.push_back(global_klass);
}
- void HandleTempClass(art::Handle<art::mirror::Class> temp_klass,
+ void HandleTempClass(art::Thread* self,
+ art::Handle<art::mirror::Class> temp_klass,
art::Handle<art::mirror::Class> klass)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
- std::unique_lock<std::mutex> mu(temp_classes_lock);
- if (temp_classes.empty()) {
- return;
- }
-
- art::Thread* self = art::Thread::Current();
- for (auto it = temp_classes.begin(); it != temp_classes.end(); ++it) {
- if (temp_klass.Get() == art::ObjPtr<art::mirror::Class>::DownCast(self->DecodeJObject(*it))) {
- temp_classes.erase(it);
- FixupTempClass(temp_klass, klass);
+ bool requires_fixup = false;
+ {
+ std::unique_lock<std::mutex> mu(temp_classes_lock);
+ if (temp_classes.empty()) {
+ return;
}
+
+ for (auto it = temp_classes.begin(); it != temp_classes.end(); ++it) {
+ if (temp_klass.Get() == art::ObjPtr<art::mirror::Class>::DownCast(self->DecodeJObject(*it))) {
+ self->GetJniEnv()->DeleteGlobalRef(*it);
+ temp_classes.erase(it);
+ requires_fixup = true;
+ break;
+ }
+ }
+ }
+ if (requires_fixup) {
+ FixupTempClass(self, temp_klass, klass);
}
}
- void FixupTempClass(art::Handle<art::mirror::Class> temp_klass ATTRIBUTE_UNUSED,
- art::Handle<art::mirror::Class> klass ATTRIBUTE_UNUSED)
+ void FixupTempClass(art::Thread* self,
+ art::Handle<art::mirror::Class> temp_klass,
+ art::Handle<art::mirror::Class> klass)
REQUIRES_SHARED(art::Locks::mutator_lock_) {
- // TODO: Implement.
+ // Suspend everything.
+ art::gc::Heap* heap = art::Runtime::Current()->GetHeap();
+ if (heap->IsGcConcurrentAndMoving()) {
+ // Need to take a heap dump while GC isn't running. See the
+ // comment in Heap::VisitObjects().
+ heap->IncrementDisableMovingGC(self);
+ }
+ {
+ art::ScopedThreadSuspension sts(self, art::kWaitingForVisitObjects);
+ art::ScopedSuspendAll ssa("FixupTempClass");
+
+ art::mirror::Class* input = temp_klass.Get();
+ art::mirror::Class* output = klass.Get();
+
+ FixupGlobalReferenceTables(input, output);
+ FixupLocalReferenceTables(self, input, output);
+ FixupHeap(input, output);
+ }
+ if (heap->IsGcConcurrentAndMoving()) {
+ heap->DecrementDisableMovingGC(self);
+ }
+ }
+
+ class RootUpdater : public art::RootVisitor {
+ public:
+ RootUpdater(const art::mirror::Class* input, art::mirror::Class* output)
+ : input_(input), output_(output) {}
+
+ void VisitRoots(art::mirror::Object*** roots,
+ size_t count,
+ const art::RootInfo& info ATTRIBUTE_UNUSED)
+ OVERRIDE {
+ for (size_t i = 0; i != count; ++i) {
+ if (*roots[i] == input_) {
+ *roots[i] = output_;
+ }
+ }
+ }
+
+ void VisitRoots(art::mirror::CompressedReference<art::mirror::Object>** roots,
+ size_t count,
+ const art::RootInfo& info ATTRIBUTE_UNUSED)
+ OVERRIDE REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ for (size_t i = 0; i != count; ++i) {
+ if (roots[i]->AsMirrorPtr() == input_) {
+ roots[i]->Assign(output_);
+ }
+ }
+ }
+
+ private:
+ const art::mirror::Class* input_;
+ art::mirror::Class* output_;
+ };
+
+ void FixupGlobalReferenceTables(art::mirror::Class* input, art::mirror::Class* output)
+ REQUIRES(art::Locks::mutator_lock_) {
+ art::JavaVMExt* java_vm = art::Runtime::Current()->GetJavaVM();
+
+ // Fix up the global table with a root visitor.
+ RootUpdater global_update(input, output);
+ java_vm->VisitRoots(&global_update);
+
+ class WeakGlobalUpdate : public art::IsMarkedVisitor {
+ public:
+ WeakGlobalUpdate(art::mirror::Class* root_input, art::mirror::Class* root_output)
+ : input_(root_input), output_(root_output) {}
+
+ art::mirror::Object* IsMarked(art::mirror::Object* obj) OVERRIDE {
+ if (obj == input_) {
+ return output_;
+ }
+ return obj;
+ }
+
+ private:
+ const art::mirror::Class* input_;
+ art::mirror::Class* output_;
+ };
+ WeakGlobalUpdate weak_global_update(input, output);
+ java_vm->SweepJniWeakGlobals(&weak_global_update);
+ }
+
+ void FixupLocalReferenceTables(art::Thread* self,
+ art::mirror::Class* input,
+ art::mirror::Class* output)
+ REQUIRES(art::Locks::mutator_lock_) {
+ class LocalUpdate {
+ public:
+ LocalUpdate(const art::mirror::Class* root_input, art::mirror::Class* root_output)
+ : input_(root_input), output_(root_output) {}
+
+ static void Callback(art::Thread* t, void* arg) REQUIRES(art::Locks::mutator_lock_) {
+ LocalUpdate* local = reinterpret_cast<LocalUpdate*>(arg);
+
+ // Fix up the local table with a root visitor.
+ RootUpdater local_update(local->input_, local->output_);
+ t->GetJniEnv()->locals.VisitRoots(
+ &local_update, art::RootInfo(art::kRootJNILocal, t->GetThreadId()));
+ }
+
+ private:
+ const art::mirror::Class* input_;
+ art::mirror::Class* output_;
+ };
+ LocalUpdate local_upd(input, output);
+ art::MutexLock mu(self, *art::Locks::thread_list_lock_);
+ art::Runtime::Current()->GetThreadList()->ForEach(LocalUpdate::Callback, &local_upd);
+ }
+
+ void FixupHeap(art::mirror::Class* input, art::mirror::Class* output)
+ REQUIRES(art::Locks::mutator_lock_) {
+ class HeapFixupVisitor {
+ public:
+ HeapFixupVisitor(const art::mirror::Class* root_input, art::mirror::Class* root_output)
+ : input_(root_input), output_(root_output) {}
+
+ void operator()(art::mirror::Object* src,
+ art::MemberOffset field_offset,
+ bool is_static ATTRIBUTE_UNUSED) const
+ REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ art::mirror::HeapReference<art::mirror::Object>* trg =
+ src->GetFieldObjectReferenceAddr(field_offset);
+ if (trg->AsMirrorPtr() == input_) {
+ DCHECK_NE(field_offset.Uint32Value(), 0u); // This shouldn't be the class field of
+ // an object.
+ trg->Assign(output_);
+ }
+ }
+
+ void operator()(art::ObjPtr<art::mirror::Class> klass ATTRIBUTE_UNUSED,
+ art::ObjPtr<art::mirror::Reference> reference) const
+ REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ art::mirror::Object* val = reference->GetReferent();
+ if (val == input_) {
+ reference->SetReferent<false>(output_);
+ }
+ }
+
+ void VisitRoot(art::mirror::CompressedReference<art::mirror::Object>* root ATTRIBUTE_UNUSED)
+ const {
+ LOG(FATAL) << "Unreachable";
+ }
+
+ void VisitRootIfNonNull(
+ art::mirror::CompressedReference<art::mirror::Object>* root ATTRIBUTE_UNUSED) const {
+ LOG(FATAL) << "Unreachable";
+ }
+
+ static void AllObjectsCallback(art::mirror::Object* obj, void* arg)
+ REQUIRES_SHARED(art::Locks::mutator_lock_) {
+ HeapFixupVisitor* hfv = reinterpret_cast<HeapFixupVisitor*>(arg);
+
+ // Visit references, not native roots.
+ obj->VisitReferences<false>(*hfv, *hfv);
+ }
+
+ private:
+ const art::mirror::Class* input_;
+ art::mirror::Class* output_;
+ };
+ HeapFixupVisitor hfv(input, output);
+ art::Runtime::Current()->GetHeap()->VisitObjectsPaused(HeapFixupVisitor::AllObjectsCallback,
+ &hfv);
}
// A set of all the temp classes we have handed out. We have to fix up references to these.
diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc
index f0c0dbc..843fd8c 100644
--- a/runtime/openjdkjvmti/ti_redefine.cc
+++ b/runtime/openjdkjvmti/ti_redefine.cc
@@ -38,12 +38,17 @@
#include "art_jvmti.h"
#include "base/array_slice.h"
#include "base/logging.h"
+#include "debugger.h"
#include "dex_file.h"
#include "dex_file_types.h"
#include "events-inl.h"
#include "gc/allocation_listener.h"
#include "gc/heap.h"
#include "instrumentation.h"
+#include "jdwp/jdwp.h"
+#include "jdwp/jdwp_constants.h"
+#include "jdwp/jdwp_event.h"
+#include "jdwp/object_registry.h"
#include "jit/jit.h"
#include "jit/jit_code_cache.h"
#include "jni_env_ext-inl.h"
@@ -966,6 +971,23 @@
return true;
}
+void Redefiner::ClassRedefinition::UnregisterBreakpoints() {
+ DCHECK(art::Dbg::IsDebuggerActive());
+ art::JDWP::JdwpState* state = art::Dbg::GetJdwpState();
+ if (state != nullptr) {
+ state->UnregisterLocationEventsOnClass(GetMirrorClass());
+ }
+}
+
+void Redefiner::UnregisterAllBreakpoints() {
+ if (LIKELY(!art::Dbg::IsDebuggerActive())) {
+ return;
+ }
+ for (Redefiner::ClassRedefinition& redef : redefinitions_) {
+ redef.UnregisterBreakpoints();
+ }
+}
+
bool Redefiner::CheckAllRedefinitionAreValid() {
for (Redefiner::ClassRedefinition& redef : redefinitions_) {
if (!redef.CheckRedefinitionIsValid()) {
@@ -1044,6 +1066,7 @@
// cleaned up by the GC eventually.
return result_;
}
+ // At this point we can no longer fail without corrupting the runtime state.
int32_t counter = 0;
for (Redefiner::ClassRedefinition& redef : redefinitions_) {
if (holder.GetSourceClassLoader(counter) == nullptr) {
@@ -1051,6 +1074,7 @@
}
counter++;
}
+ UnregisterAllBreakpoints();
// Disable GC and wait for it to be done if we are a moving GC. This is fine since we are done
// allocating so no deadlocks.
art::gc::Heap* heap = runtime_->GetHeap();
@@ -1083,9 +1107,7 @@
holder.GetOriginalDexFileBytes(counter));
counter++;
}
- // TODO Verify the new Class.
// TODO Shrink the obsolete method maps if possible?
- // TODO find appropriate class loader.
// TODO Put this into a scoped thing.
runtime_->GetThreadList()->ResumeAll();
// Get back shared mutator lock as expected for return.
diff --git a/runtime/openjdkjvmti/ti_redefine.h b/runtime/openjdkjvmti/ti_redefine.h
index 421d22e..c441377 100644
--- a/runtime/openjdkjvmti/ti_redefine.h
+++ b/runtime/openjdkjvmti/ti_redefine.h
@@ -207,6 +207,8 @@
void ReleaseDexFile() REQUIRES_SHARED(art::Locks::mutator_lock_);
+ void UnregisterBreakpoints() REQUIRES_SHARED(art::Locks::mutator_lock_);
+
private:
Redefiner* driver_;
jclass klass_;
@@ -250,6 +252,7 @@
bool FinishAllRemainingAllocations(RedefinitionDataHolder& holder)
REQUIRES_SHARED(art::Locks::mutator_lock_);
void ReleaseAllDexFiles() REQUIRES_SHARED(art::Locks::mutator_lock_);
+ void UnregisterAllBreakpoints() REQUIRES_SHARED(art::Locks::mutator_lock_);
void RecordFailure(jvmtiError result, const std::string& class_sig, const std::string& error_msg);
void RecordFailure(jvmtiError result, const std::string& error_msg) {
diff --git a/runtime/thread-inl.h b/runtime/thread-inl.h
index c92305f..8d94626 100644
--- a/runtime/thread-inl.h
+++ b/runtime/thread-inl.h
@@ -80,7 +80,34 @@
}
}
-inline void Thread::CheckEmptyCheckpoint() {
+inline void Thread::CheckEmptyCheckpointFromWeakRefAccess(BaseMutex* cond_var_mutex) {
+ Thread* self = Thread::Current();
+ DCHECK_EQ(self, this);
+ for (;;) {
+ if (ReadFlag(kEmptyCheckpointRequest)) {
+ RunEmptyCheckpoint();
+ // Check we hold only an expected mutex when accessing weak ref.
+ if (kIsDebugBuild) {
+ for (int i = kLockLevelCount - 1; i >= 0; --i) {
+ BaseMutex* held_mutex = self->GetHeldMutex(static_cast<LockLevel>(i));
+ if (held_mutex != nullptr &&
+ held_mutex != Locks::mutator_lock_ &&
+ held_mutex != cond_var_mutex) {
+ std::vector<BaseMutex*>& expected_mutexes = Locks::expected_mutexes_on_weak_ref_access_;
+ CHECK(std::find(expected_mutexes.begin(), expected_mutexes.end(), held_mutex) !=
+ expected_mutexes.end())
+ << "Holding unexpected mutex " << held_mutex->GetName()
+ << " when accessing weak ref";
+ }
+ }
+ }
+ } else {
+ break;
+ }
+ }
+}
+
+inline void Thread::CheckEmptyCheckpointFromMutex() {
DCHECK_EQ(Thread::Current(), this);
for (;;) {
if (ReadFlag(kEmptyCheckpointRequest)) {
diff --git a/runtime/thread.h b/runtime/thread.h
index 3a1b7da..a46e799 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -176,7 +176,8 @@
void CheckSuspend() REQUIRES_SHARED(Locks::mutator_lock_);
// Process a pending empty checkpoint if pending.
- void CheckEmptyCheckpoint() REQUIRES_SHARED(Locks::mutator_lock_);
+ void CheckEmptyCheckpointFromWeakRefAccess(BaseMutex* cond_var_mutex);
+ void CheckEmptyCheckpointFromMutex();
static Thread* FromManagedThread(const ScopedObjectAccessAlreadyRunnable& ts,
ObjPtr<mirror::Object> thread_peer)
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index df8acc3..caed369 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -379,13 +379,15 @@
return count;
}
-size_t ThreadList::RunEmptyCheckpoint(std::vector<uint32_t>& runnable_thread_ids) {
+void ThreadList::RunEmptyCheckpoint() {
Thread* self = Thread::Current();
Locks::mutator_lock_->AssertNotExclusiveHeld(self);
Locks::thread_list_lock_->AssertNotHeld(self);
Locks::thread_suspend_count_lock_->AssertNotHeld(self);
-
+ std::vector<uint32_t> runnable_thread_ids;
size_t count = 0;
+ Barrier* barrier = empty_checkpoint_barrier_.get();
+ barrier->Init(self, 0);
{
MutexLock mu(self, *Locks::thread_list_lock_);
MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
@@ -415,8 +417,72 @@
// checkpoint request. Otherwise we will hang as they are blocking in the kRunnable state.
Runtime::Current()->GetHeap()->GetReferenceProcessor()->BroadcastForSlowPath(self);
Runtime::Current()->BroadcastForNewSystemWeaks(/*broadcast_for_checkpoint*/true);
-
- return count;
+ {
+ ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun);
+ uint64_t total_wait_time = 0;
+ bool first_iter = true;
+ while (true) {
+ // Wake up the runnable threads blocked on the mutexes that another thread, which is blocked
+ // on a weak ref access, holds (indirectly blocking for weak ref access through another thread
+ // and a mutex.) This needs to be done periodically because the thread may be preempted
+ // between the CheckEmptyCheckpointFromMutex call and the subsequent futex wait in
+ // Mutex::ExclusiveLock, etc. when the wakeup via WakeupToRespondToEmptyCheckpoint
+ // arrives. This could cause a *very rare* deadlock, if not repeated. Most of the cases are
+ // handled in the first iteration.
+ for (BaseMutex* mutex : Locks::expected_mutexes_on_weak_ref_access_) {
+ mutex->WakeupToRespondToEmptyCheckpoint();
+ }
+ static constexpr uint64_t kEmptyCheckpointPeriodicTimeoutMs = 100; // 100ms
+ static constexpr uint64_t kEmptyCheckpointTotalTimeoutMs = 600 * 1000; // 10 minutes.
+ size_t barrier_count = first_iter ? count : 0;
+ first_iter = false; // Don't add to the barrier count from the second iteration on.
+ bool timed_out = barrier->Increment(self, barrier_count, kEmptyCheckpointPeriodicTimeoutMs);
+ if (!timed_out) {
+ break; // Success
+ }
+ // This is a very rare case.
+ total_wait_time += kEmptyCheckpointPeriodicTimeoutMs;
+ if (kIsDebugBuild && total_wait_time > kEmptyCheckpointTotalTimeoutMs) {
+ std::ostringstream ss;
+ ss << "Empty checkpoint timeout\n";
+ ss << "Barrier count " << barrier->GetCount(self) << "\n";
+ ss << "Runnable thread IDs";
+ for (uint32_t tid : runnable_thread_ids) {
+ ss << " " << tid;
+ }
+ ss << "\n";
+ Locks::mutator_lock_->Dump(ss);
+ ss << "\n";
+ LOG(FATAL_WITHOUT_ABORT) << ss.str();
+ // Some threads in 'runnable_thread_ids' are probably stuck. Try to dump their stacks.
+ // Avoid using ThreadList::Dump() initially because it is likely to get stuck as well.
+ {
+ ScopedObjectAccess soa(self);
+ MutexLock mu1(self, *Locks::thread_list_lock_);
+ for (Thread* thread : GetList()) {
+ uint32_t tid = thread->GetThreadId();
+ bool is_in_runnable_thread_ids =
+ std::find(runnable_thread_ids.begin(), runnable_thread_ids.end(), tid) !=
+ runnable_thread_ids.end();
+ if (is_in_runnable_thread_ids &&
+ thread->ReadFlag(kEmptyCheckpointRequest)) {
+ // Found a runnable thread that hasn't responded to the empty checkpoint request.
+ // Assume it's stuck and safe to dump its stack.
+ thread->Dump(LOG_STREAM(FATAL_WITHOUT_ABORT),
+ /*dump_native_stack*/ true,
+ /*backtrace_map*/ nullptr,
+ /*force_dump_stack*/ true);
+ }
+ }
+ }
+ LOG(FATAL_WITHOUT_ABORT)
+ << "Dumped runnable threads that haven't responded to empty checkpoint.";
+ // Now use ThreadList::Dump() to dump more threads, noting it may get stuck.
+ Dump(LOG_STREAM(FATAL_WITHOUT_ABORT));
+ LOG(FATAL) << "Dumped all threads.";
+ }
+ }
+ }
}
// Request that a checkpoint function be run on all active (non-suspended)
diff --git a/runtime/thread_list.h b/runtime/thread_list.h
index b60fca1..70917eb 100644
--- a/runtime/thread_list.h
+++ b/runtime/thread_list.h
@@ -109,9 +109,7 @@
// in-flight mutator heap access (eg. a read barrier.) Runnable threads will respond by
// decrementing the empty checkpoint barrier count. This works even when the weak ref access is
// disabled. Only one concurrent use is currently supported.
- // In debug build, runnable_thread_ids will be populated with the thread IDS of the runnable
- // thread to wait for.
- size_t RunEmptyCheckpoint(std::vector<uint32_t>& runnable_thread_ids)
+ void RunEmptyCheckpoint()
REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
size_t RunCheckpointOnRunnableThreads(Closure* checkpoint_function)
diff --git a/test/616-cha-native/expected.txt b/test/616-cha-native/expected.txt
new file mode 100644
index 0000000..6a5618e
--- /dev/null
+++ b/test/616-cha-native/expected.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/616-cha-native/info.txt b/test/616-cha-native/info.txt
new file mode 100644
index 0000000..a17bcab
--- /dev/null
+++ b/test/616-cha-native/info.txt
@@ -0,0 +1,2 @@
+Test for Class Hierarchy Analysis (CHA) single-implementation status updating
+behavior on an overridden native method.
diff --git a/test/616-cha-native/src/Main.java b/test/616-cha-native/src/Main.java
new file mode 100644
index 0000000..53a463c
--- /dev/null
+++ b/test/616-cha-native/src/Main.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+abstract class A {
+ public abstract void foo();
+}
+
+class B extends A {
+ public native void foo();
+}
+
+class C extends B {
+ public void foo() {}
+}
+
+public class Main {
+ public static void main(String[] args) {
+ System.loadLibrary(args[0]);
+ }
+}
diff --git a/test/616-cha/src/Main.java b/test/616-cha/src/Main.java
index b617944..beea90a 100644
--- a/test/616-cha/src/Main.java
+++ b/test/616-cha/src/Main.java
@@ -196,8 +196,6 @@
// should return true for those cases.
assertSingleImplementation(java.lang.String.class, "charAt", true);
assertSingleImplementation(java.lang.Thread.class, "join", true);
- // We don't set single-implementation modifier bit for native methods.
- assertSingleImplementation(java.lang.Thread.class, "isInterrupted", false);
if (isInterpreted()) {
sIsOptimizing = false;
diff --git a/test/636-arm64-veneer-pool/build b/test/636-arm64-veneer-pool/build
new file mode 100755
index 0000000..27cc4d6
--- /dev/null
+++ b/test/636-arm64-veneer-pool/build
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# Copyright 2017 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.
+# Make us exit on a failure.
+
+set -e
+
+# Use javac+dx instead of jack.
+export USE_JACK=false
+./default-build "$@"
diff --git a/test/636-arm64-veneer-pool/expected.txt b/test/636-arm64-veneer-pool/expected.txt
new file mode 100644
index 0000000..b0aad4d
--- /dev/null
+++ b/test/636-arm64-veneer-pool/expected.txt
@@ -0,0 +1 @@
+passed
diff --git a/test/636-arm64-veneer-pool/info.txt b/test/636-arm64-veneer-pool/info.txt
new file mode 100644
index 0000000..2393be0
--- /dev/null
+++ b/test/636-arm64-veneer-pool/info.txt
@@ -0,0 +1 @@
+Regression test for an issue with VIXL ARM64 veneer pools (b/34850123).
diff --git a/test/636-arm64-veneer-pool/src/Main.java b/test/636-arm64-veneer-pool/src/Main.java
new file mode 100644
index 0000000..8229fee
--- /dev/null
+++ b/test/636-arm64-veneer-pool/src/Main.java
@@ -0,0 +1,4223 @@
+/*
+ * Copyright (C) 2017 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 C0 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C2 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C3 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C4 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C5 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mImpl(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C6 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C7 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C8 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C9 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C10 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C11 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C12 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C13 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C14 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C15 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C16 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C17 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C18 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C19 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C20 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C21 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C22 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C23 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C24 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C25 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C26 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C27 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C28 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C29 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C30 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C31 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C32 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C33 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C34 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C35 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C36 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C37 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C38 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C39 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C40 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C41 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C42 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C43 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C44 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C45 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C46 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C47 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C48 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C49 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C50 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C51 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C52 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C53 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C54 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C55 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C56 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C57 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C58 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C59 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C60 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C61 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C62 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C63 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C64 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C65 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C66 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C67 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C68 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C69 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C70 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C71 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C72 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C73 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C74 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C75 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C76 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C77 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C78 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C79 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C80 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C81 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C82 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C83 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C84 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C85 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C86 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C87 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C88 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C89 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C90 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mReport_Factory(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mApi(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C91 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C92 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C93 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C94 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mImpl(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C95 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C96 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C97 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C98 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C99 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C100 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C101 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C102 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C103 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C104 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C105 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void m_InMemoryScanner(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void m_Scanner(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C106 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C107 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C108 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C109 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C110 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C111 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C112 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C113 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C114 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C115 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C116 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C117 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C118 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C119 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C120 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C121 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C122 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C123 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C124 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C125 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C126 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C127 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C128 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C129 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C130 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C131 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C132 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C133 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C134 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C135 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C136 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C137 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C138 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C139 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C140 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C141 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C142 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C143 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C144 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C145 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C146 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C147 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C148 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C149 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C150 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C151 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C152 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C153 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C154 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C155 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C156 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C157 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C158 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C159 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C160 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C161 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C162 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C163 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C164 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C165 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C166 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C167 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C168 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C169 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C170 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C171 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C172 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C173 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C174 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C175 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C176 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C177 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C178 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C179 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C180 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C181 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C182 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C183 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C184 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C185 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C186 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C187 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C188 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C189 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C190 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C191 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C192 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C193 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C194 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C195 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C196 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C197 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C198 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C199 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C200 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C201 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C202 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C203 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C204 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C205 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C206 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C207 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C208 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C209 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C210 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C211 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C212 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C213 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C214 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C215 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C216 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C217 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C218 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C219 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C220 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C221 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C222 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C223 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C224 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C225 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C226 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C227 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C228 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C229 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C230 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C231 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C232 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C233 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C234 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C235 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C236 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C237 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C238 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C239 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C240 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C241 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C242 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C243 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C244 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C245 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C246 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C247 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C248 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C249 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C250 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C251 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C252 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C253 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C254 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C255 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mFactory(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C256 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C257 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C258 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C259 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C260 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C261 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C262 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C263 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C264 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C265 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C266 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C267 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C268 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C269 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C270 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C271 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C272 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C273 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C274 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C275 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C276 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C277 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C278 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C279 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C280 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C281 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C282 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C283 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C284 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C285 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C286 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C287 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C288 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C289 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C290 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C291 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C292 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C293 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C294 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C295 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C296 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C297 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C298 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C299 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C300 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C301 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C302 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C303 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C304 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C305 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C306 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C307 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C308 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C309 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C310 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C311 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C312 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C313 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C314 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C315 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C316 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C317 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C318 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C319 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C320 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C321 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C322 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C323 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C324 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C325 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C326 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C327 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C328 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C329 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C330 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C331 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C332 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C333 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C334 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C335 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C336 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C337 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C338 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C339 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C340 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C341 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C342 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C343 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C344 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C345 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C346 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C347 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C348 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C349 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C350 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C351 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C352 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C353 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C354 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C355 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C356 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C357 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C358 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C359 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C360 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C361 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C362 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C363 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C364 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C365 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C366 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C367 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C368 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C369 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C370 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C371 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C372 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C373 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C374 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C375 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C376 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C377 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C378 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C379 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C380 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C381 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C382 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C383 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C384 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C385 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C386 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C387 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C388 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C389 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C390 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C391 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C392 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C393 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C394 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C395 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C396 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C397 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C398 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C399 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C400 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C401 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C402 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C403 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C404 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C405 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C406 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C407 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C408 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C409 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C410 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C411 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C412 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C413 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C414 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C415 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C416 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C417 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C418 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C419 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C420 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C421 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C422 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C423 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C424 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C425 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C426 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C427 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C428 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C429 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C430 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C431 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C432 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C433 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C434 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C435 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C436 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C437 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C438 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C439 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C440 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C441 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C442 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C443 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C444 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C445 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C446 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C447 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C448 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C449 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C450 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C451 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C452 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C453 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C454 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C455 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C456 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C457 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mMap(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C458 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C459 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C460 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C461 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C462 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C463 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C464 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C465 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C466 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C467 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C468 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C469 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C470 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C471 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C472 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C473 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C474 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C475 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C476 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C477 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C478 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C479 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C480 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C481 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C482 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C483 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C484 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C485 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C486 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C487 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C488 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C489 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C490 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C491 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C492 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C493 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C494 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C495 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C496 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C497 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C498 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C499 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C500 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C501 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C502 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C503 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C504 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C505 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C506 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C507 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C508 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C509 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C510 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C511 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C512 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C513 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C514 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C515 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C516 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C517 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C518 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C519 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C520 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C521 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C522 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C523 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C524 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C525 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C526 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C527 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C528 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C529 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C530 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C531 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C532 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C533 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C534 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C535 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C536 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C537 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C538 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C539 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C540 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C541 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C542 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C543 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C544 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C545 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C546 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C547 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C548 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C549 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C550 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C551 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C552 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C553 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C554 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C555 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C556 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C557 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C558 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C559 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C560 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C561 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C562 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C563 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C564 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C565 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C566 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C567 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C568 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C569 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C570 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C571 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C572 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C573 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C574 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C575 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C576 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C577 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mDebug(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C578 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C579 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C580 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C581 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C582 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C583 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C584 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C585 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C586 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C587 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C588 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C589 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C590 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C591 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C592 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C593 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C594 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C595 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C596 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C597 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C598 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C599 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C600 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C601 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C602 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C603 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C604 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C605 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C606 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C607 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C608 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C609 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C610 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C611 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C612 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C613 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C614 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C615 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C616 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C617 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C618 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C619 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C620 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C621 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C622 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C623 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C624 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C625 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C626 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C627 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C628 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C629 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C630 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C631 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C632 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C633 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C634 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C635 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C636 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C637 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C638 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C639 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C640 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C641 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C642 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C643 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C644 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C645 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C646 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C647 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C648 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C649 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C650 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C651 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C652 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C653 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C654 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C655 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C656 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C657 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C658 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C659 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C660 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C661 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C662 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C663 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C664 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C665 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C666 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C667 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C668 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C669 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C670 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C671 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C672 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C673 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C674 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C675 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C676 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C677 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C678 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C679 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C680 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C681 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C682 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C683 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C684 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C685 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C686 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C687 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C688 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C689 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C690 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C691 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C692 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C693 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C694 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C695 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C696 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C697 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C698 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C699 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C700 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C701 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C702 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C703 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C704 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C705 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C706 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C707 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C708 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C709 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C710 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C711 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C712 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C713 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C714 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C715 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C716 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C717 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C718 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C719 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C720 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C721 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C722 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C723 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C724 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C725 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C726 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C727 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C728 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C729 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C730 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C731 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C732 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C733 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C734 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C735 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C736 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C737 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C738 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C739 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C740 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C741 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C742 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C743 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C744 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C745 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C746 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C747 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C748 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C749 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C750 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C751 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C752 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C753 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C754 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C755 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C756 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C757 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C758 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C759 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C760 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C761 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C762 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C763 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C764 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C765 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C766 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C767 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C768 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C769 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C770 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C771 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C772 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C773 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C774 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C775 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C776 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C777 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C778 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C779 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C780 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C781 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C782 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C783 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C784 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C785 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C786 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C787 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C788 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C789 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C790 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C791 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C792 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C793 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C794 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C795 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C796 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C797 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C798 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C799 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C800 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C801 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C802 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C803 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C804 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C805 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C806 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C807 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C808 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C809 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C810 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C811 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C812 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C813 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C814 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C815 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C816 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C817 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C818 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C819 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C820 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C821 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C822 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C823 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C824 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C825 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C826 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C827 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C828 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C829 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C830 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C831 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C832 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C833 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C834 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C835 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C836 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C837 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C838 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C839 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C840 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C841 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C842 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C843 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C844 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C845 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C846 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C847 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C848 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mMap(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C849 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C850 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C851 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C852 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C853 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C854 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C855 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C856 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C857 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C858 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C859 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C860 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C861 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C862 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C863 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C864 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C865 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C866 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C867 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C868 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C869 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C870 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mImpl(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C871 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C872 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C873 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C874 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C875 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C876 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C877 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C878 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C879 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C880 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C881 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C882 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C883 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C884 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C885 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C886 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C887 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C888 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C889 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C890 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C891 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C892 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C893 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C894 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C895 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C896 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C897 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C898 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C899 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C900 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C901 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C902 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C903 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C904 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C905 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C906 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C907 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C908 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C909 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C910 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C911 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C912 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C913 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C914 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C915 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C916 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C917 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C918 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C919 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C920 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C921 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C922 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C923 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C924 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C925 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C926 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C927 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C928 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C929 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C930 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C931 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C932 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C933 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C934 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C935 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C936 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C937 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C938 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C939 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C940 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C941 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C942 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C943 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C944 {
+ public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+ public static void mManager(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } }
+}
+class C945 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C946 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C947 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C948 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C949 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C950 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C951 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C952 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C953 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C954 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C955 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C956 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C957 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C958 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C959 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C960 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C961 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C962 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C963 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C964 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C965 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C966 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C967 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C968 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C969 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C970 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C971 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C972 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C973 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C974 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C975 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C976 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C977 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C978 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C979 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C980 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C981 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C982 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C983 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C984 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C985 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C986 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C987 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C988 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C989 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C990 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C991 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C992 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C993 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C994 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C995 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C996 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C997 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C998 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C999 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1000 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1001 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1002 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1003 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1004 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1005 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1006 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1007 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1008 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1009 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1010 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1011 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1012 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1013 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1014 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1015 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1016 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1017 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1018 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1019 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1020 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1021 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1022 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1023 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1024 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1025 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1026 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1027 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1028 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1029 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1030 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1031 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1032 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1033 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1034 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1035 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1036 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1037 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1038 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1039 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1040 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1041 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1042 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1043 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1044 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1045 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1046 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1047 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1048 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1049 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1050 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1051 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1052 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1053 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1054 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1055 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1056 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1057 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1058 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1059 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1060 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1061 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1062 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1063 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1064 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1065 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1066 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1067 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1068 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1069 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1070 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1071 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1072 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1073 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1074 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1075 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1076 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1077 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1078 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1079 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1080 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1081 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1082 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1083 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1084 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1085 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1086 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1087 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1088 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1089 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1090 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1091 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1092 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1093 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1094 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1095 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1096 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1097 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1098 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1099 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1100 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1101 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1102 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1103 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1104 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1105 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1106 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1107 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1108 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1109 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1110 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1111 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1112 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1113 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1114 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1115 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1116 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1117 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1118 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1119 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1120 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1121 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1122 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1123 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1124 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1125 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1126 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1127 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1128 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1129 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1130 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1131 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1132 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1133 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1134 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1135 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1136 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1137 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1138 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1139 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1140 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1141 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1142 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1143 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1144 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1145 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1146 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1147 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1148 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1149 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1150 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1151 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1152 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1153 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1154 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1155 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1156 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1157 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1158 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1159 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1160 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1161 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1162 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1163 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1164 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1165 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1166 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1167 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1168 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1169 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1170 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1171 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1172 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1173 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1174 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1175 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1176 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1177 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1178 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1179 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1180 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1181 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1181a { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1181b { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1182 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1183 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1184 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1185 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1186 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1187 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1188 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1189 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1190 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1191 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1192 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1193 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1194 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1195 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1196 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1197 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1198 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1199 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1200 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1201 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1202 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1203 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1204 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1205 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1206 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1207 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1208 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1209 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1210 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1211 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+class C1212 { public static void m(Context c, Binder b) { /* Defeat inlining. */ if (Main.doThrow) { throw new Error(); } } }
+
+class Context {}
+class Binder {}
+
+public class Main {
+
+ java.util.HashMap<String, Integer> typeMap;
+ private void buildTypeMap() {}
+
+ // TODO: Add Checker assertions?
+ public void configure(Context context, Class<?> cls, Binder binder) {
+ if (this.typeMap == null) {
+ buildTypeMap();
+ }
+ Integer num = (Integer) this.typeMap.get(cls.getName());
+ if (num != null) {
+ switch (num.intValue()) {
+ case 0:
+ C0.m(context, binder);
+ return;
+ case 1:
+ C1.m(context, binder);
+ return;
+ case 2:
+ C2.m(context, binder);
+ return;
+ case 3:
+ C3.m(context, binder);
+ return;
+ case 4:
+ C4.m(context, binder);
+ return;
+ case 5:
+ C5.m(context, binder);
+ return;
+ case 6:
+ C6.m(context, binder);
+ C7.m(context, binder);
+ C8.m(context, binder);
+ return;
+ case 7:
+ C9.m(context, binder);
+ return;
+ case 8:
+ C10.m(context, binder);
+ return;
+ case 9:
+ C11.m(context, binder);
+ return;
+ case 10:
+ C12.m(context, binder);
+ return;
+ case 11:
+ C13.m(context, binder);
+ return;
+ case 12:
+ C14.m(context, binder);
+ return;
+ case 13:
+ C15.m(context, binder);
+ return;
+ case 14:
+ C16.m(context, binder);
+ return;
+ case 15:
+ C17.m(context, binder);
+ return;
+ case 16:
+ C18.m(context, binder);
+ C19.m(context, binder);
+ return;
+ case 17:
+ C20.m(context, binder);
+ return;
+ case 18:
+ C21.m(context, binder);
+ return;
+ case 19:
+ C22.m(context, binder);
+ return;
+ case 20:
+ C23.m(context, binder);
+ C24.m(context, binder);
+ C25.m(context, binder);
+ C26.m(context, binder);
+ C27.m(context, binder);
+ C28.m(context, binder);
+ C29.m(context, binder);
+ C30.m(context, binder);
+ C31.m(context, binder);
+ C32.m(context, binder);
+ C33.m(context, binder);
+ C34.m(context, binder);
+ C35.m(context, binder);
+ C36.m(context, binder);
+ C37.m(context, binder);
+ C38.m(context, binder);
+ C39.m(context, binder);
+ C40.m(context, binder);
+ C41.m(context, binder);
+ C42.m(context, binder);
+ C43.m(context, binder);
+ C44.m(context, binder);
+ C45.m(context, binder);
+ C46.m(context, binder);
+ C47.m(context, binder);
+ C48.m(context, binder);
+ C49.m(context, binder);
+ C50.m(context, binder);
+ C51.m(context, binder);
+ C52.m(context, binder);
+ C53.m(context, binder);
+ C54.m(context, binder);
+ C55.m(context, binder);
+ C56.m(context, binder);
+ C57.m(context, binder);
+ C58.m(context, binder);
+ C59.m(context, binder);
+ C60.m(context, binder);
+ C61.m(context, binder);
+ C62.m(context, binder);
+ C63.m(context, binder);
+ C64.m(context, binder);
+ C65.m(context, binder);
+ C66.m(context, binder);
+ C67.m(context, binder);
+ C68.m(context, binder);
+ C69.m(context, binder);
+ C70.m(context, binder);
+ C71.m(context, binder);
+ C72.m(context, binder);
+ C73.m(context, binder);
+ C74.m(context, binder);
+ C75.m(context, binder);
+ C76.m(context, binder);
+ C77.m(context, binder);
+ C78.m(context, binder);
+ C79.m(context, binder);
+ C80.m(context, binder);
+ C81.m(context, binder);
+ C82.m(context, binder);
+ C83.m(context, binder);
+ C84.m(context, binder);
+ C85.m(context, binder);
+ return;
+ case 21:
+ C86.m(context, binder);
+ return;
+ case 22:
+ C87.m(context, binder);
+ return;
+ case 23:
+ C88.m(context, binder);
+ C89.m(context, binder);
+ return;
+ case 24:
+ C90.m(context, binder);
+ return;
+ case 25:
+ C91.m(context, binder);
+ return;
+ case 26:
+ C92.m(context, binder);
+ return;
+ case 27:
+ C93.m(context, binder);
+ return;
+ case 28:
+ C94.m(context, binder);
+ return;
+ case 29:
+ C95.m(context, binder);
+ return;
+ case 30:
+ C96.m(context, binder);
+ return;
+ case 31:
+ C97.m(context, binder);
+ return;
+ case 32:
+ C98.m(context, binder);
+ C99.m(context, binder);
+ return;
+ case 33:
+ C100.m(context, binder);
+ return;
+ case 34:
+ C101.m(context, binder);
+ return;
+ case 35:
+ C102.m(context, binder);
+ return;
+ case 36:
+ C103.m(context, binder);
+ return;
+ case 37:
+ C104.m(context, binder);
+ return;
+ case 38:
+ C105.m(context, binder);
+ return;
+ case 39:
+ C106.m(context, binder);
+ return;
+ case 40:
+ C107.m(context, binder);
+ return;
+ case 41:
+ C108.m(context, binder);
+ return;
+ case 42:
+ C109.m(context, binder);
+ return;
+ case 43:
+ C110.m(context, binder);
+ return;
+ case 44:
+ C111.m(context, binder);
+ return;
+ case 45:
+ C112.m(context, binder);
+ return;
+ case 46:
+ C113.m(context, binder);
+ return;
+ case 47:
+ C114.m(context, binder);
+ return;
+ case 48:
+ C115.m(context, binder);
+ return;
+ case 49:
+ C116.m(context, binder);
+ return;
+ case 50:
+ C117.m(context, binder);
+ C118.m(context, binder);
+ return;
+ case 51:
+ C119.m(context, binder);
+ return;
+ case 52:
+ C120.m(context, binder);
+ return;
+ case 53:
+ C121.m(context, binder);
+ return;
+ case 54:
+ C122.m(context, binder);
+ return;
+ case 55:
+ C123.m(context, binder);
+ return;
+ case 56:
+ C124.m(context, binder);
+ return;
+ case 57:
+ C125.m(context, binder);
+ return;
+ case 58:
+ C126.m(context, binder);
+ return;
+ case 59:
+ C127.m(context, binder);
+ return;
+ case 60:
+ C128.m(context, binder);
+ return;
+ case 61:
+ C129.m(context, binder);
+ return;
+ case 62:
+ C130.m(context, binder);
+ C131.m(context, binder);
+ C132.m(context, binder);
+ C133.m(context, binder);
+ C134.m(context, binder);
+ C135.m(context, binder);
+ C136.m(context, binder);
+ C137.m(context, binder);
+ return;
+ case 63:
+ C138.m(context, binder);
+ return;
+ case 64:
+ C139.m(context, binder);
+ return;
+ case 65:
+ C140.m(context, binder);
+ return;
+ case 66:
+ C141.m(context, binder);
+ return;
+ case 67:
+ C142.m(context, binder);
+ return;
+ case 68:
+ C143.m(context, binder);
+ C144.m(context, binder);
+ C145.m(context, binder);
+ return;
+ case 69:
+ C146.m(context, binder);
+ return;
+ case 70:
+ C147.m(context, binder);
+ return;
+ case 71:
+ C148.m(context, binder);
+ return;
+ case 72:
+ C149.m(context, binder);
+ return;
+ case 73:
+ C150.m(context, binder);
+ return;
+ case 74:
+ C151.m(context, binder);
+ return;
+ case 75:
+ C152.m(context, binder);
+ return;
+ case 76:
+ C153.m(context, binder);
+ return;
+ case 77:
+ C154.m(context, binder);
+ return;
+ case 78:
+ C155.m(context, binder);
+ return;
+ case 79:
+ C156.m(context, binder);
+ return;
+ case 80:
+ C157.m(context, binder);
+ C158.m(context, binder);
+ C159.m(context, binder);
+ return;
+ case 81:
+ C160.m(context, binder);
+ return;
+ case 82:
+ C161.m(context, binder);
+ return;
+ case 83:
+ C162.m(context, binder);
+ return;
+ case 84:
+ C163.m(context, binder);
+ return;
+ case 85:
+ C164.m(context, binder);
+ C165.m(context, binder);
+ C166.m(context, binder);
+ C167.m(context, binder);
+ C168.m(context, binder);
+ C169.m(context, binder);
+ C170.m(context, binder);
+ C171.m(context, binder);
+ C172.m(context, binder);
+ C173.m(context, binder);
+ C174.m(context, binder);
+ C175.m(context, binder);
+ C176.m(context, binder);
+ C177.m(context, binder);
+ C178.m(context, binder);
+ C179.m(context, binder);
+ C180.m(context, binder);
+ C181.m(context, binder);
+ C182.m(context, binder);
+ C183.m(context, binder);
+ C184.m(context, binder);
+ return;
+ case 86:
+ C185.m(context, binder);
+ return;
+ case 87:
+ C186.m(context, binder);
+ return;
+ case 88:
+ C187.m(context, binder);
+ return;
+ case 89:
+ C188.m(context, binder);
+ return;
+ case 90:
+ C189.m(context, binder);
+ return;
+ case 91:
+ C190.m(context, binder);
+ return;
+ case 92:
+ C191.m(context, binder);
+ return;
+ case 93:
+ C192.m(context, binder);
+ return;
+ case 94:
+ C193.m(context, binder);
+ return;
+ case 95:
+ C194.m(context, binder);
+ return;
+ case 96:
+ C195.m(context, binder);
+ return;
+ case 97:
+ C196.m(context, binder);
+ return;
+ case 98:
+ C197.m(context, binder);
+ return;
+ case 99:
+ C198.m(context, binder);
+ return;
+ case 100:
+ C199.m(context, binder);
+ return;
+ case 101:
+ C200.m(context, binder);
+ return;
+ case 102:
+ C201.m(context, binder);
+ return;
+ case 103:
+ C202.m(context, binder);
+ C203.m(context, binder);
+ C204.m(context, binder);
+ C205.m(context, binder);
+ C206.m(context, binder);
+ return;
+ case 104:
+ C207.m(context, binder);
+ return;
+ case 105:
+ C208.m(context, binder);
+ return;
+ case 106:
+ C209.m(context, binder);
+ return;
+ case 107:
+ C210.m(context, binder);
+ return;
+ case 108:
+ C211.m(context, binder);
+ return;
+ case 109:
+ C212.m(context, binder);
+ return;
+ case 110:
+ C213.m(context, binder);
+ return;
+ case 111:
+ C214.m(context, binder);
+ return;
+ case 112:
+ C215.m(context, binder);
+ C216.m(context, binder);
+ C217.m(context, binder);
+ C218.m(context, binder);
+ C219.m(context, binder);
+ C220.m(context, binder);
+ C221.m(context, binder);
+ C222.m(context, binder);
+ C223.m(context, binder);
+ C224.m(context, binder);
+ C225.m(context, binder);
+ C226.m(context, binder);
+ return;
+ case 113:
+ C227.m(context, binder);
+ return;
+ case 114:
+ C228.m(context, binder);
+ return;
+ case 115:
+ C229.m(context, binder);
+ return;
+ case 116:
+ C230.m(context, binder);
+ return;
+ case 117:
+ C231.m(context, binder);
+ return;
+ case 118:
+ C232.m(context, binder);
+ return;
+ case 119:
+ C233.m(context, binder);
+ return;
+ case 120:
+ C234.m(context, binder);
+ return;
+ case 121:
+ C235.m(context, binder);
+ return;
+ case 122:
+ C236.m(context, binder);
+ return;
+ case 123:
+ C237.m(context, binder);
+ return;
+ case 124:
+ C238.m(context, binder);
+ return;
+ case 125:
+ C239.m(context, binder);
+ return;
+ case 126:
+ C240.m(context, binder);
+ return;
+ case 127:
+ C241.m(context, binder);
+ return;
+ case 128:
+ C242.m(context, binder);
+ return;
+ case 129:
+ C243.m(context, binder);
+ C244.m(context, binder);
+ C245.m(context, binder);
+ C246.m(context, binder);
+ C247.m(context, binder);
+ C248.m(context, binder);
+ C249.m(context, binder);
+ C250.m(context, binder);
+ C251.m(context, binder);
+ return;
+ case 130:
+ C252.m(context, binder);
+ return;
+ case 131:
+ C253.m(context, binder);
+ return;
+ case 132:
+ C254.m(context, binder);
+ return;
+ case 133:
+ C255.m(context, binder);
+ return;
+ case 134:
+ C256.m(context, binder);
+ return;
+ case 135:
+ C257.m(context, binder);
+ return;
+ case 136:
+ C258.m(context, binder);
+ return;
+ case 137:
+ C259.m(context, binder);
+ return;
+ case 138:
+ C260.m(context, binder);
+ return;
+ case 139:
+ C261.m(context, binder);
+ return;
+ case 140:
+ C262.m(context, binder);
+ return;
+ case 141:
+ C263.m(context, binder);
+ return;
+ case 142:
+ C264.m(context, binder);
+ return;
+ case 143:
+ C265.m(context, binder);
+ return;
+ case 144:
+ C266.m(context, binder);
+ C267.m(context, binder);
+ return;
+ case 145:
+ C268.m(context, binder);
+ return;
+ case 146:
+ C269.m(context, binder);
+ return;
+ case 147:
+ C270.m(context, binder);
+ return;
+ case 148:
+ C271.m(context, binder);
+ return;
+ case 149:
+ C272.m(context, binder);
+ return;
+ case 150:
+ C273.m(context, binder);
+ return;
+ case 151:
+ C274.m(context, binder);
+ return;
+ case 152:
+ C275.m(context, binder);
+ return;
+ case 153:
+ C276.m(context, binder);
+ return;
+ case 154:
+ C277.m(context, binder);
+ return;
+ case 155:
+ C278.m(context, binder);
+ return;
+ case 156:
+ C279.m(context, binder);
+ return;
+ case 157:
+ C280.m(context, binder);
+ return;
+ case 158:
+ C281.m(context, binder);
+ return;
+ case 159:
+ C282.m(context, binder);
+ return;
+ case 160:
+ C283.m(context, binder);
+ return;
+ case 161:
+ C284.m(context, binder);
+ return;
+ case 162:
+ C285.m(context, binder);
+ return;
+ case 163:
+ C286.m(context, binder);
+ return;
+ case 164:
+ C287.m(context, binder);
+ return;
+ case 165:
+ C288.m(context, binder);
+ return;
+ case 166:
+ C289.m(context, binder);
+ return;
+ case 167:
+ C290.m(context, binder);
+ return;
+ case 168:
+ C291.m(context, binder);
+ C292.m(context, binder);
+ C293.m(context, binder);
+ C294.m(context, binder);
+ C295.m(context, binder);
+ C296.m(context, binder);
+ C297.m(context, binder);
+ return;
+ case 169:
+ C298.m(context, binder);
+ return;
+ case 170:
+ C299.m(context, binder);
+ return;
+ case 171:
+ C300.m(context, binder);
+ return;
+ case 172:
+ C301.m(context, binder);
+ return;
+ case 173:
+ C302.m(context, binder);
+ return;
+ case 174:
+ C303.m(context, binder);
+ return;
+ case 175:
+ C304.m(context, binder);
+ return;
+ case 176:
+ C305.m(context, binder);
+ return;
+ case 177:
+ C306.m(context, binder);
+ return;
+ case 178:
+ C307.m(context, binder);
+ return;
+ case 179:
+ C308.m(context, binder);
+ return;
+ case 180:
+ C309.m(context, binder);
+ return;
+ case 181:
+ C310.m(context, binder);
+ return;
+ case 182:
+ C311.m(context, binder);
+ return;
+ case 183:
+ C312.m(context, binder);
+ return;
+ case 184:
+ C313.m(context, binder);
+ return;
+ case 185:
+ C314.m(context, binder);
+ return;
+ case 186:
+ C315.m(context, binder);
+ return;
+ case 187:
+ C316.m(context, binder);
+ return;
+ case 188:
+ C317.m(context, binder);
+ return;
+ case 189:
+ C318.m(context, binder);
+ return;
+ case 190:
+ C319.m(context, binder);
+ return;
+ case 191:
+ C320.m(context, binder);
+ return;
+ case 192:
+ C321.m(context, binder);
+ return;
+ case 193:
+ C322.m(context, binder);
+ return;
+ case 194:
+ C323.m(context, binder);
+ C324.m(context, binder);
+ C325.m(context, binder);
+ return;
+ case 195:
+ C326.m(context, binder);
+ return;
+ case 196:
+ C327.m(context, binder);
+ return;
+ case 197:
+ C328.m(context, binder);
+ return;
+ case 198:
+ C329.m(context, binder);
+ return;
+ case 199:
+ C330.m(context, binder);
+ return;
+ case 200:
+ C331.m(context, binder);
+ return;
+ case 201:
+ C332.m(context, binder);
+ return;
+ case 202:
+ C333.m(context, binder);
+ return;
+ case 203:
+ C334.m(context, binder);
+ C335.m(context, binder);
+ C336.m(context, binder);
+ C337.m(context, binder);
+ C338.m(context, binder);
+ C339.m(context, binder);
+ C340.m(context, binder);
+ C341.m(context, binder);
+ C342.m(context, binder);
+ C343.m(context, binder);
+ C344.m(context, binder);
+ C345.m(context, binder);
+ return;
+ case 204:
+ C346.m(context, binder);
+ return;
+ case 205:
+ C347.m(context, binder);
+ return;
+ case 206:
+ C348.m(context, binder);
+ return;
+ case 207:
+ C349.m(context, binder);
+ return;
+ case 208:
+ C350.m(context, binder);
+ return;
+ case 209:
+ C351.m(context, binder);
+ return;
+ case 210:
+ C352.m(context, binder);
+ C353.m(context, binder);
+ return;
+ case 211:
+ C354.m(context, binder);
+ return;
+ case 212:
+ C355.m(context, binder);
+ C356.m(context, binder);
+ C357.m(context, binder);
+ C358.m(context, binder);
+ C359.m(context, binder);
+ C360.m(context, binder);
+ C361.m(context, binder);
+ C362.m(context, binder);
+ C363.m(context, binder);
+ C364.m(context, binder);
+ C365.m(context, binder);
+ C366.m(context, binder);
+ C367.m(context, binder);
+ C368.m(context, binder);
+ C369.m(context, binder);
+ C370.m(context, binder);
+ C371.m(context, binder);
+ return;
+ case 213:
+ C372.m(context, binder);
+ return;
+ case 214:
+ C373.m(context, binder);
+ return;
+ case 215:
+ C374.m(context, binder);
+ return;
+ case 216:
+ C375.m(context, binder);
+ C376.m(context, binder);
+ C377.m(context, binder);
+ C378.m(context, binder);
+ C379.m(context, binder);
+ C380.m(context, binder);
+ C381.m(context, binder);
+ C382.m(context, binder);
+ return;
+ case 217:
+ C383.m(context, binder);
+ return;
+ case 218:
+ C384.m(context, binder);
+ return;
+ case 219:
+ C385.m(context, binder);
+ return;
+ case 220:
+ C386.m(context, binder);
+ return;
+ case 221:
+ C387.m(context, binder);
+ return;
+ case 222:
+ C388.m(context, binder);
+ return;
+ case 223:
+ C389.m(context, binder);
+ return;
+ case 224:
+ C390.m(context, binder);
+ return;
+ case 225:
+ C391.m(context, binder);
+ return;
+ case 226:
+ C392.m(context, binder);
+ return;
+ case 227:
+ C393.m(context, binder);
+ C394.m(context, binder);
+ return;
+ case 228:
+ C395.m(context, binder);
+ return;
+ case 229:
+ C396.m(context, binder);
+ return;
+ case 230:
+ C397.m(context, binder);
+ return;
+ case 231:
+ C398.m(context, binder);
+ return;
+ case 232:
+ C399.m(context, binder);
+ return;
+ case 233:
+ C400.m(context, binder);
+ return;
+ case 234:
+ C401.m(context, binder);
+ return;
+ case 235:
+ C402.m(context, binder);
+ return;
+ case 236:
+ C403.m(context, binder);
+ return;
+ case 237:
+ C404.m(context, binder);
+ return;
+ case 238:
+ C405.m(context, binder);
+ return;
+ case 239:
+ C406.m(context, binder);
+ return;
+ case 240:
+ C407.m(context, binder);
+ return;
+ case 241:
+ C408.m(context, binder);
+ return;
+ case 242:
+ C409.m(context, binder);
+ return;
+ case 243:
+ C410.m(context, binder);
+ return;
+ case 244:
+ C411.m(context, binder);
+ return;
+ case 245:
+ C412.m(context, binder);
+ return;
+ case 246:
+ C413.m(context, binder);
+ return;
+ case 247:
+ C414.m(context, binder);
+ return;
+ case 248:
+ C415.m(context, binder);
+ return;
+ case 249:
+ C416.m(context, binder);
+ return;
+ case 250:
+ C417.m(context, binder);
+ return;
+ case 251:
+ C418.m(context, binder);
+ return;
+ case 252:
+ C419.m(context, binder);
+ return;
+ case 253:
+ C420.m(context, binder);
+ return;
+ case 254:
+ C421.m(context, binder);
+ return;
+ case 255:
+ C422.m(context, binder);
+ return;
+ case 256:
+ C423.m(context, binder);
+ return;
+ case 257:
+ C424.m(context, binder);
+ return;
+ case 258:
+ C425.m(context, binder);
+ return;
+ case 259:
+ C426.m(context, binder);
+ return;
+ case 260:
+ C427.m(context, binder);
+ return;
+ case 261:
+ C428.m(context, binder);
+ return;
+ case 262:
+ C429.m(context, binder);
+ return;
+ case 263:
+ C430.m(context, binder);
+ return;
+ case 264:
+ C431.m(context, binder);
+ return;
+ case 265:
+ C432.m(context, binder);
+ return;
+ case 266:
+ C433.m(context, binder);
+ return;
+ case 267:
+ C434.m(context, binder);
+ C435.m(context, binder);
+ C436.m(context, binder);
+ C437.m(context, binder);
+ return;
+ case 268:
+ C438.m(context, binder);
+ return;
+ case 269:
+ C439.m(context, binder);
+ return;
+ case 270:
+ C440.m(context, binder);
+ return;
+ case 271:
+ C441.m(context, binder);
+ return;
+ case 272:
+ C442.m(context, binder);
+ return;
+ case 273:
+ C443.m(context, binder);
+ return;
+ case 274:
+ C444.m(context, binder);
+ return;
+ case 275:
+ C445.m(context, binder);
+ return;
+ case 276:
+ C446.m(context, binder);
+ return;
+ case 277:
+ C447.m(context, binder);
+ return;
+ case 278:
+ C448.m(context, binder);
+ return;
+ case 279:
+ C449.m(context, binder);
+ return;
+ case 280:
+ C450.m(context, binder);
+ return;
+ case 281:
+ C451.m(context, binder);
+ return;
+ case 282:
+ C452.m(context, binder);
+ return;
+ case 283:
+ C453.m(context, binder);
+ return;
+ case 284:
+ C454.m(context, binder);
+ return;
+ case 285:
+ C455.m(context, binder);
+ return;
+ case 286:
+ C456.m(context, binder);
+ return;
+ case 287:
+ C457.m(context, binder);
+ return;
+ case 288:
+ C458.m(context, binder);
+ return;
+ case 289:
+ C459.m(context, binder);
+ return;
+ case 290:
+ C460.m(context, binder);
+ return;
+ case 291:
+ C461.m(context, binder);
+ return;
+ case 292:
+ C462.m(context, binder);
+ return;
+ case 293:
+ C463.m(context, binder);
+ return;
+ case 294:
+ C464.m(context, binder);
+ return;
+ case 295:
+ C465.m(context, binder);
+ return;
+ case 296:
+ C466.m(context, binder);
+ return;
+ case 297:
+ C467.m(context, binder);
+ return;
+ case 298:
+ C468.m(context, binder);
+ return;
+ case 299:
+ C469.m(context, binder);
+ return;
+ case 300:
+ C470.m(context, binder);
+ return;
+ case 301:
+ C471.m(context, binder);
+ return;
+ case 302:
+ C472.m(context, binder);
+ return;
+ case 303:
+ C473.m(context, binder);
+ return;
+ case 304:
+ C474.m(context, binder);
+ return;
+ case 305:
+ C475.m(context, binder);
+ return;
+ case 306:
+ C476.m(context, binder);
+ return;
+ case 307:
+ C477.m(context, binder);
+ return;
+ case 308:
+ C478.m(context, binder);
+ return;
+ case 309:
+ C479.m(context, binder);
+ return;
+ case 310:
+ C480.m(context, binder);
+ return;
+ case 311:
+ C481.m(context, binder);
+ return;
+ case 312:
+ C482.m(context, binder);
+ return;
+ case 313:
+ C483.m(context, binder);
+ return;
+ case 314:
+ C484.m(context, binder);
+ return;
+ case 315:
+ C485.m(context, binder);
+ return;
+ case 316:
+ C486.m(context, binder);
+ return;
+ case 317:
+ C487.m(context, binder);
+ return;
+ case 318:
+ C488.m(context, binder);
+ return;
+ case 319:
+ C489.m(context, binder);
+ return;
+ case 320:
+ C490.m(context, binder);
+ return;
+ case 321:
+ C491.m(context, binder);
+ C492.m(context, binder);
+ C493.m(context, binder);
+ C494.m(context, binder);
+ C495.m(context, binder);
+ C496.m(context, binder);
+ C497.m(context, binder);
+ C498.m(context, binder);
+ return;
+ case 322:
+ C499.m(context, binder);
+ return;
+ case 323:
+ C500.m(context, binder);
+ return;
+ case 324:
+ C501.m(context, binder);
+ return;
+ case 325:
+ C502.m(context, binder);
+ return;
+ case 326:
+ C503.m(context, binder);
+ return;
+ case 327:
+ C504.m(context, binder);
+ return;
+ case 328:
+ C505.m(context, binder);
+ return;
+ case 329:
+ C506.m(context, binder);
+ return;
+ case 330:
+ C507.m(context, binder);
+ return;
+ case 331:
+ C508.m(context, binder);
+ return;
+ case 332:
+ C509.m(context, binder);
+ return;
+ case 333:
+ C510.m(context, binder);
+ return;
+ case 334:
+ C511.m(context, binder);
+ return;
+ case 335:
+ C512.m(context, binder);
+ return;
+ case 336:
+ C513.m(context, binder);
+ return;
+ case 337:
+ C514.m(context, binder);
+ return;
+ case 338:
+ C515.m(context, binder);
+ return;
+ case 339:
+ C516.m(context, binder);
+ return;
+ case 340:
+ C517.m(context, binder);
+ return;
+ case 341:
+ C518.m(context, binder);
+ return;
+ case 342:
+ C519.m(context, binder);
+ return;
+ case 343:
+ C520.m(context, binder);
+ return;
+ case 344:
+ C255.mFactory(context, binder);
+ return;
+ case 345:
+ C522.m(context, binder);
+ return;
+ case 346:
+ C523.m(context, binder);
+ return;
+ case 347:
+ C524.m(context, binder);
+ return;
+ case 348:
+ C525.m(context, binder);
+ return;
+ case 349:
+ C526.m(context, binder);
+ return;
+ case 350:
+ C527.m(context, binder);
+ return;
+ case 351:
+ C528.m(context, binder);
+ return;
+ case 352:
+ C529.m(context, binder);
+ return;
+ case 353:
+ C530.m(context, binder);
+ return;
+ case 354:
+ C531.m(context, binder);
+ return;
+ case 355:
+ C532.m(context, binder);
+ return;
+ case 356:
+ C533.m(context, binder);
+ return;
+ case 357:
+ C534.m(context, binder);
+ return;
+ case 358:
+ C535.m(context, binder);
+ return;
+ case 359:
+ C536.m(context, binder);
+ return;
+ case 360:
+ C537.m(context, binder);
+ return;
+ case 361:
+ C538.m(context, binder);
+ return;
+ case 362:
+ C539.m(context, binder);
+ return;
+ case 363:
+ C540.m(context, binder);
+ return;
+ case 364:
+ C541.m(context, binder);
+ return;
+ case 365:
+ C542.m(context, binder);
+ return;
+ case 366:
+ C543.m(context, binder);
+ return;
+ case 367:
+ C544.m(context, binder);
+ C545.m(context, binder);
+ return;
+ case 368:
+ C546.m(context, binder);
+ return;
+ case 369:
+ C547.m(context, binder);
+ return;
+ case 370:
+ C548.m(context, binder);
+ return;
+ case 371:
+ C549.m(context, binder);
+ return;
+ case 372:
+ C550.m(context, binder);
+ return;
+ case 373:
+ C551.m(context, binder);
+ return;
+ case 374:
+ C552.m(context, binder);
+ return;
+ case 375:
+ C553.m(context, binder);
+ return;
+ case 376:
+ C554.m(context, binder);
+ return;
+ case 377:
+ C555.m(context, binder);
+ return;
+ case 378:
+ C556.m(context, binder);
+ return;
+ case 379:
+ C557.m(context, binder);
+ return;
+ case 380:
+ C5.mImpl(context, binder);
+ return;
+ case 381:
+ C559.m(context, binder);
+ return;
+ case 382:
+ C560.m(context, binder);
+ return;
+ case 383:
+ C561.m(context, binder);
+ return;
+ case 384:
+ C562.m(context, binder);
+ return;
+ case 385:
+ C563.m(context, binder);
+ return;
+ case 386:
+ C564.m(context, binder);
+ return;
+ case 387:
+ C565.m(context, binder);
+ return;
+ case 388:
+ C566.m(context, binder);
+ return;
+ case 389:
+ C567.m(context, binder);
+ return;
+ case 390:
+ C568.m(context, binder);
+ return;
+ case 391:
+ C569.m(context, binder);
+ return;
+ case 392:
+ C570.m(context, binder);
+ return;
+ case 393:
+ C571.m(context, binder);
+ return;
+ case 394:
+ C572.m(context, binder);
+ return;
+ case 395:
+ C573.m(context, binder);
+ return;
+ case 396:
+ C574.m(context, binder);
+ return;
+ case 397:
+ C575.m(context, binder);
+ return;
+ case 398:
+ C576.m(context, binder);
+ return;
+ case 399:
+ C577.m(context, binder);
+ return;
+ case 400:
+ C578.m(context, binder);
+ return;
+ case 401:
+ C579.m(context, binder);
+ return;
+ case 402:
+ C580.m(context, binder);
+ return;
+ case 403:
+ C581.m(context, binder);
+ return;
+ case 404:
+ C582.m(context, binder);
+ return;
+ case 405:
+ C583.m(context, binder);
+ return;
+ case 406:
+ C584.m(context, binder);
+ C585.m(context, binder);
+ C586.m(context, binder);
+ C587.m(context, binder);
+ C588.m(context, binder);
+ C589.m(context, binder);
+ C590.m(context, binder);
+ C591.m(context, binder);
+ C592.m(context, binder);
+ C593.m(context, binder);
+ C594.m(context, binder);
+ return;
+ case 407:
+ C595.m(context, binder);
+ return;
+ case 408:
+ C596.m(context, binder);
+ return;
+ case 409:
+ C597.m(context, binder);
+ C598.m(context, binder);
+ return;
+ case 410:
+ C599.m(context, binder);
+ return;
+ case 411:
+ C600.m(context, binder);
+ return;
+ case 412:
+ C601.m(context, binder);
+ return;
+ case 413:
+ C602.m(context, binder);
+ return;
+ case 414:
+ C603.m(context, binder);
+ return;
+ case 415:
+ C604.m(context, binder);
+ return;
+ case 416:
+ C605.m(context, binder);
+ return;
+ case 417:
+ C606.m(context, binder);
+ return;
+ case 418:
+ C607.m(context, binder);
+ return;
+ case 419:
+ C608.m(context, binder);
+ return;
+ case 420:
+ C609.m(context, binder);
+ return;
+ case 421:
+ C610.m(context, binder);
+ return;
+ case 422:
+ C611.m(context, binder);
+ return;
+ case 423:
+ C612.m(context, binder);
+ return;
+ case 424:
+ C613.m(context, binder);
+ return;
+ case 425:
+ C614.m(context, binder);
+ C615.m(context, binder);
+ C616.m(context, binder);
+ return;
+ case 426:
+ C617.m(context, binder);
+ return;
+ case 427:
+ C618.m(context, binder);
+ return;
+ case 428:
+ C619.m(context, binder);
+ return;
+ case 429:
+ C620.m(context, binder);
+ return;
+ case 430:
+ C621.m(context, binder);
+ return;
+ case 431:
+ C622.m(context, binder);
+ return;
+ case 432:
+ C623.m(context, binder);
+ return;
+ case 433:
+ C624.m(context, binder);
+ return;
+ case 434:
+ C625.m(context, binder);
+ return;
+ case 435:
+ C626.m(context, binder);
+ return;
+ case 436:
+ C627.m(context, binder);
+ return;
+ case 437:
+ C628.m(context, binder);
+ return;
+ case 438:
+ C629.m(context, binder);
+ return;
+ case 439:
+ C630.m(context, binder);
+ return;
+ case 440:
+ C631.m(context, binder);
+ return;
+ case 441:
+ C632.m(context, binder);
+ return;
+ case 442:
+ C633.m(context, binder);
+ return;
+ case 443:
+ C634.m(context, binder);
+ return;
+ case 444:
+ C635.m(context, binder);
+ return;
+ case 445:
+ C636.m(context, binder);
+ return;
+ case 446:
+ C637.m(context, binder);
+ return;
+ case 447:
+ C638.m(context, binder);
+ return;
+ case 448:
+ C639.m(context, binder);
+ return;
+ case 449:
+ C640.m(context, binder);
+ return;
+ case 450:
+ C641.m(context, binder);
+ return;
+ case 451:
+ C642.m(context, binder);
+ return;
+ case 452:
+ C643.m(context, binder);
+ return;
+ case 453:
+ C644.m(context, binder);
+ return;
+ case 454:
+ C645.m(context, binder);
+ return;
+ case 455:
+ C646.m(context, binder);
+ return;
+ case 456:
+ C647.m(context, binder);
+ return;
+ case 457:
+ C648.m(context, binder);
+ return;
+ case 458:
+ C649.m(context, binder);
+ return;
+ case 459:
+ C650.m(context, binder);
+ return;
+ case 460:
+ C651.m(context, binder);
+ return;
+ case 461:
+ C652.m(context, binder);
+ return;
+ case 462:
+ C653.m(context, binder);
+ return;
+ case 463:
+ C654.m(context, binder);
+ return;
+ case 464:
+ C655.m(context, binder);
+ return;
+ case 465:
+ C656.m(context, binder);
+ return;
+ case 466:
+ C657.m(context, binder);
+ return;
+ case 467:
+ C658.m(context, binder);
+ return;
+ case 468:
+ C659.m(context, binder);
+ return;
+ case 469:
+ C660.m(context, binder);
+ return;
+ case 470:
+ C661.m(context, binder);
+ return;
+ case 471:
+ C90.mReport_Factory(context, binder);
+ return;
+ case 472:
+ C663.m(context, binder);
+ return;
+ case 473:
+ C664.m(context, binder);
+ return;
+ case 474:
+ C665.m(context, binder);
+ return;
+ case 475:
+ C666.m(context, binder);
+ return;
+ case 476:
+ C667.m(context, binder);
+ return;
+ case 477:
+ C668.m(context, binder);
+ return;
+ case 478:
+ C105.m_InMemoryScanner(context, binder);
+ return;
+ case 479:
+ C670.m(context, binder);
+ C671.m(context, binder);
+ return;
+ case 480:
+ C672.m(context, binder);
+ return;
+ case 481:
+ C673.m(context, binder);
+ return;
+ case 482:
+ C674.m(context, binder);
+ return;
+ case 483:
+ C675.m(context, binder);
+ return;
+ case 484:
+ C676.m(context, binder);
+ return;
+ case 485:
+ C677.m(context, binder);
+ return;
+ case 486:
+ C678.m(context, binder);
+ return;
+ case 487:
+ C679.m(context, binder);
+ C680.m(context, binder);
+ C681.m(context, binder);
+ C682.m(context, binder);
+ C683.m(context, binder);
+ C684.m(context, binder);
+ C685.m(context, binder);
+ return;
+ case 488:
+ C686.m(context, binder);
+ return;
+ case 489:
+ C687.m(context, binder);
+ return;
+ case 490:
+ C688.m(context, binder);
+ return;
+ case 491:
+ C689.m(context, binder);
+ return;
+ case 492:
+ C690.m(context, binder);
+ return;
+ case 493:
+ C691.m(context, binder);
+ C692.m(context, binder);
+ C693.m(context, binder);
+ C694.m(context, binder);
+ C695.m(context, binder);
+ C696.m(context, binder);
+ C697.m(context, binder);
+ C698.m(context, binder);
+ C699.m(context, binder);
+ C700.m(context, binder);
+ C701.m(context, binder);
+ C702.m(context, binder);
+ C703.m(context, binder);
+ C704.m(context, binder);
+ C705.m(context, binder);
+ C706.m(context, binder);
+ C707.m(context, binder);
+ C708.m(context, binder);
+ C709.m(context, binder);
+ C710.m(context, binder);
+ C711.m(context, binder);
+ C712.m(context, binder);
+ C713.m(context, binder);
+ C714.m(context, binder);
+ C715.m(context, binder);
+ C716.m(context, binder);
+ C717.m(context, binder);
+ C718.m(context, binder);
+ C719.m(context, binder);
+ C720.m(context, binder);
+ return;
+ case 494:
+ C721.m(context, binder);
+ C722.m(context, binder);
+ C723.m(context, binder);
+ return;
+ case 495:
+ C724.m(context, binder);
+ return;
+ case 496:
+ C725.m(context, binder);
+ return;
+ case 497:
+ C726.m(context, binder);
+ return;
+ case 498:
+ C727.m(context, binder);
+ return;
+ case 499:
+ C728.m(context, binder);
+ return;
+ case 500:
+ C729.m(context, binder);
+ return;
+ case 501:
+ C730.m(context, binder);
+ return;
+ case 502:
+ C731.m(context, binder);
+ return;
+ case 503:
+ C732.m(context, binder);
+ return;
+ case 504:
+ C733.m(context, binder);
+ return;
+ case 505:
+ C734.m(context, binder);
+ return;
+ case 506:
+ C735.m(context, binder);
+ return;
+ case 507:
+ C736.m(context, binder);
+ return;
+ case 508:
+ C737.m(context, binder);
+ return;
+ case 509:
+ C738.m(context, binder);
+ return;
+ case 510:
+ C739.m(context, binder);
+ return;
+ case 511:
+ C740.m(context, binder);
+ return;
+ case 512:
+ C741.m(context, binder);
+ return;
+ case 513:
+ C742.m(context, binder);
+ return;
+ case 514:
+ C743.m(context, binder);
+ return;
+ case 515:
+ C744.m(context, binder);
+ return;
+ case 516:
+ C745.m(context, binder);
+ return;
+ case 517:
+ C746.m(context, binder);
+ return;
+ case 518:
+ C747.m(context, binder);
+ return;
+ case 519:
+ C748.m(context, binder);
+ return;
+ case 520:
+ C749.m(context, binder);
+ return;
+ case 521:
+ C750.m(context, binder);
+ C751.m(context, binder);
+ C752.m(context, binder);
+ C753.m(context, binder);
+ C754.m(context, binder);
+ C755.m(context, binder);
+ C756.m(context, binder);
+ C757.m(context, binder);
+ C758.m(context, binder);
+ C759.m(context, binder);
+ C760.m(context, binder);
+ C761.m(context, binder);
+ return;
+ case 522:
+ C762.m(context, binder);
+ return;
+ case 523:
+ C763.m(context, binder);
+ return;
+ case 524:
+ C764.m(context, binder);
+ return;
+ case 525:
+ C765.m(context, binder);
+ return;
+ case 526:
+ C766.m(context, binder);
+ return;
+ case 527:
+ C767.m(context, binder);
+ return;
+ case 528:
+ C768.m(context, binder);
+ return;
+ case 529:
+ C769.m(context, binder);
+ return;
+ case 530:
+ C770.m(context, binder);
+ return;
+ case 531:
+ C771.m(context, binder);
+ return;
+ case 532:
+ C772.m(context, binder);
+ return;
+ case 533:
+ C773.m(context, binder);
+ return;
+ case 534:
+ C774.m(context, binder);
+ return;
+ case 535:
+ C775.m(context, binder);
+ return;
+ case 536:
+ C776.m(context, binder);
+ return;
+ case 537:
+ C777.m(context, binder);
+ return;
+ case 538:
+ C778.m(context, binder);
+ return;
+ case 539:
+ C779.m(context, binder);
+ return;
+ case 540:
+ C780.m(context, binder);
+ return;
+ case 541:
+ C781.m(context, binder);
+ return;
+ case 542:
+ C90.mApi(context, binder);
+ return;
+ case 543:
+ C783.m(context, binder);
+ return;
+ case 544:
+ C784.m(context, binder);
+ return;
+ case 545:
+ C785.m(context, binder);
+ return;
+ case 546:
+ C786.m(context, binder);
+ return;
+ case 547:
+ C787.m(context, binder);
+ return;
+ case 548:
+ C788.m(context, binder);
+ return;
+ case 549:
+ C789.m(context, binder);
+ return;
+ case 550:
+ C790.m(context, binder);
+ return;
+ case 551:
+ C791.m(context, binder);
+ return;
+ case 552:
+ C792.m(context, binder);
+ return;
+ case 553:
+ C793.m(context, binder);
+ return;
+ case 554:
+ C794.m(context, binder);
+ return;
+ case 555:
+ C795.m(context, binder);
+ C796.m(context, binder);
+ return;
+ case 556:
+ C797.m(context, binder);
+ return;
+ case 557:
+ C798.m(context, binder);
+ return;
+ case 558:
+ C799.m(context, binder);
+ return;
+ case 559:
+ C800.m(context, binder);
+ return;
+ case 560:
+ C801.m(context, binder);
+ return;
+ case 561:
+ C802.m(context, binder);
+ return;
+ case 562:
+ C803.m(context, binder);
+ C804.m(context, binder);
+ C805.m(context, binder);
+ C806.m(context, binder);
+ return;
+ case 563:
+ C807.m(context, binder);
+ return;
+ case 564:
+ C808.m(context, binder);
+ return;
+ case 565:
+ C809.m(context, binder);
+ return;
+ case 566:
+ C810.m(context, binder);
+ return;
+ case 567:
+ C811.m(context, binder);
+ return;
+ case 568:
+ C812.m(context, binder);
+ return;
+ case 569:
+ C813.m(context, binder);
+ C814.m(context, binder);
+ C815.m(context, binder);
+ C816.m(context, binder);
+ C817.m(context, binder);
+ C818.m(context, binder);
+ C819.m(context, binder);
+ C820.m(context, binder);
+ C821.m(context, binder);
+ return;
+ case 570:
+ C822.m(context, binder);
+ C823.m(context, binder);
+ return;
+ case 571:
+ C824.m(context, binder);
+ return;
+ case 572:
+ C825.m(context, binder);
+ return;
+ case 573:
+ C826.m(context, binder);
+ return;
+ case 574:
+ C827.m(context, binder);
+ return;
+ case 575:
+ C828.m(context, binder);
+ return;
+ case 576:
+ C829.m(context, binder);
+ return;
+ case 577:
+ C830.m(context, binder);
+ return;
+ case 578:
+ C831.m(context, binder);
+ return;
+ case 579:
+ C832.m(context, binder);
+ return;
+ case 580:
+ C833.m(context, binder);
+ return;
+ case 581:
+ C834.m(context, binder);
+ return;
+ case 582:
+ C835.m(context, binder);
+ return;
+ case 583:
+ C836.m(context, binder);
+ return;
+ case 584:
+ C837.m(context, binder);
+ return;
+ case 585:
+ C838.m(context, binder);
+ return;
+ case 586:
+ C105.m_Scanner(context, binder);
+ C840.m(context, binder);
+ return;
+ case 587:
+ C94.mImpl(context, binder);
+ return;
+ case 588:
+ C842.m(context, binder);
+ C843.m(context, binder);
+ C844.m(context, binder);
+ C845.m(context, binder);
+ return;
+ case 589:
+ C846.m(context, binder);
+ return;
+ case 590:
+ C847.m(context, binder);
+ return;
+ case 591:
+ C848.m(context, binder);
+ return;
+ case 592:
+ C849.m(context, binder);
+ return;
+ case 593:
+ C850.m(context, binder);
+ return;
+ case 594:
+ C851.m(context, binder);
+ return;
+ case 595:
+ C852.m(context, binder);
+ return;
+ case 596:
+ C853.m(context, binder);
+ return;
+ case 597:
+ C854.m(context, binder);
+ return;
+ case 598:
+ C855.m(context, binder);
+ return;
+ case 599:
+ C856.m(context, binder);
+ return;
+ case 600:
+ C857.m(context, binder);
+ return;
+ case 601:
+ C858.m(context, binder);
+ return;
+ case 602:
+ C859.m(context, binder);
+ return;
+ case 603:
+ C860.m(context, binder);
+ return;
+ case 604:
+ C861.m(context, binder);
+ return;
+ case 605:
+ C862.m(context, binder);
+ return;
+ case 606:
+ C863.m(context, binder);
+ return;
+ case 607:
+ C864.m(context, binder);
+ return;
+ case 608:
+ C865.m(context, binder);
+ return;
+ case 609:
+ C866.m(context, binder);
+ return;
+ case 610:
+ C867.m(context, binder);
+ return;
+ case 611:
+ C868.m(context, binder);
+ return;
+ case 612:
+ C869.m(context, binder);
+ return;
+ case 613:
+ C870.m(context, binder);
+ return;
+ case 614:
+ C871.m(context, binder);
+ return;
+ case 615:
+ C872.m(context, binder);
+ return;
+ case 616:
+ C873.m(context, binder);
+ return;
+ case 617:
+ C874.m(context, binder);
+ return;
+ case 618:
+ C875.m(context, binder);
+ return;
+ case 619:
+ C876.m(context, binder);
+ return;
+ case 620:
+ C877.m(context, binder);
+ return;
+ case 621:
+ C878.m(context, binder);
+ return;
+ case 622:
+ C879.m(context, binder);
+ C880.m(context, binder);
+ return;
+ case 623:
+ C881.m(context, binder);
+ return;
+ case 624:
+ C882.m(context, binder);
+ return;
+ case 625:
+ C883.m(context, binder);
+ return;
+ case 626:
+ C884.m(context, binder);
+ C885.m(context, binder);
+ C886.m(context, binder);
+ C887.m(context, binder);
+ C888.m(context, binder);
+ return;
+ case 627:
+ C889.m(context, binder);
+ return;
+ case 628:
+ C890.m(context, binder);
+ return;
+ case 629:
+ C891.m(context, binder);
+ return;
+ case 630:
+ C892.m(context, binder);
+ return;
+ case 631:
+ C893.m(context, binder);
+ return;
+ case 632:
+ C894.m(context, binder);
+ return;
+ case 633:
+ C895.m(context, binder);
+ return;
+ case 634:
+ C896.m(context, binder);
+ return;
+ case 635:
+ C897.m(context, binder);
+ return;
+ case 636:
+ C898.m(context, binder);
+ return;
+ case 637:
+ C899.m(context, binder);
+ return;
+ case 638:
+ C900.m(context, binder);
+ return;
+ case 639:
+ C901.m(context, binder);
+ return;
+ case 640:
+ C870.mImpl(context, binder);
+ return;
+ case 641:
+ C903.m(context, binder);
+ return;
+ case 642:
+ C904.m(context, binder);
+ return;
+ case 643:
+ C905.m(context, binder);
+ return;
+ case 644:
+ C906.m(context, binder);
+ C907.m(context, binder);
+ C908.m(context, binder);
+ C909.m(context, binder);
+ C910.m(context, binder);
+ return;
+ case 645:
+ C911.m(context, binder);
+ return;
+ case 646:
+ C912.m(context, binder);
+ C913.m(context, binder);
+ return;
+ case 647:
+ C914.m(context, binder);
+ return;
+ case 648:
+ C915.m(context, binder);
+ return;
+ case 649:
+ C916.m(context, binder);
+ return;
+ case 650:
+ C917.m(context, binder);
+ C918.m(context, binder);
+ return;
+ case 651:
+ C919.m(context, binder);
+ return;
+ case 652:
+ C920.m(context, binder);
+ return;
+ case 653:
+ C921.m(context, binder);
+ return;
+ case 654:
+ C922.m(context, binder);
+ return;
+ case 655:
+ C923.m(context, binder);
+ C924.m(context, binder);
+ C925.m(context, binder);
+ C926.m(context, binder);
+ C927.m(context, binder);
+ C928.m(context, binder);
+ C929.m(context, binder);
+ C930.m(context, binder);
+ C931.m(context, binder);
+ C932.m(context, binder);
+ C933.m(context, binder);
+ C934.m(context, binder);
+ C935.m(context, binder);
+ return;
+ case 656:
+ C936.m(context, binder);
+ return;
+ case 657:
+ C937.m(context, binder);
+ return;
+ case 658:
+ C938.m(context, binder);
+ return;
+ case 659:
+ C939.m(context, binder);
+ return;
+ case 660:
+ C940.m(context, binder);
+ return;
+ case 661:
+ C941.m(context, binder);
+ return;
+ case 662:
+ C942.m(context, binder);
+ return;
+ case 663:
+ C943.m(context, binder);
+ return;
+ case 664:
+ C944.m(context, binder);
+ return;
+ case 665:
+ C945.m(context, binder);
+ return;
+ case 666:
+ C946.m(context, binder);
+ return;
+ case 667:
+ C947.m(context, binder);
+ return;
+ case 668:
+ C948.m(context, binder);
+ return;
+ case 669:
+ C949.m(context, binder);
+ return;
+ case 670:
+ C950.m(context, binder);
+ return;
+ case 671:
+ C951.m(context, binder);
+ return;
+ case 672:
+ C952.m(context, binder);
+ C953.m(context, binder);
+ C954.m(context, binder);
+ C955.m(context, binder);
+ return;
+ case 673:
+ C956.m(context, binder);
+ return;
+ case 674:
+ C957.m(context, binder);
+ C958.m(context, binder);
+ return;
+ case 675:
+ C959.m(context, binder);
+ return;
+ case 676:
+ C960.m(context, binder);
+ C961.m(context, binder);
+ return;
+ case 677:
+ C962.m(context, binder);
+ return;
+ case 678:
+ C963.m(context, binder);
+ return;
+ case 679:
+ C964.m(context, binder);
+ return;
+ case 680:
+ C965.m(context, binder);
+ return;
+ case 681:
+ C966.m(context, binder);
+ return;
+ case 682:
+ C967.m(context, binder);
+ return;
+ case 683:
+ C968.m(context, binder);
+ return;
+ case 684:
+ C969.m(context, binder);
+ return;
+ case 685:
+ C970.m(context, binder);
+ return;
+ case 686:
+ C971.m(context, binder);
+ C972.m(context, binder);
+ return;
+ case 687:
+ C973.m(context, binder);
+ return;
+ case 688:
+ C974.m(context, binder);
+ return;
+ case 689:
+ C975.m(context, binder);
+ return;
+ case 690:
+ C976.m(context, binder);
+ return;
+ case 691:
+ C977.m(context, binder);
+ return;
+ case 692:
+ C978.m(context, binder);
+ return;
+ case 693:
+ C979.m(context, binder);
+ return;
+ case 694:
+ C980.m(context, binder);
+ return;
+ case 695:
+ C981.m(context, binder);
+ return;
+ case 696:
+ C982.m(context, binder);
+ return;
+ case 697:
+ C983.m(context, binder);
+ C984.m(context, binder);
+ C985.m(context, binder);
+ return;
+ case 698:
+ C986.m(context, binder);
+ return;
+ case 699:
+ C987.m(context, binder);
+ return;
+ case 700:
+ C988.m(context, binder);
+ return;
+ case 701:
+ C989.m(context, binder);
+ return;
+ case 702:
+ C990.m(context, binder);
+ return;
+ case 703:
+ C991.m(context, binder);
+ return;
+ case 704:
+ C992.m(context, binder);
+ return;
+ case 705:
+ C993.m(context, binder);
+ return;
+ case 706:
+ C994.m(context, binder);
+ return;
+ case 707:
+ C995.m(context, binder);
+ return;
+ case 708:
+ C996.m(context, binder);
+ return;
+ case 709:
+ C997.m(context, binder);
+ return;
+ case 710:
+ C998.m(context, binder);
+ return;
+ case 711:
+ C999.m(context, binder);
+ return;
+ case 712:
+ C1000.m(context, binder);
+ return;
+ case 713:
+ C1001.m(context, binder);
+ return;
+ case 714:
+ C1002.m(context, binder);
+ return;
+ case 715:
+ C1003.m(context, binder);
+ return;
+ case 716:
+ C1004.m(context, binder);
+ return;
+ case 717:
+ C1005.m(context, binder);
+ return;
+ case 718:
+ C1006.m(context, binder);
+ return;
+ case 719:
+ C1007.m(context, binder);
+ return;
+ case 720:
+ C1008.m(context, binder);
+ return;
+ case 721:
+ C1009.m(context, binder);
+ return;
+ case 722:
+ C1010.m(context, binder);
+ return;
+ case 723:
+ C1011.m(context, binder);
+ return;
+ case 724:
+ C1012.m(context, binder);
+ return;
+ case 725:
+ C1013.m(context, binder);
+ return;
+ case 726:
+ C1014.m(context, binder);
+ return;
+ case 727:
+ C1015.m(context, binder);
+ return;
+ case 728:
+ C577.mDebug(context, binder);
+ return;
+ case 729:
+ C1017.m(context, binder);
+ return;
+ case 730:
+ C1018.m(context, binder);
+ return;
+ case 731:
+ C1019.m(context, binder);
+ return;
+ case 732:
+ C1020.m(context, binder);
+ return;
+ case 733:
+ C1021.m(context, binder);
+ return;
+ case 734:
+ C1022.m(context, binder);
+ return;
+ case 735:
+ C1023.m(context, binder);
+ return;
+ case 736:
+ C1024.m(context, binder);
+ return;
+ case 737:
+ C1025.m(context, binder);
+ return;
+ case 738:
+ C1026.m(context, binder);
+ return;
+ case 739:
+ C1027.m(context, binder);
+ return;
+ case 740:
+ C1028.m(context, binder);
+ return;
+ case 741:
+ C1029.m(context, binder);
+ return;
+ case 742:
+ C1030.m(context, binder);
+ return;
+ case 743:
+ C1031.m(context, binder);
+ return;
+ case 744:
+ C1032.m(context, binder);
+ return;
+ case 745:
+ C1033.m(context, binder);
+ return;
+ case 746:
+ C1034.m(context, binder);
+ return;
+ case 747:
+ C1035.m(context, binder);
+ return;
+ case 748:
+ C1036.m(context, binder);
+ C1037.m(context, binder);
+ return;
+ case 749:
+ C1038.m(context, binder);
+ C1039.m(context, binder);
+ C1040.m(context, binder);
+ C1041.m(context, binder);
+ return;
+ case 750:
+ C1042.m(context, binder);
+ return;
+ case 751:
+ C1043.m(context, binder);
+ return;
+ case 752:
+ C1044.m(context, binder);
+ return;
+ case 753:
+ C1045.m(context, binder);
+ return;
+ case 754:
+ C1046.m(context, binder);
+ return;
+ case 755:
+ C1047.m(context, binder);
+ return;
+ case 756:
+ C848.mMap(context, binder);
+ return;
+ case 757:
+ C1049.m(context, binder);
+ return;
+ case 758:
+ C1050.m(context, binder);
+ return;
+ case 759:
+ C1051.m(context, binder);
+ return;
+ case 760:
+ C1052.m(context, binder);
+ return;
+ case 761:
+ C1053.m(context, binder);
+ return;
+ case 762:
+ C1054.m(context, binder);
+ return;
+ case 763:
+ C1055.m(context, binder);
+ return;
+ case 764:
+ C1056.m(context, binder);
+ return;
+ case 765:
+ C1057.m(context, binder);
+ return;
+ case 766:
+ C1058.m(context, binder);
+ return;
+ case 767:
+ C1059.m(context, binder);
+ return;
+ case 768:
+ C1060.m(context, binder);
+ return;
+ case 769:
+ C1061.m(context, binder);
+ return;
+ case 770:
+ C1062.m(context, binder);
+ return;
+ case 771:
+ C1063.m(context, binder);
+ return;
+ case 772:
+ C1064.m(context, binder);
+ return;
+ case 773:
+ C1065.m(context, binder);
+ return;
+ case 774:
+ C1066.m(context, binder);
+ return;
+ case 775:
+ C1067.m(context, binder);
+ return;
+ case 776:
+ C1068.m(context, binder);
+ return;
+ case 777:
+ C1069.m(context, binder);
+ return;
+ case 778:
+ C1070.m(context, binder);
+ return;
+ case 779:
+ C1071.m(context, binder);
+ return;
+ case 780:
+ C1072.m(context, binder);
+ return;
+ case 781:
+ C1073.m(context, binder);
+ C1074.m(context, binder);
+ C1075.m(context, binder);
+ C1076.m(context, binder);
+ C1077.m(context, binder);
+ C1078.m(context, binder);
+ C1079.m(context, binder);
+ C1080.m(context, binder);
+ return;
+ case 782:
+ C1081.m(context, binder);
+ return;
+ case 783:
+ C1082.m(context, binder);
+ return;
+ case 784:
+ C1083.m(context, binder);
+ return;
+ case 785:
+ C1084.m(context, binder);
+ return;
+ case 786:
+ C1085.m(context, binder);
+ return;
+ case 787:
+ C1086.m(context, binder);
+ return;
+ case 788:
+ C1087.m(context, binder);
+ return;
+ case 789:
+ C1088.m(context, binder);
+ return;
+ case 790:
+ C944.mManager(context, binder);
+ return;
+ case 791:
+ C1090.m(context, binder);
+ return;
+ case 792:
+ C1091.m(context, binder);
+ return;
+ case 793:
+ C1092.m(context, binder);
+ return;
+ case 794:
+ C1093.m(context, binder);
+ return;
+ case 795:
+ C1094.m(context, binder);
+ return;
+ case 796:
+ C1095.m(context, binder);
+ return;
+ case 797:
+ C1096.m(context, binder);
+ return;
+ case 798:
+ C1097.m(context, binder);
+ return;
+ case 799:
+ C1098.m(context, binder);
+ return;
+ case 800:
+ C1099.m(context, binder);
+ return;
+ case 801:
+ C1100.m(context, binder);
+ return;
+ case 802:
+ C1101.m(context, binder);
+ C1102.m(context, binder);
+ C1103.m(context, binder);
+ C1104.m(context, binder);
+ C1105.m(context, binder);
+ C1106.m(context, binder);
+ C1107.m(context, binder);
+ C1108.m(context, binder);
+ return;
+ case 803:
+ C1109.m(context, binder);
+ return;
+ case 804:
+ C1110.m(context, binder);
+ return;
+ case 805:
+ C1111.m(context, binder);
+ return;
+ case 806:
+ C1112.m(context, binder);
+ return;
+ case 807:
+ C1113.m(context, binder);
+ return;
+ case 808:
+ C1114.m(context, binder);
+ C1115.m(context, binder);
+ C1116.m(context, binder);
+ C1117.m(context, binder);
+ return;
+ case 809:
+ C1118.m(context, binder);
+ return;
+ case 810:
+ C1119.m(context, binder);
+ C1120.m(context, binder);
+ C1121.m(context, binder);
+ return;
+ case 811:
+ C1122.m(context, binder);
+ return;
+ case 812:
+ C1123.m(context, binder);
+ return;
+ case 813:
+ C1124.m(context, binder);
+ return;
+ case 814:
+ C1125.m(context, binder);
+ return;
+ case 815:
+ C1126.m(context, binder);
+ return;
+ case 816:
+ C1127.m(context, binder);
+ return;
+ case 817:
+ C1128.m(context, binder);
+ return;
+ case 818:
+ C1129.m(context, binder);
+ return;
+ case 819:
+ C1130.m(context, binder);
+ return;
+ case 820:
+ C1131.m(context, binder);
+ return;
+ case 821:
+ C1132.m(context, binder);
+ return;
+ case 822:
+ C1133.m(context, binder);
+ return;
+ case 823:
+ C1134.m(context, binder);
+ return;
+ case 824:
+ C1135.m(context, binder);
+ return;
+ case 825:
+ C1136.m(context, binder);
+ return;
+ case 826:
+ C1137.m(context, binder);
+ C1138.m(context, binder);
+ C1139.m(context, binder);
+ C1140.m(context, binder);
+ C1141.m(context, binder);
+ C1142.m(context, binder);
+ C1143.m(context, binder);
+ C1144.m(context, binder);
+ C1145.m(context, binder);
+ C1146.m(context, binder);
+ C1147.m(context, binder);
+ C1148.m(context, binder);
+ C1149.m(context, binder);
+ C1150.m(context, binder);
+ C1151.m(context, binder);
+ C1152.m(context, binder);
+ C1153.m(context, binder);
+ C1154.m(context, binder);
+ C1155.m(context, binder);
+ C1156.m(context, binder);
+ C1157.m(context, binder);
+ C1158.m(context, binder);
+ return;
+ case 827:
+ C1159.m(context, binder);
+ return;
+ case 828:
+ C457.mMap(context, binder);
+ return;
+ case 829:
+ C1161.m(context, binder);
+ C1162.m(context, binder);
+ C1163.m(context, binder);
+ C1164.m(context, binder);
+ C1165.m(context, binder);
+ C1166.m(context, binder);
+ C1167.m(context, binder);
+ C1168.m(context, binder);
+ C1169.m(context, binder);
+ C1170.m(context, binder);
+ C1171.m(context, binder);
+ C1172.m(context, binder);
+ C1173.m(context, binder);
+ C1174.m(context, binder);
+ C1175.m(context, binder);
+ C1176.m(context, binder);
+ C1177.m(context, binder);
+ C1178.m(context, binder);
+ C1179.m(context, binder);
+ C1180.m(context, binder);
+ C1181.m(context, binder);
+ C1181a.m(context, binder);
+ C1181b.m(context, binder);
+ return;
+ case 830:
+ C1184.m(context, binder);
+ return;
+ case 831:
+ C1185.m(context, binder);
+ return;
+ case 832:
+ C1186.m(context, binder);
+ return;
+ case 833:
+ C1187.m(context, binder);
+ return;
+ case 834:
+ C1188.m(context, binder);
+ return;
+ case 835:
+ C1189.m(context, binder);
+ return;
+ case 836:
+ C1190.m(context, binder);
+ return;
+ case 837:
+ C1191.m(context, binder);
+ return;
+ case 838:
+ C1192.m(context, binder);
+ return;
+ case 839:
+ C1193.m(context, binder);
+ return;
+ case 840:
+ C1194.m(context, binder);
+ return;
+ case 841:
+ C1195.m(context, binder);
+ return;
+ case 842:
+ C1196.m(context, binder);
+ return;
+ case 843:
+ C1197.m(context, binder);
+ return;
+ case 844:
+ C1198.m(context, binder);
+ return;
+ case 845:
+ C1199.m(context, binder);
+ return;
+ case 846:
+ C1200.m(context, binder);
+ return;
+ case 847:
+ C1201.m(context, binder);
+ return;
+ case 848:
+ C1202.m(context, binder);
+ return;
+ case 849:
+ C1203.m(context, binder);
+ return;
+ case 850:
+ C1204.m(context, binder);
+ return;
+ case 851:
+ C1205.m(context, binder);
+ return;
+ case 852:
+ C1206.m(context, binder);
+ return;
+ case 853:
+ C1207.m(context, binder);
+ return;
+ case 854:
+ C1208.m(context, binder);
+ return;
+ case 855:
+ C1209.m(context, binder);
+ return;
+ case 856:
+ C1210.m(context, binder);
+ return;
+ case 857:
+ C1211.m(context, binder);
+ return;
+ case 858:
+ C1212.m(context, binder);
+ return;
+ default:
+ return;
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ System.out.println("passed");
+ }
+
+ static boolean doThrow = false;
+}
diff --git a/test/912-classes/classes.cc b/test/912-classes/classes.cc
index e659ea3..3ccfe86 100644
--- a/test/912-classes/classes.cc
+++ b/test/912-classes/classes.cc
@@ -430,5 +430,145 @@
return found ? JNI_TRUE : JNI_FALSE;
}
+class ClassLoadPrepareEquality {
+ public:
+ static constexpr const char* kClassName = "LMain$ClassE;";
+ static constexpr const char* kStorageFieldName = "STATIC";
+ static constexpr const char* kStorageFieldSig = "Ljava/lang/Object;";
+ static constexpr const char* kStorageWeakFieldName = "WEAK";
+ static constexpr const char* kStorageWeakFieldSig = "Ljava/lang/ref/Reference;";
+ static constexpr const char* kWeakClassName = "java/lang/ref/WeakReference";
+ static constexpr const char* kWeakInitSig = "(Ljava/lang/Object;)V";
+ static constexpr const char* kWeakGetSig = "()Ljava/lang/Object;";
+
+ static void JNICALL ClassLoadCallback(jvmtiEnv* jenv,
+ JNIEnv* jni_env,
+ jthread thread ATTRIBUTE_UNUSED,
+ jclass klass) {
+ std::string name = GetClassName(jenv, jni_env, klass);
+ if (name == kClassName) {
+ found_ = true;
+ stored_class_ = jni_env->NewGlobalRef(klass);
+ weakly_stored_class_ = jni_env->NewWeakGlobalRef(klass);
+ // The following is bad and relies on implementation details. But otherwise a test would be
+ // a lot more complicated.
+ local_stored_class_ = jni_env->NewLocalRef(klass);
+ // Store the value into a field in the heap.
+ SetOrCompare(jni_env, klass, true);
+ }
+ }
+
+ static void JNICALL ClassPrepareCallback(jvmtiEnv* jenv,
+ JNIEnv* jni_env,
+ jthread thread ATTRIBUTE_UNUSED,
+ jclass klass) {
+ std::string name = GetClassName(jenv, jni_env, klass);
+ if (name == kClassName) {
+ CHECK(stored_class_ != nullptr);
+ CHECK(jni_env->IsSameObject(stored_class_, klass));
+ CHECK(jni_env->IsSameObject(weakly_stored_class_, klass));
+ CHECK(jni_env->IsSameObject(local_stored_class_, klass));
+ // Look up the value in a field in the heap.
+ SetOrCompare(jni_env, klass, false);
+ compared_ = true;
+ }
+ }
+
+ static void SetOrCompare(JNIEnv* jni_env, jobject value, bool set) {
+ CHECK(storage_class_ != nullptr);
+
+ // Simple direct storage.
+ jfieldID field = jni_env->GetStaticFieldID(storage_class_, kStorageFieldName, kStorageFieldSig);
+ CHECK(field != nullptr);
+
+ if (set) {
+ jni_env->SetStaticObjectField(storage_class_, field, value);
+ CHECK(!jni_env->ExceptionCheck());
+ } else {
+ ScopedLocalRef<jobject> stored(jni_env, jni_env->GetStaticObjectField(storage_class_, field));
+ CHECK(jni_env->IsSameObject(value, stored.get()));
+ }
+
+ // Storage as a reference.
+ ScopedLocalRef<jclass> weak_ref_class(jni_env, jni_env->FindClass(kWeakClassName));
+ CHECK(weak_ref_class.get() != nullptr);
+ jfieldID weak_field = jni_env->GetStaticFieldID(storage_class_,
+ kStorageWeakFieldName,
+ kStorageWeakFieldSig);
+ CHECK(weak_field != nullptr);
+ if (set) {
+ // Create a WeakReference.
+ jmethodID weak_init = jni_env->GetMethodID(weak_ref_class.get(), "<init>", kWeakInitSig);
+ CHECK(weak_init != nullptr);
+ ScopedLocalRef<jobject> weak_obj(jni_env, jni_env->NewObject(weak_ref_class.get(),
+ weak_init,
+ value));
+ CHECK(weak_obj.get() != nullptr);
+ jni_env->SetStaticObjectField(storage_class_, weak_field, weak_obj.get());
+ CHECK(!jni_env->ExceptionCheck());
+ } else {
+ // Check the reference value.
+ jmethodID get_referent = jni_env->GetMethodID(weak_ref_class.get(), "get", kWeakGetSig);
+ CHECK(get_referent != nullptr);
+ ScopedLocalRef<jobject> weak_obj(jni_env, jni_env->GetStaticObjectField(storage_class_,
+ weak_field));
+ CHECK(weak_obj.get() != nullptr);
+ ScopedLocalRef<jobject> weak_referent(jni_env, jni_env->CallObjectMethod(weak_obj.get(),
+ get_referent));
+ CHECK(weak_referent.get() != nullptr);
+ CHECK(jni_env->IsSameObject(value, weak_referent.get()));
+ }
+ }
+
+ static void CheckFound() {
+ CHECK(found_);
+ CHECK(compared_);
+ }
+
+ static void Free(JNIEnv* env) {
+ if (stored_class_ != nullptr) {
+ env->DeleteGlobalRef(stored_class_);
+ DCHECK(weakly_stored_class_ != nullptr);
+ env->DeleteWeakGlobalRef(weakly_stored_class_);
+ // Do not attempt to delete the local ref. It will be out of date by now.
+ }
+ }
+
+ static jclass storage_class_;
+
+ private:
+ static jobject stored_class_;
+ static jweak weakly_stored_class_;
+ static jobject local_stored_class_;
+ static bool found_;
+ static bool compared_;
+};
+jclass ClassLoadPrepareEquality::storage_class_ = nullptr;
+jobject ClassLoadPrepareEquality::stored_class_ = nullptr;
+jweak ClassLoadPrepareEquality::weakly_stored_class_ = nullptr;
+jobject ClassLoadPrepareEquality::local_stored_class_ = nullptr;
+bool ClassLoadPrepareEquality::found_ = false;
+bool ClassLoadPrepareEquality::compared_ = false;
+
+extern "C" JNIEXPORT void JNICALL Java_Main_setEqualityEventStorageClass(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jclass klass) {
+ ClassLoadPrepareEquality::storage_class_ =
+ reinterpret_cast<jclass>(env->NewGlobalRef(klass));
+}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_enableClassLoadPrepareEqualityEvents(
+ JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jboolean b) {
+ EnableEvents(env,
+ b,
+ ClassLoadPrepareEquality::ClassLoadCallback,
+ ClassLoadPrepareEquality::ClassPrepareCallback);
+ if (b == JNI_FALSE) {
+ ClassLoadPrepareEquality::Free(env);
+ ClassLoadPrepareEquality::CheckFound();
+ env->DeleteGlobalRef(ClassLoadPrepareEquality::storage_class_);
+ ClassLoadPrepareEquality::storage_class_ = nullptr;
+ }
+}
+
} // namespace Test912Classes
} // namespace art
diff --git a/test/912-classes/src/Main.java b/test/912-classes/src/Main.java
index e3aceb9..005074f 100644
--- a/test/912-classes/src/Main.java
+++ b/test/912-classes/src/Main.java
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+import java.lang.ref.Reference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.util.Arrays;
@@ -290,6 +291,8 @@
if (hasJit() && !isLoadedClass("Main$ClassD")) {
testClassEventsJit();
}
+
+ testClassLoadPrepareEquality();
}
private static void testClassEventsJit() throws Exception {
@@ -312,6 +315,16 @@
}
}
+ private static void testClassLoadPrepareEquality() throws Exception {
+ setEqualityEventStorageClass(ClassF.class);
+
+ enableClassLoadPrepareEqualityEvents(true);
+
+ Class.forName("Main$ClassE");
+
+ enableClassLoadPrepareEqualityEvents(false);
+ }
+
private static void printClassLoaderClasses(ClassLoader cl) {
for (;;) {
if (cl == null || !cl.getClass().getName().startsWith("dalvik.system")) {
@@ -383,6 +396,9 @@
private static native void enableClassLoadSeenEvents(boolean b);
private static native boolean hadLoadEvent();
+ private static native void setEqualityEventStorageClass(Class<?> c);
+ private static native void enableClassLoadPrepareEqualityEvents(boolean b);
+
private static class TestForNonInit {
public static double dummy = Math.random(); // So it can't be compile-time initialized.
}
@@ -409,6 +425,18 @@
static int x = 1;
}
+ public static class ClassE {
+ public void foo() {
+ }
+ public void bar() {
+ }
+ }
+
+ public static class ClassF {
+ public static Object STATIC = null;
+ public static Reference<Object> WEAK = null;
+ }
+
private static final String DEX1 = System.getenv("DEX_LOCATION") + "/912-classes.jar";
private static final String DEX2 = System.getenv("DEX_LOCATION") + "/912-classes-ex.jar";
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 84df924..784f49c 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -252,11 +252,6 @@
"variant": "jit"
},
{
- "test": "912-classes",
- "variant": "jit",
- "bug": "http://b/34655682"
- },
- {
"tests": ["570-checker-select",
"484-checker-register-hints"],
"description": ["These tests were based on the linear scan allocator,",
diff --git a/test/testrunner/testrunner.py b/test/testrunner/testrunner.py
index f60a6c9..81b7953 100755
--- a/test/testrunner/testrunner.py
+++ b/test/testrunner/testrunner.py
@@ -767,7 +767,10 @@
build_targets += 'test-art-host-run-test-dependencies'
if 'target' in TARGET_TYPES:
build_targets += 'test-art-target-run-test-dependencies'
- build_command = 'make -j' + str(n_thread) + ' ' + build_targets
+ build_command = 'make'
+ build_command += ' -j' + str(n_thread)
+ build_command += ' -C ' + env.ANDROID_BUILD_TOP
+ build_command += ' ' + build_targets
if subprocess.call(build_command.split()):
sys.exit(1)
if user_requested_test:
@@ -786,7 +789,6 @@
except SystemExit:
pass
except:
- print "hello"
print_analysis()
sys.exit(1)
diff --git a/tools/run-libcore-tests.sh b/tools/run-libcore-tests.sh
index 729a3e5..6e123ce 100755
--- a/tools/run-libcore-tests.sh
+++ b/tools/run-libcore-tests.sh
@@ -14,6 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# Exit as a stop-gap measure for b/35308152.
+exit 0
+
if [ ! -d libcore ]; then
echo "Script needs to be run at the root of the android tree"
exit 1