changeset 13587:a72b048d682d mvt

8187679: [MVT] VM crashes with "assert(k != __null && !(((ThreadShadow*)__the_thread__)->has_pending_exception())) failed: can resolve klass?" Reviewed-by: fparain, roland
author thartmann
date Fri, 22 Sep 2017 08:08:42 +0200
parents 8431727f44a1
children 488f0d311b80
files src/share/vm/oops/method.cpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/runtime/sharedRuntime.hpp test/compiler/valhalla/valuetypes/MyValue1.java test/compiler/valhalla/valuetypes/TestUnresolvedValueClass.java
diffstat 5 files changed, 104 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/oops/method.cpp	Wed Sep 20 08:44:32 2017 +0200
+++ b/src/share/vm/oops/method.cpp	Fri Sep 22 08:08:42 2017 +0200
@@ -1120,7 +1120,7 @@
   // Adapters for compiled code are made eagerly here.  They are fairly
   // small (generally < 100 bytes) and quick to make (and cached and shared)
   // so making them eagerly shouldn't be too expensive.
-  AdapterHandlerEntry* adapter = AdapterHandlerLibrary::get_adapter(mh);
+  AdapterHandlerEntry* adapter = AdapterHandlerLibrary::get_adapter(mh, CHECK_0);
   if (adapter == NULL ) {
     if (!is_init_completed()) {
       // Don't throw exceptions during VM initialization because java.lang.* classes
--- a/src/share/vm/runtime/sharedRuntime.cpp	Wed Sep 20 08:44:32 2017 +0200
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Fri Sep 22 08:08:42 2017 +0200
@@ -2646,8 +2646,8 @@
   return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, sig_extended);
 }
 
-AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
-  AdapterHandlerEntry* entry = get_adapter0(method);
+AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method, TRAPS) {
+  AdapterHandlerEntry* entry = get_adapter0(method, CHECK_NULL);
   if (method->is_shared()) {
     // See comments around Method::link_method()
     MutexLocker mu(AdapterHandlerLibrary_lock);
@@ -2670,7 +2670,7 @@
   return entry;
 }
 
-AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter0(const methodHandle& method) {
+AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter0(const methodHandle& method, TRAPS) {
   // Use customized signature handler.  Need to lock around updates to
   // the AdapterHandlerTable (it is not safe for concurrent readers
   // and a single writer: this could be fixed if it becomes a
@@ -2729,8 +2729,7 @@
             // is not __Value, to avoid lookups from the compiler thread.
             Klass* k = ss.as_klass(Handle(THREAD, holder->class_loader()),
                                    Handle(THREAD, holder->protection_domain()),
-                                   SignatureStream::ReturnNull, THREAD);
-            assert(k != NULL && !HAS_PENDING_EXCEPTION, "can resolve klass?");
+                                   SignatureStream::ReturnNull, CHECK_NULL);
             const Array<SigEntry>* sig_vk = ValueKlass::cast(k)->extended_sig();
             sig_extended.appendAll(sig_vk);
           }
--- a/src/share/vm/runtime/sharedRuntime.hpp	Wed Sep 20 08:44:32 2017 +0200
+++ b/src/share/vm/runtime/sharedRuntime.hpp	Fri Sep 22 08:08:42 2017 +0200
@@ -710,7 +710,7 @@
   static AdapterHandlerEntry* _abstract_method_handler;
   static BufferBlob* buffer_blob();
   static void initialize();
-  static AdapterHandlerEntry* get_adapter0(const methodHandle& method);
+  static AdapterHandlerEntry* get_adapter0(const methodHandle& method, TRAPS);
 
  public:
 
@@ -718,7 +718,7 @@
                                         address i2c_entry, address c2i_entry, address c2i_unverified_entry,
                                         Symbol* sig_extended = NULL);
   static void create_native_wrapper(const methodHandle& method);
-  static AdapterHandlerEntry* get_adapter(const methodHandle& method);
+  static AdapterHandlerEntry* get_adapter(const methodHandle& method, TRAPS);
 
   static void print_handler(const CodeBlob* b) { print_handler_on(tty, b); }
   static void print_handler_on(outputStream* st, const CodeBlob* b);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/valhalla/valuetypes/MyValue1.java	Fri Sep 22 08:08:42 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+__ByValue final class MyValue1 {
+    final int x;
+
+    private MyValue1() {
+        x = 0;
+    }
+
+    __ValueFactory static MyValue1 create() {
+        return __MakeDefault MyValue1();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/valhalla/valuetypes/TestUnresolvedValueClass.java	Fri Sep 22 08:08:42 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 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 8187679
+ * @summary The VM should exit gracefully when unable to resolve a value type argument
+ * @library /test/lib
+ * @compile -XDenableValueTypes TestUnresolvedValueClass.java
+ * @run main/othervm -XX:+EnableValhalla TestUnresolvedValueClass
+ */
+
+import java.io.File;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class TestUnresolvedValueClass {
+    final static String TEST_CLASSES = System.getProperty("test.classes") + File.separator;
+
+    // Method with unresolved value type argument
+    static void test1(MyValue1 vt) {
+
+    }
+
+    static public void main(String[] args) throws Exception {
+        if (args.length == 0) {
+            // Delete MyValue1.class to cause a NoClassDefFoundError
+            File unresolved = new File(TEST_CLASSES, "MyValue1.class");
+            if (!unresolved.exists() || !unresolved.delete()) {
+                throw new RuntimeException("Could not delete: " + unresolved);
+            }
+
+            // Run test in new VM instance
+            String[] arg = {"-XX:+EnableValhalla", "-XX:+ValueTypePassFieldsAsArgs", "TestUnresolvedValueClass", "run"};
+            OutputAnalyzer output = ProcessTools.executeTestJvm(arg);
+
+            // Adapter creation for TestUnresolvedValueClass::test1 should fail with a
+            // ClassNotFoundException because the class for argument 'vt' was not found.
+            output.shouldContain("java.lang.ClassNotFoundException: MyValue1");
+            output.shouldHaveExitValue(1);
+        }
+    }
+}