summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/graph_visualizer.cc19
-rw-r--r--compiler/optimizing/instruction_simplifier.cc4
-rw-r--r--test/500-instanceof/expected.txt0
-rw-r--r--test/500-instanceof/info.txt2
-rw-r--r--test/500-instanceof/src/Main.java32
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(); }
+}