From 6de1938e562b0d06e462512dd806166e754035ea Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Fri, 8 Jan 2016 17:37:10 +0000 Subject: ART: Remove incorrect HFakeString optimization Simplification of HFakeString assumes that it cannot be used until String. is called which is not true and causes different behaviour between the compiler and the interpreter. This patch removes the optimization together with the HFakeString instruction. Instead, HNewInstance is generated and an empty String allocated until it is replaced with the result of the StringFactory call. This is consistent with the behaviour of the interpreter but is too conservative. A follow-up CL will attempt to optimize out the initial allocation when possible. Bug: 26457745 Bug: 26486014 Change-Id: I7139e37ed00a880715bfc234896a930fde670c44 --- compiler/optimizing/graph_checker.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'compiler/optimizing/graph_checker.cc') diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index 6d0bdbe19b..2fe5b07b19 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -606,6 +606,34 @@ void SSAChecker::VisitInstruction(HInstruction* instruction) { instruction->GetId())); } } + + if (instruction->CanThrowIntoCatchBlock()) { + // Find the top-level environment. This corresponds to the environment of + // the catch block since we do not inline methods with try/catch. + HEnvironment* environment = instruction->GetEnvironment(); + while (environment->GetParent() != nullptr) { + environment = environment->GetParent(); + } + + // Find all catch blocks and test that `instruction` has an environment + // value for each one. + const HTryBoundary& entry = instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry(); + for (HBasicBlock* catch_block : entry.GetExceptionHandlers()) { + for (HInstructionIterator phi_it(catch_block->GetPhis()); !phi_it.Done(); phi_it.Advance()) { + HPhi* catch_phi = phi_it.Current()->AsPhi(); + if (environment->GetInstructionAt(catch_phi->GetRegNumber()) == nullptr) { + AddError(StringPrintf("Instruction %s:%d throws into catch block %d " + "with catch phi %d for vreg %d but its " + "corresponding environment slot is empty.", + instruction->DebugName(), + instruction->GetId(), + catch_block->GetBlockId(), + catch_phi->GetId(), + catch_phi->GetRegNumber())); + } + } + } + } } static Primitive::Type PrimitiveKind(Primitive::Type type) { -- cgit v1.2.3-59-g8ed1b