changeset 12691:9211c2e89c1c jdk-9+159

Merge
author jwilhelm
date Fri, 24 Feb 2017 19:48:33 +0100
parents b7cf26006c35 3bce1c91d1a7
children 94b4e2e5331d 40d9f4c7daf7
files
diffstat 16 files changed, 478 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/.mx.jvmci/suite.py	Fri Feb 24 12:01:33 2017 +0100
+++ b/.mx.jvmci/suite.py	Fri Feb 24 19:48:33 2017 +0100
@@ -43,7 +43,7 @@
     # ------------- JVMCI:Service -------------
 
     "jdk.vm.ci.services" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
@@ -52,7 +52,7 @@
     # ------------- JVMCI:API -------------
 
     "jdk.vm.ci.common" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "checkstyle" : "jdk.vm.ci.services",
       "javaCompliance" : "9",
@@ -60,7 +60,7 @@
     },
 
     "jdk.vm.ci.meta" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "checkstyle" : "jdk.vm.ci.services",
       "javaCompliance" : "9",
@@ -68,7 +68,7 @@
     },
 
     "jdk.vm.ci.code" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : ["jdk.vm.ci.meta"],
       "checkstyle" : "jdk.vm.ci.services",
@@ -92,7 +92,7 @@
     },
 
     "jdk.vm.ci.runtime" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : [
         "jdk.vm.ci.code",
@@ -119,7 +119,7 @@
     # ------------- JVMCI:HotSpot -------------
 
     "jdk.vm.ci.aarch64" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : ["jdk.vm.ci.code"],
       "checkstyle" : "jdk.vm.ci.services",
@@ -128,7 +128,7 @@
     },
 
     "jdk.vm.ci.amd64" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : ["jdk.vm.ci.code"],
       "checkstyle" : "jdk.vm.ci.services",
@@ -137,7 +137,7 @@
     },
 
     "jdk.vm.ci.sparc" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : ["jdk.vm.ci.code"],
       "checkstyle" : "jdk.vm.ci.services",
@@ -146,7 +146,7 @@
     },
 
     "jdk.vm.ci.hotspot" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : [
         "jdk.vm.ci.common",
@@ -175,7 +175,7 @@
     },
 
     "jdk.vm.ci.hotspot.aarch64" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : [
         "jdk.vm.ci.aarch64",
@@ -187,7 +187,7 @@
     },
 
     "jdk.vm.ci.hotspot.amd64" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : [
         "jdk.vm.ci.amd64",
@@ -199,7 +199,7 @@
     },
 
     "jdk.vm.ci.hotspot.sparc" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "dependencies" : [
         "jdk.vm.ci.sparc",
@@ -221,12 +221,12 @@
     # ------------- Distributions -------------
 
     "JVMCI_SERVICES" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "dependencies" : ["jdk.vm.ci.services"],
     },
 
     "JVMCI_API" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "dependencies" : [
         "jdk.vm.ci.runtime",
         "jdk.vm.ci.common",
@@ -240,7 +240,7 @@
     },
 
     "JVMCI_HOTSPOT" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
+      "subDir" : "src/jdk.internal.vm.ci/share/classes",
       "dependencies" : [
         "jdk.vm.ci.hotspot.aarch64",
         "jdk.vm.ci.hotspot.amd64",
--- a/src/cpu/x86/vm/templateTable_x86.cpp	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/cpu/x86/vm/templateTable_x86.cpp	Fri Feb 24 19:48:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -2210,7 +2210,6 @@
       // Out-of-line code to allocate method data oop.
       __ bind(profile_method);
       __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
-      __ load_unsigned_byte(rbx, Address(rbcp, 0));  // restore target bytecode
       __ set_method_data_pointer_for_bcp();
       __ jmp(dispatch);
     }
@@ -2225,10 +2224,8 @@
                  CAST_FROM_FN_PTR(address,
                                   InterpreterRuntime::frequency_counter_overflow),
                  rdx);
-      __ load_unsigned_byte(rbx, Address(rbcp, 0));  // restore target bytecode
 
       // rax: osr nmethod (osr ok) or NULL (osr not possible)
-      // rbx: target bytecode
       // rdx: scratch
       // r14: locals pointer
       // r13: bcp
