summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_builder.cc
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2022-06-24 11:16:35 +0100
committer Santiago Aboy Solanes <solanes@google.com> 2022-09-06 12:35:47 +0000
commitf976aa822dd35496e4e936b5802af0d53d39ac95 (patch)
tree41fd63809b52f7ffcbc6b7c81e8fb2d1c03af307 /compiler/optimizing/instruction_builder.cc
parent65fd6a37398356112316946358e2c58e1a5df631 (diff)
Add an environment to the beginning of catch blocks
We can use the HNop to generate an environment for us and start using the existing environment infrastructure (e.g. EmitEnvironment) for recording the catch block's environment. This is done to provide support for try catch inlining since it requires several environments rather than just the one. When doing so, we now have a HNop at the beginning of each catch block. We have to modify code sinking to allow it to sink code past this HNop because if we don't we will sink code right before this instruction which will break the invariant of that HNop being the first instruction of a catch block. Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: I16e7b8cad499fd2d6f7415112b46206db8daf544
Diffstat (limited to 'compiler/optimizing/instruction_builder.cc')
-rw-r--r--compiler/optimizing/instruction_builder.cc9
1 files changed, 9 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 605427ba11..ba58c8d1fe 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -343,6 +343,10 @@ static bool IsBlockPopulated(HBasicBlock* block) {
// Suspend checks were inserted into loop headers during building of dominator tree.
DCHECK(block->GetFirstInstruction()->IsSuspendCheck());
return block->GetFirstInstruction() != block->GetLastInstruction();
+ } else if (block->IsCatchBlock()) {
+ // Nops were inserted into the beginning of catch blocks.
+ DCHECK(block->GetFirstInstruction()->IsNop());
+ return block->GetFirstInstruction() != block->GetLastInstruction();
} else {
return !block->GetInstructions().IsEmpty();
}
@@ -387,6 +391,11 @@ bool HInstructionBuilder::Build() {
// This is slightly odd because the loop header might not be empty (TryBoundary).
// But we're still creating the environment with locals from the top of the block.
InsertInstructionAtTop(suspend_check);
+ } else if (current_block_->IsCatchBlock()) {
+ // We add an environment emitting instruction at the beginning of each catch block, in order
+ // to support try catch inlining.
+ // This is slightly odd because the catch block might not be empty (TryBoundary).
+ InsertInstructionAtTop(new (allocator_) HNop(block_dex_pc, /* needs_environment= */ true));
}
if (block_dex_pc == kNoDexPc || current_block_ != block_builder_->GetBlockAt(block_dex_pc)) {