summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/critical_native_abi_fixup_arm.cc3
-rw-r--r--compiler/optimizing/inliner.cc6
-rw-r--r--compiler/optimizing/instruction_builder.cc35
-rw-r--r--compiler/optimizing/instruction_simplifier.cc2
-rw-r--r--compiler/optimizing/load_store_analysis_test.cc30
-rw-r--r--compiler/optimizing/nodes.cc4
-rw-r--r--compiler/optimizing/nodes.h40
-rw-r--r--compiler/optimizing/optimizing_unit_test.h3
8 files changed, 83 insertions, 40 deletions
diff --git a/compiler/optimizing/critical_native_abi_fixup_arm.cc b/compiler/optimizing/critical_native_abi_fixup_arm.cc
index 03fb26bf1e..77e156608b 100644
--- a/compiler/optimizing/critical_native_abi_fixup_arm.cc
+++ b/compiler/optimizing/critical_native_abi_fixup_arm.cc
@@ -74,7 +74,8 @@ static void FixUpArguments(HInvokeStaticOrDirect* invoke) {
dispatch_info,
kStatic,
target_method,
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !block->GetGraph()->IsDebuggable());
// The intrinsic has no side effects and does not need environment or dex cache on ARM.
new_input->SetSideEffects(SideEffects::None());
IntrinsicOptimizations opt(new_input);
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index da498d4277..4bf62f3c26 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1321,7 +1321,8 @@ bool HInliner::TryDevirtualize(HInvoke* invoke_instruction,
dispatch_info,
kDirect,
MethodReference(method->GetDexFile(), method->GetDexMethodIndex()),
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInputsRef inputs = invoke_instruction->GetInputs();
DCHECK_EQ(inputs.size(), invoke_instruction->GetNumberOfArguments());
for (size_t index = 0; index != inputs.size(); ++index) {
@@ -1527,7 +1528,8 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction,
invoke_instruction->GetMethodReference(), // Use existing invoke's method's reference.
method,
MethodReference(method->GetDexFile(), method->GetDexMethodIndex()),
- method->GetMethodIndex());
+ method->GetMethodIndex(),
+ !graph_->IsDebuggable());
DCHECK_NE(new_invoke->GetIntrinsic(), Intrinsics::kNone);
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 e99b8a02d1..2576b02c9f 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -469,6 +469,9 @@ void HInstructionBuilder::BuildIntrinsic(ArtMethod* method) {
current_block_ = graph_->GetEntryBlock();
InitializeBlockLocals();
InitializeParameters();
+ if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) {
+ AppendInstruction(new (allocator_) HMethodEntryHook(0u));
+ }
AppendInstruction(new (allocator_) HGoto(0u));
// Fill the body.
@@ -504,14 +507,21 @@ void HInstructionBuilder::BuildIntrinsic(ArtMethod* method) {
dispatch_info,
invoke_type,
target_method,
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false);
}
// Add the return instruction.
if (return_type_ == DataType::Type::kVoid) {
+ if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) {
+ AppendInstruction(new (allocator_) HMethodExitHook(graph_->GetNullConstant(), kNoDexPc));
+ }
AppendInstruction(new (allocator_) HReturnVoid());
} else {
+ if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) {
+ AppendInstruction(new (allocator_) HMethodExitHook(latest_result_, kNoDexPc));
+ }
AppendInstruction(new (allocator_) HReturn(latest_result_));
}
@@ -1050,7 +1060,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
dispatch_info,
invoke_type,
resolved_method_reference,
- HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kImplicit,
+ !graph_->IsDebuggable());
return HandleStringInit(invoke, operands, shorty);
}
@@ -1063,7 +1074,7 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
}
// Try to build an HIR replacement for the intrinsic.
- if (UNLIKELY(resolved_method->IsIntrinsic())) {
+ if (UNLIKELY(resolved_method->IsIntrinsic()) && !graph_->IsDebuggable()) {
// All intrinsics are in the primary boot image, so their class can always be referenced
// and we do not need to rely on the implicit class initialization check. The class should
// be initialized but we do not require that here.
@@ -1114,7 +1125,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
dispatch_info,
invoke_type,
resolved_method_reference,
- clinit_check_requirement);
+ clinit_check_requirement,
+ !graph_->IsDebuggable());
if (clinit_check != nullptr) {
// Add the class initialization check as last input of `invoke`.
DCHECK_EQ(clinit_check_requirement, HInvokeStaticOrDirect::ClinitCheckRequirement::kExplicit);
@@ -1130,7 +1142,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
method_reference,
resolved_method,
resolved_method_reference,
- /*vtable_index=*/ imt_or_vtable_index);
+ /*vtable_index=*/ imt_or_vtable_index,
+ !graph_->IsDebuggable());
} else {
DCHECK_EQ(invoke_type, kInterface);
if (kIsDebugBuild) {
@@ -1151,7 +1164,8 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction,
resolved_method,
resolved_method_reference,
/*imt_index=*/ imt_or_vtable_index,
- load_kind);
+ load_kind,
+ !graph_->IsDebuggable());
}
return HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false);
}
@@ -1350,12 +1364,14 @@ bool HInstructionBuilder::BuildInvokePolymorphic(uint32_t dex_pc,
method_reference,
resolved_method,
resolved_method_reference,
- proto_idx);
+ proto_idx,
+ !graph_->IsDebuggable());
if (!HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false)) {
return false;
}
- if (invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvoke &&
+ if (invoke->GetIntrinsic() != Intrinsics::kNone &&
+ invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvoke &&
invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvokeExact &&
VarHandleAccessorNeedsReturnTypeCheck(invoke, return_type)) {
// Type check is needed because VarHandle intrinsics do not type check the retrieved reference.
@@ -1388,7 +1404,8 @@ bool HInstructionBuilder::BuildInvokeCustom(uint32_t dex_pc,
call_site_idx,
return_type,
dex_pc,
- method_reference);
+ method_reference,
+ !graph_->IsDebuggable());
return HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false);
}
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index bf51b5dcf4..0c2fd5de56 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -2465,7 +2465,7 @@ void InstructionSimplifierVisitor::SimplifySystemArrayCopy(HInvoke* instruction)
DCHECK(method != nullptr);
DCHECK(method->IsStatic());
DCHECK(method->GetDeclaringClass() == system);
- invoke->SetResolvedMethod(method);
+ invoke->SetResolvedMethod(method, !codegen_->GetGraph()->IsDebuggable());
// Sharpen the new invoke. Note that we do not update the dex method index of
// the invoke, as we would need to look it up in the current dex file, and it
// is unlikely that it exists. The most usual situation for such typed
diff --git a/compiler/optimizing/load_store_analysis_test.cc b/compiler/optimizing/load_store_analysis_test.cc
index 635f1b5fb2..8c6812f184 100644
--- a/compiler/optimizing/load_store_analysis_test.cc
+++ b/compiler/optimizing/load_store_analysis_test.cc
@@ -894,7 +894,8 @@ TEST_F(LoadStoreAnalysisTest, PartialEscape) {
{},
InvokeType::kStatic,
{ nullptr, 0 },
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_left = new (GetAllocator()) HGoto();
call_left->SetRawInputAt(0, new_inst);
left->AddInstruction(call_left);
@@ -1003,7 +1004,8 @@ TEST_F(LoadStoreAnalysisTest, PartialEscape2) {
{},
InvokeType::kStatic,
{ nullptr, 0 },
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_left = new (GetAllocator()) HGoto();
call_left->SetRawInputAt(0, new_inst);
left->AddInstruction(call_left);
@@ -1126,7 +1128,8 @@ TEST_F(LoadStoreAnalysisTest, PartialEscape3) {
{},
InvokeType::kStatic,
{ nullptr, 0 },
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_left = new (GetAllocator()) HGoto();
call_left->SetRawInputAt(0, new_inst);
left->AddInstruction(call_left);
@@ -1406,7 +1409,8 @@ TEST_F(LoadStoreAnalysisTest, TotalEscapeAdjacentNoPredicated) {
{},
InvokeType::kStatic,
{nullptr, 0},
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_left = new (GetAllocator()) HGoto();
call_left->SetRawInputAt(0, new_inst);
left->AddInstruction(call_left);
@@ -1507,7 +1511,8 @@ TEST_F(LoadStoreAnalysisTest, TotalEscapeAdjacent) {
{},
InvokeType::kStatic,
{ nullptr, 0 },
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_left = new (GetAllocator()) HGoto();
call_left->SetRawInputAt(0, new_inst);
left->AddInstruction(call_left);
@@ -1618,7 +1623,8 @@ TEST_F(LoadStoreAnalysisTest, TotalEscape) {
{},
InvokeType::kStatic,
{ nullptr, 0 },
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_left = new (GetAllocator()) HGoto();
call_left->SetRawInputAt(0, new_inst);
left->AddInstruction(call_left);
@@ -1634,7 +1640,8 @@ TEST_F(LoadStoreAnalysisTest, TotalEscape) {
{},
InvokeType::kStatic,
{ nullptr, 0 },
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* write_right = new (GetAllocator()) HInstanceFieldSet(new_inst,
c0,
nullptr,
@@ -1803,7 +1810,8 @@ TEST_F(LoadStoreAnalysisTest, DoubleDiamondEscape) {
{},
InvokeType::kStatic,
{ nullptr, 0 },
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_left = new (GetAllocator()) HGoto();
call_left->SetRawInputAt(0, new_inst);
high_left->AddInstruction(call_left);
@@ -1859,7 +1867,8 @@ TEST_F(LoadStoreAnalysisTest, DoubleDiamondEscape) {
{},
InvokeType::kStatic,
{ nullptr, 0 },
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_low_left = new (GetAllocator()) HGoto();
call_low_left->SetRawInputAt(0, new_inst);
low_left->AddInstruction(call_low_left);
@@ -2016,7 +2025,8 @@ TEST_F(LoadStoreAnalysisTest, PartialPhiPropagation1) {
{},
InvokeType::kStatic,
{nullptr, 0},
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
HInstruction* goto_left_merge = new (GetAllocator()) HGoto();
left_phi->SetRawInputAt(0, obj_param);
left_phi->SetRawInputAt(1, new_inst);
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 8d678cd33d..83b58763a4 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -3571,8 +3571,8 @@ static inline IntrinsicExceptions GetExceptionsIntrinsic(Intrinsics i) {
return kCanThrow;
}
-void HInvoke::SetResolvedMethod(ArtMethod* method) {
- if (method != nullptr && method->IsIntrinsic()) {
+void HInvoke::SetResolvedMethod(ArtMethod* method, bool enable_intrinsic_opt) {
+ if (method != nullptr && method->IsIntrinsic() && enable_intrinsic_opt) {
Intrinsics intrinsic = static_cast<Intrinsics>(method->GetIntrinsic());
SetIntrinsic(intrinsic,
NeedsEnvironmentIntrinsic(intrinsic),
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 822ac9a0a1..5ca723a3c3 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -4757,7 +4757,7 @@ class HInvoke : public HVariableInputSizeInstruction {
bool IsIntrinsic() const { return intrinsic_ != Intrinsics::kNone; }
ArtMethod* GetResolvedMethod() const { return resolved_method_; }
- void SetResolvedMethod(ArtMethod* method);
+ void SetResolvedMethod(ArtMethod* method, bool enable_intrinsic_opt);
MethodReference GetMethodReference() const { return method_reference_; }
@@ -4786,7 +4786,8 @@ class HInvoke : public HVariableInputSizeInstruction {
MethodReference method_reference,
ArtMethod* resolved_method,
MethodReference resolved_method_reference,
- InvokeType invoke_type)
+ InvokeType invoke_type,
+ bool enable_intrinsic_opt)
: HVariableInputSizeInstruction(
kind,
return_type,
@@ -4802,7 +4803,7 @@ class HInvoke : public HVariableInputSizeInstruction {
intrinsic_optimizations_(0) {
SetPackedField<InvokeTypeField>(invoke_type);
SetPackedFlag<kFlagCanThrow>(true);
- SetResolvedMethod(resolved_method);
+ SetResolvedMethod(resolved_method, enable_intrinsic_opt);
}
DEFAULT_COPY_CONSTRUCTOR(Invoke);
@@ -4835,7 +4836,8 @@ class HInvokeUnresolved final : public HInvoke {
method_reference,
nullptr,
MethodReference(nullptr, 0u),
- invoke_type) {
+ invoke_type,
+ /* enable_intrinsic_opt= */ false) {
}
bool IsClonable() const override { return true; }
@@ -4858,7 +4860,8 @@ class HInvokePolymorphic final : public HInvoke {
// to pass intrinsic information to the HInvokePolymorphic node.
ArtMethod* resolved_method,
MethodReference resolved_method_reference,
- dex::ProtoIndex proto_idx)
+ dex::ProtoIndex proto_idx,
+ bool enable_intrinsic_opt)
: HInvoke(kInvokePolymorphic,
allocator,
number_of_arguments,
@@ -4868,7 +4871,8 @@ class HInvokePolymorphic final : public HInvoke {
method_reference,
resolved_method,
resolved_method_reference,
- kPolymorphic),
+ kPolymorphic,
+ enable_intrinsic_opt),
proto_idx_(proto_idx) {
}
@@ -4890,7 +4894,8 @@ class HInvokeCustom final : public HInvoke {
uint32_t call_site_index,
DataType::Type return_type,
uint32_t dex_pc,
- MethodReference method_reference)
+ MethodReference method_reference,
+ bool enable_intrinsic_opt)
: HInvoke(kInvokeCustom,
allocator,
number_of_arguments,
@@ -4900,7 +4905,8 @@ class HInvokeCustom final : public HInvoke {
method_reference,
/* resolved_method= */ nullptr,
MethodReference(nullptr, 0u),
- kStatic),
+ kStatic,
+ enable_intrinsic_opt),
call_site_index_(call_site_index) {
}
@@ -4947,7 +4953,8 @@ class HInvokeStaticOrDirect final : public HInvoke {
DispatchInfo dispatch_info,
InvokeType invoke_type,
MethodReference resolved_method_reference,
- ClinitCheckRequirement clinit_check_requirement)
+ ClinitCheckRequirement clinit_check_requirement,
+ bool enable_intrinsic_opt)
: HInvoke(kInvokeStaticOrDirect,
allocator,
number_of_arguments,
@@ -4960,7 +4967,8 @@ class HInvokeStaticOrDirect final : public HInvoke {
method_reference,
resolved_method,
resolved_method_reference,
- invoke_type),
+ invoke_type,
+ enable_intrinsic_opt),
dispatch_info_(dispatch_info) {
SetPackedField<ClinitCheckRequirementField>(clinit_check_requirement);
}
@@ -5172,7 +5180,8 @@ class HInvokeVirtual final : public HInvoke {
MethodReference method_reference,
ArtMethod* resolved_method,
MethodReference resolved_method_reference,
- uint32_t vtable_index)
+ uint32_t vtable_index,
+ bool enable_intrinsic_opt)
: HInvoke(kInvokeVirtual,
allocator,
number_of_arguments,
@@ -5182,7 +5191,8 @@ class HInvokeVirtual final : public HInvoke {
method_reference,
resolved_method,
resolved_method_reference,
- kVirtual),
+ kVirtual,
+ enable_intrinsic_opt),
vtable_index_(vtable_index) {
}
@@ -5234,7 +5244,8 @@ class HInvokeInterface final : public HInvoke {
ArtMethod* resolved_method,
MethodReference resolved_method_reference,
uint32_t imt_index,
- MethodLoadKind load_kind)
+ MethodLoadKind load_kind,
+ bool enable_intrinsic_opt)
: HInvoke(kInvokeInterface,
allocator,
number_of_arguments + (NeedsCurrentMethod(load_kind) ? 1 : 0),
@@ -5244,7 +5255,8 @@ class HInvokeInterface final : public HInvoke {
method_reference,
resolved_method,
resolved_method_reference,
- kInterface),
+ kInterface,
+ enable_intrinsic_opt),
imt_index_(imt_index),
hidden_argument_load_kind_(load_kind) {
}
diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h
index f18ffc7f83..2e05c41f01 100644
--- a/compiler/optimizing/optimizing_unit_test.h
+++ b/compiler/optimizing/optimizing_unit_test.h
@@ -461,7 +461,8 @@ class OptimizingUnitTestHelper {
HInvokeStaticOrDirect::DispatchInfo{},
InvokeType::kStatic,
/* resolved_method_reference= */ method_reference,
- HInvokeStaticOrDirect::ClinitCheckRequirement::kNone);
+ HInvokeStaticOrDirect::ClinitCheckRequirement::kNone,
+ !graph_->IsDebuggable());
for (auto [ins, idx] : ZipCount(MakeIterationRange(args))) {
res->SetRawInputAt(idx, ins);
}