8059299: assert(adr_type != NULL) failed: expecting TypeKlassPtr
Summary: Use top() for dead paths when initializing Phi node of exceptions klasses in Parse::catch_inline_exceptions().
Reviewed-by: jrose, vlivanov
--- a/hotspot/src/share/vm/opto/doCall.cpp Wed Oct 01 12:34:45 2014 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp Thu Oct 02 11:36:44 2014 -0700
@@ -802,10 +802,16 @@
// each arm of the Phi. If I know something clever about the exceptions
// I'm loading the class from, I can replace the LoadKlass with the
// klass constant for the exception oop.
- if( ex_node->is_Phi() ) {
- ex_klass_node = new PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT );
- for( uint i = 1; i < ex_node->req(); i++ ) {
- Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() );
+ if (ex_node->is_Phi()) {
+ ex_klass_node = new PhiNode(ex_node->in(0), TypeKlassPtr::OBJECT);
+ for (uint i = 1; i < ex_node->req(); i++) {
+ Node* ex_in = ex_node->in(i);
+ if (ex_in == top() || ex_in == NULL) {
+ // This path was not taken.
+ ex_klass_node->init_req(i, top());
+ continue;
+ }
+ Node* p = basic_plus_adr(ex_in, ex_in, oopDesc::klass_offset_in_bytes());
Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
ex_klass_node->init_req( i, k );
}
--- a/hotspot/test/TEST.groups Wed Oct 01 12:34:45 2014 -0700
+++ b/hotspot/test/TEST.groups Thu Oct 02 11:36:44 2014 -0700
@@ -440,7 +440,7 @@
compiler/codegen/ \
compiler/cpuflags/RestoreMXCSR.java \
compiler/EscapeAnalysis/ \
- compiler/exceptions/TestRecursiveReplacedException.java \
+ compiler/exceptions/ \
compiler/floatingpoint/ModNaN.java \
compiler/gcbarriers/G1CrashTest.java \
compiler/inlining/ \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/exceptions/CatchInlineExceptions.java Thu Oct 02 11:36:44 2014 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8059299
+ * @summary assert(adr_type != NULL) failed: expecting TypeKlassPtr
+ * @run main/othervm -Xbatch CatchInlineExceptions
+ */
+
+class Exception1 extends Exception {};
+class Exception2 extends Exception {};
+
+public class CatchInlineExceptions {
+ private static int counter0;
+ private static int counter1;
+ private static int counter2;
+ private static int counter;
+
+ static void foo(int i) throws Exception {
+ if ((i & 1023) == 2) {
+ counter0++;
+ throw new Exception2();
+ }
+ }
+
+ static void test(int i) throws Exception {
+ try {
+ foo(i);
+ }
+ catch (Exception e) {
+ if (e instanceof Exception1) {
+ counter1++;
+ } else if (e instanceof Exception2) {
+ counter2++;
+ }
+ counter++;
+ throw e;
+ }
+ }
+
+ public static void main(String[] args) throws Throwable {
+ for (int i = 0; i < 15000; i++) {
+ try {
+ test(i);
+ } catch (Exception e) {
+ // expected
+ }
+ }
+ if (counter1 != 0) {
+ throw new RuntimeException("Failed: counter1(" + counter1 + ") != 0");
+ }
+ if (counter2 != counter) {
+ throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter0(" + counter0 + ")");
+ }
+ if (counter2 != counter) {
+ throw new RuntimeException("Failed: counter2(" + counter2 + ") != counter(" + counter + ")");
+ }
+ System.out.println("TEST PASSED");
+ }
+}