@@ -2238,12 +2235,13 @@
       __ cmpb(Address(rax, nmethod::state_offset()), nmethod::in_use);
       __ jcc(Assembler::notEqual, dispatch);
 
-      // We have the address of an on stack replacement routine in rax
-      // We need to prepare to execute the OSR method. First we must
-      // migrate the locals and monitors off of the stack.
-
-      LP64_ONLY(__ mov(r13, rax));                             // save the nmethod
-      NOT_LP64(__ mov(rbx, rax));                             // save the nmethod
+      // We have the address of an on stack replacement routine in rax.
+      // In preparation of invoking it, first we must migrate the locals
+      // and monitors from off the interpreter frame on the stack.
+      // Ensure to save the osr nmethod over the migration call,
+      // it will be preserved in rbx.
+      __ mov(rbx, rax);
+
       NOT_LP64(__ get_thread(rcx));
 
       call_VM(noreg, CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin));
@@ -2258,7 +2256,6 @@
       const Register retaddr   = LP64_ONLY(j_rarg2) NOT_LP64(rdi);
       const Register sender_sp = LP64_ONLY(j_rarg1) NOT_LP64(rdx);
 
-
       // pop the interpreter frame
       __ movptr(sender_sp, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp
       __ leave();                                // remove frame anchor
@@ -2274,8 +2271,7 @@
       __ push(retaddr);
 
       // and begin the OSR nmethod
-      LP64_ONLY(__ jmp(Address(r13, nmethod::osr_entry_point_offset())));
-      NOT_LP64(__ jmp(Address(rbx, nmethod::osr_entry_point_offset())));
+      __ jmp(Address(rbx, nmethod::osr_entry_point_offset()));
     }
   }
 }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/Main.java	Fri Feb 24 19:48:33 2017 +0100
@@ -625,7 +625,9 @@
 
     private void reportError(Throwable e) {
         log.println("Error: " + e.getMessage());
-        e.printStackTrace(log);
+        if (options.info) {
+            e.printStackTrace(log);
+        }
         log.flush();
     }
 
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/ClassSearch.java	Fri Feb 24 19:48:33 2017 +0100
@@ -77,7 +77,7 @@
         }
 
         if (found == null) {
-            throw new InternalError("Failed to find: " + searchFor.toString());
+            throw new InternalError("Failed to find " + searchFor.getType() + " file: " + searchFor.getName());
         }
         return found;
     }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/SearchFor.java	Fri Feb 24 19:48:33 2017 +0100
