diff options
25 files changed, 2130 insertions, 79 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 35109fa538..51fef7c9cb 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -21,6 +21,8 @@ #include "class_linker.h" #include "constant_folding.h" #include "dead_code_elimination.h" +#include "dex/verified_method.h" +#include "dex/verification_results.h" #include "driver/compiler_driver-inl.h" #include "driver/compiler_options.h" #include "driver/dex_compilation_unit.h" @@ -32,13 +34,12 @@ #include "optimizing_compiler.h" #include "reference_type_propagation.h" #include "register_allocator.h" +#include "quick/inline_method_analyser.h" #include "sharpening.h" #include "ssa_builder.h" #include "ssa_phi_elimination.h" #include "scoped_thread_state_change.h" #include "thread.h" -#include "dex/verified_method.h" -#include "dex/verification_results.h" namespace art { @@ -488,6 +489,11 @@ bool HInliner::TryInline(HInvoke* invoke_instruction, ArtMethod* method, bool do // dex file here (though the transitivity of an inline chain would allow checking the calller). if (!compiler_driver_->MayInline(method->GetDexFile(), outer_compilation_unit_.GetDexFile())) { + if (TryPatternSubstitution(invoke_instruction, method, do_rtp)) { + VLOG(compiler) << "Successfully replaced pattern of invoke " << PrettyMethod(method); + MaybeRecordStat(kReplacedInvokeWithSimplePattern); + return true; + } VLOG(compiler) << "Won't inline " << PrettyMethod(method) << " in " << outer_compilation_unit_.GetDexFile()->GetLocation() << " (" << caller_compilation_unit_.GetDexFile()->GetLocation() << ") from " @@ -559,6 +565,140 @@ bool HInliner::TryInline(HInvoke* invoke_instruction, ArtMethod* method, bool do return true; } +static HInstruction* GetInvokeInputForArgVRegIndex(HInvoke* invoke_instruction, + size_t arg_vreg_index) + SHARED_REQUIRES(Locks::mutator_lock_) { + size_t input_index = 0; + for (size_t i = 0; i < arg_vreg_index; ++i, ++input_index) { + DCHECK_LT(input_index, invoke_instruction->GetNumberOfArguments()); + if (Primitive::Is64BitType(invoke_instruction->InputAt(input_index)->GetType())) { + ++i; + DCHECK_NE(i, arg_vreg_index); + } + } + DCHECK_LT(input_index, invoke_instruction->GetNumberOfArguments()); + return invoke_instruction->InputAt(input_index); +} + +// Try to recognize known simple patterns and replace invoke call with appropriate instructions. +bool HInliner::TryPatternSubstitution(HInvoke* invoke_instruction, + ArtMethod* resolved_method, + bool do_rtp) { + InlineMethod inline_method; + if (!InlineMethodAnalyser::AnalyseMethodCode(resolved_method, &inline_method)) { + return false; + } + + HInstruction* return_replacement = nullptr; + switch (inline_method.opcode) { + case kInlineOpNop: + DCHECK_EQ(invoke_instruction->GetType(), Primitive::kPrimVoid); + break; + case kInlineOpReturnArg: + return_replacement = GetInvokeInputForArgVRegIndex(invoke_instruction, + inline_method.d.return_data.arg); + break; + case kInlineOpNonWideConst: + if (resolved_method->GetShorty()[0] == 'L') { + DCHECK_EQ(inline_method.d.data, 0u); + return_replacement = graph_->GetNullConstant(); + } else { + return_replacement = graph_->GetIntConstant(static_cast<int32_t>(inline_method.d.data)); + } + break; + case kInlineOpIGet: { + const InlineIGetIPutData& data = inline_method.d.ifield_data; + if (data.method_is_static || data.object_arg != 0u) { + // TODO: Needs null check. + return false; + } + HInstruction* obj = GetInvokeInputForArgVRegIndex(invoke_instruction, data.object_arg); + HInstanceFieldGet* iget = CreateInstanceFieldGet(resolved_method, data.field_idx, obj); + DCHECK_EQ(iget->GetFieldOffset().Uint32Value(), data.field_offset); + DCHECK_EQ(iget->IsVolatile() ? 1u : 0u, data.is_volatile); + invoke_instruction->GetBlock()->InsertInstructionBefore(iget, invoke_instruction); + return_replacement = iget; + break; + } + case kInlineOpIPut: { + const InlineIGetIPutData& data = inline_method.d.ifield_data; + if (data.method_is_static || data.object_arg != 0u) { + // TODO: Needs null check. + return false; + } + HInstruction* obj = GetInvokeInputForArgVRegIndex(invoke_instruction, data.object_arg); + HInstruction* value = GetInvokeInputForArgVRegIndex(invoke_instruction, data.src_arg); + HInstanceFieldSet* iput = CreateInstanceFieldSet(resolved_method, data.field_idx, obj, value); + DCHECK_EQ(iput->GetFieldOffset().Uint32Value(), data.field_offset); + DCHECK_EQ(iput->IsVolatile() ? 1u : 0u, data.is_volatile); + invoke_instruction->GetBlock()->InsertInstructionBefore(iput, invoke_instruction); + if (data.return_arg_plus1 != 0u) { + size_t return_arg = data.return_arg_plus1 - 1u; + return_replacement = GetInvokeInputForArgVRegIndex(invoke_instruction, return_arg); + } + break; + } + default: + LOG(FATAL) << "UNREACHABLE"; + UNREACHABLE(); + } + + if (return_replacement != nullptr) { + invoke_instruction->ReplaceWith(return_replacement); + } + invoke_instruction->GetBlock()->RemoveInstruction(invoke_instruction); + + FixUpReturnReferenceType(resolved_method, invoke_instruction, return_replacement, do_rtp); + return true; +} + +HInstanceFieldGet* HInliner::CreateInstanceFieldGet(ArtMethod* resolved_method, + uint32_t field_index, + HInstruction* obj) + SHARED_REQUIRES(Locks::mutator_lock_) { + Handle<mirror::DexCache> dex_cache(handles_->NewHandle(resolved_method->GetDexCache())); + size_t pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet()); + ArtField* resolved_field = dex_cache->GetResolvedField(field_index, pointer_size); + DCHECK(resolved_field != nullptr); + HInstanceFieldGet* iget = new (graph_->GetArena()) HInstanceFieldGet( + obj, + resolved_field->GetTypeAsPrimitiveType(), + resolved_field->GetOffset(), + resolved_field->IsVolatile(), + field_index, + resolved_field->GetDeclaringClass()->GetDexClassDefIndex(), + *resolved_method->GetDexFile(), + dex_cache, + kNoDexPc); + if (iget->GetType() == Primitive::kPrimNot) { + ReferenceTypePropagation rtp(graph_, handles_); + rtp.Visit(iget); + } + return iget; +} + +HInstanceFieldSet* HInliner::CreateInstanceFieldSet(ArtMethod* resolved_method, + uint32_t field_index, + HInstruction* obj, + HInstruction* value) + SHARED_REQUIRES(Locks::mutator_lock_) { + Handle<mirror::DexCache> dex_cache(handles_->NewHandle(resolved_method->GetDexCache())); + size_t pointer_size = InstructionSetPointerSize(codegen_->GetInstructionSet()); + ArtField* resolved_field = dex_cache->GetResolvedField(field_index, pointer_size); + DCHECK(resolved_field != nullptr); + HInstanceFieldSet* iput = new (graph_->GetArena()) HInstanceFieldSet( + obj, + value, + resolved_field->GetTypeAsPrimitiveType(), + resolved_field->GetOffset(), + resolved_field->IsVolatile(), + field_index, + resolved_field->GetDeclaringClass()->GetDexClassDefIndex(), + *resolved_method->GetDexFile(), + dex_cache, + kNoDexPc); + return iput; +} bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, HInvoke* invoke_instruction, bool same_dex_file, @@ -815,7 +955,14 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, if (return_replacement != nullptr) { DCHECK_EQ(graph_, return_replacement->GetBlock()->GetGraph()); } + FixUpReturnReferenceType(resolved_method, invoke_instruction, return_replacement, do_rtp); + return true; +} +void HInliner::FixUpReturnReferenceType(ArtMethod* resolved_method, + HInvoke* invoke_instruction, + HInstruction* return_replacement, + bool do_rtp) { // Check the integrity of reference types and run another type propagation if needed. if (return_replacement != nullptr) { if (return_replacement->GetType() == Primitive::kPrimNot) { @@ -849,8 +996,6 @@ bool HInliner::TryBuildAndInline(ArtMethod* resolved_method, } } } - - return true; } } // namespace art diff --git a/compiler/optimizing/inliner.h b/compiler/optimizing/inliner.h index 3c01751a70..0127d55192 100644 --- a/compiler/optimizing/inliner.h +++ b/compiler/optimizing/inliner.h @@ -65,6 +65,20 @@ class HInliner : public HOptimization { bool TryInline(HInvoke* invoke_instruction, ArtMethod* resolved_method, bool do_rtp = true) SHARED_REQUIRES(Locks::mutator_lock_); + // Try to recognize known simple patterns and replace invoke call with appropriate instructions. + bool TryPatternSubstitution(HInvoke* invoke_instruction, ArtMethod* resolved_method, bool do_rtp) + SHARED_REQUIRES(Locks::mutator_lock_); + + // Create a new HInstanceFieldGet. + HInstanceFieldGet* CreateInstanceFieldGet(ArtMethod* resolved_method, + uint32_t field_index, + HInstruction* obj); + // Create a new HInstanceFieldSet. + HInstanceFieldSet* CreateInstanceFieldSet(ArtMethod* resolved_method, + uint32_t field_index, + HInstruction* obj, + HInstruction* value); + // Try to inline the target of a monomorphic call. If successful, the code // in the graph will look like: // if (receiver.getClass() != ic.GetMonomorphicType()) deopt @@ -90,6 +104,12 @@ class HInliner : public HOptimization { uint32_t dex_pc) const SHARED_REQUIRES(Locks::mutator_lock_); + void FixUpReturnReferenceType(ArtMethod* resolved_method, + HInvoke* invoke_instruction, + HInstruction* return_replacement, + bool do_rtp) + SHARED_REQUIRES(Locks::mutator_lock_); + HGraph* const outermost_graph_; const DexCompilationUnit& outer_compilation_unit_; const DexCompilationUnit& caller_compilation_unit_; diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h index 881beb49a6..52a7b10cad 100644 --- a/compiler/optimizing/optimizing_compiler_stats.h +++ b/compiler/optimizing/optimizing_compiler_stats.h @@ -29,6 +29,7 @@ enum MethodCompilationStat { kAttemptCompilation = 0, kCompiled, kInlinedInvoke, + kReplacedInvokeWithSimplePattern, kInstructionSimplifications, kInstructionSimplificationsArch, kUnresolvedMethod, @@ -97,6 +98,7 @@ class OptimizingCompilerStats { case kAttemptCompilation : name = "AttemptCompilation"; break; case kCompiled : name = "Compiled"; break; case kInlinedInvoke : name = "InlinedInvoke"; break; + case kReplacedInvokeWithSimplePattern: name = "ReplacedInvokeWithSimplePattern"; break; case kInstructionSimplifications: name = "InstructionSimplifications"; break; case kInstructionSimplificationsArch: name = "InstructionSimplificationsArch"; break; case kUnresolvedMethod : name = "UnresolvedMethod"; break; diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index 779f319e61..1224a48fa0 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -94,7 +94,6 @@ ReferenceTypePropagation::ReferenceTypePropagation(HGraph* graph, : HOptimization(graph, name), handle_cache_(handles), worklist_(graph->GetArena()->Adapter(kArenaAllocReferenceTypePropagation)) { - worklist_.reserve(kDefaultWorklistSize); } void ReferenceTypePropagation::ValidateTypes() { @@ -125,7 +124,14 @@ void ReferenceTypePropagation::ValidateTypes() { } } +void ReferenceTypePropagation::Visit(HInstruction* instruction) { + RTPVisitor visitor(graph_, &handle_cache_, &worklist_); + instruction->Accept(&visitor); +} + void ReferenceTypePropagation::Run() { + worklist_.reserve(kDefaultWorklistSize); + // To properly propagate type info we need to visit in the dominator-based order. // Reverse post order guarantees a node's dominators are visited first. // We take advantage of this order in `VisitBasicBlock`. diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h index 47ba0277ae..a7f10a65ab 100644 --- a/compiler/optimizing/reference_type_propagation.h +++ b/compiler/optimizing/reference_type_propagation.h @@ -35,6 +35,9 @@ class ReferenceTypePropagation : public HOptimization { StackHandleScopeCollection* handles, const char* name = kReferenceTypePropagationPassName); + // Visit a single instruction. + void Visit(HInstruction* instruction); + void Run() OVERRIDE; static constexpr const char* kReferenceTypePropagationPassName = "reference_type_propagation"; diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 262505b53b..0e67f49a09 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -6253,15 +6253,7 @@ bool ClassLinker::LinkInterfaceMethods( } // case kAbstractFound } if (LIKELY(fill_tables)) { - if (current_method != nullptr) { - // We found a default method implementation. Record it in the iftable and IMT. - method_array->SetElementPtrSize(j, current_method, image_pointer_size_); - SetIMTRef(unimplemented_method, - imt_conflict_method, - image_pointer_size_, - current_method, - /*out*/imt_ptr); - } else if (!super_interface) { + if (current_method == nullptr && !super_interface) { // We could not find an implementation for this method and since it is a brand new // interface we searched the entire vtable (and all default methods) for an // implementation but couldn't find one. We therefore need to make a miranda method. @@ -6277,7 +6269,17 @@ bool ClassLinker::LinkInterfaceMethods( new(miranda_method) ArtMethod(interface_method, image_pointer_size_); miranda_methods.push_back(miranda_method); } - method_array->SetElementPtrSize(j, miranda_method, image_pointer_size_); + current_method = miranda_method; + } + + if (current_method != nullptr) { + // We found a default method implementation. Record it in the iftable and IMT. + method_array->SetElementPtrSize(j, current_method, image_pointer_size_); + SetIMTRef(unimplemented_method, + imt_conflict_method, + image_pointer_size_, + current_method, + /*out*/imt_ptr); } } } // For each method in interface end. diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc index 5e7f1a20fd..8356814354 100644 --- a/runtime/gc/reference_processor.cc +++ b/runtime/gc/reference_processor.cc @@ -277,11 +277,7 @@ bool ReferenceProcessor::MakeCircularListIfUnenqueued(mirror::FinalizerReference MutexLock mu2(self, *Locks::reference_queue_finalizer_references_lock_); if (!reference->IsEnqueued()) { CHECK(reference->IsFinalizerReferenceInstance()); - if (Runtime::Current()->IsActiveTransaction()) { - reference->SetPendingNext<true>(reference); - } else { - reference->SetPendingNext<false>(reference); - } + reference->SetPendingNext(reference); return true; } return false; diff --git a/runtime/gc/reference_queue.cc b/runtime/gc/reference_queue.cc index 56957baebf..67dcc2d1a8 100644 --- a/runtime/gc/reference_queue.cc +++ b/runtime/gc/reference_queue.cc @@ -49,17 +49,9 @@ void ReferenceQueue::EnqueuePendingReference(mirror::Reference* ref) { list_ = ref; } else { mirror::Reference* head = list_->GetPendingNext(); - if (Runtime::Current()->IsActiveTransaction()) { - ref->SetPendingNext<true>(head); - } else { - ref->SetPendingNext<false>(head); - } - } - if (Runtime::Current()->IsActiveTransaction()) { - list_->SetPendingNext<true>(ref); - } else { - list_->SetPendingNext<false>(ref); + ref->SetPendingNext(head); } + list_->SetPendingNext(ref); } mirror::Reference* ReferenceQueue::DequeuePendingReference() { @@ -74,18 +66,10 @@ mirror::Reference* ReferenceQueue::DequeuePendingReference() { list_ = nullptr; } else { mirror::Reference* next = head->GetPendingNext(); - if (Runtime::Current()->IsActiveTransaction()) { - list_->SetPendingNext<true>(next); - } else { - list_->SetPendingNext<false>(next); - } + list_->SetPendingNext(next); ref = head; } - if (Runtime::Current()->IsActiveTransaction()) { - ref->SetPendingNext<true>(nullptr); - } else { - ref->SetPendingNext<false>(nullptr); - } + ref->SetPendingNext(nullptr); Heap* heap = Runtime::Current()->GetHeap(); if (kUseBakerOrBrooksReadBarrier && heap->CurrentCollectorType() == kCollectorTypeCC && heap->ConcurrentCopyingCollector()->IsActive()) { diff --git a/runtime/mirror/reference.h b/runtime/mirror/reference.h index 51ae760515..5e467ab94a 100644 --- a/runtime/mirror/reference.h +++ b/runtime/mirror/reference.h @@ -22,6 +22,7 @@ #include "object.h" #include "object_callbacks.h" #include "read_barrier_option.h" +#include "runtime.h" #include "thread.h" namespace art { @@ -80,9 +81,14 @@ class MANAGED Reference : public Object { Reference* GetPendingNext() SHARED_REQUIRES(Locks::mutator_lock_) { return GetFieldObject<Reference>(PendingNextOffset()); } - template<bool kTransactionActive> - void SetPendingNext(Reference* pending_next) SHARED_REQUIRES(Locks::mutator_lock_) { - SetFieldObject<kTransactionActive>(PendingNextOffset(), pending_next); + + void SetPendingNext(Reference* pending_next) + SHARED_REQUIRES(Locks::mutator_lock_) { + if (Runtime::Current()->IsActiveTransaction()) { + SetFieldObject<true>(PendingNextOffset(), pending_next); + } else { + SetFieldObject<false>(PendingNextOffset(), pending_next); + } } bool IsEnqueued() SHARED_REQUIRES(Locks::mutator_lock_) { diff --git a/runtime/quick/inline_method_analyser.cc b/runtime/quick/inline_method_analyser.cc index 65543942c7..17306c9842 100644 --- a/runtime/quick/inline_method_analyser.cc +++ b/runtime/quick/inline_method_analyser.cc @@ -71,14 +71,37 @@ static_assert(InlineMethodAnalyser::IGetVariant(Instruction::IGET_SHORT) == // we need to be able to detect possibly inlined method, we pass a null inline method to indicate // we don't want to take unresolved methods and fields into account during analysis. bool InlineMethodAnalyser::AnalyseMethodCode(verifier::MethodVerifier* verifier, - InlineMethod* method) { + InlineMethod* result) { DCHECK(verifier != nullptr); if (!Runtime::Current()->UseJit()) { - DCHECK_EQ(verifier->CanLoadClasses(), method != nullptr); + DCHECK_EQ(verifier->CanLoadClasses(), result != nullptr); + } + + // Note: verifier->GetMethod() may be null. + return AnalyseMethodCode(verifier->CodeItem(), + verifier->GetMethodReference(), + (verifier->GetAccessFlags() & kAccStatic) != 0u, + verifier->GetMethod(), + result); +} + +bool InlineMethodAnalyser::AnalyseMethodCode(ArtMethod* method, InlineMethod* result) { + const DexFile::CodeItem* code_item = method->GetCodeItem(); + if (code_item == nullptr) { + // Native or abstract. + return false; } + return AnalyseMethodCode( + code_item, method->ToMethodReference(), method->IsStatic(), method, result); +} + +bool InlineMethodAnalyser::AnalyseMethodCode(const DexFile::CodeItem* code_item, + const MethodReference& method_ref, + bool is_static, + ArtMethod* method, + InlineMethod* result) { // We currently support only plain return or 2-instruction methods. - const DexFile::CodeItem* code_item = verifier->CodeItem(); DCHECK_NE(code_item->insns_size_in_code_units_, 0u); const Instruction* instruction = Instruction::At(code_item->insns_); Instruction::Code opcode = instruction->Opcode(); @@ -86,21 +109,21 @@ bool InlineMethodAnalyser::AnalyseMethodCode(verifier::MethodVerifier* verifier, switch (opcode) { case Instruction::RETURN_VOID: if (method != nullptr) { - method->opcode = kInlineOpNop; - method->flags = kInlineSpecial; - method->d.data = 0u; + result->opcode = kInlineOpNop; + result->flags = kInlineSpecial; + result->d.data = 0u; } return true; case Instruction::RETURN: case Instruction::RETURN_OBJECT: case Instruction::RETURN_WIDE: - return AnalyseReturnMethod(code_item, method); + return AnalyseReturnMethod(code_item, result); case Instruction::CONST: case Instruction::CONST_4: case Instruction::CONST_16: case Instruction::CONST_HIGH16: // TODO: Support wide constants (RETURN_WIDE). - return AnalyseConstMethod(code_item, method); + return AnalyseConstMethod(code_item, result); case Instruction::IGET: case Instruction::IGET_OBJECT: case Instruction::IGET_BOOLEAN: @@ -112,7 +135,7 @@ bool InlineMethodAnalyser::AnalyseMethodCode(verifier::MethodVerifier* verifier, // case Instruction::IGET_QUICK: // case Instruction::IGET_WIDE_QUICK: // case Instruction::IGET_OBJECT_QUICK: - return AnalyseIGetMethod(verifier, method); + return AnalyseIGetMethod(code_item, method_ref, is_static, method, result); case Instruction::IPUT: case Instruction::IPUT_OBJECT: case Instruction::IPUT_BOOLEAN: @@ -124,7 +147,7 @@ bool InlineMethodAnalyser::AnalyseMethodCode(verifier::MethodVerifier* verifier, // case Instruction::IPUT_QUICK: // case Instruction::IPUT_WIDE_QUICK: // case Instruction::IPUT_OBJECT_QUICK: - return AnalyseIPutMethod(verifier, method); + return AnalyseIPutMethod(code_item, method_ref, is_static, method, result); default: return false; } @@ -194,9 +217,11 @@ bool InlineMethodAnalyser::AnalyseConstMethod(const DexFile::CodeItem* code_item return true; } -bool InlineMethodAnalyser::AnalyseIGetMethod(verifier::MethodVerifier* verifier, +bool InlineMethodAnalyser::AnalyseIGetMethod(const DexFile::CodeItem* code_item, + const MethodReference& method_ref, + bool is_static, + ArtMethod* method, InlineMethod* result) { - const DexFile::CodeItem* code_item = verifier->CodeItem(); const Instruction* instruction = Instruction::At(code_item->insns_); Instruction::Code opcode = instruction->Opcode(); DCHECK(IsInstructionIGet(opcode)); @@ -227,10 +252,10 @@ bool InlineMethodAnalyser::AnalyseIGetMethod(verifier::MethodVerifier* verifier, return false; // Not returning the value retrieved by IGET? } - if ((verifier->GetAccessFlags() & kAccStatic) != 0u || object_arg != 0u) { + if (is_static || object_arg != 0u) { // TODO: Implement inlining of IGET on non-"this" registers (needs correct stack trace for NPE). // Allow synthetic accessors. We don't care about losing their stack frame in NPE. - if (!IsSyntheticAccessor(verifier->GetMethodReference())) { + if (!IsSyntheticAccessor(method_ref)) { return false; } } @@ -243,13 +268,13 @@ bool InlineMethodAnalyser::AnalyseIGetMethod(verifier::MethodVerifier* verifier, if (result != nullptr) { InlineIGetIPutData* data = &result->d.ifield_data; - if (!ComputeSpecialAccessorInfo(field_idx, false, verifier, data)) { + if (!ComputeSpecialAccessorInfo(method, field_idx, false, data)) { return false; } result->opcode = kInlineOpIGet; result->flags = kInlineSpecial; data->op_variant = IGetVariant(opcode); - data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0u ? 1u : 0u; + data->method_is_static = is_static ? 1u : 0u; data->object_arg = object_arg; // Allow IGET on any register, not just "this". data->src_arg = 0u; data->return_arg_plus1 = 0u; @@ -257,9 +282,11 @@ bool InlineMethodAnalyser::AnalyseIGetMethod(verifier::MethodVerifier* verifier, return true; } -bool InlineMethodAnalyser::AnalyseIPutMethod(verifier::MethodVerifier* verifier, +bool InlineMethodAnalyser::AnalyseIPutMethod(const DexFile::CodeItem* code_item, + const MethodReference& method_ref, + bool is_static, + ArtMethod* method, InlineMethod* result) { - const DexFile::CodeItem* code_item = verifier->CodeItem(); const Instruction* instruction = Instruction::At(code_item->insns_); Instruction::Code opcode = instruction->Opcode(); DCHECK(IsInstructionIPut(opcode)); @@ -292,10 +319,10 @@ bool InlineMethodAnalyser::AnalyseIPutMethod(verifier::MethodVerifier* verifier, uint32_t object_arg = object_reg - arg_start; uint32_t src_arg = src_reg - arg_start; - if ((verifier->GetAccessFlags() & kAccStatic) != 0u || object_arg != 0u) { + if (is_static || object_arg != 0u) { // TODO: Implement inlining of IPUT on non-"this" registers (needs correct stack trace for NPE). // Allow synthetic accessors. We don't care about losing their stack frame in NPE. - if (!IsSyntheticAccessor(verifier->GetMethodReference())) { + if (!IsSyntheticAccessor(method_ref)) { return false; } } @@ -310,13 +337,13 @@ bool InlineMethodAnalyser::AnalyseIPutMethod(verifier::MethodVerifier* verifier, if (result != nullptr) { InlineIGetIPutData* data = &result->d.ifield_data; - if (!ComputeSpecialAccessorInfo(field_idx, true, verifier, data)) { + if (!ComputeSpecialAccessorInfo(method, field_idx, true, data)) { return false; } result->opcode = kInlineOpIPut; result->flags = kInlineSpecial; data->op_variant = IPutVariant(opcode); - data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0u ? 1u : 0u; + data->method_is_static = is_static ? 1u : 0u; data->object_arg = object_arg; // Allow IPUT on any register, not just "this". data->src_arg = src_arg; data->return_arg_plus1 = return_arg_plus1; @@ -324,15 +351,17 @@ bool InlineMethodAnalyser::AnalyseIPutMethod(verifier::MethodVerifier* verifier, return true; } -bool InlineMethodAnalyser::ComputeSpecialAccessorInfo(uint32_t field_idx, bool is_put, - verifier::MethodVerifier* verifier, +bool InlineMethodAnalyser::ComputeSpecialAccessorInfo(ArtMethod* method, + uint32_t field_idx, + bool is_put, InlineIGetIPutData* result) { - mirror::DexCache* dex_cache = verifier->GetDexCache(); - uint32_t method_idx = verifier->GetMethodReference().dex_method_index; - auto* cl = Runtime::Current()->GetClassLinker(); - ArtMethod* method = dex_cache->GetResolvedMethod(method_idx, cl->GetImagePointerSize()); - ArtField* field = cl->GetResolvedField(field_idx, dex_cache); - if (method == nullptr || field == nullptr || field->IsStatic()) { + if (method == nullptr) { + return false; + } + mirror::DexCache* dex_cache = method->GetDexCache(); + size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); + ArtField* field = dex_cache->GetResolvedField(field_idx, pointer_size); + if (field == nullptr || field->IsStatic()) { return false; } mirror::Class* method_class = method->GetDeclaringClass(); diff --git a/runtime/quick/inline_method_analyser.h b/runtime/quick/inline_method_analyser.h index 1bb816bb20..046d2257f4 100644 --- a/runtime/quick/inline_method_analyser.h +++ b/runtime/quick/inline_method_analyser.h @@ -188,7 +188,9 @@ class InlineMethodAnalyser { * @param method placeholder for the inline method data. * @return true if the method is a candidate for inlining, false otherwise. */ - static bool AnalyseMethodCode(verifier::MethodVerifier* verifier, InlineMethod* method) + static bool AnalyseMethodCode(verifier::MethodVerifier* verifier, InlineMethod* result) + SHARED_REQUIRES(Locks::mutator_lock_); + static bool AnalyseMethodCode(ArtMethod* method, InlineMethod* result) SHARED_REQUIRES(Locks::mutator_lock_); static constexpr bool IsInstructionIGet(Instruction::Code opcode) { @@ -211,17 +213,32 @@ class InlineMethodAnalyser { static bool IsSyntheticAccessor(MethodReference ref); private: + static bool AnalyseMethodCode(const DexFile::CodeItem* code_item, + const MethodReference& method_ref, + bool is_static, + ArtMethod* method, + InlineMethod* result) + SHARED_REQUIRES(Locks::mutator_lock_); static bool AnalyseReturnMethod(const DexFile::CodeItem* code_item, InlineMethod* result); static bool AnalyseConstMethod(const DexFile::CodeItem* code_item, InlineMethod* result); - static bool AnalyseIGetMethod(verifier::MethodVerifier* verifier, InlineMethod* result) + static bool AnalyseIGetMethod(const DexFile::CodeItem* code_item, + const MethodReference& method_ref, + bool is_static, + ArtMethod* method, + InlineMethod* result) SHARED_REQUIRES(Locks::mutator_lock_); - static bool AnalyseIPutMethod(verifier::MethodVerifier* verifier, InlineMethod* result) + static bool AnalyseIPutMethod(const DexFile::CodeItem* code_item, + const MethodReference& method_ref, + bool is_static, + ArtMethod* method, + InlineMethod* result) SHARED_REQUIRES(Locks::mutator_lock_); // Can we fast path instance field access in a verified accessor? // If yes, computes field's offset and volatility and whether the method is static or not. - static bool ComputeSpecialAccessorInfo(uint32_t field_idx, bool is_put, - verifier::MethodVerifier* verifier, + static bool ComputeSpecialAccessorInfo(ArtMethod* method, + uint32_t field_idx, + bool is_put, InlineIGetIPutData* result) SHARED_REQUIRES(Locks::mutator_lock_); }; diff --git a/runtime/verifier/method_verifier-inl.h b/runtime/verifier/method_verifier-inl.h index f52d0110aa..def61db81a 100644 --- a/runtime/verifier/method_verifier-inl.h +++ b/runtime/verifier/method_verifier-inl.h @@ -50,6 +50,10 @@ inline mirror::DexCache* MethodVerifier::GetDexCache() { return dex_cache_.Get(); } +inline ArtMethod* MethodVerifier::GetMethod() const { + return mirror_method_; +} + inline MethodReference MethodVerifier::GetMethodReference() const { return MethodReference(dex_file_, dex_method_idx_); } diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index a26e0fba13..613d5af212 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -270,6 +270,7 @@ class MethodVerifier { ALWAYS_INLINE InstructionFlags& GetInstructionFlags(size_t index); mirror::ClassLoader* GetClassLoader() SHARED_REQUIRES(Locks::mutator_lock_); mirror::DexCache* GetDexCache() SHARED_REQUIRES(Locks::mutator_lock_); + ArtMethod* GetMethod() const SHARED_REQUIRES(Locks::mutator_lock_); MethodReference GetMethodReference() const; uint32_t GetAccessFlags() const; bool HasCheckCasts() const; diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc index 71ed4a2a76..30f613c389 100644 --- a/runtime/verifier/reg_type_cache.cc +++ b/runtime/verifier/reg_type_cache.cc @@ -155,7 +155,7 @@ mirror::Class* RegTypeCache::ResolveClass(const char* descriptor, mirror::ClassL } else { klass = class_linker->LookupClass(self, descriptor, ComputeModifiedUtf8Hash(descriptor), loader); - if (klass != nullptr && !klass->IsLoaded()) { + if (klass != nullptr && !klass->IsResolved()) { // We found the class but without it being loaded its not safe for use. klass = nullptr; } diff --git a/test/569-checker-pattern-replacement/expected.txt b/test/569-checker-pattern-replacement/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/569-checker-pattern-replacement/expected.txt diff --git a/test/569-checker-pattern-replacement/info.txt b/test/569-checker-pattern-replacement/info.txt new file mode 100644 index 0000000000..4dfa932000 --- /dev/null +++ b/test/569-checker-pattern-replacement/info.txt @@ -0,0 +1 @@ +Test pattern substitution used when we cannot inline. diff --git a/test/569-checker-pattern-replacement/run b/test/569-checker-pattern-replacement/run new file mode 100755 index 0000000000..f7e9df211f --- /dev/null +++ b/test/569-checker-pattern-replacement/run @@ -0,0 +1,18 @@ +#!/bin/bash +# +# Copyright (C) 2016 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +exec ${RUN} "$@" \ + -Xcompiler-option --no-inline-from=core-oj,569-checker-pattern-replacement.jar:classes2.dex diff --git a/test/569-checker-pattern-replacement/src-multidex/Second.java b/test/569-checker-pattern-replacement/src-multidex/Second.java new file mode 100644 index 0000000000..cba1dc8dcb --- /dev/null +++ b/test/569-checker-pattern-replacement/src-multidex/Second.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public final class Second { + public static void staticNop(int unused) { } + + public void nop() { } + + public static Object staticReturnArg2(int unused1, String arg2) { + return arg2; + } + + public long returnArg1(long arg1) { + return arg1; + } + + public static int staticReturn9() { + return 9; + } + + public int return7(Object unused) { + return 7; + } + + public static String staticReturnNull() { + return null; + } + + public Object returnNull() { + return null; + } + + public int getInstanceIntField() { + return instanceIntField; + } + + public double getInstanceDoubleField(int unused1) { + return instanceDoubleField; + } + + public Object getInstanceObjectField(long unused1) { + return instanceObjectField; + } + + public String getInstanceStringField(Object unused1, String unused2, long unused3) { + return instanceStringField; + } + + public static int staticGetInstanceIntField(Second s) { + return s.instanceIntField; + } + + public double getInstanceDoubleFieldFromParam(Second s) { + return s.instanceDoubleField; + } + + public int getStaticIntField() { + return staticIntField; + } + + public void setInstanceLongField(int ignored, long value) { + instanceLongField = value; + } + + public int setInstanceLongFieldReturnArg2(long value, int arg2) { + instanceLongField = value; + return arg2; + } + + public static void staticSetInstanceLongField(Second s, long value) { + s.instanceLongField = value; + } + + public void setInstanceLongFieldThroughParam(Second s, long value) { + s.instanceLongField = value; + } + + public void setStaticFloatField(float value) { + staticFloatField = value; + } + + public int instanceIntField = 42; + public double instanceDoubleField = -42.0; + public Object instanceObjectField = null; + public String instanceStringField = "dummy"; + public long instanceLongField = 0; // Overwritten by setters. + + public static int staticIntField = 4242; + public static float staticFloatField = 0.0f; // Overwritten by setters. +} diff --git a/test/569-checker-pattern-replacement/src/Main.java b/test/569-checker-pattern-replacement/src/Main.java new file mode 100644 index 0000000000..9a85c81249 --- /dev/null +++ b/test/569-checker-pattern-replacement/src/Main.java @@ -0,0 +1,380 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Main { + /// CHECK-START: void Main.staticNop() inliner (before) + /// CHECK: InvokeStaticOrDirect + + /// CHECK-START: void Main.staticNop() inliner (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static void staticNop() { + Second.staticNop(11); + } + + /// CHECK-START: void Main.nop(Second) inliner (before) + /// CHECK: InvokeVirtual + + /// CHECK-START: void Main.nop(Second) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static void nop(Second s) { + s.nop(); + } + + /// CHECK-START: java.lang.Object Main.staticReturnArg2(java.lang.String) inliner (before) + /// CHECK-DAG: <<Value:l\d+>> ParameterValue + /// CHECK-DAG: <<Ignored:i\d+>> IntConstant 77 + /// CHECK-DAG: <<ClinitCk:l\d+>> ClinitCheck + /// CHECK-DAG: <<Invoke:l\d+>> InvokeStaticOrDirect [<<Ignored>>,<<Value>>,<<ClinitCk>>] + /// CHECK-DAG: Return [<<Invoke>>] + + /// CHECK-START: java.lang.Object Main.staticReturnArg2(java.lang.String) inliner (after) + /// CHECK-DAG: <<Value:l\d+>> ParameterValue + /// CHECK-DAG: Return [<<Value>>] + + /// CHECK-START: java.lang.Object Main.staticReturnArg2(java.lang.String) inliner (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static Object staticReturnArg2(String value) { + return Second.staticReturnArg2(77, value); + } + + /// CHECK-START: long Main.returnArg1(Second, long) inliner (before) + /// CHECK-DAG: <<Second:l\d+>> ParameterValue + /// CHECK-DAG: <<Value:j\d+>> ParameterValue + /// CHECK-DAG: <<NullCk:l\d+>> NullCheck [<<Second>>] + /// CHECK-DAG: <<Invoke:j\d+>> InvokeVirtual [<<NullCk>>,<<Value>>] + /// CHECK-DAG: Return [<<Invoke>>] + + /// CHECK-START: long Main.returnArg1(Second, long) inliner (after) + /// CHECK-DAG: <<Value:j\d+>> ParameterValue + /// CHECK-DAG: Return [<<Value>>] + + /// CHECK-START: long Main.returnArg1(Second, long) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static long returnArg1(Second s, long value) { + return s.returnArg1(value); + } + + /// CHECK-START: int Main.staticReturn9() inliner (before) + /// CHECK: {{i\d+}} InvokeStaticOrDirect + + /// CHECK-START: int Main.staticReturn9() inliner (before) + /// CHECK-NOT: IntConstant 9 + + /// CHECK-START: int Main.staticReturn9() inliner (after) + /// CHECK-DAG: <<Const9:i\d+>> IntConstant 9 + /// CHECK-DAG: Return [<<Const9>>] + + /// CHECK-START: int Main.staticReturn9() inliner (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static int staticReturn9() { + return Second.staticReturn9(); + } + + /// CHECK-START: int Main.return7(Second) inliner (before) + /// CHECK: {{i\d+}} InvokeVirtual + + /// CHECK-START: int Main.return7(Second) inliner (before) + /// CHECK-NOT: IntConstant 7 + + /// CHECK-START: int Main.return7(Second) inliner (after) + /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7 + /// CHECK-DAG: Return [<<Const7>>] + + /// CHECK-START: int Main.return7(Second) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static int return7(Second s) { + return s.return7(null); + } + + /// CHECK-START: java.lang.String Main.staticReturnNull() inliner (before) + /// CHECK: {{l\d+}} InvokeStaticOrDirect + + /// CHECK-START: java.lang.String Main.staticReturnNull() inliner (before) + /// CHECK-NOT: NullConstant + + /// CHECK-START: java.lang.String Main.staticReturnNull() inliner (after) + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: Return [<<Null>>] + + /// CHECK-START: java.lang.String Main.staticReturnNull() inliner (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static String staticReturnNull() { + return Second.staticReturnNull(); + } + + /// CHECK-START: java.lang.Object Main.returnNull(Second) inliner (before) + /// CHECK: {{l\d+}} InvokeVirtual + + /// CHECK-START: java.lang.Object Main.returnNull(Second) inliner (before) + /// CHECK-NOT: NullConstant + + /// CHECK-START: java.lang.Object Main.returnNull(Second) inliner (after) + /// CHECK-DAG: <<Null:l\d+>> NullConstant + /// CHECK-DAG: Return [<<Null>>] + + /// CHECK-START: java.lang.Object Main.returnNull(Second) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static Object returnNull(Second s) { + return s.returnNull(); + } + + /// CHECK-START: int Main.getInt(Second) inliner (before) + /// CHECK: {{i\d+}} InvokeVirtual + + /// CHECK-START: int Main.getInt(Second) inliner (after) + /// CHECK: {{i\d+}} InstanceFieldGet + + /// CHECK-START: int Main.getInt(Second) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static int getInt(Second s) { + return s.getInstanceIntField(); + } + + /// CHECK-START: double Main.getDouble(Second) inliner (before) + /// CHECK: {{d\d+}} InvokeVirtual + + /// CHECK-START: double Main.getDouble(Second) inliner (after) + /// CHECK: {{d\d+}} InstanceFieldGet + + /// CHECK-START: double Main.getDouble(Second) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static double getDouble(Second s) { + return s.getInstanceDoubleField(22); + } + + /// CHECK-START: java.lang.Object Main.getObject(Second) inliner (before) + /// CHECK: {{l\d+}} InvokeVirtual + + /// CHECK-START: java.lang.Object Main.getObject(Second) inliner (after) + /// CHECK: {{l\d+}} InstanceFieldGet + + /// CHECK-START: java.lang.Object Main.getObject(Second) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static Object getObject(Second s) { + return s.getInstanceObjectField(-1L); + } + + /// CHECK-START: java.lang.String Main.getString(Second) inliner (before) + /// CHECK: {{l\d+}} InvokeVirtual + + /// CHECK-START: java.lang.String Main.getString(Second) inliner (after) + /// CHECK: {{l\d+}} InstanceFieldGet + + /// CHECK-START: java.lang.String Main.getString(Second) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static String getString(Second s) { + return s.getInstanceStringField(null, "whatever", 1234L); + } + + /// CHECK-START: int Main.staticGetInt(Second) inliner (before) + /// CHECK: {{i\d+}} InvokeStaticOrDirect + + /// CHECK-START: int Main.staticGetInt(Second) inliner (after) + /// CHECK: {{i\d+}} InvokeStaticOrDirect + + /// CHECK-START: int Main.staticGetInt(Second) inliner (after) + /// CHECK-NOT: InstanceFieldGet + + public static int staticGetInt(Second s) { + return Second.staticGetInstanceIntField(s); + } + + /// CHECK-START: double Main.getDoubleFromParam(Second) inliner (before) + /// CHECK: {{d\d+}} InvokeVirtual + + /// CHECK-START: double Main.getDoubleFromParam(Second) inliner (after) + /// CHECK: {{d\d+}} InvokeVirtual + + /// CHECK-START: double Main.getDoubleFromParam(Second) inliner (after) + /// CHECK-NOT: InstanceFieldGet + + public static double getDoubleFromParam(Second s) { + return s.getInstanceDoubleFieldFromParam(s); + } + + /// CHECK-START: int Main.getStaticInt(Second) inliner (before) + /// CHECK: {{i\d+}} InvokeVirtual + + /// CHECK-START: int Main.getStaticInt(Second) inliner (after) + /// CHECK: {{i\d+}} InvokeVirtual + + /// CHECK-START: int Main.getStaticInt(Second) inliner (after) + /// CHECK-NOT: InstanceFieldGet + /// CHECK-NOT: StaticFieldGet + + public static int getStaticInt(Second s) { + return s.getStaticIntField(); + } + + /// CHECK-START: long Main.setLong(Second, long) inliner (before) + /// CHECK: InvokeVirtual + + /// CHECK-START: long Main.setLong(Second, long) inliner (after) + /// CHECK: InstanceFieldSet + + /// CHECK-START: long Main.setLong(Second, long) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static long setLong(Second s, long value) { + s.setInstanceLongField(-1, value); + return s.instanceLongField; + } + + /// CHECK-START: long Main.setLongReturnArg2(Second, long, int) inliner (before) + /// CHECK: InvokeVirtual + + /// CHECK-START: long Main.setLongReturnArg2(Second, long, int) inliner (after) + /// CHECK-DAG: <<Second:l\d+>> ParameterValue + /// CHECK-DAG: <<Value:j\d+>> ParameterValue + /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue + /// CHECK-DAG: <<NullCk:l\d+>> NullCheck [<<Second>>] + /// CHECK-DAG: InstanceFieldSet [<<NullCk>>,<<Value>>] + /// CHECK-DAG: <<NullCk2:l\d+>> NullCheck [<<Second>>] + /// CHECK-DAG: <<IGet:j\d+>> InstanceFieldGet [<<NullCk2>>] + /// CHECK-DAG: <<Conv:j\d+>> TypeConversion [<<Arg2>>] + /// CHECK-DAG: <<Add:j\d+>> Add [<<IGet>>,<<Conv>>] + /// CHECK-DAG: Return [<<Add>>] + + /// CHECK-START: long Main.setLongReturnArg2(Second, long, int) inliner (after) + /// CHECK-NOT: InvokeVirtual + + public static long setLongReturnArg2(Second s, long value, int arg2) { + int result = s.setInstanceLongFieldReturnArg2(value, arg2); + return s.instanceLongField + result; + } + + /// CHECK-START: long Main.staticSetLong(Second, long) inliner (before) + /// CHECK: InvokeStaticOrDirect + + /// CHECK-START: long Main.staticSetLong(Second, long) inliner (after) + /// CHECK: InvokeStaticOrDirect + + /// CHECK-START: long Main.staticSetLong(Second, long) inliner (after) + /// CHECK-NOT: InstanceFieldSet + + public static long staticSetLong(Second s, long value) { + Second.staticSetInstanceLongField(s, value); + return s.instanceLongField; + } + + /// CHECK-START: long Main.setLongThroughParam(Second, long) inliner (before) + /// CHECK: InvokeVirtual + + /// CHECK-START: long Main.setLongThroughParam(Second, long) inliner (after) + /// CHECK: InvokeVirtual + + /// CHECK-START: long Main.setLongThroughParam(Second, long) inliner (after) + /// CHECK-NOT: InstanceFieldSet + + public static long setLongThroughParam(Second s, long value) { + s.setInstanceLongFieldThroughParam(s, value); + return s.instanceLongField; + } + + /// CHECK-START: float Main.setStaticFloat(Second, float) inliner (before) + /// CHECK: InvokeVirtual + + /// CHECK-START: float Main.setStaticFloat(Second, float) inliner (after) + /// CHECK: InvokeVirtual + + /// CHECK-START: float Main.setStaticFloat(Second, float) inliner (after) + /// CHECK-NOT: InstanceFieldSet + /// CHECK-NOT: StaticFieldSet + + public static float setStaticFloat(Second s, float value) { + s.setStaticFloatField(value); + return s.staticFloatField; + } + + /// CHECK-START: java.lang.Object Main.newObject() inliner (before) + /// CHECK-DAG: <<Obj:l\d+>> NewInstance + /// CHECK-DAG: InvokeStaticOrDirect [<<Obj>>] method_name:java.lang.Object.<init> + + /// CHECK-START: java.lang.Object Main.newObject() inliner (after) + /// CHECK-NOT: InvokeStaticOrDirect + + public static Object newObject() { + return new Object(); + } + + public static void main(String[] args) throws Exception { + Second s = new Second(); + + // Replaced NOP pattern. + staticNop(); + nop(s); + // Replaced "return arg" pattern. + assertEquals("arbitrary string", staticReturnArg2("arbitrary string")); + assertEquals(4321L, returnArg1(s, 4321L)); + // Replaced "return const" pattern. + assertEquals(9, staticReturn9()); + assertEquals(7, return7(s)); + assertEquals(null, staticReturnNull()); + assertEquals(null, returnNull(s)); + // Replaced IGET pattern. + assertEquals(42, getInt(s)); + assertEquals(-42.0, getDouble(s)); + assertEquals(null, getObject(s)); + assertEquals("dummy", getString(s)); + // Not replaced IGET pattern. + assertEquals(42, staticGetInt(s)); + assertEquals(-42.0, getDoubleFromParam(s)); + // SGET. + assertEquals(4242, getStaticInt(s)); + // Replaced IPUT pattern. + assertEquals(111L, setLong(s, 111L)); + assertEquals(345L, setLongReturnArg2(s, 222L, 123)); + // Not replaced IPUT pattern. + assertEquals(222L, staticSetLong(s, 222L)); + assertEquals(333L, setLongThroughParam(s, 333L)); + // SPUT. + assertEquals(-11.5f, setStaticFloat(s, -11.5f)); + + if (newObject() == null) { + throw new AssertionError("new Object() cannot be null."); + } + } + + private static void assertEquals(int expected, int actual) { + if (expected != actual) { + throw new AssertionError("Wrong result: " + expected + " != " + actual); + } + } + + private static void assertEquals(double expected, double actual) { + if (expected != actual) { + throw new AssertionError("Wrong result: " + expected + " != " + actual); + } + } + + private static void assertEquals(Object expected, Object actual) { + if (expected != actual && (expected == null || !expected.equals(actual))) { + throw new AssertionError("Wrong result: " + expected + " != " + actual); + } + } +} diff --git a/test/972-default-imt-collision/expected.txt b/test/972-default-imt-collision/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/972-default-imt-collision/expected.txt diff --git a/test/972-default-imt-collision/info.txt b/test/972-default-imt-collision/info.txt new file mode 100644 index 0000000000..adecee3be5 --- /dev/null +++ b/test/972-default-imt-collision/info.txt @@ -0,0 +1 @@ +Test for interaction of miranda and non-miranda methods on interface dispatch. diff --git a/test/972-default-imt-collision/smali/Iface1.smali b/test/972-default-imt-collision/smali/Iface1.smali new file mode 100644 index 0000000000..088c29c6a0 --- /dev/null +++ b/test/972-default-imt-collision/smali/Iface1.smali @@ -0,0 +1,32 @@ +# /* +# * Copyright (C) 2016 The Android Open Source Project +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# */ +# +# public interface Iface1 { +# public default void sayHi() { +# System.out.println("FAILED: We should never invoke this method!"); +# } +# } + +.class public abstract interface LIface1; +.super Ljava/lang/Object; + +.method public sayHi()V + .locals 2 + sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v0, "FAILED: We should never invoke this method!" + invoke-virtual {v1,v0}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + return-void +.end method diff --git a/test/972-default-imt-collision/smali/Iface2.smali b/test/972-default-imt-collision/smali/Iface2.smali new file mode 100644 index 0000000000..4320e7e1f6 --- /dev/null +++ b/test/972-default-imt-collision/smali/Iface2.smali @@ -0,0 +1,277 @@ +# /* +# * Copyright (C) 2016 The Android Open Source Project +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# */ +# +# public interface Iface2 { +# public void notImplementedMethod0(); +# public void notImplementedMethod1(); +# public void notImplementedMethod2(); +# public void notImplementedMethod3(); +# public void notImplementedMethod4(); +# public void notImplementedMethod5(); +# public void notImplementedMethod6(); +# public void notImplementedMethod7(); +# public void notImplementedMethod8(); +# public void notImplementedMethod9(); +# public void notImplementedMethod10(); +# public void notImplementedMethod11(); +# public void notImplementedMethod12(); +# public void notImplementedMethod13(); +# public void notImplementedMethod14(); +# public void notImplementedMethod15(); +# public void notImplementedMethod16(); +# public void notImplementedMethod17(); +# public void notImplementedMethod18(); +# public void notImplementedMethod19(); +# public void notImplementedMethod20(); +# public void notImplementedMethod21(); +# public void notImplementedMethod22(); +# public void notImplementedMethod23(); +# public void notImplementedMethod24(); +# public void notImplementedMethod25(); +# public void notImplementedMethod26(); +# public void notImplementedMethod27(); +# public void notImplementedMethod28(); +# public void notImplementedMethod29(); +# public void notImplementedMethod30(); +# public void notImplementedMethod31(); +# public void notImplementedMethod32(); +# public void notImplementedMethod33(); +# public void notImplementedMethod34(); +# public void notImplementedMethod35(); +# public void notImplementedMethod36(); +# public void notImplementedMethod37(); +# public void notImplementedMethod38(); +# public void notImplementedMethod39(); +# public void notImplementedMethod40(); +# public void notImplementedMethod41(); +# public void notImplementedMethod42(); +# public void notImplementedMethod43(); +# public void notImplementedMethod44(); +# public void notImplementedMethod45(); +# public void notImplementedMethod46(); +# public void notImplementedMethod47(); +# public void notImplementedMethod48(); +# public void notImplementedMethod49(); +# public void notImplementedMethod50(); +# public void notImplementedMethod51(); +# public void notImplementedMethod52(); +# public void notImplementedMethod53(); +# public void notImplementedMethod54(); +# public void notImplementedMethod55(); +# public void notImplementedMethod56(); +# public void notImplementedMethod57(); +# public void notImplementedMethod58(); +# public void notImplementedMethod59(); +# public void notImplementedMethod60(); +# public void notImplementedMethod61(); +# public void notImplementedMethod62(); +# public void notImplementedMethod63(); +# } + +.class public abstract interface LIface2; +.super Ljava/lang/Object; + +.method public abstract notImplementedMethod0()V +.end method + +.method public abstract notImplementedMethod1()V +.end method + +.method public abstract notImplementedMethod2()V +.end method + +.method public abstract notImplementedMethod3()V +.end method + +.method public abstract notImplementedMethod4()V +.end method + +.method public abstract notImplementedMethod5()V +.end method + +.method public abstract notImplementedMethod6()V +.end method + +.method public abstract notImplementedMethod7()V +.end method + +.method public abstract notImplementedMethod8()V +.end method + +.method public abstract notImplementedMethod9()V +.end method + +.method public abstract notImplementedMethod10()V +.end method + +.method public abstract notImplementedMethod11()V +.end method + +.method public abstract notImplementedMethod12()V +.end method + +.method public abstract notImplementedMethod13()V +.end method + +.method public abstract notImplementedMethod14()V +.end method + +.method public abstract notImplementedMethod15()V +.end method + +.method public abstract notImplementedMethod16()V +.end method + +.method public abstract notImplementedMethod17()V +.end method + +.method public abstract notImplementedMethod18()V +.end method + +.method public abstract notImplementedMethod19()V +.end method + +.method public abstract notImplementedMethod20()V +.end method + +.method public abstract notImplementedMethod21()V +.end method + +.method public abstract notImplementedMethod22()V +.end method + +.method public abstract notImplementedMethod23()V +.end method + +.method public abstract notImplementedMethod24()V +.end method + +.method public abstract notImplementedMethod25()V +.end method + +.method public abstract notImplementedMethod26()V +.end method + +.method public abstract notImplementedMethod27()V +.end method + +.method public abstract notImplementedMethod28()V +.end method + +.method public abstract notImplementedMethod29()V +.end method + +.method public abstract notImplementedMethod30()V +.end method + +.method public abstract notImplementedMethod31()V +.end method + +.method public abstract notImplementedMethod32()V +.end method + +.method public abstract notImplementedMethod33()V +.end method + +.method public abstract notImplementedMethod34()V +.end method + +.method public abstract notImplementedMethod35()V +.end method + +.method public abstract notImplementedMethod36()V +.end method + +.method public abstract notImplementedMethod37()V +.end method + +.method public abstract notImplementedMethod38()V +.end method + +.method public abstract notImplementedMethod39()V +.end method + +.method public abstract notImplementedMethod40()V +.end method + +.method public abstract notImplementedMethod41()V +.end method + +.method public abstract notImplementedMethod42()V +.end method + +.method public abstract notImplementedMethod43()V +.end method + +.method public abstract notImplementedMethod44()V +.end method + +.method public abstract notImplementedMethod45()V +.end method + +.method public abstract notImplementedMethod46()V +.end method + +.method public abstract notImplementedMethod47()V +.end method + +.method public abstract notImplementedMethod48()V +.end method + +.method public abstract notImplementedMethod49()V +.end method + +.method public abstract notImplementedMethod50()V +.end method + +.method public abstract notImplementedMethod51()V +.end method + +.method public abstract notImplementedMethod52()V +.end method + +.method public abstract notImplementedMethod53()V +.end method + +.method public abstract notImplementedMethod54()V +.end method + +.method public abstract notImplementedMethod55()V +.end method + +.method public abstract notImplementedMethod56()V +.end method + +.method public abstract notImplementedMethod57()V +.end method + +.method public abstract notImplementedMethod58()V +.end method + +.method public abstract notImplementedMethod59()V +.end method + +.method public abstract notImplementedMethod60()V +.end method + +.method public abstract notImplementedMethod61()V +.end method + +.method public abstract notImplementedMethod62()V +.end method + +.method public abstract notImplementedMethod63()V +.end method diff --git a/test/972-default-imt-collision/smali/Klass.smali b/test/972-default-imt-collision/smali/Klass.smali new file mode 100644 index 0000000000..a98f9a7e99 --- /dev/null +++ b/test/972-default-imt-collision/smali/Klass.smali @@ -0,0 +1,993 @@ +# /* +# * Copyright (C) 2016 The Android Open Source Project +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# */ +# public class Klass implements Iface1, Iface2 { +# public static void testMe(Iface2 me) { +# try { +# me.notImplementedMethod0(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod0!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod1(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod1!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod2(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod2!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod3(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod3!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod4(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod4!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod5(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod5!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod6(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod6!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod7(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod7!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod8(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod8!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod9(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod9!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod10(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod10!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod11(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod11!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod12(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod12!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod13(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod13!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod14(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod14!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod15(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod15!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod16(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod16!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod17(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod17!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod18(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod18!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod19(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod19!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod20(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod20!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod21(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod21!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod22(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod22!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod23(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod23!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod24(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod24!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod25(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod25!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod26(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod26!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod27(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod27!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod28(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod28!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod29(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod29!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod30(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod30!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod31(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod31!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod32(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod32!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod33(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod33!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod34(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod34!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod35(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod35!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod36(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod36!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod37(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod37!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod38(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod38!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod39(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod39!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod40(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod40!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod41(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod41!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod42(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod42!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod43(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod43!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod44(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod44!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod45(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod45!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod46(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod46!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod47(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod47!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod48(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod48!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod49(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod49!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod50(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod50!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod51(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod51!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod52(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod52!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod53(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod53!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod54(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod54!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod55(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod55!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod56(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod56!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod57(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod57!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod58(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod58!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod59(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod59!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod60(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod60!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod61(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod61!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod62(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod62!"); +# } catch (AbstractMethodError e) { /* do nothing */ } +# try { +# me.notImplementedMethod63(); +# System.out.println("FAILED TO THROW AbstractMethodError when calling notImplementedMethod63!"); +# } catch (AbstractMethodError e) { /* do nothing */ } } +# } +# } + +.class public LKlass; +.super Ljava/lang/Object; +.implements LIface1; +.implements LIface2; + +.method public constructor <init>()V + .registers 1 + invoke-direct {p0}, Ljava/lang/Object;-><init>()V + return-void +.end method + +.method public static testMe(LIface2;)V +.locals 5 + :try_0_start + invoke-interface {p0}, LIface2;->notImplementedMethod0()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod0!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_0_end + :try_0_end + .catch Ljava/lang/AbstractMethodError; {:try_0_start .. :try_0_end} :catch_0_end + :catch_0_end + + + :try_1_start + invoke-interface {p0}, LIface2;->notImplementedMethod1()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod1!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_1_end + :try_1_end + .catch Ljava/lang/AbstractMethodError; {:try_1_start .. :try_1_end} :catch_1_end + :catch_1_end + + + :try_2_start + invoke-interface {p0}, LIface2;->notImplementedMethod2()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod2!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_2_end + :try_2_end + .catch Ljava/lang/AbstractMethodError; {:try_2_start .. :try_2_end} :catch_2_end + :catch_2_end + + + :try_3_start + invoke-interface {p0}, LIface2;->notImplementedMethod3()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod3!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_3_end + :try_3_end + .catch Ljava/lang/AbstractMethodError; {:try_3_start .. :try_3_end} :catch_3_end + :catch_3_end + + + :try_4_start + invoke-interface {p0}, LIface2;->notImplementedMethod4()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod4!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_4_end + :try_4_end + .catch Ljava/lang/AbstractMethodError; {:try_4_start .. :try_4_end} :catch_4_end + :catch_4_end + + + :try_5_start + invoke-interface {p0}, LIface2;->notImplementedMethod5()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod5!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_5_end + :try_5_end + .catch Ljava/lang/AbstractMethodError; {:try_5_start .. :try_5_end} :catch_5_end + :catch_5_end + + + :try_6_start + invoke-interface {p0}, LIface2;->notImplementedMethod6()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod6!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_6_end + :try_6_end + .catch Ljava/lang/AbstractMethodError; {:try_6_start .. :try_6_end} :catch_6_end + :catch_6_end + + + :try_7_start + invoke-interface {p0}, LIface2;->notImplementedMethod7()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod7!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_7_end + :try_7_end + .catch Ljava/lang/AbstractMethodError; {:try_7_start .. :try_7_end} :catch_7_end + :catch_7_end + + + :try_8_start + invoke-interface {p0}, LIface2;->notImplementedMethod8()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod8!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_8_end + :try_8_end + .catch Ljava/lang/AbstractMethodError; {:try_8_start .. :try_8_end} :catch_8_end + :catch_8_end + + + :try_9_start + invoke-interface {p0}, LIface2;->notImplementedMethod9()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod9!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_9_end + :try_9_end + .catch Ljava/lang/AbstractMethodError; {:try_9_start .. :try_9_end} :catch_9_end + :catch_9_end + + + :try_10_start + invoke-interface {p0}, LIface2;->notImplementedMethod10()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod10!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_10_end + :try_10_end + .catch Ljava/lang/AbstractMethodError; {:try_10_start .. :try_10_end} :catch_10_end + :catch_10_end + + + :try_11_start + invoke-interface {p0}, LIface2;->notImplementedMethod11()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod11!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_11_end + :try_11_end + .catch Ljava/lang/AbstractMethodError; {:try_11_start .. :try_11_end} :catch_11_end + :catch_11_end + + + :try_12_start + invoke-interface {p0}, LIface2;->notImplementedMethod12()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod12!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_12_end + :try_12_end + .catch Ljava/lang/AbstractMethodError; {:try_12_start .. :try_12_end} :catch_12_end + :catch_12_end + + + :try_13_start + invoke-interface {p0}, LIface2;->notImplementedMethod13()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod13!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_13_end + :try_13_end + .catch Ljava/lang/AbstractMethodError; {:try_13_start .. :try_13_end} :catch_13_end + :catch_13_end + + + :try_14_start + invoke-interface {p0}, LIface2;->notImplementedMethod14()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod14!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_14_end + :try_14_end + .catch Ljava/lang/AbstractMethodError; {:try_14_start .. :try_14_end} :catch_14_end + :catch_14_end + + + :try_15_start + invoke-interface {p0}, LIface2;->notImplementedMethod15()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod15!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_15_end + :try_15_end + .catch Ljava/lang/AbstractMethodError; {:try_15_start .. :try_15_end} :catch_15_end + :catch_15_end + + + :try_16_start + invoke-interface {p0}, LIface2;->notImplementedMethod16()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod16!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_16_end + :try_16_end + .catch Ljava/lang/AbstractMethodError; {:try_16_start .. :try_16_end} :catch_16_end + :catch_16_end + + + :try_17_start + invoke-interface {p0}, LIface2;->notImplementedMethod17()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod17!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_17_end + :try_17_end + .catch Ljava/lang/AbstractMethodError; {:try_17_start .. :try_17_end} :catch_17_end + :catch_17_end + + + :try_18_start + invoke-interface {p0}, LIface2;->notImplementedMethod18()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod18!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_18_end + :try_18_end + .catch Ljava/lang/AbstractMethodError; {:try_18_start .. :try_18_end} :catch_18_end + :catch_18_end + + + :try_19_start + invoke-interface {p0}, LIface2;->notImplementedMethod19()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod19!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_19_end + :try_19_end + .catch Ljava/lang/AbstractMethodError; {:try_19_start .. :try_19_end} :catch_19_end + :catch_19_end + + + :try_20_start + invoke-interface {p0}, LIface2;->notImplementedMethod20()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod20!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_20_end + :try_20_end + .catch Ljava/lang/AbstractMethodError; {:try_20_start .. :try_20_end} :catch_20_end + :catch_20_end + + + :try_21_start + invoke-interface {p0}, LIface2;->notImplementedMethod21()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod21!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_21_end + :try_21_end + .catch Ljava/lang/AbstractMethodError; {:try_21_start .. :try_21_end} :catch_21_end + :catch_21_end + + + :try_22_start + invoke-interface {p0}, LIface2;->notImplementedMethod22()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod22!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_22_end + :try_22_end + .catch Ljava/lang/AbstractMethodError; {:try_22_start .. :try_22_end} :catch_22_end + :catch_22_end + + + :try_23_start + invoke-interface {p0}, LIface2;->notImplementedMethod23()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod23!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_23_end + :try_23_end + .catch Ljava/lang/AbstractMethodError; {:try_23_start .. :try_23_end} :catch_23_end + :catch_23_end + + + :try_24_start + invoke-interface {p0}, LIface2;->notImplementedMethod24()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod24!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_24_end + :try_24_end + .catch Ljava/lang/AbstractMethodError; {:try_24_start .. :try_24_end} :catch_24_end + :catch_24_end + + + :try_25_start + invoke-interface {p0}, LIface2;->notImplementedMethod25()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod25!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_25_end + :try_25_end + .catch Ljava/lang/AbstractMethodError; {:try_25_start .. :try_25_end} :catch_25_end + :catch_25_end + + + :try_26_start + invoke-interface {p0}, LIface2;->notImplementedMethod26()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod26!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_26_end + :try_26_end + .catch Ljava/lang/AbstractMethodError; {:try_26_start .. :try_26_end} :catch_26_end + :catch_26_end + + + :try_27_start + invoke-interface {p0}, LIface2;->notImplementedMethod27()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod27!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_27_end + :try_27_end + .catch Ljava/lang/AbstractMethodError; {:try_27_start .. :try_27_end} :catch_27_end + :catch_27_end + + + :try_28_start + invoke-interface {p0}, LIface2;->notImplementedMethod28()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod28!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_28_end + :try_28_end + .catch Ljava/lang/AbstractMethodError; {:try_28_start .. :try_28_end} :catch_28_end + :catch_28_end + + + :try_29_start + invoke-interface {p0}, LIface2;->notImplementedMethod29()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod29!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_29_end + :try_29_end + .catch Ljava/lang/AbstractMethodError; {:try_29_start .. :try_29_end} :catch_29_end + :catch_29_end + + + :try_30_start + invoke-interface {p0}, LIface2;->notImplementedMethod30()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod30!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_30_end + :try_30_end + .catch Ljava/lang/AbstractMethodError; {:try_30_start .. :try_30_end} :catch_30_end + :catch_30_end + + + :try_31_start + invoke-interface {p0}, LIface2;->notImplementedMethod31()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod31!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_31_end + :try_31_end + .catch Ljava/lang/AbstractMethodError; {:try_31_start .. :try_31_end} :catch_31_end + :catch_31_end + + + :try_32_start + invoke-interface {p0}, LIface2;->notImplementedMethod32()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod32!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_32_end + :try_32_end + .catch Ljava/lang/AbstractMethodError; {:try_32_start .. :try_32_end} :catch_32_end + :catch_32_end + + + :try_33_start + invoke-interface {p0}, LIface2;->notImplementedMethod33()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod33!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_33_end + :try_33_end + .catch Ljava/lang/AbstractMethodError; {:try_33_start .. :try_33_end} :catch_33_end + :catch_33_end + + + :try_34_start + invoke-interface {p0}, LIface2;->notImplementedMethod34()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod34!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_34_end + :try_34_end + .catch Ljava/lang/AbstractMethodError; {:try_34_start .. :try_34_end} :catch_34_end + :catch_34_end + + + :try_35_start + invoke-interface {p0}, LIface2;->notImplementedMethod35()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod35!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_35_end + :try_35_end + .catch Ljava/lang/AbstractMethodError; {:try_35_start .. :try_35_end} :catch_35_end + :catch_35_end + + + :try_36_start + invoke-interface {p0}, LIface2;->notImplementedMethod36()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod36!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_36_end + :try_36_end + .catch Ljava/lang/AbstractMethodError; {:try_36_start .. :try_36_end} :catch_36_end + :catch_36_end + + + :try_37_start + invoke-interface {p0}, LIface2;->notImplementedMethod37()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod37!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_37_end + :try_37_end + .catch Ljava/lang/AbstractMethodError; {:try_37_start .. :try_37_end} :catch_37_end + :catch_37_end + + + :try_38_start + invoke-interface {p0}, LIface2;->notImplementedMethod38()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod38!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_38_end + :try_38_end + .catch Ljava/lang/AbstractMethodError; {:try_38_start .. :try_38_end} :catch_38_end + :catch_38_end + + + :try_39_start + invoke-interface {p0}, LIface2;->notImplementedMethod39()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod39!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_39_end + :try_39_end + .catch Ljava/lang/AbstractMethodError; {:try_39_start .. :try_39_end} :catch_39_end + :catch_39_end + + + :try_40_start + invoke-interface {p0}, LIface2;->notImplementedMethod40()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod40!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_40_end + :try_40_end + .catch Ljava/lang/AbstractMethodError; {:try_40_start .. :try_40_end} :catch_40_end + :catch_40_end + + + :try_41_start + invoke-interface {p0}, LIface2;->notImplementedMethod41()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod41!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_41_end + :try_41_end + .catch Ljava/lang/AbstractMethodError; {:try_41_start .. :try_41_end} :catch_41_end + :catch_41_end + + + :try_42_start + invoke-interface {p0}, LIface2;->notImplementedMethod42()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod42!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_42_end + :try_42_end + .catch Ljava/lang/AbstractMethodError; {:try_42_start .. :try_42_end} :catch_42_end + :catch_42_end + + + :try_43_start + invoke-interface {p0}, LIface2;->notImplementedMethod43()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod43!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_43_end + :try_43_end + .catch Ljava/lang/AbstractMethodError; {:try_43_start .. :try_43_end} :catch_43_end + :catch_43_end + + + :try_44_start + invoke-interface {p0}, LIface2;->notImplementedMethod44()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod44!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_44_end + :try_44_end + .catch Ljava/lang/AbstractMethodError; {:try_44_start .. :try_44_end} :catch_44_end + :catch_44_end + + + :try_45_start + invoke-interface {p0}, LIface2;->notImplementedMethod45()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod45!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_45_end + :try_45_end + .catch Ljava/lang/AbstractMethodError; {:try_45_start .. :try_45_end} :catch_45_end + :catch_45_end + + + :try_46_start + invoke-interface {p0}, LIface2;->notImplementedMethod46()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod46!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_46_end + :try_46_end + .catch Ljava/lang/AbstractMethodError; {:try_46_start .. :try_46_end} :catch_46_end + :catch_46_end + + + :try_47_start + invoke-interface {p0}, LIface2;->notImplementedMethod47()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod47!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_47_end + :try_47_end + .catch Ljava/lang/AbstractMethodError; {:try_47_start .. :try_47_end} :catch_47_end + :catch_47_end + + + :try_48_start + invoke-interface {p0}, LIface2;->notImplementedMethod48()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod48!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_48_end + :try_48_end + .catch Ljava/lang/AbstractMethodError; {:try_48_start .. :try_48_end} :catch_48_end + :catch_48_end + + + :try_49_start + invoke-interface {p0}, LIface2;->notImplementedMethod49()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod49!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_49_end + :try_49_end + .catch Ljava/lang/AbstractMethodError; {:try_49_start .. :try_49_end} :catch_49_end + :catch_49_end + + + :try_50_start + invoke-interface {p0}, LIface2;->notImplementedMethod50()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod50!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_50_end + :try_50_end + .catch Ljava/lang/AbstractMethodError; {:try_50_start .. :try_50_end} :catch_50_end + :catch_50_end + + + :try_51_start + invoke-interface {p0}, LIface2;->notImplementedMethod51()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod51!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_51_end + :try_51_end + .catch Ljava/lang/AbstractMethodError; {:try_51_start .. :try_51_end} :catch_51_end + :catch_51_end + + + :try_52_start + invoke-interface {p0}, LIface2;->notImplementedMethod52()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod52!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_52_end + :try_52_end + .catch Ljava/lang/AbstractMethodError; {:try_52_start .. :try_52_end} :catch_52_end + :catch_52_end + + + :try_53_start + invoke-interface {p0}, LIface2;->notImplementedMethod53()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod53!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_53_end + :try_53_end + .catch Ljava/lang/AbstractMethodError; {:try_53_start .. :try_53_end} :catch_53_end + :catch_53_end + + + :try_54_start + invoke-interface {p0}, LIface2;->notImplementedMethod54()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod54!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_54_end + :try_54_end + .catch Ljava/lang/AbstractMethodError; {:try_54_start .. :try_54_end} :catch_54_end + :catch_54_end + + + :try_55_start + invoke-interface {p0}, LIface2;->notImplementedMethod55()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod55!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_55_end + :try_55_end + .catch Ljava/lang/AbstractMethodError; {:try_55_start .. :try_55_end} :catch_55_end + :catch_55_end + + + :try_56_start + invoke-interface {p0}, LIface2;->notImplementedMethod56()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod56!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_56_end + :try_56_end + .catch Ljava/lang/AbstractMethodError; {:try_56_start .. :try_56_end} :catch_56_end + :catch_56_end + + + :try_57_start + invoke-interface {p0}, LIface2;->notImplementedMethod57()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod57!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_57_end + :try_57_end + .catch Ljava/lang/AbstractMethodError; {:try_57_start .. :try_57_end} :catch_57_end + :catch_57_end + + + :try_58_start + invoke-interface {p0}, LIface2;->notImplementedMethod58()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod58!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_58_end + :try_58_end + .catch Ljava/lang/AbstractMethodError; {:try_58_start .. :try_58_end} :catch_58_end + :catch_58_end + + + :try_59_start + invoke-interface {p0}, LIface2;->notImplementedMethod59()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod59!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_59_end + :try_59_end + .catch Ljava/lang/AbstractMethodError; {:try_59_start .. :try_59_end} :catch_59_end + :catch_59_end + + + :try_60_start + invoke-interface {p0}, LIface2;->notImplementedMethod60()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod60!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_60_end + :try_60_end + .catch Ljava/lang/AbstractMethodError; {:try_60_start .. :try_60_end} :catch_60_end + :catch_60_end + + + :try_61_start + invoke-interface {p0}, LIface2;->notImplementedMethod61()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod61!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_61_end + :try_61_end + .catch Ljava/lang/AbstractMethodError; {:try_61_start .. :try_61_end} :catch_61_end + :catch_61_end + + + :try_62_start + invoke-interface {p0}, LIface2;->notImplementedMethod62()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod62!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_62_end + :try_62_end + .catch Ljava/lang/AbstractMethodError; {:try_62_start .. :try_62_end} :catch_62_end + :catch_62_end + + + :try_63_start + invoke-interface {p0}, LIface2;->notImplementedMethod63()V + sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream; + const-string v1, "FAILED TO THROW AbstractMethodError when calling notImplementedMethod63!" + invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/Object;)V + goto :catch_63_end + :try_63_end + .catch Ljava/lang/AbstractMethodError; {:try_63_start .. :try_63_end} :catch_63_end + :catch_63_end + return-void +.end method diff --git a/test/972-default-imt-collision/src/Main.java b/test/972-default-imt-collision/src/Main.java new file mode 100644 index 0000000000..6819e43ae7 --- /dev/null +++ b/test/972-default-imt-collision/src/Main.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.lang.reflect.*; + +public class Main { + public static void main(String[] args) { + try { + Class<?> c = Class.forName("Klass"); + Object o = c.newInstance(); + Class<?> iface = Class.forName("Iface2"); + Method test = c.getMethod("testMe", iface); + test.invoke(null, o); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("FAILED: could not run testMe!"); + } + } +} |