From 7cb499b1af1575c854860b0d6a103c4a2a59a569 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Wed, 17 Jun 2015 11:35:11 +0100 Subject: [PATCH] Fix bug in optimizing around instanceof. We were too aggressive when removing instanceof. We should not remove it when there is one of the two static types that is an interface. Change-Id: I1fd80915b99b094f7b4393e7adb2b160201b30d5 --- compiler/optimizing/graph_visualizer.cc | 19 ++++++++++++++++ compiler/optimizing/instruction_simplifier.cc | 4 +++- test/500-instanceof/expected.txt | 0 test/500-instanceof/info.txt | 2 ++ test/500-instanceof/src/Main.java | 32 +++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 test/500-instanceof/expected.txt create mode 100644 test/500-instanceof/info.txt create mode 100644 test/500-instanceof/src/Main.java diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index fd2e4e81d..b64791788 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -21,6 +21,7 @@ #include "licm.h" #include "nodes.h" #include "optimization.h" +#include "reference_type_propagation.h" #include "register_allocator.h" #include "ssa_liveness_analysis.h" @@ -354,6 +355,24 @@ class HGraphVisualizerPrinter : public HGraphVisitor { } else { StartAttributeStream("loop") << "B" << info->GetHeader()->GetBlockId(); } + } else if (IsPass(ReferenceTypePropagation::kReferenceTypePropagationPassName) + && is_after_pass_) { + if (instruction->GetType() == Primitive::kPrimNot) { + if (instruction->IsLoadClass()) { + ScopedObjectAccess soa(Thread::Current()); + StartAttributeStream("klass") + << PrettyClass(instruction->AsLoadClass()->GetLoadedClassRTI().GetTypeHandle().Get()); + } else { + ReferenceTypeInfo info = instruction->GetReferenceTypeInfo(); + if (info.IsTop()) { + StartAttributeStream("klass") << "java.lang.Object"; + } else { + ScopedObjectAccess soa(Thread::Current()); + StartAttributeStream("klass") << PrettyClass(info.GetTypeHandle().Get()); + } + StartAttributeStream("exact") << std::boolalpha << info.IsExact() << std::noboolalpha; + } + } } } diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 98a5841f8..2daeeb3c0 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -206,7 +206,9 @@ static bool TypeCheckHasKnownOutcome(HLoadClass* klass, HInstruction* object, bo // The test failed at compile time so will also fail at runtime. *outcome = false; return true; - } else if (!class_rti.IsInterface() && !obj_rti.IsSupertypeOf(class_rti)) { + } else if (!class_rti.IsInterface() + && !obj_rti.IsInterface() + && !obj_rti.IsSupertypeOf(class_rti)) { // Different type hierarchy. The test will fail. *outcome = false; return true; diff --git a/test/500-instanceof/expected.txt b/test/500-instanceof/expected.txt new file mode 100644 index 000000000..e69de29bb diff --git a/test/500-instanceof/info.txt b/test/500-instanceof/info.txt new file mode 100644 index 000000000..b28756aa3 --- /dev/null +++ b/test/500-instanceof/info.txt @@ -0,0 +1,2 @@ +Regression test for optimizing which used to be +too aggresive in removing instanceof checks. diff --git a/test/500-instanceof/src/Main.java b/test/500-instanceof/src/Main.java new file mode 100644 index 000000000..80fdb0288 --- /dev/null +++ b/test/500-instanceof/src/Main.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +interface Itf { +} + +class Foo { +} + +class Main extends Foo implements Itf { + public static void main(String[] args) { + Itf parent = getParent(); + if (!(parent instanceof Foo)) { + throw new Error("Instanceof should have succeeded"); + } + } + + static Itf getParent() { return new Main(); } +} -- 2.11.0