8027572: assert(r != 0) failed: invalid
authorroland
Wed, 13 Nov 2013 13:45:50 +0100
changeset 21581 73584c201e2d
parent 21580 488e43800f51
child 21582 6c76cdd733fe
8027572: assert(r != 0) failed: invalid Summary: null classes should be expected in profiles with conflicts Reviewed-by: kvn, iveresov
hotspot/src/share/vm/ci/ciMethodData.hpp
hotspot/src/share/vm/oops/instanceKlass.cpp
hotspot/src/share/vm/oops/methodData.cpp
hotspot/src/share/vm/oops/methodData.hpp
hotspot/test/compiler/profiling/unloadingconflict/B.java
hotspot/test/compiler/profiling/unloadingconflict/TestProfileConflictClassUnloading.java
--- a/hotspot/src/share/vm/ci/ciMethodData.hpp	Wed Nov 13 01:50:14 2013 -0800
+++ b/hotspot/src/share/vm/ci/ciMethodData.hpp	Wed Nov 13 13:45:50 2013 +0100
@@ -77,7 +77,9 @@
   static ciKlass* valid_ciklass(intptr_t k) {
     if (!TypeEntries::is_type_none(k) &&
         !TypeEntries::is_type_unknown(k)) {
-      return (ciKlass*)TypeEntries::klass_part(k);
+      ciKlass* res = (ciKlass*)TypeEntries::klass_part(k);
+      assert(res != NULL, "invalid");
+      return res;
     } else {
       return NULL;
     }
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Nov 13 01:50:14 2013 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Nov 13 13:45:50 2013 +0100
@@ -2211,6 +2211,10 @@
            data = mdo->next_data(data)) {
         data->clean_weak_klass_links(is_alive);
       }
+      ParametersTypeData* parameters = mdo->parameters_type_data();
+      if (parameters != NULL) {
+        parameters->clean_weak_klass_links(is_alive);
+      }
     }
   }
 }
--- a/hotspot/src/share/vm/oops/methodData.cpp	Wed Nov 13 01:50:14 2013 -0800
+++ b/hotspot/src/share/vm/oops/methodData.cpp	Wed Nov 13 13:45:50 2013 +0100
@@ -275,23 +275,23 @@
 }
 
 bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) {
-  return !is_type_none(p) &&
-    !((Klass*)klass_part(p))->is_loader_alive(is_alive_cl);
+  Klass* k = (Klass*)klass_part(p);
+  return k != NULL && k->is_loader_alive(is_alive_cl);
 }
 
 void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
   for (int i = 0; i < _number_of_entries; i++) {
     intptr_t p = type(i);
-    if (is_loader_alive(is_alive_cl, p)) {
-      set_type(i, type_none());
+    if (!is_loader_alive(is_alive_cl, p)) {
+      set_type(i, with_status((Klass*)NULL, p));
     }
   }
 }
 
 void ReturnTypeEntry::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
   intptr_t p = type();
-  if (is_loader_alive(is_alive_cl, p)) {
-    set_type(type_none());
+  if (!is_loader_alive(is_alive_cl, p)) {
+    set_type(with_status((Klass*)NULL, p));
   }
 }
 
--- a/hotspot/src/share/vm/oops/methodData.hpp	Wed Nov 13 01:50:14 2013 -0800
+++ b/hotspot/src/share/vm/oops/methodData.hpp	Wed Nov 13 13:45:50 2013 +0100
@@ -690,7 +690,6 @@
   // recorded type: cell without bit 0 and 1
   static intptr_t klass_part(intptr_t v) {
     intptr_t r = v & type_klass_mask;
-    assert (r != 0, "invalid");
     return r;
   }
 
@@ -698,7 +697,9 @@
   static Klass* valid_klass(intptr_t k) {
     if (!is_type_none(k) &&
         !is_type_unknown(k)) {
-      return (Klass*)klass_part(k);
+      Klass* res = (Klass*)klass_part(k);
+      assert(res != NULL, "invalid");
+      return res;
     } else {
       return NULL;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/profiling/unloadingconflict/B.java	Wed Nov 13 13:45:50 2013 +0100
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+public class B {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/profiling/unloadingconflict/TestProfileConflictClassUnloading.java	Wed Nov 13 13:45:50 2013 +0100
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013, 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 8027572
+ * @summary class unloading resets profile, method compiled after the profile is first set and before class loading sets unknown bit with not recorded class
+ * @build B
+ * @run main/othervm -XX:TypeProfileLevel=222 -XX:-BackgroundCompilation TestProfileConflictClassUnloading
+ *
+ */
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Paths;
+
+public class TestProfileConflictClassUnloading {
+    static class A {
+    }
+
+
+    static void m1(Object o) {
+    }
+
+    static void m2(Object o) {
+        m1(o);
+    }
+
+    static void m3(A a, boolean do_call) {
+        if (!do_call) {
+            return;
+        }
+        m2(a);
+    }
+
+    public static ClassLoader newClassLoader() {
+        try {
+            return new URLClassLoader(new URL[] {
+                    Paths.get(System.getProperty("test.classes",".")).toUri().toURL(),
+            }, null);
+        } catch (MalformedURLException e){
+            throw new RuntimeException("Unexpected URL conversion failure", e);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        ClassLoader loader = newClassLoader();
+        Object o = loader.loadClass("B").newInstance();
+        // collect conflicting profiles
+        for (int i = 0; i < 5000; i++) {
+            m2(o);
+        }
+        // prepare for conflict
+        A a = new A();
+        for (int i = 0; i < 5000; i++) {
+            m3(a, false);
+        }
+        // unload class in profile
+        o = null;
+        loader = null;
+        System.gc();
+        // record the conflict
+        m3(a, true);
+        // trigger another GC
+        System.gc();
+    }
+}