8219335: "failed: unexpected type" assert failure in ConnectionGraph::split_unique_types() with unsafe accesses
authorroland
Mon, 18 Feb 2019 17:41:31 +0100
changeset 53875 7a6fb8a48434
parent 53874 b2fb6f782d84
child 53876 8bc3d3eeaa53
8219335: "failed: unexpected type" assert failure in ConnectionGraph::split_unique_types() with unsafe accesses Reviewed-by: thartmann, kvn
src/hotspot/share/opto/escape.cpp
test/hotspot/jtreg/compiler/unsafe/MaybeOffHeapUnsafeAccessToNewObject.java
--- a/src/hotspot/share/opto/escape.cpp	Thu Feb 21 09:21:21 2019 -0500
+++ b/src/hotspot/share/opto/escape.cpp	Mon Feb 18 17:41:31 2019 +0100
@@ -1726,6 +1726,18 @@
     // access its field since the field value is unknown after it.
     //
     Node* n = field->ideal_node();
+
+    // Test for an unsafe access that was parsed as maybe off heap
+    // (with a CheckCastPP to raw memory).
+    assert(n->is_AddP(), "expect an address computation");
+    if (n->in(AddPNode::Base)->is_top() &&
+        n->in(AddPNode::Address)->Opcode() == Op_CheckCastPP) {
+      assert(n->in(AddPNode::Address)->bottom_type()->isa_rawptr(), "raw address so raw cast expected");
+      assert(_igvn->type(n->in(AddPNode::Address)->in(1))->isa_oopptr(), "cast pattern at unsafe access expected");
+      jobj->set_scalar_replaceable(false);
+      return;
+    }
+
     for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
       Node* u = n->fast_out(i);
       if (u->is_LoadStore() || (u->is_Mem() && u->as_Mem()->is_mismatched_access())) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/unsafe/MaybeOffHeapUnsafeAccessToNewObject.java	Mon Feb 18 17:41:31 2019 +0100
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. 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 8219335
+ * @summary "failed: unexpected type" assert failure in ConnectionGraph::split_unique_types() with unsafe accesses
+ *
+ * @modules java.base/jdk.internal.misc
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -XX:-TieredCompilation -Xcomp -XX:CompileOnly=MaybeOffHeapUnsafeAccessToNewObject::test1 -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline MaybeOffHeapUnsafeAccessToNewObject
+ */
+
+import java.lang.reflect.Field;
+import jdk.internal.misc.Unsafe;
+
+public class MaybeOffHeapUnsafeAccessToNewObject {
+    public volatile int f_int = -1;
+
+
+    public static Unsafe unsafe = Unsafe.getUnsafe();
+    public static final long f_int_off;
+
+    static {
+        Field f_int_field = null;
+        try {
+            f_int_field = MaybeOffHeapUnsafeAccessToNewObject.class.getField("f_int");
+        } catch (Exception e) {
+            System.out.println("reflection failed " + e);
+            e.printStackTrace();
+        }
+        f_int_off = unsafe.objectFieldOffset(f_int_field);
+    }
+
+    static public void main(String[] args) {
+        MaybeOffHeapUnsafeAccessToNewObject o = new MaybeOffHeapUnsafeAccessToNewObject();
+        test1();
+    }
+
+    static Object test1_helper1(Object t) {
+        return t;
+    }
+
+    static long test1_helper2(long off) {
+        return off;
+    }
+
+    static int test1() {
+        MaybeOffHeapUnsafeAccessToNewObject t = new MaybeOffHeapUnsafeAccessToNewObject();
+        Object o = test1_helper1(t);
+        long off = test1_helper2(f_int_off);
+        return unsafe.getInt(o, off);
+    }
+
+}