diff options
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 19 | ||||
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 4 | ||||
-rw-r--r-- | test/500-instanceof/expected.txt | 0 | ||||
-rw-r--r-- | test/500-instanceof/info.txt | 2 | ||||
-rw-r--r-- | test/500-instanceof/src/Main.java | 32 |
5 files changed, 56 insertions, 1 deletions
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index fd2e4e81df..b64791788d 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 98a5841f80..2daeeb3c0c 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 0000000000..e69de29bb2 --- /dev/null +++ b/test/500-instanceof/expected.txt diff --git a/test/500-instanceof/info.txt b/test/500-instanceof/info.txt new file mode 100644 index 0000000000..b28756aa34 --- /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 0000000000..80fdb0288d --- /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(); } +} |