summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_builder.cc
diff options
context:
space:
mode:
author Almaz Mingaleev <mingaleev@google.com> 2023-08-22 15:00:44 +0100
committer Almaz Mingaleev <mingaleev@google.com> 2024-08-28 13:31:56 +0000
commit93163edd92664c79da56ffcf5de32b7b872136ce (patch)
treedad21273d417cf020aa527171dc00465076b6434 /compiler/optimizing/instruction_builder.cc
parent46a77ad7d269ba087c4075029d92fe00b04fb6bb (diff)
x86_64: Add instrinsic for MethodHandle::invokeExact...
... which targets invoke-virtual methods. New entrypoint changes deliverException's offset, hence arm test change. Bug: 297147201 Test: ./art/test/testrunner/testrunner.py --host --64 -b --optimizing Test: ./art/test.py --host -g Change-Id: I636fc60c088bfdf9b695c92de47f1c539e3956f1
Diffstat (limited to 'compiler/optimizing/instruction_builder.cc')
-rw-r--r--compiler/optimizing/instruction_builder.cc32
1 files changed, 32 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index c97c78ca17..d7553dd14f 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -1390,8 +1390,20 @@ bool HInstructionBuilder::BuildInvokePolymorphic(uint32_t dex_pc,
&is_string_constructor);
MethodReference method_reference(&graph_->GetDexFile(), method_idx);
+
+ bool is_invoke_exact =
+ static_cast<Intrinsics>(resolved_method->GetIntrinsic()) ==
+ Intrinsics::kMethodHandleInvokeExact;
+ bool can_be_virtual = number_of_arguments >= 2 &&
+ DataType::FromShorty(shorty[1]) == DataType::Type::kReference;
+
+ bool can_be_intrinsified = is_invoke_exact && can_be_virtual;
+
+ uint32_t number_of_other_inputs = can_be_intrinsified ? 1u : 0u;
+
HInvoke* invoke = new (allocator_) HInvokePolymorphic(allocator_,
number_of_arguments,
+ number_of_other_inputs,
return_type,
dex_pc,
method_reference,
@@ -1402,6 +1414,8 @@ bool HInstructionBuilder::BuildInvokePolymorphic(uint32_t dex_pc,
return false;
}
+ DCHECK_EQ(invoke->AsInvokePolymorphic()->CanTargetInvokeVirtual(), can_be_intrinsified);
+
if (invoke->GetIntrinsic() != Intrinsics::kNone &&
invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvoke &&
invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvokeExact &&
@@ -1879,6 +1893,24 @@ bool HInstructionBuilder::SetupInvokeArguments(HInstruction* invoke,
graph_->GetCurrentMethod());
}
+ if (invoke->IsInvokePolymorphic()) {
+ HInvokePolymorphic* invoke_polymorphic = invoke->AsInvokePolymorphic();
+
+ if (invoke_polymorphic->CanTargetInvokeVirtual()) {
+ HLoadMethodType* load_method_type =
+ new (allocator_) HLoadMethodType(graph_->GetCurrentMethod(),
+ invoke_polymorphic->GetProtoIndex(),
+ graph_->GetDexFile(),
+ invoke_polymorphic->GetDexPc());
+ HSharpening::ProcessLoadMethodType(load_method_type,
+ code_generator_,
+ *dex_compilation_unit_,
+ graph_->GetHandleCache()->GetHandles());
+ invoke->SetRawInputAt(invoke_polymorphic->GetNumberOfArguments(), load_method_type);
+ AppendInstruction(load_method_type);
+ }
+ }
+
return true;
}