summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_builder.cc
diff options
context:
space:
mode:
author Mythri Alle <mythria@google.com> 2021-10-13 15:39:37 +0000
committer Mythri Alle <mythria@google.com> 2021-11-01 08:31:54 +0000
commit2d4feeb67912d64b9e980e6687794826a5c22f9d (patch)
tree7ab2071bbf5d5907d205b8e2a092ea9869974ba1 /compiler/optimizing/instruction_builder.cc
parent60abdd9c89525a277d75df19ff2792614651e1ff (diff)
Add support for calling entry / exit hooks directly from JIT code
The idea of this CL is to avoid maintaining the instrumentation stack and manipulating the return addresses on the stack to call the entry / exit hooks. This Cl only addresses this for JITed code. In follow up CLs, we will extend this to others (native, nterp). Once we have everything in place we could remove the complexity of instrumentation stack. This CL introduces new nodes (HMethodEntry / HMethodExit(Void)) that generate code to call the trace entry / exit hooks when instrumentation_stubs are installed. Currently these are introduced for JITed code in debuggable mode. The entry / exit hooks roughly do the same this as instrumentation entry / exit points. We also extend the JITed frame slots by adding a ShouldDeoptimize slot. This will be used to force deoptimization of frames when requested by jvmti (for ex: structural re-definition). Test: art/testrunner.py Change-Id: Id4aa439731d214a8d2b820a67e75415ca1d5424e
Diffstat (limited to 'compiler/optimizing/instruction_builder.cc')
-rw-r--r--compiler/optimizing/instruction_builder.cc11
1 files changed, 11 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 390a2bb0be..ed760f190d 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -372,6 +372,9 @@ bool HInstructionBuilder::Build() {
if (current_block_->IsEntryBlock()) {
InitializeParameters();
AppendInstruction(new (allocator_) HSuspendCheck(0u));
+ if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) {
+ AppendInstruction(new (allocator_) HMethodEntryHook(0u));
+ }
AppendInstruction(new (allocator_) HGoto(0u));
continue;
} else if (current_block_->IsExitBlock()) {
@@ -822,10 +825,18 @@ void HInstructionBuilder::BuildReturn(const Instruction& instruction,
compilation_stats_,
MethodCompilationStat::kConstructorFenceGeneratedFinal);
}
+ if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) {
+ // Return value is not used for void functions. We pass NullConstant to
+ // avoid special cases when generating code.
+ AppendInstruction(new (allocator_) HMethodExitHook(graph_->GetNullConstant(), dex_pc));
+ }
AppendInstruction(new (allocator_) HReturnVoid(dex_pc));
} else {
DCHECK(!RequiresConstructorBarrier(dex_compilation_unit_));
HInstruction* value = LoadLocal(instruction.VRegA(), type);
+ if (graph_->IsDebuggable() && code_generator_->GetCompilerOptions().IsJitCompiler()) {
+ AppendInstruction(new (allocator_) HMethodExitHook(value, dex_pc));
+ }
AppendInstruction(new (allocator_) HReturn(value, dex_pc));
}
current_block_ = nullptr;