Move the resolved_method_reference to HInvoke.
In order to also be used by HInvokeInterface.
Test: test.py
Change-Id: If72071a5347a13843f2c3ad8da4af4d6aaee6444
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 66433fb..4eb671e 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1290,6 +1290,7 @@
invoke_instruction->GetDexPc(),
invoke_instruction->GetMethodReference(), // Use interface method's reference.
method,
+ MethodReference(method->GetDexFile(), method->GetDexMethodIndex()),
method->GetMethodIndex());
DCHECK_NE(new_invoke->GetIntrinsic(), Intrinsics::kNone);
HInputsRef inputs = invoke_instruction->GetInputs();
@@ -1340,6 +1341,7 @@
invoke_instruction->GetDexPc(),
MethodReference(invoke_instruction->GetMethodReference().dex_file, dex_method_index),
method,
+ MethodReference(method->GetDexFile(), method->GetDexMethodIndex()),
method->GetMethodIndex());
HInputsRef inputs = invoke_instruction->GetInputs();
for (size_t index = 0; index != inputs.size(); ++index) {
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index e9d1ee2..3fe51ea 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -876,7 +876,8 @@
ArtMethod* referrer,
const DexCompilationUnit& dex_compilation_unit,
/*inout*/InvokeType* invoke_type,
- /*out*/MethodReference* method_info,
+ /*out*/MethodReference* resolved_method_info,
+ /*out*/uint16_t* imt_or_vtable_index,
/*out*/bool* is_string_constructor) {
ScopedObjectAccess soa(Thread::Current());
@@ -979,20 +980,14 @@
}
}
- if (*invoke_type == kDirect || *invoke_type == kStatic || *invoke_type == kSuper) {
- // Record the target method needed for HInvokeStaticOrDirect.
- *method_info =
+ *resolved_method_info =
MethodReference(resolved_method->GetDexFile(), resolved_method->GetDexMethodIndex());
- } else if (*invoke_type == kVirtual) {
+ if (*invoke_type == kVirtual) {
// For HInvokeVirtual we need the vtable index.
- *method_info = MethodReference(/*file=*/ nullptr, resolved_method->GetVtableIndex());
+ *imt_or_vtable_index = resolved_method->GetVtableIndex();
} else if (*invoke_type == kInterface) {
// For HInvokeInterface we need the IMT index.
- *method_info = MethodReference(/*file=*/ nullptr, ImTable::GetImtIndex(resolved_method));
- } else {
- // For HInvokePolymorphic we don't need the target method yet
- DCHECK_EQ(*invoke_type, kPolymorphic);
- DCHECK(method_info == nullptr);
+ *imt_or_vtable_index = ImTable::GetImtIndex(resolved_method);
}
*is_string_constructor =
@@ -1016,13 +1011,15 @@
number_of_arguments++;
}
- MethodReference method_info(nullptr, 0u);
+ MethodReference resolved_method_reference(nullptr, 0u);
bool is_string_constructor = false;
+ uint16_t imt_or_vtable_index = DexFile::kDexNoIndex16;
ArtMethod* resolved_method = ResolveMethod(method_idx,
graph_->GetArtMethod(),
*dex_compilation_unit_,
&invoke_type,
- &method_info,
+ &resolved_method_reference,
+ &imt_or_vtable_index,
&is_string_constructor);
MethodReference method_reference(&graph_->GetDexFile(), method_idx);
@@ -1058,7 +1055,7 @@
/* resolved_method= */ nullptr,
dispatch_info,
invoke_type,
- method_info,
+ resolved_method_reference,
HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit);
return HandleStringInit(invoke, operands, shorty);
}
@@ -1089,10 +1086,11 @@
bool has_method_id = true;
if (invoke_type == kSuper) {
uint32_t dex_method_index = method_reference.index;
- if (IsSameDexFile(*method_info.dex_file, *dex_compilation_unit_->GetDexFile())) {
+ if (IsSameDexFile(*resolved_method_reference.dex_file,
+ *dex_compilation_unit_->GetDexFile())) {
// Update the method index to the one resolved. Note that this may be a no-op if
// we resolved to the method referenced by the instruction.
- dex_method_index = method_info.index;
+ dex_method_index = resolved_method_reference.index;
} else {
// Try to find a dex method index in this caller's dex file.
ScopedObjectAccess soa(Thread::Current());
@@ -1120,7 +1118,7 @@
resolved_method,
dispatch_info,
invoke_type,
- method_info,
+ resolved_method_reference,
clinit_check_requirement);
if (clinit_check != nullptr) {
// Add the class initialization check as last input of `invoke`.
@@ -1130,14 +1128,14 @@
invoke->SetArgumentAt(clinit_check_index, clinit_check);
}
} else if (invoke_type == kVirtual) {
- DCHECK(method_info.dex_file == nullptr);
invoke = new (allocator_) HInvokeVirtual(allocator_,
number_of_arguments,
return_type,
dex_pc,
method_reference,
resolved_method,
- /*vtable_index=*/ method_info.index);
+ resolved_method_reference,
+ /*vtable_index=*/ imt_or_vtable_index);
} else {
DCHECK_EQ(invoke_type, kInterface);
invoke = new (allocator_) HInvokeInterface(allocator_,
@@ -1146,7 +1144,8 @@
dex_pc,
method_reference,
resolved_method,
- /*imt_index=*/ method_info.index);
+ resolved_method_reference,
+ /*imt_index=*/ imt_or_vtable_index);
}
return HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false);
}
@@ -1179,11 +1178,14 @@
// even if we don't need it afterwards.
InvokeType invoke_type = InvokeType::kPolymorphic;
bool is_string_constructor = false;
+ uint16_t imt_or_vtable_index = DexFile::kDexNoIndex16;
+ MethodReference resolved_method_reference(nullptr, 0u);
ArtMethod* resolved_method = ResolveMethod(method_idx,
graph_->GetArtMethod(),
*dex_compilation_unit_,
&invoke_type,
- /* method_info= */ nullptr,
+ &resolved_method_reference,
+ &imt_or_vtable_index,
&is_string_constructor);
MethodReference method_reference(&graph_->GetDexFile(), method_idx);
@@ -1193,6 +1195,7 @@
dex_pc,
method_reference,
resolved_method,
+ resolved_method_reference,
proto_idx);
if (!HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false)) {
return false;
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 93d29cd..d7a66f1 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4477,6 +4477,10 @@
MethodReference GetMethodReference() const { return method_reference_; }
+ const MethodReference GetResolvedMethodReference() const {
+ return resolved_method_reference_;
+ }
+
DECLARE_ABSTRACT_INSTRUCTION(Invoke);
protected:
@@ -4497,6 +4501,7 @@
uint32_t dex_pc,
MethodReference method_reference,
ArtMethod* resolved_method,
+ MethodReference resolved_method_reference,
InvokeType invoke_type)
: HVariableInputSizeInstruction(
kind,
@@ -4508,6 +4513,7 @@
kArenaAllocInvokeInputs),
number_of_arguments_(number_of_arguments),
method_reference_(method_reference),
+ resolved_method_reference_(resolved_method_reference),
intrinsic_(Intrinsics::kNone),
intrinsic_optimizations_(0) {
SetPackedField<InvokeTypeField>(invoke_type);
@@ -4520,6 +4526,8 @@
uint32_t number_of_arguments_;
ArtMethod* resolved_method_;
const MethodReference method_reference_;
+ // Cached values of the resolved method, to avoid needing the mutator lock.
+ const MethodReference resolved_method_reference_;
Intrinsics intrinsic_;
// A magic word holding optimizations for intrinsics. See intrinsics.h.
@@ -4542,6 +4550,7 @@
dex_pc,
method_reference,
nullptr,
+ MethodReference(nullptr, 0u),
invoke_type) {
}
@@ -4564,6 +4573,7 @@
// method (e.g. VarHandle.get), resolved using the class linker. It is needed
// to pass intrinsic information to the HInvokePolymorphic node.
ArtMethod* resolved_method,
+ MethodReference resolved_method_reference,
dex::ProtoIndex proto_idx)
: HInvoke(kInvokePolymorphic,
allocator,
@@ -4573,6 +4583,7 @@
dex_pc,
method_reference,
resolved_method,
+ resolved_method_reference,
kPolymorphic),
proto_idx_(proto_idx) {
}
@@ -4604,6 +4615,7 @@
dex_pc,
method_reference,
/* resolved_method= */ nullptr,
+ MethodReference(nullptr, 0u),
kStatic),
call_site_index_(call_site_index) {
}
@@ -4663,8 +4675,8 @@
dex_pc,
method_reference,
resolved_method,
+ resolved_method_reference,
invoke_type),
- resolved_method_reference_(resolved_method_reference),
dispatch_info_(dispatch_info) {
SetPackedField<ClinitCheckRequirementField>(clinit_check_requirement);
}
@@ -4752,10 +4764,6 @@
return GetInvokeType() == kStatic;
}
- const MethodReference GetResolvedMethodReference() const {
- return resolved_method_reference_;
- }
-
// Does this method load kind need the current method as an input?
static bool NeedsCurrentMethodInput(DispatchInfo dispatch_info) {
return dispatch_info.method_load_kind == MethodLoadKind::kRecursive ||
@@ -4854,8 +4862,6 @@
kFieldClinitCheckRequirement,
kFieldClinitCheckRequirementSize>;
- // Cached values of the resolved method, to avoid needing the mutator lock.
- const MethodReference resolved_method_reference_;
DispatchInfo dispatch_info_;
};
std::ostream& operator<<(std::ostream& os, MethodLoadKind rhs);
@@ -4870,6 +4876,7 @@
uint32_t dex_pc,
MethodReference method_reference,
ArtMethod* resolved_method,
+ MethodReference resolved_method_reference,
uint32_t vtable_index)
: HInvoke(kInvokeVirtual,
allocator,
@@ -4879,6 +4886,7 @@
dex_pc,
method_reference,
resolved_method,
+ resolved_method_reference,
kVirtual),
vtable_index_(vtable_index) {
}
@@ -4932,6 +4940,7 @@
uint32_t dex_pc,
MethodReference method_reference,
ArtMethod* resolved_method,
+ MethodReference resolved_method_reference,
uint32_t imt_index)
: HInvoke(kInvokeInterface,
allocator,
@@ -4941,6 +4950,7 @@
dex_pc,
method_reference,
resolved_method,
+ resolved_method_reference,
kInterface),
imt_index_(imt_index) {
}