From b7d8e8cf7063fdec1cce6ebd33e33804976bd978 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Thu, 17 Sep 2015 15:47:05 +0100 Subject: Optimizing: Do not use range-based loop when inserting elements. When we iterate over the elements of a container and we may insert new elements into that container, it's wrong to use the range-based loop. Bug: 24133462 Change-Id: Iee35fbcf88ed3bcd6155cbeba09bd256032a16be --- compiler/optimizing/builder.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'compiler/optimizing/builder.cc') diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 9772ee78c3..274a2a699f 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -342,7 +342,10 @@ void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item) ArenaBitVector can_block_throw(arena_, graph_->GetBlocks().size(), /* expandable */ true); // Scan blocks and mark those which contain throwing instructions. - for (HBasicBlock* block : graph_->GetBlocks()) { + // NOTE: We're appending new blocks inside the loop, so we need to use index because iterators + // can be invalidated. We remember the initial size to avoid iterating over the new blocks. + for (size_t block_id = 0u, end = graph_->GetBlocks().size(); block_id != end; ++block_id) { + HBasicBlock* block = graph_->GetBlocks()[block_id]; bool can_throw = false; for (HInstructionIterator insn(block->GetInstructions()); !insn.Done(); insn.Advance()) { if (insn.Current()->CanThrow()) { @@ -380,7 +383,10 @@ void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item) // (c) link the new blocks to corresponding exception handlers. // We cannot iterate only over blocks in `branch_targets_` because switch-case // blocks share the same dex_pc. - for (HBasicBlock* try_block : graph_->GetBlocks()) { + // NOTE: We're appending new blocks inside the loop, so we need to use index because iterators + // can be invalidated. We remember the initial size to avoid iterating over the new blocks. + for (size_t block_id = 0u, end = graph_->GetBlocks().size(); block_id != end; ++block_id) { + HBasicBlock* try_block = graph_->GetBlocks()[block_id]; // TryBoundary blocks are added at the end of the list and not iterated over. DCHECK(!try_block->IsSingleTryBoundary()); -- cgit v1.2.3-59-g8ed1b