diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2015-04-03 11:02:38 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2015-04-03 12:36:38 +0100 |
commit | 3dcd58cd54a922b864494fb7fff4a7f7a8562db9 (patch) | |
tree | 1e7b416de3dd46b0301f835632f8b3d0392beb97 /compiler/optimizing | |
parent | d43f160dc294655885a2c273307d34585c4ce97b (diff) | |
download | art-3dcd58cd54a922b864494fb7fff4a7f7a8562db9.zip art-3dcd58cd54a922b864494fb7fff4a7f7a8562db9.tar.gz art-3dcd58cd54a922b864494fb7fff4a7f7a8562db9.tar.bz2 |
Fix a bug when creating a HDeoptimization instruction.
We need to copy the environment, instead of just pointing
to an existing one. Otherwise, if the instruction that initially
holds the environemnt gets removed from the graph, any update
to an instruction in that environment will not be reflected in it.
bug:20058506
Change-Id: I2a62476d0851ecbc3707c0da395d8502ee437422
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/bounds_check_elimination.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 12 | ||||
-rw-r--r-- | compiler/optimizing/nodes_test.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.cc | 2 |
4 files changed, 14 insertions, 4 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc index 01f7e91..dce02f7 100644 --- a/compiler/optimizing/bounds_check_elimination.cc +++ b/compiler/optimizing/bounds_check_elimination.cc @@ -1011,7 +1011,7 @@ class BCEVisitor : public HGraphVisitor { HDeoptimize(cond, bounds_check->GetDexPc()); block->InsertInstructionBefore(cond, bounds_check); block->InsertInstructionBefore(deoptimize, bounds_check); - deoptimize->SetEnvironment(bounds_check->GetEnvironment()); + deoptimize->CopyEnvironmentFrom(bounds_check->GetEnvironment()); } void AddComparesWithDeoptimization(HBasicBlock* block) { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 6827cd0..f764eb4 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1192,7 +1192,17 @@ class HInstruction : public ArenaObject<kArenaAllocMisc> { bool HasEnvironment() const { return environment_ != nullptr; } HEnvironment* GetEnvironment() const { return environment_; } - void SetEnvironment(HEnvironment* environment) { environment_ = environment; } + // Set the `environment_` field. Raw because this method does not + // update the uses lists. + void SetRawEnvironment(HEnvironment* environment) { environment_ = environment; } + + // Set the environment of this instruction, copying it from `environment`. While + // copying, the uses lists are being updated. + void CopyEnvironmentFrom(HEnvironment* environment) { + ArenaAllocator* allocator = GetBlock()->GetGraph()->GetArena(); + environment_ = new (allocator) HEnvironment(allocator, environment->Size()); + environment_->CopyFrom(environment); + } // Returns the number of entries in the environment. Typically, that is the // number of dex registers in a method. It could be more in case of inlining. diff --git a/compiler/optimizing/nodes_test.cc b/compiler/optimizing/nodes_test.cc index 4cf22d3..4e83ce5 100644 --- a/compiler/optimizing/nodes_test.cc +++ b/compiler/optimizing/nodes_test.cc @@ -50,7 +50,7 @@ TEST(Node, RemoveInstruction) { exit_block->AddInstruction(new (&allocator) HExit()); HEnvironment* environment = new (&allocator) HEnvironment(&allocator, 1); - null_check->SetEnvironment(environment); + null_check->SetRawEnvironment(environment); environment->SetRawEnvAt(0, parameter); parameter->AddEnvUseAt(null_check->GetEnvironment(), 0); diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index fcc4e69..e154ea4 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -487,7 +487,7 @@ void SsaBuilder::VisitInstruction(HInstruction* instruction) { HEnvironment* environment = new (GetGraph()->GetArena()) HEnvironment( GetGraph()->GetArena(), current_locals_->Size()); environment->CopyFrom(current_locals_); - instruction->SetEnvironment(environment); + instruction->SetRawEnvironment(environment); } void SsaBuilder::VisitTemporary(HTemporary* temp) { |