summaryrefslogtreecommitdiff
path: root/compiler/optimizing/builder.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2015-09-17 15:47:05 +0100
committer Vladimir Marko <vmarko@google.com> 2015-09-17 16:06:59 +0100
commitb7d8e8cf7063fdec1cce6ebd33e33804976bd978 (patch)
tree8d60856999139cf5b0b0f145f69c35a84a60716c /compiler/optimizing/builder.cc
parenta201d5eeb0903408df925a1ed1686a55238a274c (diff)
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
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r--compiler/optimizing/builder.cc10
1 files changed, 8 insertions, 2 deletions
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());