summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/inliner.cc153
-rw-r--r--compiler/optimizing/inliner.h20
-rw-r--r--compiler/optimizing/optimizing_compiler_stats.h2
-rw-r--r--compiler/optimizing/reference_type_propagation.cc8
-rw-r--r--compiler/optimizing/reference_type_propagation.h3
-rw-r--r--runtime/class_linker.cc22
-rw-r--r--runtime/gc/reference_processor.cc6
-rw-r--r--runtime/gc/reference_queue.cc24
-rw-r--r--runtime/mirror/reference.h12
-rw-r--r--runtime/quick/inline_method_analyser.cc89
-rw-r--r--runtime/quick/inline_method_analyser.h27
-rw-r--r--runtime/verifier/method_verifier-inl.h4
-rw-r--r--runtime/verifier/method_verifier.h1
-rw-r--r--runtime/verifier/reg_type_cache.cc2
-rw-r--r--test/569-checker-pattern-replacement/expected.txt0
-rw-r--r--test/569-checker-pattern-replacement/info.txt1
-rwxr-xr-xtest/569-checker-pattern-replacement/run18
-rw-r--r--test/569-checker-pattern-replacement/src-multidex/Second.java103
-rw-r--r--test/569-checker-pattern-replacement/src/Main.java380
-rw-r--r--test/972-default-imt-collision/expected.txt0
-rw-r--r--test/972-default-imt-collision/info.txt1
-rw-r--r--test/972-default-imt-collision/smali/Iface1.smali32
-rw-r--r--test/972-default-imt-collision/smali/Iface2.smali277
-rw-r--r--test/972-default-imt-collision/smali/Klass.smali993
-rw-r--r--test/972-default-imt-collision/src/Main.java31
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!");
+ }
+ }
+}