diff options
| -rw-r--r-- | compiler/optimizing/builder.cc | 18 | ||||
| -rw-r--r-- | compiler/optimizing/builder.h | 10 | ||||
| -rw-r--r-- | compiler/optimizing/nodes.h | 2 |
3 files changed, 23 insertions, 7 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 883c983fed..54155dbef4 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -346,11 +346,19 @@ void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item) // Catch blocks are always considered an entry point into the TryItem in // order to avoid splitting exceptional edges (they might not have been // created yet). We separate the move-exception (if present) from the - // rest of the block and insert a TryBoundary after it. - HInstruction* split_position = try_block->GetFirstInstruction(); - if (split_position->IsLoadException()) { - DCHECK(split_position->GetNext()->IsStoreLocal()); - split_position = split_position->GetNext()->GetNext(); + // rest of the block and insert a TryBoundary after it, creating a + // landing pad for the exceptional edges. + HInstruction* first_insn = try_block->GetFirstInstruction(); + HInstruction* split_position = nullptr; + if (first_insn->IsLoadException()) { + // Catch block starts with a LoadException. Split the block after the + // StoreLocal that must come after the load. + DCHECK(first_insn->GetNext()->IsStoreLocal()); + split_position = first_insn->GetNext()->GetNext(); + } else { + // Catch block does not obtain the exception. Split at the beginning + // to create an empty catch block. + split_position = first_insn; } DCHECK(split_position != nullptr); HBasicBlock* catch_block = try_block; diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index 9744a55687..cae762b49f 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -98,9 +98,19 @@ class HGraphBuilder : public ValueObject { HBasicBlock* FindBlockStartingAt(int32_t dex_pc) const; HBasicBlock* FindOrCreateBlockStartingAt(int32_t dex_pc); + // Returns whether the dex_pc of `block` lies within the given range. bool IsBlockInPcRange(HBasicBlock* block, uint32_t dex_pc_start, uint32_t dex_pc_end); + + // Adds new blocks to `branch_targets_` starting at the limits of TryItems and + // their exception handlers. void CreateBlocksForTryCatch(const DexFile::CodeItem& code_item); + + // Splits edges which cross the boundaries of TryItems, inserts TryBoundary + // instructions and links them to the corresponding catch blocks. void InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item); + + // Splits a single edge, inserting a TryBoundary of given `kind` and linking + // it to exception handlers of `try_item`. void SplitTryBoundaryEdge(HBasicBlock* predecessor, HBasicBlock* successor, HTryBoundary::BoundaryKind kind, diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 5c102453f5..04c3963675 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1957,8 +1957,6 @@ class HTryBoundary : public HTemplateInstruction<0> { bool IsControlFlow() const OVERRIDE { return true; } - bool CanThrow() const OVERRIDE { return true; } - // Returns the block's non-exceptional successor (index zero). HBasicBlock* GetNormalFlowSuccessor() const { return GetBlock()->GetSuccessors().Get(0); } |