@@ -27,7 +27,7 @@
     private final String type;
 
     public SearchFor(String name) {
-        this(name, "unknown");
+        this(name, "");
     }
 
     public SearchFor(String name, String type) {
@@ -36,7 +36,7 @@
     }
 
     public boolean isUnknown() {
-        return "unknown".equals(type);
+        return "".equals(type);
     }
 
     public String getType() {
@@ -49,6 +49,6 @@
 
     @Override
     public String toString() {
-        return type + ":" + name;
+        return type + ": " + name;
     }
 }
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/classname/ClassNameSourceProvider.java	Fri Feb 24 19:48:33 2017 +0100
@@ -31,7 +31,7 @@
 import java.nio.file.Paths;
 
 public class ClassNameSourceProvider implements SourceProvider {
-    public final static String TYPE = "classname";
+    public final static String TYPE = "class";
     private final ClassLoader classLoader;
 
     public ClassNameSourceProvider(FileSupport fileSupport) {
@@ -47,6 +47,10 @@
 
     @Override
     public ClassSource findSource(String name, SearchPath searchPath) {
+        Path path = Paths.get(name);
+        if (ClassSource.pathIsClassFile(path)) {
+            name = ClassSource.makeClassName(path);
+        }
         try {
             classLoader.loadClass(name);
             return new ClassNameSource(name, classLoader);
--- a/src/share/vm/classfile/classFileParser.cpp	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Feb 24 19:48:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -3052,7 +3052,13 @@
                          "Class is both outer and inner class in class file %s", CHECK_0);
     }
     // Access flags
-    jint flags = cfs->get_u2_fast() & RECOGNIZED_INNER_CLASS_MODIFIERS;
+    jint flags;
+    // JVM_ACC_MODULE is defined in JDK-9 and later.
+    if (_major_version >= JAVA_9_VERSION) {
+      flags = cfs->get_u2_fast() & (RECOGNIZED_INNER_CLASS_MODIFIERS | JVM_ACC_MODULE);
+    } else {
+      flags = cfs->get_u2_fast() & RECOGNIZED_INNER_CLASS_MODIFIERS;
+    }
     if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
       // Set abstract bit for old class files for backward compatibility
       flags |= JVM_ACC_ABSTRACT;
@@ -4524,6 +4530,18 @@
 // utility methods for format checking
 
 void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) const {
+  const bool is_module = (flags & JVM_ACC_MODULE) != 0;
+  assert(_major_version >= JAVA_9_VERSION || !is_module, "JVM_ACC_MODULE should not be set");
+  if (is_module) {
+    ResourceMark rm(THREAD);
+    Exceptions::fthrow(
+      THREAD_AND_LOCATION,
+      vmSymbols::java_lang_NoClassDefFoundError(),
+      "%s is not a class because access_flag ACC_MODULE is set",
+      _class_name->as_C_string());
+    return;
+  }
+
   if (!_need_verify) { return; }
 
   const bool is_interface  = (flags & JVM_ACC_INTERFACE)  != 0;
@@ -4532,14 +4550,12 @@
   const bool is_super      = (flags & JVM_ACC_SUPER)      != 0;
   const bool is_enum       = (flags & JVM_ACC_ENUM)       != 0;
   const bool is_annotation = (flags & JVM_ACC_ANNOTATION) != 0;
-  const bool is_module_info= (flags & JVM_ACC_MODULE)     != 0;
   const bool major_gte_15  = _major_version >= JAVA_1_5_VERSION;
 
   if ((is_abstract && is_final) ||
       (is_interface && !is_abstract) ||
       (is_interface && major_gte_15 && (is_super || is_enum)) ||
-      (!is_interface && major_gte_15 && is_annotation) ||
-      is_module_info) {
+      (!is_interface && major_gte_15 && is_annotation)) {
     ResourceMark rm(THREAD);
     Exceptions::fthrow(
       THREAD_AND_LOCATION,
@@ -5734,16 +5750,23 @@
   stream->guarantee_more(8, CHECK);  // flags, this_class, super_class, infs_len
 
   // Access flags
-  jint flags = stream->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS;
+  jint flags;
+  // JVM_ACC_MODULE is defined in JDK-9 and later.
+  if (_major_version >= JAVA_9_VERSION) {
+    flags = stream->get_u2_fast() & (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_MODULE);
+  } else {
+    flags = stream->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS;
+  }
 
   if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
     // Set abstract bit for old class files for backward compatibility
     flags |= JVM_ACC_ABSTRACT;
   }
 
+  verify_legal_class_modifiers(flags, CHECK);
+
   _access_flags.set_flags(flags);
 
-  verify_legal_class_modifiers((jint)_access_flags.as_int(), CHECK);
 
   // This class and superclass
   _this_class_index = stream->get_u2_fast();
--- a/src/share/vm/runtime/os_ext.hpp	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/share/vm/runtime/os_ext.hpp	Fri Feb 24 19:48:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, 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
--- a/src/share/vm/runtime/vframe.cpp	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/share/vm/runtime/vframe.cpp	Fri Feb 24 19:48:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -463,14 +463,15 @@
 entryVFrame::entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread)
 : externalVFrame(fr, reg_map, thread) {}
 
-
-void vframeStreamCommon::found_bad_method_frame() {
+#ifdef ASSERT
+void vframeStreamCommon::found_bad_method_frame() const {
   // 6379830 Cut point for an assertion that occasionally fires when
   // we are using the performance analyzer.
   // Disable this assert when testing the analyzer with fastdebug.
   // -XX:SuppressErrorAt=vframe.cpp:XXX (XXX=following line number)
-  assert(false, "invalid bci or invalid scope desc");
+  fatal("invalid bci or invalid scope desc");
 }
+#endif
 
 // top-frame will be skipped
 vframeStream::vframeStream(JavaThread* thread, frame top_frame,
--- a/src/share/vm/runtime/vframe.hpp	Fri Feb 24 12:01:33 2017 +0100
+++ b/src/share/vm/runtime/vframe.hpp	Fri Feb 24 19:48:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -297,14 +297,14 @@
   void fill_from_compiled_frame(int decode_offset);
   void fill_from_compiled_native_frame();
 
-  void found_bad_method_frame();
-
   void fill_from_interpreter_frame();
   bool fill_from_frame();
 
   // Helper routine for security_get_caller_frame
   void skip_prefixed_method_and_wrappers();
 
+  DEBUG_ONLY(void found_bad_method_frame() const;)
+
  public:
   // Constructor
   vframeStreamCommon(JavaThread* thread) : _reg_map(thread, false) {
@@ -407,9 +407,9 @@
       nm()->print_code();
       nm()->print_pcs();
     }
+    found_bad_method_frame();
 #endif
     // Provide a cheap fallback in product mode.  (See comment above.)
-    found_bad_method_frame();
     fill_from_compiled_native_frame();
     return;
   }
@@ -523,7 +523,7 @@
   // In this scenario, pretend that the interpreter is at the point
   // of entering the method.
   if (bci < 0) {
-    found_bad_method_frame();
+    DEBUG_ONLY(found_bad_method_frame();)
     bci = 0;
   }
   _mode   = interpreted_mode;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/classFileParserBug/AccModuleTest.java	Fri Feb 24 19:48:33 2017 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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 8174725
+ * @summary Throw NoClassDefFoundError if class access_flags have ACC_MODULE set
+ * @compile BadAccModule.jcod BadAccModInrClss.jcod
+ * @run main AccModuleTest
+ */
+
+// Test that classes with access_flags containing ACC_MODULE cause ClassDefNotFoundErrors.
+public class AccModuleTest {
+    public static void main(String args[]) throws Throwable {
+
+        System.out.println("Regression test for bug 8174725");
+        try {
+            Class newClass = Class.forName("BadAccModule");
+            throw new RuntimeException("Expected NoClassDefFoundError exception not thrown");
+        } catch (java.lang.NoClassDefFoundError e) {
+            if (!e.getMessage().contains("BadAccModule is not a class because access_flag ACC_MODULE is set")) {
+                throw new RuntimeException("Wrong NoClassDefFoundError exception for AccModuleTest: " + e.getMessage());
+            }
+        }
+        try {
+            Class newClass = Class.forName("BadAccModInrClss");
+            throw new RuntimeException("Expected NoClassDefFoundError exception not thrown");
+        } catch (java.lang.NoClassDefFoundError e) {
+            if (!e.getMessage().contains("BadAccModInrClss is not a class because access_flag ACC_MODULE is set")) {
+                throw new RuntimeException("Wrong NoClassDefFoundError exception for BadAccModInrClss: " + e.getMessage());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/classFileParserBug/BadAccModInrClss.jcod	Fri Feb 24 19:48:33 2017 +0100
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+/*
+ * This tests that a class in an InnerClasses attribute with ACC_MODULE set
+ * causes a NoClassDefFoundError exception to get thrown.
+ */
+
+class BadAccModInrClss {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [22] { // Constant Pool
+    ; // first element is empty
+    Field #3 #14; // #1     at 0x0A
+    Method #4 #15; // #2     at 0x0F
+    class #16; // #3     at 0x14
+    class #19; // #4     at 0x17
+    Utf8 "this$0"; // #5     at 0x1A
+    Utf8 "La;"; // #6     at 0x23
+    Utf8 "Synthetic"; // #7     at 0x29
+    Utf8 "<init>"; // #8     at 0x35
+    Utf8 "(Ljava/lang/Object;)V"; // #9     at 0x3E
+    Utf8 "Code"; // #10     at 0x56
+    Utf8 "LineNumberTable"; // #11     at 0x5D
+    Utf8 "SourceFile"; // #12     at 0x6F
+    Utf8 "a.java"; // #13     at 0x7C
+    NameAndType #5 #6; // #14     at 0x85
+    NameAndType #8 #20; // #15     at 0x8A
+    Utf8 "BadAccModInrClss"; // #16     at 0x8F
+    Utf8 "Loc"; // #17     at 0x9E
+    Utf8 "InnerClasses"; // #18     at 0xA4
+    Utf8 "java/lang/Object"; // #19     at 0xB3
+    Utf8 "()V"; // #20     at 0xC6
+    Utf8 "EnclosingMethod"; // #21     at 0xCC
+  } // Constant Pool
+
+  0x0000; // access
+  #3;// this_cpx
+  #4;// super_cpx
+
+  [0] { // Interfaces
+  } // Interfaces
+
+  [1] { // fields
+    { // Member at 0xE8
+      0x0000; // access
+      #5; // name_cpx
+      #6; // sig_cpx
+      [1] { // Attributes
+        Attr(#7, 0) { // Synthetic at 0xF0
+        } // end Synthetic
+      } // Attributes
+    } // Member
+  } // fields
+
+  [1] { // methods
+    { // Member at 0xF8
+      0x0001; // access
+      #8; // name_cpx
+      #20; // sig_cpx
+      [1] { // Attributes
+        Attr(#10, 17) { // Code at 0x0100
+          2; // max_stack
+          2; // max_locals
+          Bytes[5]{
+            0x2AB70002B1;
+          };
+          [0] { // Traps
+          } // end Traps
+          [0] { // Attributes
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [3] { // Attributes
+    Attr(#12, 2) { // SourceFile at 0x0119
+      #13;
+    } // end SourceFile
+    ;
+    Attr(#18, 10) { // InnerClasses at 0x0121
+      [1] { // InnerClasses
+        #3 #0 #17 0x8000; //  at 0x0131
+      }
+    } // end InnerClasses
+    ;
+    Attr(#21, 4) { // EnclosingMethod at 0x0131
+      0x0004000F;
+    } // end EnclosingMethod
+  } // Attributes
+} // end class BadAccModInrClss
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/classFileParserBug/BadAccModule.jcod	Fri Feb 24 19:48:33 2017 +0100
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ *
+ */
+
+// This is a .jcod file for a simple "Hello World" program with ACC_MODULE added
+// to its access_flags. (See line 67.)  This should cause a NoClassDefFoundError
+// when loading the class.
+class BadAccModule {
+  0xCAFEBABE;
+  0; // minor version
+  53; // version
+  [32] { // Constant Pool
+    ; // first element is empty
+    Method #6 #17; // #1     at 0x0A
+    Field #18 #19; // #2     at 0x0F
+    String #20; // #3     at 0x14
+    Method #21 #22; // #4     at 0x17
+    class #23; // #5     at 0x1C
+    class #24; // #6     at 0x1F
+    Utf8 "<init>"; // #7     at 0x22
+    Utf8 "()V"; // #8     at 0x2B
+    Utf8 "Code"; // #9     at 0x31
+    Utf8 "LineNumberTable"; // #10     at 0x38
+    Utf8 "main"; // #11     at 0x4A
+    Utf8 "([Ljava/lang/String;)V"; // #12     at 0x51
+    Utf8 "Exceptions"; // #13     at 0x6A
+    class #25; // #14     at 0x77
+    Utf8 "SourceFile"; // #15     at 0x7A
+    Utf8 "BadAccModule.java"; // #16     at 0x87
+    NameAndType #7 #8; // #17     at 0x9B
+    class #26; // #18     at 0xA0
+    NameAndType #27 #28; // #19     at 0xA3
+    Utf8 "Hello World"; // #20     at 0xA8
+    class #29; // #21     at 0xB6
+    NameAndType #30 #31; // #22     at 0xB9
+    Utf8 "BadAccModule"; // #23     at 0xBE
+    Utf8 "java/lang/Object"; // #24     at 0xCD
+    Utf8 "java/lang/Throwable"; // #25     at 0xE0
+    Utf8 "java/lang/System"; // #26     at 0xF6
+    Utf8 "out"; // #27     at 0x0109
+    Utf8 "Ljava/io/PrintStream;"; // #28     at 0x010F
+    Utf8 "java/io/PrintStream"; // #29     at 0x0127
+    Utf8 "println"; // #30     at 0x013D
+    Utf8 "(Ljava/lang/String;)V"; // #31     at 0x0147
+  } // Constant Pool
+
+  0x8021; // access  Added ACC_MODULE (0x8000) !!!
+  #5;// this_cpx
+  #6;// super_cpx
+
+  [0] { // Interfaces
+  } // Interfaces
+
+  [0] { // fields
+  } // fields
+
+  [2] { // methods
+    { // Member at 0x016B
+      0x0001; // access
+      #7; // name_cpx
+      #8; // sig_cpx
+      [1] { // Attributes
+        Attr(#9, 29) { // Code at 0x0173
+          1; // max_stack
+          1; // max_locals
+          Bytes[5]{
+            0x2AB70001B1;
+          };
+          [0] { // Traps
+          } // end Traps
+          [1] { // Attributes
+            Attr(#10, 6) { // LineNumberTable at 0x018A
+              [1] { // LineNumberTable
+                0  1; //  at 0x0196
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member at 0x0196
+      0x0009; // access
+      #11; // name_cpx
+      #12; // sig_cpx
+      [2] { // Attributes
+        Attr(#9, 37) { // Code at 0x019E
+          2; // max_stack
+          1; // max_locals
+          Bytes[9]{
+            0xB200021203B60004;
+            0xB1;
+          };
+          [0] { // Traps
+          } // end Traps
+          [1] { // Attributes
+            Attr(#10, 10) { // LineNumberTable at 0x01B9
+              [2] { // LineNumberTable
+                0  4; //  at 0x01C5
+                8  5; //  at 0x01C9
+              }
+            } // end LineNumberTable
+          } // Attributes
+        } // end Code
+        ;
+        Attr(#13, 4) { // Exceptions at 0x01C9
+          [1] { // Exceptions
+            #14; //  at 0x01D3
+          }
+        } // end Exceptions
+      } // Attributes
+    } // Member
+  } // methods
+
+  [1] { // Attributes
+    Attr(#15, 2) { // SourceFile at 0x01D5
+      #16;
+    } // end SourceFile
+  } // Attributes
+} // end class BadAccModule
--- a/test/runtime/modules/acc_module.jcod	Fri Feb 24 12:01:33 2017 +0100
+++ b/test/runtime/modules/acc_module.jcod	Fri Feb 24 19:48:33 2017 +0100
@@ -23,7 +23,8 @@
 
 /*
  * This class consists of the following java code, but has an illegal class
- * access_flags value of 0x8000, that should be ignored by the JVM.
+ * access_flags value of 0x8000, that should be ignored by the JVM because
+ * the class file version is < 53.
  *
  *    public class acc_module {
  *       public static void main(String[] args) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/sa/LingeredAppWithInterface.java	Fri Feb 24 19:48:33 2017 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+import jdk.test.lib.apps.LingeredApp;
+
+interface Language {
+    static final long nbrOfWords = 99999;
+    public abstract long getNbrOfWords();
+}
+
+class ParselTongue implements Language {
+    public long getNbrOfWords() {
+        return nbrOfWords * 4;
+    }
+}
+
+public class LingeredAppWithInterface extends LingeredApp {
+
+    public static void main(String args[]) {
+        ParselTongue lang = new ParselTongue();
+        Language muggleSpeak = new Language() {
+            public long getNbrOfWords() {
+                return nbrOfWords * 8;
+            }
+        };
+
+        // Not tested at this point. The test needs to be enhanced
+        // later to test for the sizes of the Lambda MetaFactory
+        // generated anonymous classes too. (After JDK-8160228 gets
+        // fixed.)
+        Runnable r2 = () -> System.out.println("Hello world!");
+        r2.run();
+
+        System.out.println(lang.getNbrOfWords() + muggleSpeak.getNbrOfWords());
+
+        LingeredApp.main(args);
+    }
+}
--- a/test/serviceability/sa/TestInstanceKlassSizeForInterface.java	Fri Feb 24 12:01:33 2017 +0100
+++ b/test/serviceability/sa/TestInstanceKlassSizeForInterface.java	Fri Feb 24 19:48:33 2017 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -21,11 +21,15 @@
  * questions.
  */
 
+import java.util.ArrayList;
+import java.util.List;
+
 import sun.jvm.hotspot.HotSpotAgent;
 import sun.jvm.hotspot.utilities.SystemDictionaryHelper;
 import sun.jvm.hotspot.oops.InstanceKlass;
 import sun.jvm.hotspot.debugger.*;
 
+import jdk.test.lib.apps.LingeredApp;
 import jdk.test.lib.JDKToolLauncher;
 import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.Platform;
@@ -45,29 +49,20 @@
  * @run main/othervm TestInstanceKlassSizeForInterface
  */
 
-interface Language {
-    static final long nbrOfWords = 99999;
-    public abstract long getNbrOfWords();
-}
-
-class ParselTongue implements Language {
-    public long getNbrOfWords() {
-      return nbrOfWords * 4;
-    }
-}
-
 public class TestInstanceKlassSizeForInterface {
 
-    private static void SAInstanceKlassSize(int pid,
+    private static LingeredAppWithInterface theApp = null;
+
+    private static void SAInstanceKlassSize(int lingeredAppPid,
                                             String[] instanceKlassNames) {
 
         HotSpotAgent agent = new HotSpotAgent();
         try {
-            agent.attach((int)pid);
+            agent.attach(lingeredAppPid);
         }
         catch (DebuggerException e) {
             System.out.println(e.getMessage());
-            System.err.println("Unable to connect to process ID: " + pid);
+            System.err.println("Unable to connect to process ID: " + lingeredAppPid);
 
             agent.detach();
             e.printStackTrace();
@@ -98,11 +93,9 @@
     }
 
     private static void createAnotherToAttach(
-                            String[] instanceKlassNames) throws Exception {
+                            String[] instanceKlassNames,
+                            int lingeredAppPid) throws Exception {
 
-        ProcessBuilder pb = new ProcessBuilder();
-
-        // Grab the pid from the current java process and pass it
         String[] toolArgs = {
             "--add-modules=jdk.hotspot.agent",
             "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot=ALL-UNNAMED",
@@ -110,23 +103,26 @@
             "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED",
             "--add-exports=jdk.hotspot.agent/sun.jvm.hotspot.debugger=ALL-UNNAMED",
             "TestInstanceKlassSizeForInterface",
-            Long.toString(ProcessTools.getProcessId())
+            Integer.toString(lingeredAppPid)
         };
 
+        // Start a new process to attach to the LingeredApp process
+        ProcessBuilder processBuilder = ProcessTools
+                  .createJavaProcessBuilder(toolArgs);
+        OutputAnalyzer SAOutput = ProcessTools.executeProcess(processBuilder);
+        SAOutput.shouldHaveExitValue(0);
+        System.out.println(SAOutput.getOutput());
+
+        // Run jcmd on the LingeredApp process
+        ProcessBuilder pb = new ProcessBuilder();
         pb.command(new String[] {
                           JDKToolFinder.getJDKTool("jcmd"),
-                          Long.toString(ProcessTools.getProcessId()),
+                          Long.toString(lingeredAppPid),
                           "GC.class_stats",
                           "VTab,ITab,OopMap,KlassBytes"
                       }
                   );
 
-        // Start a new process to attach to the current process
-        ProcessBuilder processBuilder = ProcessTools
-                  .createJavaProcessBuilder(toolArgs);
-        OutputAnalyzer SAOutput = ProcessTools.executeProcess(processBuilder);
-        System.out.println(SAOutput.getOutput());
-
         OutputAnalyzer jcmdOutput = new OutputAnalyzer(pb.start());
         System.out.println(jcmdOutput.getOutput());
 
@@ -153,7 +149,7 @@
         String[] instanceKlassNames = new String[] {
                                           "Language",
                                           "ParselTongue",
-                                          "TestInstanceKlassSizeForInterface$1"
+                                          "LingeredAppWithInterface$1"
                                       };
 
         if (!Platform.shouldSAAttach()) {
@@ -163,22 +159,17 @@
         }
 
         if (args == null || args.length == 0) {
-            ParselTongue lang = new ParselTongue();
+            try {
+                List<String> vmArgs = new ArrayList<String>();
+                vmArgs.addAll(Utils.getVmOptions());
 
-            Language ventro = new Language() {
-                public long getNbrOfWords() {
-                    return nbrOfWords * 8;
-                }
-            };
-
-            // Not tested at this point. The test needs to be enhanced
-            // later to test for the sizes of the Lambda MetaFactory
-            // generated anonymous classes too. (After JDK-8160228 gets
-            // fixed.)
-            Runnable r2 = () -> System.out.println("Hello world!");
-            r2.run();
-
-            createAnotherToAttach(instanceKlassNames);
+                theApp = new LingeredAppWithInterface();
+                LingeredApp.startApp(vmArgs, theApp);
+                createAnotherToAttach(instanceKlassNames,
+                                      (int)theApp.getPid());
+            } finally {
+                LingeredApp.stopApp(theApp);
+            }
         } else {
             SAInstanceKlassSize(Integer.parseInt(args[0]), instanceKlassNames);
         }