changeset 47488:2af7932c2f6f

8190287: Update JDK's internal ASM to ASMv6 Reviewed-by: alanb, mchung, sundar
author ksrini
date Thu, 02 Nov 2017 13:18:23 -0700
parents c15c00e48c3a
children 6d0e943bcd24
files src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceModuleVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt test/hotspot/jtreg/runtime/constantPool/ConstModule.java test/jdk/java/lang/ModuleTests/AnnotationsTest.java test/jdk/java/lang/invoke/DefineClassTest.java test/jdk/java/util/ServiceLoader/BadProvidersTest.java test/jdk/lib/testlibrary/ModuleTargetHelper.java test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java
diffstat 83 files changed, 3795 insertions(+), 1303 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -70,7 +70,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -85,7 +85,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public AnnotationVisitor(final int api) {
         this(api, null);
@@ -96,13 +96,13 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param av
      *            the annotation visitor to which this visitor must delegate
      *            method calls. May be null.
      */
     public AnnotationVisitor(final int api, final AnnotationVisitor av) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
@@ -118,7 +118,7 @@
      *            the actual value, whose type must be {@link Byte},
      *            {@link Boolean}, {@link Character}, {@link Short},
      *            {@link Integer} , {@link Long}, {@link Float}, {@link Double},
-     *            {@link String} or {@link Type} or OBJECT or ARRAY sort. This
+     *            {@link String} or {@link Type} of OBJECT or ARRAY sort. This
      *            value can also be an array of byte, boolean, short, char, int,
      *            long, float or double values (this is equivalent to using
      *            {@link #visitArray visitArray} and visiting each array element
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/AnnotationWriter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -133,7 +133,7 @@
      */
     AnnotationWriter(final ClassWriter cw, final boolean named,
             final ByteVector bv, final ByteVector parent, final int offset) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         this.cw = cw;
         this.named = named;
         this.bv = bv;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java	Thu Nov 02 13:18:23 2017 -0700
@@ -73,31 +73,6 @@
 public class ClassReader {
 
     /**
-     * True to enable signatures support.
-     */
-    static final boolean SIGNATURES = true;
-
-    /**
-     * True to enable annotations support.
-     */
-    static final boolean ANNOTATIONS = true;
-
-    /**
-     * True to enable stack map frames support.
-     */
-    static final boolean FRAMES = true;
-
-    /**
-     * True to enable bytecode writing support.
-     */
-    static final boolean WRITER = true;
-
-    /**
-     * True to enable JSR_W and GOTO_W support.
-     */
-    static final boolean RESIZE = true;
-
-    /**
      * Flag to skip method code. If this class is set <code>CODE</code>
      * attribute won't be visited. This can be used, for example, to retrieve
      * annotations for methods and method parameters.
@@ -134,6 +109,21 @@
     public static final int EXPAND_FRAMES = 8;
 
     /**
+     * Flag to expand the ASM pseudo instructions into an equivalent sequence of
+     * standard bytecode instructions. When resolving a forward jump it may
+     * happen that the signed 2 bytes offset reserved for it is not sufficient
+     * to store the bytecode offset. In this case the jump instruction is
+     * replaced with a temporary ASM pseudo instruction using an unsigned 2
+     * bytes offset (see Label#resolve). This internal flag is used to re-read
+     * classes containing such instructions, in order to replace them with
+     * standard instructions. In addition, when this flag is used, GOTO_W and
+     * JSR_W are <i>not</i> converted into GOTO and JSR, to make sure that
+     * infinite loops where a GOTO_W is replaced with a GOTO in ClassReader and
+     * converted back to a GOTO_W in ClassWriter cannot occur.
+     */
+    static final int EXPAND_ASM_INSNS = 256;
+
+    /**
      * The class to be parsed. <i>The content of this array must not be
      * modified. This field is intended for {@link Attribute} sub classes, and
      * is normally not needed by class generators or adapters.</i>
@@ -195,7 +185,7 @@
     public ClassReader(final byte[] b, final int off, final int len) {
         this.b = b;
         // checks the class version
-        if (readShort(off + 6) > Opcodes.V1_9) {
+        if (readShort(off + 6) > Opcodes.V9) {
             throw new IllegalArgumentException();
         }
         // parses the constant pool
@@ -234,6 +224,8 @@
             // case ClassWriter.CLASS:
             // case ClassWriter.STR:
             // case ClassWriter.MTYPE
+            // case ClassWriter.PACKAGE:
+            // case ClassWriter.MODULE:
             default:
                 size = 3;
                 break;
@@ -377,7 +369,9 @@
                 break;
             // case ClassWriter.STR:
             // case ClassWriter.CLASS:
-            // case ClassWriter.MTYPE
+            // case ClassWriter.MTYPE:
+            // case ClassWriter.MODULE:
+            // case ClassWriter.PACKAGE:
             default:
                 item.set(tag, readUTF8(index, buf), null, null);
                 break;
@@ -584,11 +578,14 @@
         String enclosingOwner = null;
         String enclosingName = null;
         String enclosingDesc = null;
+        String moduleMainClass = null;
         int anns = 0;
         int ianns = 0;
         int tanns = 0;
         int itanns = 0;
         int innerClasses = 0;
+        int module = 0;
+        int packages = 0;
         Attribute attributes = null;
 
         u = getAttributes();
@@ -607,13 +604,11 @@
                     enclosingName = readUTF8(items[item], c);
                     enclosingDesc = readUTF8(items[item] + 2, c);
                 }
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
+            } else if ("Signature".equals(attrName)) {
                 signature = readUTF8(u + 8, c);
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
                 anns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
                 tanns = u + 8;
             } else if ("Deprecated".equals(attrName)) {
                 access |= Opcodes.ACC_DEPRECATED;
@@ -623,12 +618,16 @@
             } else if ("SourceDebugExtension".equals(attrName)) {
                 int len = readInt(u + 4);
                 sourceDebug = readUTF(u + 8, len, new char[len]);
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
                 ianns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
                 itanns = u + 8;
+            } else if ("Module".equals(attrName)) {
+                module = u + 8;
+            } else if ("ModuleMainClass".equals(attrName)) {
+                moduleMainClass = readClass(u + 8, c);
+            } else if ("ModulePackages".equals(attrName)) {
+                packages = u + 10;
             } else if ("BootstrapMethods".equals(attrName)) {
                 int[] bootstrapMethods = new int[readUnsignedShort(u + 8)];
                 for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) {
@@ -657,6 +656,12 @@
             classVisitor.visitSource(sourceFile, sourceDebug);
         }
 
+        // visits the module info and associated attributes
+        if (module != 0) {
+            readModule(classVisitor, context, module,
+                    moduleMainClass, packages);
+        }
+
         // visits the outer class
         if (enclosingOwner != null) {
             classVisitor.visitOuterClass(enclosingOwner, enclosingName,
@@ -664,19 +669,19 @@
         }
 
         // visits the class annotations and type annotations
-        if (ANNOTATIONS && anns != 0) {
+        if (anns != 0) {
             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         classVisitor.visitAnnotation(readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && ianns != 0) {
+        if (ianns != 0) {
             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         classVisitor.visitAnnotation(readUTF8(v, c), false));
             }
         }
-        if (ANNOTATIONS && tanns != 0) {
+        if (tanns != 0) {
             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -684,7 +689,7 @@
                                 context.typePath, readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && itanns != 0) {
+        if (itanns != 0) {
             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -727,6 +732,120 @@
     }
 
     /**
+     * Reads the module attribute and visit it.
+     *
+     * @param classVisitor
+     *           the current class visitor
+     * @param context
+     *           information about the class being parsed.
+     * @param u
+     *           start offset of the module attribute in the class file.
+     * @param mainClass
+     *           name of the main class of a module or null.
+     * @param packages
+     *           start offset of the concealed package attribute.
+     */
+    private void readModule(final ClassVisitor classVisitor,
+            final Context context, int u,
+            final String mainClass, int packages) {
+
+        char[] buffer = context.buffer;
+
+        // reads module name, flags and version
+        String name = readModule(u, buffer);
+        int flags = readUnsignedShort(u + 2);
+        String version = readUTF8(u + 4, buffer);
+        u += 6;
+
+        ModuleVisitor mv = classVisitor.visitModule(name, flags, version);
+        if (mv == null) {
+            return;
+        }
+
+        // module attributes (main class, packages)
+        if (mainClass != null) {
+            mv.visitMainClass(mainClass);
+        }
+
+        if (packages != 0) {
+            for (int i = readUnsignedShort(packages - 2); i > 0; --i) {
+                String packaze = readPackage(packages, buffer);
+                mv.visitPackage(packaze);
+                packages += 2;
+            }
+        }
+
+        // reads requires
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            String module = readModule(u, buffer);
+            int access = readUnsignedShort(u + 2);
+            String requireVersion = readUTF8(u + 4, buffer);
+            mv.visitRequire(module, access, requireVersion);
+            u += 6;
+        }
+
+        // reads exports
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            String export = readPackage(u, buffer);
+            int access = readUnsignedShort(u + 2);
+            int exportToCount = readUnsignedShort(u + 4);
+            u += 6;
+            String[] tos = null;
+            if (exportToCount != 0) {
+                tos = new String[exportToCount];
+                for (int j = 0; j < tos.length; ++j) {
+                    tos[j] = readModule(u, buffer);
+                    u += 2;
+                }
+            }
+            mv.visitExport(export, access, tos);
+        }
+
+        // reads opens
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            String open = readPackage(u, buffer);
+            int access = readUnsignedShort(u + 2);
+            int openToCount = readUnsignedShort(u + 4);
+            u += 6;
+            String[] tos = null;
+            if (openToCount != 0) {
+                tos = new String[openToCount];
+                for (int j = 0; j < tos.length; ++j) {
+                    tos[j] = readModule(u, buffer);
+                    u += 2;
+                }
+            }
+            mv.visitOpen(open, access, tos);
+        }
+
+        // read uses
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            mv.visitUse(readClass(u, buffer));
+            u += 2;
+        }
+
+        // read provides
+        u += 2;
+        for (int i = readUnsignedShort(u - 2); i > 0; --i) {
+            String service = readClass(u, buffer);
+            int provideWithCount = readUnsignedShort(u + 2);
+            u += 4;
+            String[] withs = new String[provideWithCount];
+            for (int j = 0; j < withs.length; ++j) {
+                withs[j] = readClass(u, buffer);
+                u += 2;
+            }
+            mv.visitProvide(service, withs);
+        }
+
+        mv.visitEnd();
+    }
+
+    /**
      * Reads a field and makes the given visitor visit it.
      *
      * @param classVisitor
@@ -762,24 +881,20 @@
             if ("ConstantValue".equals(attrName)) {
                 int item = readUnsignedShort(u + 8);
                 value = item == 0 ? null : readConst(item, c);
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
+            } else if ("Signature".equals(attrName)) {
                 signature = readUTF8(u + 8, c);
             } else if ("Deprecated".equals(attrName)) {
                 access |= Opcodes.ACC_DEPRECATED;
             } else if ("Synthetic".equals(attrName)) {
                 access |= Opcodes.ACC_SYNTHETIC
                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
                 anns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
                 tanns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
                 ianns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
                 itanns = u + 8;
             } else {
                 Attribute attr = readAttribute(context.attrs, attrName, u + 8,
@@ -801,19 +916,19 @@
         }
 
         // visits the field annotations and type annotations
-        if (ANNOTATIONS && anns != 0) {
+        if (anns != 0) {
             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         fv.visitAnnotation(readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && ianns != 0) {
+        if (ianns != 0) {
             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         fv.visitAnnotation(readUTF8(v, c), false));
             }
         }
-        if (ANNOTATIONS && tanns != 0) {
+        if (tanns != 0) {
             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -821,7 +936,7 @@
                                 context.typePath, readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && itanns != 0) {
+        if (itanns != 0) {
             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -895,32 +1010,26 @@
                     exceptions[j] = readClass(exception, c);
                     exception += 2;
                 }
-            } else if (SIGNATURES && "Signature".equals(attrName)) {
+            } else if ("Signature".equals(attrName)) {
                 signature = readUTF8(u + 8, c);
             } else if ("Deprecated".equals(attrName)) {
                 context.access |= Opcodes.ACC_DEPRECATED;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleAnnotations".equals(attrName)) {
                 anns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
                 tanns = u + 8;
-            } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) {
+            } else if ("AnnotationDefault".equals(attrName)) {
                 dann = u + 8;
             } else if ("Synthetic".equals(attrName)) {
                 context.access |= Opcodes.ACC_SYNTHETIC
                         | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
                 ianns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
                 itanns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleParameterAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleParameterAnnotations".equals(attrName)) {
                 mpanns = u + 8;
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) {
                 impanns = u + 8;
             } else if ("MethodParameters".equals(attrName)) {
                 methodParameters = u + 8;
@@ -953,7 +1062,7 @@
          * access, name and descriptor can have been changed, this is not
          * important since they are not copied as is from the reader).
          */
-        if (WRITER && mv instanceof MethodWriter) {
+        if (mv instanceof MethodWriter) {
             MethodWriter mw = (MethodWriter) mv;
             if (mw.cw.cr == this && signature == mw.signature) {
                 boolean sameExceptions = false;
@@ -990,26 +1099,26 @@
         }
 
         // visits the method annotations
-        if (ANNOTATIONS && dann != 0) {
+        if (dann != 0) {
             AnnotationVisitor dv = mv.visitAnnotationDefault();
             readAnnotationValue(dann, c, null, dv);
             if (dv != null) {
                 dv.visitEnd();
             }
         }
-        if (ANNOTATIONS && anns != 0) {
+        if (anns != 0) {
             for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         mv.visitAnnotation(readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && ianns != 0) {
+        if (ianns != 0) {
             for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) {
                 v = readAnnotationValues(v + 2, c, true,
                         mv.visitAnnotation(readUTF8(v, c), false));
             }
         }
-        if (ANNOTATIONS && tanns != 0) {
+        if (tanns != 0) {
             for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -1017,7 +1126,7 @@
                                 context.typePath, readUTF8(v, c), true));
             }
         }
-        if (ANNOTATIONS && itanns != 0) {
+        if (itanns != 0) {
             for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) {
                 v = readAnnotationTarget(context, v);
                 v = readAnnotationValues(v + 2, c, true,
@@ -1025,10 +1134,10 @@
                                 context.typePath, readUTF8(v, c), false));
             }
         }
-        if (ANNOTATIONS && mpanns != 0) {
+        if (mpanns != 0) {
             readParameterAnnotations(mv, context, mpanns, true);
         }
-        if (ANNOTATIONS && impanns != 0) {
+        if (impanns != 0) {
             readParameterAnnotations(mv, context, impanns, false);
         }
 
@@ -1075,7 +1184,7 @@
         int codeStart = u;
         int codeEnd = u + codeLength;
         Label[] labels = context.labels = new Label[codeLength + 2];
-        readLabel(codeLength + 1, labels);
+        createLabel(codeLength + 1, labels);
         while (u < codeEnd) {
             int offset = u - codeStart;
             int opcode = b[u] & 0xFF;
@@ -1085,11 +1194,16 @@
                 u += 1;
                 break;
             case ClassWriter.LABEL_INSN:
-                readLabel(offset + readShort(u + 1), labels);
+                createLabel(offset + readShort(u + 1), labels);
+                u += 3;
+                break;
+            case ClassWriter.ASM_LABEL_INSN:
+                createLabel(offset + readUnsignedShort(u + 1), labels);
                 u += 3;
                 break;
             case ClassWriter.LABELW_INSN:
-                readLabel(offset + readInt(u + 1), labels);
+            case ClassWriter.ASM_LABELW_INSN:
+                createLabel(offset + readInt(u + 1), labels);
                 u += 5;
                 break;
             case ClassWriter.WIDE_INSN:
@@ -1104,9 +1218,9 @@
                 // skips 0 to 3 padding bytes
                 u = u + 4 - (offset & 3);
                 // reads instruction
-                readLabel(offset + readInt(u), labels);
+                createLabel(offset + readInt(u), labels);
                 for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) {
-                    readLabel(offset + readInt(u + 12), labels);
+                    createLabel(offset + readInt(u + 12), labels);
                     u += 4;
                 }
                 u += 12;
@@ -1115,9 +1229,9 @@
                 // skips 0 to 3 padding bytes
                 u = u + 4 - (offset & 3);
                 // reads instruction
-                readLabel(offset + readInt(u), labels);
+                createLabel(offset + readInt(u), labels);
                 for (int i = readInt(u + 4); i > 0; --i) {
-                    readLabel(offset + readInt(u + 12), labels);
+                    createLabel(offset + readInt(u + 12), labels);
                     u += 8;
                 }
                 u += 8;
@@ -1147,9 +1261,9 @@
 
         // reads the try catch entries to find the labels, and also visits them
         for (int i = readUnsignedShort(u); i > 0; --i) {
-            Label start = readLabel(readUnsignedShort(u + 2), labels);
-            Label end = readLabel(readUnsignedShort(u + 4), labels);
-            Label handler = readLabel(readUnsignedShort(u + 6), labels);
+            Label start = createLabel(readUnsignedShort(u + 2), labels);
+            Label end = createLabel(readUnsignedShort(u + 4), labels);
+            Label handler = createLabel(readUnsignedShort(u + 6), labels);
             String type = readUTF8(items[readUnsignedShort(u + 8)], c);
             mv.visitTryCatchBlock(start, end, handler, type);
             u += 8;
@@ -1180,13 +1294,9 @@
                     varTable = u + 8;
                     for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
                         int label = readUnsignedShort(v + 10);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
+                        createDebugLabel(label, labels);
                         label += readUnsignedShort(v + 12);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
+                        createDebugLabel(label, labels);
                         v += 10;
                     }
                 }
@@ -1196,9 +1306,7 @@
                 if ((context.flags & SKIP_DEBUG) == 0) {
                     for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) {
                         int label = readUnsignedShort(v + 10);
-                        if (labels[label] == null) {
-                            readLabel(label, labels).status |= Label.DEBUG;
-                        }
+                        createDebugLabel(label, labels);
                         Label l = labels[label];
                         while (l.line > 0) {
                             if (l.next == null) {
@@ -1210,17 +1318,15 @@
                         v += 4;
                     }
                 }
-            } else if (ANNOTATIONS
-                    && "RuntimeVisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeVisibleTypeAnnotations".equals(attrName)) {
                 tanns = readTypeAnnotations(mv, context, u + 8, true);
                 ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1
                         : readUnsignedShort(tanns[0] + 1);
-            } else if (ANNOTATIONS
-                    && "RuntimeInvisibleTypeAnnotations".equals(attrName)) {
+            } else if ("RuntimeInvisibleTypeAnnotations".equals(attrName)) {
                 itanns = readTypeAnnotations(mv, context, u + 8, false);
                 nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1
                         : readUnsignedShort(itanns[0] + 1);
-            } else if (FRAMES && "StackMapTable".equals(attrName)) {
+            } else if ("StackMapTable".equals(attrName)) {
                 if ((context.flags & SKIP_FRAMES) == 0) {
                     stackMap = u + 10;
                     stackMapSize = readInt(u + 4);
@@ -1244,7 +1350,7 @@
                  * this by parsing the stack map table without a full decoding
                  * (see below).
                  */
-            } else if (FRAMES && "StackMap".equals(attrName)) {
+            } else if ("StackMap".equals(attrName)) {
                 if ((context.flags & SKIP_FRAMES) == 0) {
                     zip = false;
                     stackMap = u + 10;
@@ -1273,7 +1379,7 @@
         u += 2;
 
         // generates the first (implicit) stack map frame
-        if (FRAMES && stackMap != 0) {
+        if (stackMap != 0) {
             /*
              * for the first explicit frame the offset is not offset_delta + 1
              * but only offset_delta; setting the implicit frame offset to -1
@@ -1306,14 +1412,31 @@
                     int v = readUnsignedShort(i + 1);
                     if (v >= 0 && v < codeLength) {
                         if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) {
-                            readLabel(v, labels);
+                            createLabel(v, labels);
                         }
                     }
                 }
             }
         }
+        if ((context.flags & EXPAND_ASM_INSNS) != 0
+            && (context.flags & EXPAND_FRAMES) != 0) {
+            // Expanding the ASM pseudo instructions can introduce F_INSERT
+            // frames, even if the method does not currently have any frame.
+            // Also these inserted frames must be computed by simulating the
+            // effect of the bytecode instructions one by one, starting from the
+            // first one and the last existing frame (or the implicit first
+            // one). Finally, due to the way MethodWriter computes this (with
+            // the compute = INSERTED_FRAMES option), MethodWriter needs to know
+            // maxLocals before the first instruction is visited. For all these
+            // reasons we always visit the implicit first frame in this case
+            // (passing only maxLocals - the rest can be and is computed in
+            // MethodWriter).
+            mv.visitFrame(Opcodes.F_NEW, maxLocals, null, 0, null);
+        }
 
         // visits the instructions
+        int opcodeDelta = (context.flags & EXPAND_ASM_INSNS) == 0 ? -33 : 0;
+        boolean insertFrame = false;
         u = codeStart;
         while (u < codeEnd) {
             int offset = u - codeStart;
@@ -1334,7 +1457,7 @@
             }
 
             // visits the frame for this offset, if any
-            while (FRAMES && frame != null
+            while (frame != null
                     && (frame.offset == offset || frame.offset == -1)) {
                 // if there is a frame for this offset, makes the visitor visit
                 // it, and reads the next frame if there is one.
@@ -1346,6 +1469,9 @@
                         mv.visitFrame(frame.mode, frame.localDiff, frame.local,
                                 frame.stackCount, frame.stack);
                     }
+                    // if there is already a frame for this offset, there is no
+                    // need to insert a new one.
+                    insertFrame = false;
                 }
                 if (frameCount > 0) {
                     stackMap = readFrame(stackMap, zip, unzip, frame);
@@ -1354,6 +1480,13 @@
                     frame = null;
                 }
             }
+            // inserts a frame for this offset, if requested by setting
+            // insertFrame to true during the previous iteration. The actual
+            // frame content will be computed in MethodWriter.
+            if (insertFrame) {
+                mv.visitFrame(ClassWriter.F_INSERT, 0, null, 0, null);
+                insertFrame = false;
+            }
 
             // visits the instruction at this offset
             int opcode = b[u] & 0xFF;
@@ -1378,9 +1511,47 @@
                 u += 3;
                 break;
             case ClassWriter.LABELW_INSN:
-                mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]);
+                mv.visitJumpInsn(opcode + opcodeDelta, labels[offset
+                        + readInt(u + 1)]);
                 u += 5;
                 break;
+            case ClassWriter.ASM_LABEL_INSN: {
+                // changes temporary opcodes 202 to 217 (inclusive), 218
+                // and 219 to IFEQ ... JSR (inclusive), IFNULL and
+                // IFNONNULL
+                opcode = opcode < 218 ? opcode - 49 : opcode - 20;
+                Label target = labels[offset + readUnsignedShort(u + 1)];
+                // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
+                // <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is
+                // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
+                // and where <L> designates the instruction just after
+                // the GOTO_W.
+                if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
+                    mv.visitJumpInsn(opcode + 33, target);
+                } else {
+                    opcode = opcode <= 166 ? ((opcode + 1) ^ 1) - 1
+                            : opcode ^ 1;
+                    Label endif = createLabel(offset + 3, labels);
+                    mv.visitJumpInsn(opcode, endif);
+                    mv.visitJumpInsn(200, target); // GOTO_W
+                    // endif designates the instruction just after GOTO_W,
+                    // and is visited as part of the next instruction. Since
+                    // it is a jump target, we need to insert a frame here.
+                    insertFrame = true;
+                }
+                u += 3;
+                break;
+            }
+            case ClassWriter.ASM_LABELW_INSN: {
+                // replaces the pseudo GOTO_W instruction with a real one.
+                mv.visitJumpInsn(200, labels[offset + readInt(u + 1)]);
+                // The instruction just after is a jump target (because pseudo
+                // GOTO_W are used in patterns IFNOTxxx <L> GOTO_W <l> L:...,
+                // see MethodWriter), so we need to insert a frame here.
+                insertFrame = true;
+                u += 5;
+                break;
+            }
             case ClassWriter.WIDE_INSN:
                 opcode = b[u + 1] & 0xFF;
                 if (opcode == Opcodes.IINC) {
@@ -1636,8 +1807,8 @@
                 for (int j = readUnsignedShort(u + 1); j > 0; --j) {
                     int start = readUnsignedShort(u + 3);
                     int length = readUnsignedShort(u + 5);
-                    readLabel(start, context.labels);
-                    readLabel(start + length, context.labels);
+                    createLabel(start, context.labels);
+                    createLabel(start + length, context.labels);
                     u += 6;
                 }
                 u += 3;
@@ -1716,8 +1887,8 @@
             for (int i = 0; i < n; ++i) {
                 int start = readUnsignedShort(u);
                 int length = readUnsignedShort(u + 2);
-                context.start[i] = readLabel(start, context.labels);
-                context.end[i] = readLabel(start + length, context.labels);
+                context.start[i] = createLabel(start, context.labels);
+                context.end[i] = createLabel(start + length, context.labels);
                 context.index[i] = readUnsignedShort(u + 4);
                 u += 6;
             }
@@ -2137,7 +2308,7 @@
             }
         }
         frame.offset += delta + 1;
-        readLabel(frame.offset, labels);
+        createLabel(frame.offset, labels);
         return stackMap;
     }
 
@@ -2190,7 +2361,7 @@
             v += 2;
             break;
         default: // Uninitialized
-            frame[index] = readLabel(readUnsignedShort(v), labels);
+            frame[index] = createLabel(readUnsignedShort(v), labels);
             v += 2;
         }
         return v;
@@ -2217,6 +2388,39 @@
     }
 
     /**
+     * Creates a label without the Label.DEBUG flag set, for the given offset.
+     * The label is created with a call to {@link #readLabel} and its
+     * Label.DEBUG flag is cleared.
+     *
+     * @param offset
+     *            a bytecode offset in a method.
+     * @param labels
+     *            the already created labels, indexed by their offset.
+     * @return a Label without the Label.DEBUG flag set.
+     */
+    private Label createLabel(int offset, Label[] labels) {
+      Label label = readLabel(offset, labels);
+      label.status &= ~Label.DEBUG;
+      return label;
+    }
+
+    /**
+     * Creates a label with the Label.DEBUG flag set, if there is no already
+     * existing label for the given offset (otherwise does nothing). The label
+     * is created with a call to {@link #readLabel}.
+     *
+     * @param offset
+     *            a bytecode offset in a method.
+     * @param labels
+     *            the already created labels, indexed by their offset.
+     */
+    private void createDebugLabel(int offset, Label[] labels) {
+        if (labels[offset] == null) {
+            readLabel(offset, labels).status |= Label.DEBUG;
+        }
+    }
+
+    /**
      * Returns the start index of the attribute_info structure of this class.
      *
      * @return the start index of the attribute_info structure of this class.
@@ -2471,6 +2675,20 @@
     }
 
     /**
+     * Read a stringish constant item (CONSTANT_Class, CONSTANT_String,
+     * CONSTANT_MethodType, CONSTANT_Module or CONSTANT_Package
+     * @param index
+     * @param buf
+     * @return
+     */
+    private String readStringish(final int index, final char[] buf) {
+        // computes the start index of the item in b
+        // and reads the CONSTANT_Utf8 item designated by
+        // the first two bytes of this item
+        return readUTF8(items[readUnsignedShort(index)], buf);
+    }
+
+    /**
      * Reads a class constant pool item in {@link #b b}. <i>This method is
      * intended for {@link Attribute} sub classes, and is normally not needed by
      * class generators or adapters.</i>
@@ -2484,44 +2702,41 @@
      * @return the String corresponding to the specified class item.
      */
     public String readClass(final int index, final char[] buf) {
-        // computes the start index of the CONSTANT_Class item in b
-        // and reads the CONSTANT_Utf8 item designated by
-        // the first two bytes of this CONSTANT_Class item
-        return readUTF8(items[readUnsignedShort(index)], buf);
+        return readStringish(index, buf);
     }
 
     /**
-     * Reads a CONSTANT_Module_info item in {@code b}. This method is intended
-     * for {@link Attribute} sub classes, and is normally not needed by class
-     * generators or adapters.</i>
+     * Reads a module constant pool item in {@link #b b}. <i>This method is
+     * intended for {@link Attribute} sub classes, and is normally not needed by
+     * class generators or adapters.</i>
      *
-     * @param  index
-     *         the start index of an unsigned short value in {@link #b b},
-     *         whose value is the index of a module constant pool item.
-     * @param  buf
-     *         buffer to be used to read the item. This buffer must be
-     *         sufficiently large. It is not automatically resized.
+     * @param index
+     *            the start index of an unsigned short value in {@link #b b},
+     *            whose value is the index of a module constant pool item.
+     * @param buf
+     *            buffer to be used to read the item. This buffer must be
+     *            sufficiently large. It is not automatically resized.
      * @return the String corresponding to the specified module item.
      */
-    public String readModule(int index, char[] buf) {
-        return readUTF8(items[readUnsignedShort(index)], buf);
+    public String readModule(final int index, final char[] buf) {
+        return readStringish(index, buf);
     }
 
     /**
-     * Reads a CONSTANT_Package_info item in {@code b}.  This method is
-     * intended for {@link Attribute} sub slasses, and is normally not needed
-     * by class generators or adapters.</i>
+     * Reads a module constant pool item in {@link #b b}. <i>This method is
+     * intended for {@link Attribute} sub classes, and is normally not needed by
+     * class generators or adapters.</i>
      *
-     * @param  index
-     *         the start index of an unsigned short value in {@link #b b},
-     *         whose value is the index of a package constant pool item.
-     * @param  buf
-     *         buffer to be used to read the item. This buffer must be
-     *         sufficiently large. It is not automatically resized.
-     * @return the String corresponding to the specified package item.
+     * @param index
+     *            the start index of an unsigned short value in {@link #b b},
+     *            whose value is the index of a module constant pool item.
+     * @param buf
+     *            buffer to be used to read the item. This buffer must be
+     *            sufficiently large. It is not automatically resized.
+     * @return the String corresponding to the specified module item.
      */
-    public String readPackage(int index, char[] buf) {
-        return readUTF8(items[readUnsignedShort(index)], buf);
+    public String readPackage(final int index, final char[] buf) {
+        return readStringish(index, buf);
     }
 
     /**
@@ -2550,8 +2765,6 @@
         case ClassWriter.DOUBLE:
             return Double.longBitsToDouble(readLong(index));
         case ClassWriter.CLASS:
-        case ClassWriter.MODULE:
-        case ClassWriter.PACKAGE:
             return Type.getObjectType(readUTF8(index, buf));
         case ClassWriter.STR:
             return readUTF8(index, buf);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -61,7 +61,7 @@
 /**
  * A visitor to visit a Java class. The methods of this class must be called in
  * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
- * <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
+ * <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
  * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
  * <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
  * <tt>visitEnd</tt>.
@@ -72,7 +72,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -87,7 +87,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public ClassVisitor(final int api) {
         this(api, null);
@@ -98,13 +98,13 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param cv
      *            the class visitor to which this visitor must delegate method
      *            calls. May be null.
      */
     public ClassVisitor(final int api, final ClassVisitor cv) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
@@ -161,6 +161,28 @@
     }
 
     /**
+     * Visit the module corresponding to the class.
+     * @param name
+     *            module name
+     * @param access
+     *            module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+     *            and {@code ACC_MANDATED}.
+     * @param version
+     *            module version or null.
+     * @return a visitor to visit the module values, or <tt>null</tt> if
+     *         this visitor is not interested in visiting this module.
+     */
+    public ModuleVisitor visitModule(String name, int access, String version) {
+        if (api < Opcodes.ASM6) {
+            throw new RuntimeException();
+        }
+        if (cv != null) {
+            return cv.visitModule(name, access, version);
+        }
+        return null;
+    }
+
+    /**
      * Visits the enclosing class of the class. This method must be called only
      * if the class has an enclosing class.
      *
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ClassWriter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -87,8 +87,8 @@
      * {@link MethodVisitor#visitFrame} method are ignored, and the stack map
      * frames are recomputed from the methods bytecode. The arguments of the
      * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
-     * recomputed from the bytecode. In other words, computeFrames implies
-     * computeMaxs.
+     * recomputed from the bytecode. In other words, COMPUTE_FRAMES implies
+     * COMPUTE_MAXS.
      *
      * @see #ClassWriter(int)
      */
@@ -197,6 +197,27 @@
     static final int WIDE_INSN = 17;
 
     /**
+     * The type of the ASM pseudo instructions with an unsigned 2 bytes offset
+     * label (see Label#resolve).
+     */
+    static final int ASM_LABEL_INSN = 18;
+
+    /**
+     * The type of the ASM pseudo instructions with a 4 bytes offset label.
+     */
+    static final int ASM_LABELW_INSN = 19;
+
+    /**
+     * Represents a frame inserted between already existing frames. This kind of
+     * frame can only be used if the frame content can be computed from the
+     * previous existing frame and from the instructions between this existing
+     * frame and the inserted one, without any knowledge of the type hierarchy.
+     * This kind of frame is only used when an unconditional jump is inserted in
+     * a method while expanding an ASM pseudo instruction (see ClassReader).
+     */
+    static final int F_INSERT = 256;
+
+    /**
      * The instruction types of all JVM opcodes.
      */
     static final byte[] TYPE;
@@ -284,7 +305,7 @@
     /**
      * The base value for all CONSTANT_MethodHandle constant pool items.
      * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9
-     * different items.
+     * different items (from 21 to 29).
      */
     static final int HANDLE_BASE = 20;
 
@@ -434,6 +455,11 @@
     private ByteVector sourceDebug;
 
     /**
+     * The module attribute of this class.
+     */
+    private ModuleWriter moduleWriter;
+
+    /**
      * The constant pool item that contains the name of the enclosing class of
      * this class.
      */
@@ -523,25 +549,19 @@
     MethodWriter lastMethod;
 
     /**
-     * <tt>true</tt> if the maximum stack size and number of local variables
-     * must be automatically computed.
+     * Indicates what must be automatically computed.
+     *
+     * @see MethodWriter#compute
      */
-    private boolean computeMaxs;
+    private int compute;
 
     /**
-     * <tt>true</tt> if the stack map frames must be recomputed from scratch.
+     * <tt>true</tt> if some methods have wide forward jumps using ASM pseudo
+     * instructions, which need to be expanded into sequences of standard
+     * bytecode instructions. In this case the class is re-read and re-written
+     * with a ClassReader -> ClassWriter chain to perform this transformation.
      */
-    private boolean computeFrames;
-
-    /**
-     * <tt>true</tt> if the stack map tables of this class are invalid. The
-     * {@link MethodWriter#resizeInstructions} method cannot transform existing
-     * stack map tables, and so produces potentially invalid classes when it is
-     * executed. In this case the class is reread and rewritten with the
-     * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
-     * stack map tables when this option is used).
-     */
-    boolean invalidFrames;
+    boolean hasAsmInsns;
 
     // ------------------------------------------------------------------------
     // Static initializer
@@ -552,11 +572,11 @@
      */
     static {
         int i;
-        byte[] b = new byte[220];
+        byte[] b = new byte[221];
         String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
                 + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
                 + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
-                + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ";
+                + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSST";
         for (i = 0; i < b.length; ++i) {
             b[i] = (byte) (s.charAt(i) - 'A');
         }
@@ -610,8 +630,9 @@
         // // temporary opcodes used internally by ASM - see Label and
         // MethodWriter
         // for (i = 202; i < 220; ++i) {
-        // b[i] = LABEL_INSN;
+        // b[i] = ASM_LABEL_INSN;
         // }
+        // b[220] = ASM_LABELW_INSN;
         //
         // // LDC(_W) instructions
         // b[Constants.LDC] = LDC_INSN;
@@ -644,7 +665,7 @@
      *            {@link #COMPUTE_FRAMES}.
      */
     public ClassWriter(final int flags) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         index = 1;
         pool = new ByteVector();
         items = new Item[256];
@@ -653,8 +674,9 @@
         key2 = new Item();
         key3 = new Item();
         key4 = new Item();
-        this.computeMaxs = (flags & COMPUTE_MAXS) != 0;
-        this.computeFrames = (flags & COMPUTE_FRAMES) != 0;
+        this.compute = (flags & COMPUTE_FRAMES) != 0 ? MethodWriter.FRAMES
+                : ((flags & COMPUTE_MAXS) != 0 ? MethodWriter.MAXS
+                        : MethodWriter.NOTHING);
     }
 
     /**
@@ -684,9 +706,9 @@
      * @param flags
      *            option flags that can be used to modify the default behavior
      *            of this class. <i>These option flags do not affect methods
-     *            that are copied as is in the new class. This means that the
-     *            maximum stack size nor the stack frames will be computed for
-     *            these methods</i>. See {@link #COMPUTE_MAXS},
+     *            that are copied as is in the new class. This means that
+     *            neither the maximum stack size nor the stack frames will be
+     *            computed for these methods</i>. See {@link #COMPUTE_MAXS},
      *            {@link #COMPUTE_FRAMES}.
      */
     public ClassWriter(final ClassReader classReader, final int flags) {
@@ -705,9 +727,9 @@
             final String[] interfaces) {
         this.version = version;
         this.access = access;
-        this.name = (name == null) ? 0 : newClass(name);
+        this.name = newClass(name);
         thisName = name;
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             this.signature = newUTF8(signature);
         }
         this.superName = superName == null ? 0 : newClass(superName);
@@ -732,6 +754,14 @@
     }
 
     @Override
+    public final ModuleVisitor visitModule(final String name,
+            final int access, final String version) {
+        return moduleWriter = new ModuleWriter(this,
+                newModule(name), access,
+                version == null ? 0 : newUTF8(version));
+    }
+
+    @Override
     public final void visitOuterClass(final String owner, final String name,
             final String desc) {
         enclosingMethodOwner = newClass(owner);
@@ -743,9 +773,6 @@
     @Override
     public final AnnotationVisitor visitAnnotation(final String desc,
             final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write type, and reserve space for values count
         bv.putShort(newUTF8(desc)).putShort(0);
@@ -763,9 +790,6 @@
     @Override
     public final AnnotationVisitor visitTypeAnnotation(int typeRef,
             TypePath typePath, final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -805,7 +829,7 @@
         // and equality tests). If so we store the index of this inner class
         // entry (plus one) in intVal. This hack allows duplicate detection in
         // O(1) time.
-        Item nameItem = newClassItem(name);
+        Item nameItem = newStringishItem(CLASS, name);
         if (nameItem.intVal == 0) {
             ++innerClassesCount;
             innerClasses.putShort(nameItem.index);
@@ -830,7 +854,7 @@
     public final MethodVisitor visitMethod(final int access, final String name,
             final String desc, final String signature, final String[] exceptions) {
         return new MethodWriter(this, access, name, desc, signature,
-                exceptions, computeMaxs, computeFrames);
+                exceptions, compute);
     }
 
     @Override
@@ -874,7 +898,7 @@
             size += 8 + bootstrapMethods.length;
             newUTF8("BootstrapMethods");
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             ++attributeCount;
             size += 8;
             newUTF8("Signature");
@@ -912,26 +936,31 @@
             size += 8 + innerClasses.length;
             newUTF8("InnerClasses");
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             ++attributeCount;
             size += 8 + anns.getSize();
             newUTF8("RuntimeVisibleAnnotations");
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             ++attributeCount;
             size += 8 + ianns.getSize();
             newUTF8("RuntimeInvisibleAnnotations");
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             ++attributeCount;
             size += 8 + tanns.getSize();
             newUTF8("RuntimeVisibleTypeAnnotations");
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             ++attributeCount;
             size += 8 + itanns.getSize();
             newUTF8("RuntimeInvisibleTypeAnnotations");
         }
+        if (moduleWriter != null) {
+            attributeCount += 1 + moduleWriter.attributeCount;
+            size += 6 + moduleWriter.size + moduleWriter.attributesSize;
+            newUTF8("Module");
+        }
         if (attrs != null) {
             attributeCount += attrs.getCount();
             size += attrs.getSize(this, null, 0, -1, -1);
@@ -968,7 +997,7 @@
                     bootstrapMethodsCount);
             out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length);
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             out.putShort(newUTF8("Signature")).putInt(2).putShort(signature);
         }
         if (sourceFile != 0) {
@@ -979,6 +1008,11 @@
             out.putShort(newUTF8("SourceDebugExtension")).putInt(len);
             out.putByteArray(sourceDebug.data, 0, len);
         }
+        if (moduleWriter != null) {
+            out.putShort(newUTF8("Module"));
+            moduleWriter.put(out);
+            moduleWriter.putAttributes(out);
+        }
         if (enclosingMethodOwner != 0) {
             out.putShort(newUTF8("EnclosingMethod")).putInt(4);
             out.putShort(enclosingMethodOwner).putShort(enclosingMethod);
@@ -997,41 +1031,46 @@
             out.putInt(innerClasses.length + 2).putShort(innerClassesCount);
             out.putByteArray(innerClasses.data, 0, innerClasses.length);
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             out.putShort(newUTF8("RuntimeVisibleAnnotations"));
             anns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             out.putShort(newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             out.putShort(newUTF8("RuntimeVisibleTypeAnnotations"));
             tanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations"));
             itanns.put(out);
         }
         if (attrs != null) {
             attrs.put(this, null, 0, -1, -1, out);
         }
-        if (invalidFrames) {
+        if (hasAsmInsns) {
+            boolean hasFrames = false;
+            mb = firstMethod;
+            while (mb != null) {
+                hasFrames |= mb.frameCount > 0;
+                mb = (MethodWriter) mb.mv;
+            }
             anns = null;
             ianns = null;
             attrs = null;
-            innerClassesCount = 0;
-            innerClasses = null;
-            bootstrapMethodsCount = 0;
-            bootstrapMethods = null;
+            moduleWriter = null;
             firstField = null;
             lastField = null;
             firstMethod = null;
             lastMethod = null;
-            computeMaxs = false;
-            computeFrames = true;
-            invalidFrames = false;
-            new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES);
+            compute =
+                hasFrames ? MethodWriter.INSERTED_FRAMES : MethodWriter.NOTHING;
+            hasAsmInsns = false;
+            new ClassReader(out.data).accept(this,
+                    (hasFrames ? ClassReader.EXPAND_FRAMES : 0)
+                    | ClassReader.EXPAND_ASM_INSNS);
             return toByteArray();
         }
         return out.data;
@@ -1078,16 +1117,16 @@
             double val = ((Double) cst).doubleValue();
             return newDouble(val);
         } else if (cst instanceof String) {
-            return newString((String) cst);
+            return newStringishItem(STR, (String) cst);
         } else if (cst instanceof Type) {
             Type t = (Type) cst;
             int s = t.getSort();
             if (s == Type.OBJECT) {
-                return newClassItem(t.getInternalName());
+                return newStringishItem(CLASS, t.getInternalName());
             } else if (s == Type.METHOD) {
-                return newMethodTypeItem(t.getDescriptor());
+                return newStringishItem(MTYPE, t.getDescriptor());
             } else { // s == primitive type or array
-                return newClassItem(t.getDescriptor());
+                return newStringishItem(CLASS, t.getDescriptor());
             }
         } else if (cst instanceof Handle) {
             Handle h = (Handle) cst;
@@ -1136,20 +1175,21 @@
     }
 
     /**
-     * Adds a class reference to the constant pool of the class being build.
+     * Adds a string reference, a class reference, a method type, a module
+     * or a package to the constant pool of the class being build.
      * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
      *
+     * @param type
+     *            a type among STR, CLASS, MTYPE, MODULE or PACKAGE
      * @param value
-     *            the internal name of the class.
-     * @return a new or already existing class reference item.
+     *            string value of the reference.
+     * @return a new or already existing reference item.
      */
-    Item newClassItem(final String value) {
-        key2.set(CLASS, value, null, null);
+    Item newStringishItem(final int type, final String value) {
+        key2.set(type, value, null, null);
         Item result = get(key2);
         if (result == null) {
-            pool.put12(CLASS, newUTF8(value));
+            pool.put12(type, newUTF8(value));
             result = new Item(index++, key2);
             put(result);
         }
@@ -1167,72 +1207,7 @@
      * @return the index of a new or already existing class reference item.
      */
     public int newClass(final String value) {
-        return newClassItem(value).index;
-    }
-
-    /**
-     * Adds a module name to the constant pool.
-     *
-     * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param  value
-     *         the module name
-     * @return the index of a new or already existing module reference item.
-     */
-    public int newModule(String value) {
-        key2.set(MODULE, value, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(MODULE, newUTF8(value));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result.index;
-    }
-
-    /**
-     * Adds a package name to the constant pool.
-     *
-     * Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param  value
-     *         the internal name of the package.
-     * @return the index of a new or already existing package reference item.
-     */
-    public int newPackage(String value) {
-        key2.set(PACKAGE, value, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(PACKAGE, newUTF8(value));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result.index;
-    }
-
-    /**
-     * Adds a method type reference to the constant pool of the class being
-     * build. Does nothing if the constant pool already contains a similar item.
-     * <i>This method is intended for {@link Attribute} sub classes, and is
-     * normally not needed by class generators or adapters.</i>
-     *
-     * @param methodDesc
-     *            method descriptor of the method type.
-     * @return a new or already existing method type reference item.
-     */
-    Item newMethodTypeItem(final String methodDesc) {
-        key2.set(MTYPE, methodDesc, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(MTYPE, newUTF8(methodDesc));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result;
+        return newStringishItem(CLASS, value).index;
     }
 
     /**
@@ -1247,7 +1222,37 @@
      *         item.
      */
     public int newMethodType(final String methodDesc) {
-        return newMethodTypeItem(methodDesc).index;
+        return newStringishItem(MTYPE, methodDesc).index;
+    }
+
+    /**
+     * Adds a module reference to the constant pool of the class being
+     * build. Does nothing if the constant pool already contains a similar item.
+     * <i>This method is intended for {@link Attribute} sub classes, and is
+     * normally not needed by class generators or adapters.</i>
+     *
+     * @param moduleName
+     *            name of the module.
+     * @return the index of a new or already existing module reference
+     *         item.
+     */
+    public int newModule(final String moduleName) {
+        return newStringishItem(MODULE, moduleName).index;
+    }
+
+    /**
+     * Adds a package reference to the constant pool of the class being
+     * build. Does nothing if the constant pool already contains a similar item.
+     * <i>This method is intended for {@link Attribute} sub classes, and is
+     * normally not needed by class generators or adapters.</i>
+     *
+     * @param packageName
+     *            name of the package in its internal form.
+     * @return the index of a new or already existing module reference
+     *         item.
+     */
+    public int newPackage(final String packageName) {
+        return newStringishItem(PACKAGE, packageName).index;
     }
 
     /**
@@ -1629,25 +1634,6 @@
     }
 
     /**
-     * Adds a string to the constant pool of the class being build. Does nothing
-     * if the constant pool already contains a similar item.
-     *
-     * @param value
-     *            the String value.
-     * @return a new or already existing string item.
-     */
-    private Item newString(final String value) {
-        key2.set(STR, value, null, null);
-        Item result = get(key2);
-        if (result == null) {
-            pool.put12(STR, newUTF8(value));
-            result = new Item(index++, key2);
-            put(result);
-        }
-        return result;
-    }
-
-    /**
      * Adds a name and type to the constant pool of the class being build. Does
      * nothing if the constant pool already contains a similar item. <i>This
      * method is intended for {@link Attribute} sub classes, and is normally not
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/CurrentFrame.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,85 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * Information about the input stack map frame at the "current" instruction of a
+ * method. This is implemented as a Frame subclass for a "basic block"
+ * containing only one instruction.
+ *
+ * @author Eric Bruneton
+ */
+class CurrentFrame extends Frame {
+
+    /**
+     * Sets this CurrentFrame to the input stack map frame of the next "current"
+     * instruction, i.e. the instruction just after the given one. It is assumed
+     * that the value of this object when this method is called is the stack map
+     * frame status just before the given instruction is executed.
+     */
+    @Override
+    void execute(int opcode, int arg, ClassWriter cw, Item item) {
+        super.execute(opcode, arg, cw, item);
+        Frame successor = new Frame();
+        merge(cw, successor, 0);
+        set(successor);
+        owner.inputStackTop = 0;
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -69,7 +69,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -84,7 +84,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public FieldVisitor(final int api) {
         this(api, null);
@@ -95,13 +95,13 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param fv
      *            the field visitor to which this visitor must delegate method
      *            calls. May be null.
      */
     public FieldVisitor(final int api, final FieldVisitor fv) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/FieldWriter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -147,7 +147,7 @@
      */
     FieldWriter(final ClassWriter cw, final int access, final String name,
             final String desc, final String signature, final Object value) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         if (cw.firstField == null) {
             cw.firstField = this;
         } else {
@@ -158,7 +158,7 @@
         this.access = access;
         this.name = cw.newUTF8(name);
         this.desc = cw.newUTF8(desc);
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             this.signature = cw.newUTF8(signature);
         }
         if (value != null) {
@@ -173,9 +173,6 @@
     @Override
     public AnnotationVisitor visitAnnotation(final String desc,
             final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write type, and reserve space for values count
         bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -193,9 +190,6 @@
     @Override
     public AnnotationVisitor visitTypeAnnotation(final int typeRef,
             final TypePath typePath, final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -249,23 +243,23 @@
             cw.newUTF8("Deprecated");
             size += 6;
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             cw.newUTF8("Signature");
             size += 8;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             cw.newUTF8("RuntimeVisibleAnnotations");
             size += 8 + anns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             cw.newUTF8("RuntimeInvisibleAnnotations");
             size += 8 + ianns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             cw.newUTF8("RuntimeVisibleTypeAnnotations");
             size += 8 + tanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             cw.newUTF8("RuntimeInvisibleTypeAnnotations");
             size += 8 + itanns.getSize();
         }
@@ -299,19 +293,19 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             ++attributeCount;
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             ++attributeCount;
         }
         if (attrs != null) {
@@ -331,23 +325,23 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
         }
-        if (ClassReader.SIGNATURES && signature != 0) {
+        if (signature != 0) {
             out.putShort(cw.newUTF8("Signature"));
             out.putInt(2).putShort(signature);
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
             anns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
             tanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
             itanns.put(out);
         }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Frame.java	Thu Nov 02 13:18:23 2017 -0700
@@ -63,7 +63,7 @@
  *
  * @author Eric Bruneton
  */
-final class Frame {
+class Frame {
 
     /*
      * Frames are computed in a two steps process: during the visit of each
@@ -525,7 +525,7 @@
      * When the stack map frames are completely computed, this field is the
      * actual number of types in {@link #outputStack}.
      */
-    private int outputStackTop;
+    int outputStackTop;
 
     /**
      * Number of types that are initialized in the basic block.
@@ -550,6 +550,110 @@
     private int[] initializations;
 
     /**
+     * Sets this frame to the given value.
+     *
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param nLocal
+     *            the number of local variables.
+     * @param local
+     *            the local variable types. Primitive types are represented by
+     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+     *            represented by a single element). Reference types are
+     *            represented by String objects (representing internal names),
+     *            and uninitialized types by Label objects (this label
+     *            designates the NEW instruction that created this uninitialized
+     *            value).
+     * @param nStack
+     *            the number of operand stack elements.
+     * @param stack
+     *            the operand stack types (same format as the "local" array).
+     */
+    final void set(ClassWriter cw, final int nLocal, final Object[] local,
+            final int nStack, final Object[] stack) {
+        int i = convert(cw, nLocal, local, inputLocals);
+        while (i < local.length) {
+            inputLocals[i++] = TOP;
+        }
+        int nStackTop = 0;
+        for (int j = 0; j < nStack; ++j) {
+            if (stack[j] == Opcodes.LONG || stack[j] == Opcodes.DOUBLE) {
+                ++nStackTop;
+            }
+        }
+        inputStack = new int[nStack + nStackTop];
+        convert(cw, nStack, stack, inputStack);
+        outputStackTop = 0;
+        initializationCount = 0;
+    }
+
+    /**
+     * Converts types from the MethodWriter.visitFrame() format to the Frame
+     * format.
+     *
+     * @param cw
+     *            the ClassWriter to which this label belongs.
+     * @param nInput
+     *            the number of types to convert.
+     * @param input
+     *            the types to convert. Primitive types are represented by
+     *            {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
+     *            {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
+     *            {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
+     *            {@link Opcodes#UNINITIALIZED_THIS} (long and double are
+     *            represented by a single element). Reference types are
+     *            represented by String objects (representing internal names),
+     *            and uninitialized types by Label objects (this label
+     *            designates the NEW instruction that created this uninitialized
+     *            value).
+     * @param output
+     *            where to store the converted types.
+     * @return the number of output elements.
+     */
+    private static int convert(ClassWriter cw, int nInput, Object[] input,
+            int[] output) {
+        int i = 0;
+        for (int j = 0; j < nInput; ++j) {
+            if (input[j] instanceof Integer) {
+                output[i++] = BASE | ((Integer) input[j]).intValue();
+                if (input[j] == Opcodes.LONG || input[j] == Opcodes.DOUBLE) {
+                    output[i++] = TOP;
+                }
+            } else if (input[j] instanceof String) {
+                output[i++] = type(cw, Type.getObjectType((String) input[j])
+                        .getDescriptor());
+            } else {
+                output[i++] = UNINITIALIZED
+                        | cw.addUninitializedType("",
+                                ((Label) input[j]).position);
+            }
+        }
+        return i;
+    }
+
+    /**
+     * Sets this frame to the value of the given frame. WARNING: after this
+     * method is called the two frames share the same data structures. It is
+     * recommended to discard the given frame f to avoid unexpected side
+     * effects.
+     *
+     * @param f
+     *            The new frame value.
+     */
+    final void set(final Frame f) {
+        inputLocals = f.inputLocals;
+        inputStack = f.inputStack;
+        outputLocals = f.outputLocals;
+        outputStack = f.outputStack;
+        outputStackTop = f.outputStackTop;
+        initializationCount = f.initializationCount;
+        initializations = f.initializations;
+    }
+
+    /**
      * Returns the output frame local variable type at the given index.
      *
      * @param local
@@ -614,7 +718,7 @@
         }
         // pushes the type on the output stack
         outputStack[outputStackTop++] = type;
-        // updates the maximun height reached by the output stack, if needed
+        // updates the maximum height reached by the output stack, if needed
         int top = owner.inputStackTop + outputStackTop;
         if (top > owner.outputStackMax) {
             owner.outputStackMax = top;
@@ -650,7 +754,7 @@
      *            a type descriptor.
      * @return the int encoding of the given type.
      */
-    private static int type(final ClassWriter cw, final String desc) {
+    static int type(final ClassWriter cw, final String desc) {
         String t;
         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
         switch (desc.charAt(index)) {
@@ -838,7 +942,7 @@
      * @param maxLocals
      *            the maximum number of local variables of this method.
      */
-    void initInputFrame(final ClassWriter cw, final int access,
+    final void initInputFrame(final ClassWriter cw, final int access,
             final Type[] args, final int maxLocals) {
         inputLocals = new int[maxLocals];
         inputStack = new int[0];
@@ -981,7 +1085,7 @@
         case Opcodes.AALOAD:
             pop(1);
             t1 = pop();
-            push(ELEMENT_OF + t1);
+            push(t1 == NULL ? t1 : ELEMENT_OF + t1);
             break;
         case Opcodes.ISTORE:
         case Opcodes.FSTORE:
@@ -1312,7 +1416,7 @@
      * @return <tt>true</tt> if the input frame of the given label has been
      *         changed by this operation.
      */
-    boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
+    final boolean merge(final ClassWriter cw, final Frame frame, final int edge) {
         boolean changed = false;
         int i, s, dim, kind, t;
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Item.java	Thu Nov 02 13:18:23 2017 -0700
@@ -80,6 +80,7 @@
      * {@link ClassWriter#STR}, {@link ClassWriter#CLASS},
      * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD},
      * {@link ClassWriter#METH}, {@link ClassWriter#IMETH},
+     * {@link ClassWriter#MODULE}, {@link ClassWriter#PACKAGE},
      * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}.
      *
      * MethodHandle constant 9 variations are stored using a range of 9 values
@@ -239,12 +240,12 @@
         this.strVal3 = strVal3;
         switch (type) {
         case ClassWriter.CLASS:
-        case ClassWriter.MODULE:
-        case ClassWriter.PACKAGE:
             this.intVal = 0;     // intVal of a class must be zero, see visitInnerClass
         case ClassWriter.UTF8:
         case ClassWriter.STR:
         case ClassWriter.MTYPE:
+        case ClassWriter.MODULE:
+        case ClassWriter.PACKAGE:
         case ClassWriter.TYPE_NORMAL:
             hashCode = 0x7FFFFFFF & (type + strVal1.hashCode());
             return;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Label.java	Thu Nov 02 13:18:23 2017 -0700
@@ -389,13 +389,12 @@
      *            the position of this label in the bytecode.
      * @param data
      *            the bytecode of the method.
-     * @return <tt>true</tt> if a blank that was left for this label was to
+     * @return <tt>true</tt> if a blank that was left for this label was too
      *         small to store the offset. In such a case the corresponding jump
      *         instruction is replaced with a pseudo instruction (using unused
      *         opcodes) using an unsigned two bytes offset. These pseudo
-     *         instructions will need to be replaced with true instructions with
-     *         wider offsets (4 bytes instead of 2). This is done in
-     *         {@link MethodWriter#resizeInstructions}.
+     *         instructions will be replaced with standard bytecode instructions
+     *         with wider offsets (4 bytes instead of 2), in ClassReader.
      * @throws IllegalArgumentException
      *             if this label has already been resolved, or if it has not
      *             been created by the given code writer.
@@ -454,7 +453,7 @@
      * @return the first label of the series to which this label belongs.
      */
     Label getFirst() {
-        return !ClassReader.FRAMES || frame == null ? this : frame.owner;
+        return frame == null ? this : frame.owner;
     }
 
     // ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -86,7 +86,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -101,7 +101,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public MethodVisitor(final int api) {
         this(api, null);
@@ -112,13 +112,13 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this visitor must delegate method
      *            calls. May be null.
      */
     public MethodVisitor(final int api, final MethodVisitor mv) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -128,7 +128,19 @@
      *
      * @see #compute
      */
-    private static final int FRAMES = 0;
+    static final int FRAMES = 0;
+
+    /**
+     * Indicates that the stack map frames of type F_INSERT must be computed.
+     * The other frames are not (re)computed. They should all be of type F_NEW
+     * and should be sufficient to compute the content of the F_INSERT frames,
+     * together with the bytecode instructions between a F_NEW and a F_INSERT
+     * frame - and without any knowledge of the type hierarchy (by definition of
+     * F_INSERT).
+     *
+     * @see #compute
+     */
+    static final int INSERTED_FRAMES = 1;
 
     /**
      * Indicates that the maximum stack size and number of local variables must
@@ -136,14 +148,14 @@
      *
      * @see #compute
      */
-    private static final int MAXS = 1;
+    static final int MAXS = 2;
 
     /**
      * Indicates that nothing must be automatically computed.
      *
      * @see #compute
      */
-    private static final int NOTHING = 2;
+    static final int NOTHING = 3;
 
     /**
      * The class writer to which this method must be added.
@@ -277,7 +289,7 @@
     /**
      * Number of stack map frames in the StackMapTable attribute.
      */
-    private int frameCount;
+    int frameCount;
 
     /**
      * The StackMapTable attribute.
@@ -384,11 +396,6 @@
     private Attribute cattrs;
 
     /**
-     * Indicates if some jump instructions are too small and need to be resized.
-     */
-    private boolean resize;
-
-    /**
      * The number of subroutines in this method.
      */
     private int subroutines;
@@ -409,6 +416,7 @@
      * Indicates what must be automatically computed.
      *
      * @see #FRAMES
+     * @see #INSERTED_FRAMES
      * @see #MAXS
      * @see #NOTHING
      */
@@ -471,18 +479,13 @@
      * @param exceptions
      *            the internal names of the method's exceptions. May be
      *            <tt>null</tt>.
-     * @param computeMaxs
-     *            <tt>true</tt> if the maximum stack size and number of local
-     *            variables must be automatically computed.
-     * @param computeFrames
-     *            <tt>true</tt> if the stack map tables must be recomputed from
-     *            scratch.
+     * @param compute
+     *            Indicates what must be automatically computed (see #compute).
      */
     MethodWriter(final ClassWriter cw, final int access, final String name,
             final String desc, final String signature,
-            final String[] exceptions, final boolean computeMaxs,
-            final boolean computeFrames) {
-        super(Opcodes.ASM5);
+            final String[] exceptions, final int compute) {
+        super(Opcodes.ASM6);
         if (cw.firstMethod == null) {
             cw.firstMethod = this;
         } else {
@@ -497,9 +500,7 @@
         this.name = cw.newUTF8(name);
         this.desc = cw.newUTF8(desc);
         this.descriptor = desc;
-        if (ClassReader.SIGNATURES) {
-            this.signature = signature;
-        }
+        this.signature = signature;
         if (exceptions != null && exceptions.length > 0) {
             exceptionCount = exceptions.length;
             this.exceptions = new int[exceptionCount];
@@ -507,8 +508,8 @@
                 this.exceptions[i] = cw.newClass(exceptions[i]);
             }
         }
-        this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING);
-        if (computeMaxs || computeFrames) {
+        this.compute = compute;
+        if (compute != NOTHING) {
             // updates maxLocals
             int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2;
             if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -539,9 +540,6 @@
 
     @Override
     public AnnotationVisitor visitAnnotationDefault() {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         annd = new ByteVector();
         return new AnnotationWriter(cw, false, annd, null, 0);
     }
@@ -549,9 +547,6 @@
     @Override
     public AnnotationVisitor visitAnnotation(final String desc,
             final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write type, and reserve space for values count
         bv.putShort(cw.newUTF8(desc)).putShort(0);
@@ -569,9 +564,6 @@
     @Override
     public AnnotationVisitor visitTypeAnnotation(final int typeRef,
             final TypePath typePath, final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -592,9 +584,6 @@
     @Override
     public AnnotationVisitor visitParameterAnnotation(final int parameter,
             final String desc, final boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         if ("Ljava/lang/Synthetic;".equals(desc)) {
             // workaround for a bug in javac with synthetic parameters
@@ -639,11 +628,33 @@
     @Override
     public void visitFrame(final int type, final int nLocal,
             final Object[] local, final int nStack, final Object[] stack) {
-        if (!ClassReader.FRAMES || compute == FRAMES) {
+        if (compute == FRAMES) {
             return;
         }
 
-        if (type == Opcodes.F_NEW) {
+        if (compute == INSERTED_FRAMES) {
+            if (currentBlock.frame == null) {
+                // This should happen only once, for the implicit first frame
+                // (which is explicitly visited in ClassReader if the
+                // EXPAND_ASM_INSNS option is used).
+                currentBlock.frame = new CurrentFrame();
+                currentBlock.frame.owner = currentBlock;
+                currentBlock.frame.initInputFrame(cw, access,
+                        Type.getArgumentTypes(descriptor), nLocal);
+                visitImplicitFirstFrame();
+            } else {
+                if (type == Opcodes.F_NEW) {
+                    currentBlock.frame.set(cw, nLocal, local, nStack, stack);
+                } else {
+                    // In this case type is equal to F_INSERT by hypothesis, and
+                    // currentBlock.frame contains the stack map frame at the
+                    // current instruction, computed from the last F_NEW frame
+                    // and the bytecode instructions in between (via calls to
+                    // CurrentFrame#execute).
+                }
+                visitFrame(currentBlock.frame);
+            }
+        } else if (type == Opcodes.F_NEW) {
             if (previousFrame == null) {
                 visitImplicitFirstFrame();
             }
@@ -651,10 +662,10 @@
             int frameIndex = startFrame(code.length, nLocal, nStack);
             for (int i = 0; i < nLocal; ++i) {
                 if (local[i] instanceof String) {
-                    frame[frameIndex++] = Frame.OBJECT
-                            | cw.addType((String) local[i]);
+                    String desc = Type.getObjectType((String) local[i]).getDescriptor();
+                    frame[frameIndex++] = Frame.type(cw, desc);
                 } else if (local[i] instanceof Integer) {
-                    frame[frameIndex++] = ((Integer) local[i]).intValue();
+                    frame[frameIndex++] = Frame.BASE | ((Integer) local[i]).intValue();
                 } else {
                     frame[frameIndex++] = Frame.UNINITIALIZED
                             | cw.addUninitializedType("",
@@ -663,10 +674,10 @@
             }
             for (int i = 0; i < nStack; ++i) {
                 if (stack[i] instanceof String) {
-                    frame[frameIndex++] = Frame.OBJECT
-                            | cw.addType((String) stack[i]);
+                    String desc = Type.getObjectType((String) stack[i]).getDescriptor();
+                    frame[frameIndex++] = Frame.type(cw, desc);
                 } else if (stack[i] instanceof Integer) {
-                    frame[frameIndex++] = ((Integer) stack[i]).intValue();
+                    frame[frameIndex++] = Frame.BASE | ((Integer) stack[i]).intValue();
                 } else {
                     frame[frameIndex++] = Frame.UNINITIALIZED
                             | cw.addUninitializedType("",
@@ -747,7 +758,7 @@
         // update currentBlock
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, null, null);
             } else {
                 // updates current and max stack sizes
@@ -770,7 +781,7 @@
         lastCodeOffset = code.length;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, operand, null, null);
             } else if (opcode != Opcodes.NEWARRAY) {
                 // updates current and max stack sizes only for NEWARRAY
@@ -795,7 +806,7 @@
         lastCodeOffset = code.length;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, var, null, null);
             } else {
                 // updates current and max stack sizes
@@ -852,10 +863,10 @@
     @Override
     public void visitTypeInsn(final int opcode, final String type) {
         lastCodeOffset = code.length;
-        Item i = cw.newClassItem(type);
+        Item i = cw.newStringishItem(ClassWriter.CLASS, type);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, code.length, cw, i);
             } else if (opcode == Opcodes.NEW) {
                 // updates current and max stack sizes only if opcode == NEW
@@ -878,7 +889,7 @@
         Item i = cw.newFieldItem(owner, name, desc);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, cw, i);
             } else {
                 int size;
@@ -918,7 +929,7 @@
         int argSize = i.intVal;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(opcode, 0, cw, i);
             } else {
                 /*
@@ -970,7 +981,7 @@
         int argSize = i.intVal;
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i);
             } else {
                 /*
@@ -1004,7 +1015,9 @@
     }
 
     @Override
-    public void visitJumpInsn(final int opcode, final Label label) {
+    public void visitJumpInsn(int opcode, final Label label) {
+        boolean isWide = opcode >= 200; // GOTO_W
+        opcode = isWide ? opcode - 33 : opcode;
         lastCodeOffset = code.length;
         Label nextInsn = null;
         // Label currentBlock = this.currentBlock;
@@ -1019,6 +1032,8 @@
                     // creates a Label for the next basic block
                     nextInsn = new Label();
                 }
+            } else if (compute == INSERTED_FRAMES) {
+                currentBlock.frame.execute(opcode, 0, null, null);
             } else {
                 if (opcode == Opcodes.JSR) {
                     if ((label.status & Label.SUBROUTINE) == 0) {
@@ -1050,8 +1065,8 @@
             /*
              * case of a backward jump with an offset < -32768. In this case we
              * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx
-             * <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is the
-             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <l'>
+             * <l> with IFNOTxxx <L> GOTO_W <l> L:..., where IFNOTxxx is the
+             * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where <L>
              * designates the instruction just after the GOTO_W.
              */
             if (opcode == Opcodes.GOTO) {
@@ -1067,9 +1082,21 @@
                 code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
                         : opcode ^ 1);
                 code.putShort(8); // jump offset
-                code.putByte(200); // GOTO_W
+                // ASM pseudo GOTO_W insn, see ClassReader. We don't use a real
+                // GOTO_W because we might need to insert a frame just after (as
+                // the target of the IFNOTxxx jump instruction).
+                code.putByte(220);
+                cw.hasAsmInsns = true;
             }
             label.put(this, code, code.length - 1, true);
+        } else if (isWide) {
+            /*
+             * case of a GOTO_W or JSR_W specified by the user (normally
+             * ClassReader when used to resize instructions). In this case we
+             * keep the original instruction.
+             */
+            code.putByte(opcode + 33);
+            label.put(this, code, code.length - 1, true);
         } else {
             /*
              * case of a backward jump with an offset >= -32768, or of a forward
@@ -1097,7 +1124,7 @@
     @Override
     public void visitLabel(final Label label) {
         // resolves previous forward references to label, if any
-        resize |= label.resolve(this, code.length, code.data);
+        cw.hasAsmInsns |= label.resolve(this, code.length, code.data);
         // updates currentBlock
         if ((label.status & Label.DEBUG) != 0) {
             return;
@@ -1130,6 +1157,18 @@
                 previousBlock.successor = label;
             }
             previousBlock = label;
+        } else if (compute == INSERTED_FRAMES) {
+            if (currentBlock == null) {
+                // This case should happen only once, for the visitLabel call in
+                // the constructor. Indeed, if compute is equal to
+                // INSERTED_FRAMES currentBlock can not be set back to null (see
+                // #noSuccessor).
+                currentBlock = label;
+            } else {
+                // Updates the frame owner so that a correct frame offset is
+                // computed in visitFrame(Frame).
+                currentBlock.frame.owner = label;
+            }
         } else if (compute == MAXS) {
             if (currentBlock != null) {
                 // ends current block (with one new successor)
@@ -1155,7 +1194,7 @@
         Item i = cw.newConstItem(cst);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.LDC, 0, cw, i);
             } else {
                 int size;
@@ -1187,7 +1226,7 @@
     public void visitIincInsn(final int var, final int increment) {
         lastCodeOffset = code.length;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.IINC, var, null, null);
             }
         }
@@ -1271,10 +1310,10 @@
     @Override
     public void visitMultiANewArrayInsn(final String desc, final int dims) {
         lastCodeOffset = code.length;
-        Item i = cw.newClassItem(desc);
+        Item i = cw.newStringishItem(ClassWriter.CLASS, desc);
         // Label currentBlock = this.currentBlock;
         if (currentBlock != null) {
-            if (compute == FRAMES) {
+            if (compute == FRAMES || compute == INSERTED_FRAMES) {
                 currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i);
             } else {
                 // updates current stack size (max stack size unchanged because
@@ -1289,9 +1328,6 @@
     @Override
     public AnnotationVisitor visitInsnAnnotation(int typeRef,
             TypePath typePath, String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8);
@@ -1331,9 +1367,6 @@
     @Override
     public AnnotationVisitor visitTryCatchAnnotation(int typeRef,
             TypePath typePath, String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         AnnotationWriter.putTarget(typeRef, typePath, bv);
@@ -1387,9 +1420,6 @@
     public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
             TypePath typePath, Label[] start, Label[] end, int[] index,
             String desc, boolean visible) {
-        if (!ClassReader.ANNOTATIONS) {
-            return null;
-        }
         ByteVector bv = new ByteVector();
         // write target_type and target_info
         bv.putByte(typeRef >>> 24).putShort(start.length);
@@ -1430,15 +1460,7 @@
 
     @Override
     public void visitMaxs(final int maxStack, final int maxLocals) {
-        if (resize) {
-            // replaces the temporary jump opcodes introduced by Label.resolve.
-            if (ClassReader.RESIZE) {
-                resizeInstructions();
-            } else {
-                throw new RuntimeException("Method code too large!");
-            }
-        }
-        if (ClassReader.FRAMES && compute == FRAMES) {
+        if (compute == FRAMES) {
             // completes the control flow graph with exception handler blocks
             Handler handler = firstHandler;
             while (handler != null) {
@@ -1468,8 +1490,8 @@
 
             // creates and visits the first (implicit) frame
             Frame f = labels.frame;
-            Type[] args = Type.getArgumentTypes(descriptor);
-            f.initInputFrame(cw, access, args, this.maxLocals);
+            f.initInputFrame(cw, access, Type.getArgumentTypes(descriptor),
+                    this.maxLocals);
             visitFrame(f);
 
             /*
@@ -1717,7 +1739,9 @@
         } else {
             currentBlock.outputStackMax = maxStackSize;
         }
-        currentBlock = null;
+        if (compute != INSERTED_FRAMES) {
+            currentBlock = null;
+        }
     }
 
     // ------------------------------------------------------------------------
@@ -1789,7 +1813,7 @@
             if ((access & ACC_CONSTRUCTOR) == 0) {
                 frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName);
             } else {
-                frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS;
+                frame[frameIndex++] = Frame.UNINITIALIZED_THIS;
             }
         }
         int i = 1;
@@ -1801,16 +1825,16 @@
             case 'B':
             case 'S':
             case 'I':
-                frame[frameIndex++] = 1; // Opcodes.INTEGER;
+                frame[frameIndex++] = Frame.INTEGER;
                 break;
             case 'F':
-                frame[frameIndex++] = 2; // Opcodes.FLOAT;
+                frame[frameIndex++] = Frame.FLOAT;
                 break;
             case 'J':
-                frame[frameIndex++] = 4; // Opcodes.LONG;
+                frame[frameIndex++] = Frame.LONG;
                 break;
             case 'D':
-                frame[frameIndex++] = 3; // Opcodes.DOUBLE;
+                frame[frameIndex++] = Frame.DOUBLE;
                 break;
             case '[':
                 while (descriptor.charAt(i) == '[') {
@@ -1822,8 +1846,7 @@
                         ++i;
                     }
                 }
-                frame[frameIndex++] = Frame.OBJECT
-                        | cw.addType(descriptor.substring(j, ++i));
+                frame[frameIndex++] = Frame.type(cw, descriptor.substring(j, ++i));
                 break;
             case 'L':
                 while (descriptor.charAt(i) != ';') {
@@ -2083,11 +2106,11 @@
                 cw.newUTF8(zip ? "StackMapTable" : "StackMap");
                 size += 8 + stackMap.length;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 cw.newUTF8("RuntimeVisibleTypeAnnotations");
                 size += 8 + ctanns.getSize();
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 cw.newUTF8("RuntimeInvisibleTypeAnnotations");
                 size += 8 + ictanns.getSize();
             }
@@ -2111,7 +2134,7 @@
             cw.newUTF8("Deprecated");
             size += 6;
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             cw.newUTF8("Signature");
             cw.newUTF8(signature);
             size += 8;
@@ -2120,34 +2143,34 @@
             cw.newUTF8("MethodParameters");
             size += 7 + methodParameters.length;
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             cw.newUTF8("AnnotationDefault");
             size += 6 + annd.length;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             cw.newUTF8("RuntimeVisibleAnnotations");
             size += 8 + anns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             cw.newUTF8("RuntimeInvisibleAnnotations");
             size += 8 + ianns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             cw.newUTF8("RuntimeVisibleTypeAnnotations");
             size += 8 + tanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             cw.newUTF8("RuntimeInvisibleTypeAnnotations");
             size += 8 + itanns.getSize();
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             cw.newUTF8("RuntimeVisibleParameterAnnotations");
             size += 7 + 2 * (panns.length - synthetics);
             for (int i = panns.length - 1; i >= synthetics; --i) {
                 size += panns[i] == null ? 0 : panns[i].getSize();
             }
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             cw.newUTF8("RuntimeInvisibleParameterAnnotations");
             size += 7 + 2 * (ipanns.length - synthetics);
             for (int i = ipanns.length - 1; i >= synthetics; --i) {
@@ -2193,31 +2216,31 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             ++attributeCount;
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             ++attributeCount;
         }
         if (methodParameters != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             ++attributeCount;
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             ++attributeCount;
         }
         if (attrs != null) {
@@ -2238,10 +2261,10 @@
             if (stackMap != null) {
                 size += 8 + stackMap.length;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 size += 8 + ctanns.getSize();
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 size += 8 + ictanns.getSize();
             }
             if (cattrs != null) {
@@ -2273,10 +2296,10 @@
             if (stackMap != null) {
                 ++attributeCount;
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 ++attributeCount;
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 ++attributeCount;
             }
             if (cattrs != null) {
@@ -2304,11 +2327,11 @@
                 out.putInt(stackMap.length + 2).putShort(frameCount);
                 out.putByteArray(stackMap.data, 0, stackMap.length);
             }
-            if (ClassReader.ANNOTATIONS && ctanns != null) {
+            if (ctanns != null) {
                 out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
                 ctanns.put(out);
             }
-            if (ClassReader.ANNOTATIONS && ictanns != null) {
+            if (ictanns != null) {
                 out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
                 ictanns.put(out);
             }
@@ -2333,7 +2356,7 @@
         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
         }
-        if (ClassReader.SIGNATURES && signature != null) {
+        if (signature != null) {
             out.putShort(cw.newUTF8("Signature")).putInt(2)
                     .putShort(cw.newUTF8(signature));
         }
@@ -2343,32 +2366,32 @@
                     methodParametersCount);
             out.putByteArray(methodParameters.data, 0, methodParameters.length);
         }
-        if (ClassReader.ANNOTATIONS && annd != null) {
+        if (annd != null) {
             out.putShort(cw.newUTF8("AnnotationDefault"));
             out.putInt(annd.length);
             out.putByteArray(annd.data, 0, annd.length);
         }
-        if (ClassReader.ANNOTATIONS && anns != null) {
+        if (anns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
             anns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && ianns != null) {
+        if (ianns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
             ianns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && tanns != null) {
+        if (tanns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations"));
             tanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && itanns != null) {
+        if (itanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations"));
             itanns.put(out);
         }
-        if (ClassReader.ANNOTATIONS && panns != null) {
+        if (panns != null) {
             out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations"));
             AnnotationWriter.put(panns, synthetics, out);
         }
-        if (ClassReader.ANNOTATIONS && ipanns != null) {
+        if (ipanns != null) {
             out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations"));
             AnnotationWriter.put(ipanns, synthetics, out);
         }
@@ -2376,569 +2399,4 @@
             attrs.put(cw, null, 0, -1, -1, out);
         }
     }
-
-    // ------------------------------------------------------------------------
-    // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W)
-    // ------------------------------------------------------------------------
-
-    /**
-     * Resizes and replaces the temporary instructions inserted by
-     * {@link Label#resolve} for wide forward jumps, while keeping jump offsets
-     * and instruction addresses consistent. This may require to resize other
-     * existing instructions, or even to introduce new instructions: for
-     * example, increasing the size of an instruction by 2 at the middle of a
-     * method can increases the offset of an IFEQ instruction from 32766 to
-     * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W
-     * 32765. This, in turn, may require to increase the size of another jump
-     * instruction, and so on... All these operations are handled automatically
-     * by this method.
-     * <p>
-     * <i>This method must be called after all the method that is being built
-     * has been visited</i>. In particular, the {@link Label Label} objects used
-     * to construct the method are no longer valid after this method has been
-     * called.
-     */
-    private void resizeInstructions() {
-        byte[] b = code.data; // bytecode of the method
-        int u, v, label; // indexes in b
-        int i, j; // loop indexes
-        /*
-         * 1st step: As explained above, resizing an instruction may require to
-         * resize another one, which may require to resize yet another one, and
-         * so on. The first step of the algorithm consists in finding all the
-         * instructions that need to be resized, without modifying the code.
-         * This is done by the following "fix point" algorithm:
-         *
-         * Parse the code to find the jump instructions whose offset will need
-         * more than 2 bytes to be stored (the future offset is computed from
-         * the current offset and from the number of bytes that will be inserted
-         * or removed between the source and target instructions). For each such
-         * instruction, adds an entry in (a copy of) the indexes and sizes
-         * arrays (if this has not already been done in a previous iteration!).
-         *
-         * If at least one entry has been added during the previous step, go
-         * back to the beginning, otherwise stop.
-         *
-         * In fact the real algorithm is complicated by the fact that the size
-         * of TABLESWITCH and LOOKUPSWITCH instructions depends on their
-         * position in the bytecode (because of padding). In order to ensure the
-         * convergence of the algorithm, the number of bytes to be added or
-         * removed from these instructions is over estimated during the previous
-         * loop, and computed exactly only after the loop is finished (this
-         * requires another pass to parse the bytecode of the method).
-         */
-        int[] allIndexes = new int[0]; // copy of indexes
-        int[] allSizes = new int[0]; // copy of sizes
-        boolean[] resize; // instructions to be resized
-        int newOffset; // future offset of a jump instruction
-
-        resize = new boolean[code.length];
-
-        // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done
-        int state = 3;
-        do {
-            if (state == 3) {
-                state = 2;
-            }
-            u = 0;
-            while (u < b.length) {
-                int opcode = b[u] & 0xFF; // opcode of current instruction
-                int insert = 0; // bytes to be added after this instruction
-
-                switch (ClassWriter.TYPE[opcode]) {
-                case ClassWriter.NOARG_INSN:
-                case ClassWriter.IMPLVAR_INSN:
-                    u += 1;
-                    break;
-                case ClassWriter.LABEL_INSN:
-                    if (opcode > 201) {
-                        // converts temporary opcodes 202 to 217, 218 and
-                        // 219 to IFEQ ... JSR (inclusive), IFNULL and
-                        // IFNONNULL
-                        opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                        label = u + readUnsignedShort(b, u + 1);
-                    } else {
-                        label = u + readShort(b, u + 1);
-                    }
-                    newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                    if (newOffset < Short.MIN_VALUE
-                            || newOffset > Short.MAX_VALUE) {
-                        if (!resize[u]) {
-                            if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
-                                // two additional bytes will be required to
-                                // replace this GOTO or JSR instruction with
-                                // a GOTO_W or a JSR_W
-                                insert = 2;
-                            } else {
-                                // five additional bytes will be required to
-                                // replace this IFxxx <l> instruction with
-                                // IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx
-                                // is the "opposite" opcode of IFxxx (i.e.,
-                                // IFNE for IFEQ) and where <l'> designates
-                                // the instruction just after the GOTO_W.
-                                insert = 5;
-                            }
-                            resize[u] = true;
-                        }
-                    }
-                    u += 3;
-                    break;
-                case ClassWriter.LABELW_INSN:
-                    u += 5;
-                    break;
-                case ClassWriter.TABL_INSN:
-                    if (state == 1) {
-                        // true number of bytes to be added (or removed)
-                        // from this instruction = (future number of padding
-                        // bytes - current number of padding byte) -
-                        // previously over estimated variation =
-                        // = ((3 - newOffset%4) - (3 - u%4)) - u%4
-                        // = (-newOffset%4 + u%4) - u%4
-                        // = -(newOffset & 3)
-                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                        insert = -(newOffset & 3);
-                    } else if (!resize[u]) {
-                        // over estimation of the number of bytes to be
-                        // added to this instruction = 3 - current number
-                        // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3
-                        insert = u & 3;
-                        resize[u] = true;
-                    }
-                    // skips instruction
-                    u = u + 4 - (u & 3);
-                    u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12;
-                    break;
-                case ClassWriter.LOOK_INSN:
-                    if (state == 1) {
-                        // like TABL_INSN
-                        newOffset = getNewOffset(allIndexes, allSizes, 0, u);
-                        insert = -(newOffset & 3);
-                    } else if (!resize[u]) {
-                        // like TABL_INSN
-                        insert = u & 3;
-                        resize[u] = true;
-                    }
-                    // skips instruction
-                    u = u + 4 - (u & 3);
-                    u += 8 * readInt(b, u + 4) + 8;
-                    break;
-                case ClassWriter.WIDE_INSN:
-                    opcode = b[u + 1] & 0xFF;
-                    if (opcode == Opcodes.IINC) {
-                        u += 6;
-                    } else {
-                        u += 4;
-                    }
-                    break;
-                case ClassWriter.VAR_INSN:
-                case ClassWriter.SBYTE_INSN:
-                case ClassWriter.LDC_INSN:
-                    u += 2;
-                    break;
-                case ClassWriter.SHORT_INSN:
-                case ClassWriter.LDCW_INSN:
-                case ClassWriter.FIELDORMETH_INSN:
-                case ClassWriter.TYPE_INSN:
-                case ClassWriter.IINC_INSN:
-                    u += 3;
-                    break;
-                case ClassWriter.ITFMETH_INSN:
-                case ClassWriter.INDYMETH_INSN:
-                    u += 5;
-                    break;
-                // case ClassWriter.MANA_INSN:
-                default:
-                    u += 4;
-                    break;
-                }
-                if (insert != 0) {
-                    // adds a new (u, insert) entry in the allIndexes and
-                    // allSizes arrays
-                    int[] newIndexes = new int[allIndexes.length + 1];
-                    int[] newSizes = new int[allSizes.length + 1];
-                    System.arraycopy(allIndexes, 0, newIndexes, 0,
-                            allIndexes.length);
-                    System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length);
-                    newIndexes[allIndexes.length] = u;
-                    newSizes[allSizes.length] = insert;
-                    allIndexes = newIndexes;
-                    allSizes = newSizes;
-                    if (insert > 0) {
-                        state = 3;
-                    }
-                }
-            }
-            if (state < 3) {
-                --state;
-            }
-        } while (state != 0);
-
-        // 2nd step:
-        // copies the bytecode of the method into a new bytevector, updates the
-        // offsets, and inserts (or removes) bytes as requested.
-
-        ByteVector newCode = new ByteVector(code.length);
-
-        u = 0;
-        while (u < code.length) {
-            int opcode = b[u] & 0xFF;
-            switch (ClassWriter.TYPE[opcode]) {
-            case ClassWriter.NOARG_INSN:
-            case ClassWriter.IMPLVAR_INSN:
-                newCode.putByte(opcode);
-                u += 1;
-                break;
-            case ClassWriter.LABEL_INSN:
-                if (opcode > 201) {
-                    // changes temporary opcodes 202 to 217 (inclusive), 218
-                    // and 219 to IFEQ ... JSR (inclusive), IFNULL and
-                    // IFNONNULL
-                    opcode = opcode < 218 ? opcode - 49 : opcode - 20;
-                    label = u + readUnsignedShort(b, u + 1);
-                } else {
-                    label = u + readShort(b, u + 1);
-                }
-                newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                if (resize[u]) {
-                    // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx
-                    // <l> with IFNOTxxx <l'> GOTO_W <l>, where IFNOTxxx is
-                    // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ)
-                    // and where <l'> designates the instruction just after
-                    // the GOTO_W.
-                    if (opcode == Opcodes.GOTO) {
-                        newCode.putByte(200); // GOTO_W
-                    } else if (opcode == Opcodes.JSR) {
-                        newCode.putByte(201); // JSR_W
-                    } else {
-                        newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1
-                                : opcode ^ 1);
-                        newCode.putShort(8); // jump offset
-                        newCode.putByte(200); // GOTO_W
-                        // newOffset now computed from start of GOTO_W
-                        newOffset -= 3;
-                    }
-                    newCode.putInt(newOffset);
-                } else {
-                    newCode.putByte(opcode);
-                    newCode.putShort(newOffset);
-                }
-                u += 3;
-                break;
-            case ClassWriter.LABELW_INSN:
-                label = u + readInt(b, u + 1);
-                newOffset = getNewOffset(allIndexes, allSizes, u, label);
-                newCode.putByte(opcode);
-                newCode.putInt(newOffset);
-                u += 5;
-                break;
-            case ClassWriter.TABL_INSN:
-                // skips 0 to 3 padding bytes
-                v = u;
-                u = u + 4 - (v & 3);
-                // reads and copies instruction
-                newCode.putByte(Opcodes.TABLESWITCH);
-                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
-                label = v + readInt(b, u);
-                u += 4;
-                newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                newCode.putInt(newOffset);
-                j = readInt(b, u);
-                u += 4;
-                newCode.putInt(j);
-                j = readInt(b, u) - j + 1;
-                u += 4;
-                newCode.putInt(readInt(b, u - 4));
-                for (; j > 0; --j) {
-                    label = v + readInt(b, u);
-                    u += 4;
-                    newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                    newCode.putInt(newOffset);
-                }
-                break;
-            case ClassWriter.LOOK_INSN:
-                // skips 0 to 3 padding bytes
-                v = u;
-                u = u + 4 - (v & 3);
-                // reads and copies instruction
-                newCode.putByte(Opcodes.LOOKUPSWITCH);
-                newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4);
-                label = v + readInt(b, u);
-                u += 4;
-                newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                newCode.putInt(newOffset);
-                j = readInt(b, u);
-                u += 4;
-                newCode.putInt(j);
-                for (; j > 0; --j) {
-                    newCode.putInt(readInt(b, u));
-                    u += 4;
-                    label = v + readInt(b, u);
-                    u += 4;
-                    newOffset = getNewOffset(allIndexes, allSizes, v, label);
-                    newCode.putInt(newOffset);
-                }
-                break;
-            case ClassWriter.WIDE_INSN:
-                opcode = b[u + 1] & 0xFF;
-                if (opcode == Opcodes.IINC) {
-                    newCode.putByteArray(b, u, 6);
-                    u += 6;
-                } else {
-                    newCode.putByteArray(b, u, 4);
-                    u += 4;
-                }
-                break;
-            case ClassWriter.VAR_INSN:
-            case ClassWriter.SBYTE_INSN:
-            case ClassWriter.LDC_INSN:
-                newCode.putByteArray(b, u, 2);
-                u += 2;
-                break;
-            case ClassWriter.SHORT_INSN:
-            case ClassWriter.LDCW_INSN:
-            case ClassWriter.FIELDORMETH_INSN:
-            case ClassWriter.TYPE_INSN:
-            case ClassWriter.IINC_INSN:
-                newCode.putByteArray(b, u, 3);
-                u += 3;
-                break;
-            case ClassWriter.ITFMETH_INSN:
-            case ClassWriter.INDYMETH_INSN:
-                newCode.putByteArray(b, u, 5);
-                u += 5;
-                break;
-            // case MANA_INSN:
-            default:
-                newCode.putByteArray(b, u, 4);
-                u += 4;
-                break;
-            }
-        }
-
-        // updates the stack map frame labels
-        if (compute == FRAMES) {
-            Label l = labels;
-            while (l != null) {
-                /*
-                 * Detects the labels that are just after an IF instruction that
-                 * has been resized with the IFNOT GOTO_W pattern. These labels
-                 * are now the target of a jump instruction (the IFNOT
-                 * instruction). Note that we need the original label position
-                 * here. getNewOffset must therefore never have been called for
-                 * this label.
-                 */
-                u = l.position - 3;
-                if (u >= 0 && resize[u]) {
-                    l.status |= Label.TARGET;
-                }
-                getNewOffset(allIndexes, allSizes, l);
-                l = l.successor;
-            }
-            // Update the offsets in the uninitialized types
-            if (cw.typeTable != null) {
-                for (i = 0; i < cw.typeTable.length; ++i) {
-                    Item item = cw.typeTable[i];
-                    if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
-                        item.intVal = getNewOffset(allIndexes, allSizes, 0,
-                                item.intVal);
-                    }
-                }
-            }
-            // The stack map frames are not serialized yet, so we don't need
-            // to update them. They will be serialized in visitMaxs.
-        } else if (frameCount > 0) {
-            /*
-             * Resizing an existing stack map frame table is really hard. Not
-             * only the table must be parsed to update the offets, but new
-             * frames may be needed for jump instructions that were inserted by
-             * this method. And updating the offsets or inserting frames can
-             * change the format of the following frames, in case of packed
-             * frames. In practice the whole table must be recomputed. For this
-             * the frames are marked as potentially invalid. This will cause the
-             * whole class to be reread and rewritten with the COMPUTE_FRAMES
-             * option (see the ClassWriter.toByteArray method). This is not very
-             * efficient but is much easier and requires much less code than any
-             * other method I can think of.
-             */
-            cw.invalidFrames = true;
-        }
-        // updates the exception handler block labels
-        Handler h = firstHandler;
-        while (h != null) {
-            getNewOffset(allIndexes, allSizes, h.start);
-            getNewOffset(allIndexes, allSizes, h.end);
-            getNewOffset(allIndexes, allSizes, h.handler);
-            h = h.next;
-        }
-        // updates the instructions addresses in the
-        // local var and line number tables
-        for (i = 0; i < 2; ++i) {
-            ByteVector bv = i == 0 ? localVar : localVarType;
-            if (bv != null) {
-                b = bv.data;
-                u = 0;
-                while (u < bv.length) {
-                    label = readUnsignedShort(b, u);
-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label);
-                    writeShort(b, u, newOffset);
-                    label += readUnsignedShort(b, u + 2);
-                    newOffset = getNewOffset(allIndexes, allSizes, 0, label)
-                            - newOffset;
-                    writeShort(b, u + 2, newOffset);
-                    u += 10;
-                }
-            }
-        }
-        if (lineNumber != null) {
-            b = lineNumber.data;
-            u = 0;
-            while (u < lineNumber.length) {
-                writeShort(
-                        b,
-                        u,
-                        getNewOffset(allIndexes, allSizes, 0,
-                                readUnsignedShort(b, u)));
-                u += 4;
-            }
-        }
-        // updates the labels of the other attributes
-        Attribute attr = cattrs;
-        while (attr != null) {
-            Label[] labels = attr.getLabels();
-            if (labels != null) {
-                for (i = labels.length - 1; i >= 0; --i) {
-                    getNewOffset(allIndexes, allSizes, labels[i]);
-                }
-            }
-            attr = attr.next;
-        }
-
-        // replaces old bytecodes with new ones
-        code = newCode;
-    }
-
-    /**
-     * Reads an unsigned short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static int readUnsignedShort(final byte[] b, final int index) {
-        return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
-    }
-
-    /**
-     * Reads a signed short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static short readShort(final byte[] b, final int index) {
-        return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
-    }
-
-    /**
-     * Reads a signed int value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            the start index of the value to be read.
-     * @return the read value.
-     */
-    static int readInt(final byte[] b, final int index) {
-        return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16)
-                | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF);
-    }
-
-    /**
-     * Writes a short value in the given byte array.
-     *
-     * @param b
-     *            a byte array.
-     * @param index
-     *            where the first byte of the short value must be written.
-     * @param s
-     *            the value to be written in the given byte array.
-     */
-    static void writeShort(final byte[] b, final int index, final int s) {
-        b[index] = (byte) (s >>> 8);
-        b[index + 1] = (byte) s;
-    }
-
-    /**
-     * Computes the future value of a bytecode offset.
-     * <p>
-     * Note: it is possible to have several entries for the same instruction in
-     * the <tt>indexes</tt> and <tt>sizes</tt>: two entries (index=a,size=b) and
-     * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b').
-     *
-     * @param indexes
-     *            current positions of the instructions to be resized. Each
-     *            instruction must be designated by the index of its <i>last</i>
-     *            byte, plus one (or, in other words, by the index of the
-     *            <i>first</i> byte of the <i>next</i> instruction).
-     * @param sizes
-     *            the number of bytes to be <i>added</i> to the above
-     *            instructions. More precisely, for each i < <tt>len</tt>,
-     *            <tt>sizes</tt>[i] bytes will be added at the end of the
-     *            instruction designated by <tt>indexes</tt>[i] or, if
-     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
-     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
-     *            (the instruction size <i>must not</i> become negative or
-     *            null).
-     * @param begin
-     *            index of the first byte of the source instruction.
-     * @param end
-     *            index of the first byte of the target instruction.
-     * @return the future value of the given bytecode offset.
-     */
-    static int getNewOffset(final int[] indexes, final int[] sizes,
-            final int begin, final int end) {
-        int offset = end - begin;
-        for (int i = 0; i < indexes.length; ++i) {
-            if (begin < indexes[i] && indexes[i] <= end) {
-                // forward jump
-                offset += sizes[i];
-            } else if (end < indexes[i] && indexes[i] <= begin) {
-                // backward jump
-                offset -= sizes[i];
-            }
-        }
-        return offset;
-    }
-
-    /**
-     * Updates the offset of the given label.
-     *
-     * @param indexes
-     *            current positions of the instructions to be resized. Each
-     *            instruction must be designated by the index of its <i>last</i>
-     *            byte, plus one (or, in other words, by the index of the
-     *            <i>first</i> byte of the <i>next</i> instruction).
-     * @param sizes
-     *            the number of bytes to be <i>added</i> to the above
-     *            instructions. More precisely, for each i < <tt>len</tt>,
-     *            <tt>sizes</tt>[i] bytes will be added at the end of the
-     *            instruction designated by <tt>indexes</tt>[i] or, if
-     *            <tt>sizes</tt>[i] is negative, the <i>last</i> |
-     *            <tt>sizes[i]</tt>| bytes of the instruction will be removed
-     *            (the instruction size <i>must not</i> become negative or
-     *            null).
-     * @param label
-     *            the label whose offset must be updated.
-     */
-    static void getNewOffset(final int[] indexes, final int[] sizes,
-            final Label label) {
-        if ((label.status & Label.RESIZED) == 0) {
-            label.position = getNewOffset(indexes, sizes, 0, label.position);
-            label.status |= Label.RESIZED;
-        }
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,219 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * A visitor to visit a Java module. The methods of this class must be called in
+ * the following order: <tt>visitMainClass</tt> | ( <tt>visitPackage</tt> |
+ * <tt>visitRequire</tt> | <tt>visitExport</tt> | <tt>visitOpen</tt> |
+ * <tt>visitUse</tt> | <tt>visitProvide</tt> )* <tt>visitEnd</tt>.
+ *
+ * The methods {@link #visitRequire(String, int, String)}, {@link #visitExport(String, int, String...)},
+ * {@link #visitOpen(String, int, String...)} and {@link #visitPackage(String)}
+ * take as parameter a package name or a module name. Unlike the other names which are internal names
+ * (names separated by slash), module and package names are qualified names (names separated by dot).
+ *
+ * @author Remi Forax
+ */
+public abstract class ModuleVisitor {
+    /**
+     * The ASM API version implemented by this visitor. The value of this field
+     * must be {@link Opcodes#ASM6}.
+     */
+    protected final int api;
+
+    /**
+     * The module visitor to which this visitor must delegate method calls. May
+     * be null.
+     */
+    protected ModuleVisitor mv;
+
+    /**
+     * Constructs a new {@link ModuleVisitor}.
+     *
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+     */
+    public ModuleVisitor(final int api) {
+        this(api, null);
+    }
+
+    /**
+     * Constructs a new {@link ModuleVisitor}.
+     *
+     * @param api
+     *            the ASM API version implemented by this visitor. Must be {@link Opcodes#ASM6}.
+     * @param mv
+     *            the module visitor to which this visitor must delegate method
+     *            calls. May be null.
+     */
+    public ModuleVisitor(final int api, final ModuleVisitor mv) {
+        if (api != Opcodes.ASM6) {
+            throw new IllegalArgumentException();
+        }
+        this.api = api;
+        this.mv = mv;
+    }
+
+    /**
+     * Visit the main class of the current module.
+     *
+     * @param mainClass the internal name of the main class of the current module.
+     */
+    public void visitMainClass(String mainClass) {
+        if (mv != null) {
+            mv.visitMainClass(mainClass);
+        }
+    }
+
+    /**
+     * Visit a package of the current module.
+     *
+     * @param packaze the qualified name of a package.
+     */
+    public void visitPackage(String packaze) {
+        if (mv != null) {
+            mv.visitPackage(packaze);
+        }
+    }
+
+    /**
+     * Visits a dependence of the current module.
+     *
+     * @param module the qualified name of the dependence.
+     * @param access the access flag of the dependence among
+     *        ACC_TRANSITIVE, ACC_STATIC_PHASE, ACC_SYNTHETIC
+     *        and ACC_MANDATED.
+     * @param version the module version at compile time or null.
+     */
+    public void visitRequire(String module, int access, String version) {
+        if (mv != null) {
+            mv.visitRequire(module, access, version);
+        }
+    }
+
+    /**
+     * Visit an exported package of the current module.
+     *
+     * @param packaze the qualified name of the exported package.
+     * @param access the access flag of the exported package,
+     *        valid values are among {@code ACC_SYNTHETIC} and
+     *        {@code ACC_MANDATED}.
+     * @param modules the qualified names of the modules that can access to
+     *        the public classes of the exported package or
+     *        <tt>null</tt>.
+     */
+    public void visitExport(String packaze, int access, String... modules) {
+        if (mv != null) {
+            mv.visitExport(packaze, access, modules);
+        }
+    }
+
+    /**
+     * Visit an open package of the current module.
+     *
+     * @param packaze the qualified name of the opened package.
+     * @param access the access flag of the opened package,
+     *        valid values are among {@code ACC_SYNTHETIC} and
+     *        {@code ACC_MANDATED}.
+     * @param modules the qualified names of the modules that can use deep
+     *        reflection to the classes of the open package or
+     *        <tt>null</tt>.
+     */
+    public void visitOpen(String packaze, int access, String... modules) {
+        if (mv != null) {
+            mv.visitOpen(packaze, access, modules);
+        }
+    }
+
+    /**
+     * Visit a service used by the current module.
+     * The name must be the internal name of an interface or a class.
+     *
+     * @param service the internal name of the service.
+     */
+    public void visitUse(String service) {
+        if (mv != null) {
+            mv.visitUse(service);
+        }
+    }
+
+    /**
+     * Visit an implementation of a service.
+     *
+     * @param service the internal name of the service
+     * @param providers the internal names of the implementations
+     *        of the service (there is at least one provider).
+     */
+    public void visitProvide(String service, String... providers) {
+        if (mv != null) {
+            mv.visitProvide(service, providers);
+        }
+    }
+
+    /**
+     * Visits the end of the module. This method, which is the last one to be
+     * called, is used to inform the visitor that everything have been visited.
+     */
+    public void visitEnd() {
+        if (mv != null) {
+            mv.visitEnd();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/ModuleWriter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,322 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm;
+
+/**
+ * @author Remi Forax
+ */
+final class ModuleWriter extends ModuleVisitor {
+    /**
+     * The class writer to which this Module attribute must be added.
+     */
+    private final ClassWriter cw;
+
+    /**
+     * size in byte of the Module attribute.
+     */
+    int size;
+
+    /**
+     * Number of attributes associated with the current module
+     * (Version, ConcealPackages, etc)
+     */
+    int attributeCount;
+
+    /**
+     * Size in bytes of the attributes associated with the current module
+     */
+    int attributesSize;
+
+    /**
+     * module name index in the constant pool
+     */
+    private final int name;
+
+    /**
+     * module access flags
+     */
+    private final int access;
+
+    /**
+     * module version index in the constant pool or 0
+     */
+    private final int version;
+
+    /**
+     * module main class index in the constant pool or 0
+     */
+    private int mainClass;
+
+    /**
+     * number of packages
+     */
+    private int packageCount;
+
+    /**
+     * The packages in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in packageCount
+     */
+    private ByteVector packages;
+
+    /**
+     * number of requires items
+     */
+    private int requireCount;
+
+    /**
+     * The requires items in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in requireCount
+     */
+    private ByteVector requires;
+
+    /**
+     * number of exports items
+     */
+    private int exportCount;
+
+    /**
+     * The exports items in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in exportCount
+     */
+    private ByteVector exports;
+
+    /**
+     * number of opens items
+     */
+    private int openCount;
+
+    /**
+     * The opens items in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in openCount
+     */
+    private ByteVector opens;
+
+    /**
+     * number of uses items
+     */
+    private int useCount;
+
+    /**
+     * The uses items in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in useCount
+     */
+    private ByteVector uses;
+
+    /**
+     * number of provides items
+     */
+    private int provideCount;
+
+    /**
+     * The uses provides in bytecode form. This byte vector only contains
+     * the items themselves, the number of items is store in provideCount
+     */
+    private ByteVector provides;
+
+    ModuleWriter(final ClassWriter cw, final int name,
+            final int access, final int version) {
+        super(Opcodes.ASM6);
+        this.cw = cw;
+        this.size = 16;  // name + access + version + 5 counts
+        this.name = name;
+        this.access = access;
+        this.version = version;
+    }
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        if (this.mainClass == 0) { // protect against several calls to visitMainClass
+            cw.newUTF8("ModuleMainClass");
+            attributeCount++;
+            attributesSize += 8;
+        }
+        this.mainClass = cw.newClass(mainClass);
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        if (packages == null) {
+            // protect against several calls to visitPackage
+            cw.newUTF8("ModulePackages");
+            packages = new ByteVector();
+            attributeCount++;
+            attributesSize += 8;
+        }
+        packages.putShort(cw.newPackage(packaze));
+        packageCount++;
+        attributesSize += 2;
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        if (requires == null) {
+            requires = new ByteVector();
+        }
+        requires.putShort(cw.newModule(module))
+                .putShort(access)
+                .putShort(version == null? 0: cw.newUTF8(version));
+        requireCount++;
+        size += 6;
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        if (exports == null) {
+            exports = new ByteVector();
+        }
+        exports.putShort(cw.newPackage(packaze)).putShort(access);
+        if (modules == null) {
+            exports.putShort(0);
+            size += 6;
+        } else {
+            exports.putShort(modules.length);
+            for(String module: modules) {
+                exports.putShort(cw.newModule(module));
+            }
+            size += 6 + 2 * modules.length;
+        }
+        exportCount++;
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        if (opens == null) {
+            opens = new ByteVector();
+        }
+        opens.putShort(cw.newPackage(packaze)).putShort(access);
+        if (modules == null) {
+            opens.putShort(0);
+            size += 6;
+        } else {
+            opens.putShort(modules.length);
+            for(String module: modules) {
+                opens.putShort(cw.newModule(module));
+            }
+            size += 6 + 2 * modules.length;
+        }
+        openCount++;
+    }
+
+    @Override
+    public void visitUse(String service) {
+        if (uses == null) {
+            uses = new ByteVector();
+        }
+        uses.putShort(cw.newClass(service));
+        useCount++;
+        size += 2;
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        if (provides == null) {
+            provides = new ByteVector();
+        }
+        provides.putShort(cw.newClass(service));
+        provides.putShort(providers.length);
+        for(String provider: providers) {
+            provides.putShort(cw.newClass(provider));
+        }
+        provideCount++;
+        size += 4 + 2 * providers.length;
+    }
+
+    @Override
+    public void visitEnd() {
+        // empty
+    }
+
+    void putAttributes(ByteVector out) {
+        if (mainClass != 0) {
+            out.putShort(cw.newUTF8("ModuleMainClass")).putInt(2).putShort(mainClass);
+        }
+        if (packages != null) {
+            out.putShort(cw.newUTF8("ModulePackages"))
+               .putInt(2 + 2 * packageCount)
+               .putShort(packageCount)
+               .putByteArray(packages.data, 0, packages.length);
+        }
+    }
+
+    void put(ByteVector out) {
+        out.putInt(size);
+        out.putShort(name).putShort(access).putShort(version);
+        out.putShort(requireCount);
+        if (requires != null) {
+            out.putByteArray(requires.data, 0, requires.length);
+        }
+        out.putShort(exportCount);
+        if (exports != null) {
+            out.putByteArray(exports.data, 0, exports.length);
+        }
+        out.putShort(openCount);
+        if (opens != null) {
+            out.putByteArray(opens.data, 0, opens.length);
+        }
+        out.putShort(useCount);
+        if (uses != null) {
+            out.putByteArray(uses.data, 0, uses.length);
+        }
+        out.putShort(provideCount);
+        if (provides != null) {
+            out.putByteArray(provides.data, 0, provides.length);
+        }
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Opcodes.java	Thu Nov 02 13:18:23 2017 -0700
@@ -70,13 +70,13 @@
  * @author Eric Bruneton
  * @author Eugene Kuleshov
  */
-@SuppressWarnings("deprecation") // for Integer(int) constructor
 public interface Opcodes {
 
     // ASM API versions
 
     int ASM4 = 4 << 16 | 0 << 8 | 0;
     int ASM5 = 5 << 16 | 0 << 8 | 0;
+    int ASM6 = 6 << 16 | 0 << 8 | 0;
 
     // versions
 
@@ -88,7 +88,7 @@
     int V1_6 = 0 << 16 | 50;
     int V1_7 = 0 << 16 | 51;
     int V1_8 = 0 << 16 | 52;
-    int V1_9 = 0 << 16 | 53;
+    int V9 = 0 << 16 | 53;
 
     // access flags
 
@@ -99,18 +99,23 @@
     int ACC_FINAL = 0x0010; // class, field, method, parameter
     int ACC_SUPER = 0x0020; // class
     int ACC_SYNCHRONIZED = 0x0020; // method
+    int ACC_OPEN = 0x0020; // module
+    int ACC_TRANSITIVE = 0x0020; // module requires
     int ACC_VOLATILE = 0x0040; // field
     int ACC_BRIDGE = 0x0040; // method
+    int ACC_STATIC_PHASE = 0x0040; // module requires
     int ACC_VARARGS = 0x0080; // method
     int ACC_TRANSIENT = 0x0080; // field
     int ACC_NATIVE = 0x0100; // method
     int ACC_INTERFACE = 0x0200; // class
     int ACC_ABSTRACT = 0x0400; // class, method
     int ACC_STRICT = 0x0800; // method
-    int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
+    int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter, module *
     int ACC_ANNOTATION = 0x2000; // class
     int ACC_ENUM = 0x4000; // class(?) field inner
-    int ACC_MANDATED = 0x8000; // parameter
+    int ACC_MANDATED = 0x8000; // parameter, module, module *
+    int ACC_MODULE = 0x8000; // class
+
 
     // ASM specific pseudo access flags
 
@@ -177,15 +182,17 @@
      */
     int F_SAME1 = 4;
 
-    // For reference comparison purposes, construct new instances
-    // instead of using valueOf() or autoboxing.
-    Integer TOP = new Integer(0);
-    Integer INTEGER = new Integer(1);
-    Integer FLOAT = new Integer(2);
-    Integer DOUBLE = new Integer(3);
-    Integer LONG = new Integer(4);
-    Integer NULL = new Integer(5);
-    Integer UNINITIALIZED_THIS = new Integer(6);
+    // Do not try to change the following code to use auto-boxing,
+    // these values are compared by reference and not by value
+    // The constructor of Integer was deprecated in 9
+    // but we are stuck with it by backward compatibility
+    @SuppressWarnings("deprecation") Integer TOP = new Integer(0);
+    @SuppressWarnings("deprecation") Integer INTEGER = new Integer(1);
+    @SuppressWarnings("deprecation") Integer FLOAT = new Integer(2);
+    @SuppressWarnings("deprecation") Integer DOUBLE = new Integer(3);
+    @SuppressWarnings("deprecation") Integer LONG = new Integer(4);
+    @SuppressWarnings("deprecation") Integer NULL = new Integer(5);
+    @SuppressWarnings("deprecation") Integer UNINITIALIZED_THIS = new Integer(6);
 
     // opcodes // visit method (- = idem)
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java	Thu Nov 02 13:18:23 2017 -0700
@@ -406,7 +406,16 @@
      */
     public static Type getReturnType(final String methodDescriptor) {
         char[] buf = methodDescriptor.toCharArray();
-        return getType(buf, methodDescriptor.indexOf(')') + 1);
+        int off = 1;
+        while (true) {
+            char car = buf[off++];
+            if (car == ')') {
+                return getType(buf, off);
+            } else if (car == 'L') {
+                while (buf[off++] != ';') {
+                }
+            }
+        }
     }
 
     /**
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AdviceAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -112,7 +112,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this adapter delegates calls.
      * @param access
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -170,7 +170,7 @@
      */
     public AnalyzerAdapter(final String owner, final int access,
             final String name, final String desc, final MethodVisitor mv) {
-        this(Opcodes.ASM5, owner, access, name, desc, mv);
+        this(Opcodes.ASM6, owner, access, name, desc, mv);
         if (getClass() != AnalyzerAdapter.class) {
             throw new IllegalStateException();
         }
@@ -181,7 +181,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param owner
      *            the owner's class name.
      * @param access
@@ -690,6 +690,8 @@
             t1 = pop();
             if (t1 instanceof String) {
                 pushDesc(((String) t1).substring(1));
+            } else if (t1 == Opcodes.NULL) {
+                push(t1);
             } else {
                 push("java/lang/Object");
             }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/AnnotationRemapper.java	Thu Nov 02 13:18:23 2017 -0700
@@ -73,7 +73,7 @@
 
     public AnnotationRemapper(final AnnotationVisitor av,
             final Remapper remapper) {
-        this(Opcodes.ASM5, av, remapper);
+        this(Opcodes.ASM6, av, remapper);
     }
 
     protected AnnotationRemapper(final int api, final AnnotationVisitor av,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ClassRemapper.java	Thu Nov 02 13:18:23 2017 -0700
@@ -59,10 +59,14 @@
 
 package jdk.internal.org.objectweb.asm.commons;
 
+import java.util.List;
+
 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
+import jdk.internal.org.objectweb.asm.Attribute;
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.TypePath;
 
@@ -78,7 +82,7 @@
     protected String className;
 
     public ClassRemapper(final ClassVisitor cv, final Remapper remapper) {
-        this(Opcodes.ASM5, cv, remapper);
+        this(Opcodes.ASM6, cv, remapper);
     }
 
     protected ClassRemapper(final int api, final ClassVisitor cv,
@@ -97,6 +101,12 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(String name, int flags, String version) {
+        ModuleVisitor mv = super.visitModule(remapper.mapModuleName(name), flags, version);
+        return mv == null ? null : createModuleRemapper(mv);
+    }
+
+    @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
                 visible);
@@ -112,6 +122,18 @@
     }
 
     @Override
+    public void visitAttribute(Attribute attr) {
+        if (attr instanceof ModuleHashesAttribute) {
+            ModuleHashesAttribute hashesAttr = new ModuleHashesAttribute();
+            List<String> modules = hashesAttr.modules;
+            for(int i = 0; i < modules.size(); i++) {
+                modules.set(i, remapper.mapModuleName(modules.get(i)));
+            }
+        }
+        super.visitAttribute(attr);
+    }
+
+    @Override
     public FieldVisitor visitField(int access, String name, String desc,
             String signature, Object value) {
         FieldVisitor fv = super.visitField(access,
@@ -158,4 +180,8 @@
     protected AnnotationVisitor createAnnotationRemapper(AnnotationVisitor av) {
         return new AnnotationRemapper(av, remapper);
     }
+
+    protected ModuleVisitor createModuleRemapper(ModuleVisitor mv) {
+        return new ModuleRemapper(mv, remapper);
+    }
 }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java	Thu Nov 02 13:18:23 2017 -0700
@@ -75,7 +75,7 @@
     private int maxSize;
 
     public CodeSizeEvaluator(final MethodVisitor mv) {
-        this(Opcodes.ASM5, mv);
+        this(Opcodes.ASM6, mv);
     }
 
     protected CodeSizeEvaluator(final int api, final MethodVisitor mv) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/FieldRemapper.java	Thu Nov 02 13:18:23 2017 -0700
@@ -74,7 +74,7 @@
     private final Remapper remapper;
 
     public FieldRemapper(final FieldVisitor fv, final Remapper remapper) {
-        this(Opcodes.ASM5, fv, remapper);
+        this(Opcodes.ASM6, fv, remapper);
     }
 
     protected FieldRemapper(final int api, final FieldVisitor fv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/GeneratorAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -289,7 +289,7 @@
      */
     public GeneratorAdapter(final MethodVisitor mv, final int access,
             final String name, final String desc) {
-        this(Opcodes.ASM5, mv, access, name, desc);
+        this(Opcodes.ASM6, mv, access, name, desc);
         if (getClass() != GeneratorAdapter.class) {
             throw new IllegalStateException();
         }
@@ -300,7 +300,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this adapter delegates calls.
      * @param access
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -86,7 +86,7 @@
      *             If a subclass calls this constructor.
      */
     public InstructionAdapter(final MethodVisitor mv) {
-        this(Opcodes.ASM5, mv);
+        this(Opcodes.ASM6, mv);
         if (getClass() != InstructionAdapter.class) {
             throw new IllegalStateException();
         }
@@ -97,7 +97,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this adapter delegates calls.
      */
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/JSRInlinerAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -142,7 +142,7 @@
     public JSRInlinerAdapter(final MethodVisitor mv, final int access,
             final String name, final String desc, final String signature,
             final String[] exceptions) {
-        this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+        this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
         if (getClass() != JSRInlinerAdapter.class) {
             throw new IllegalStateException();
         }
@@ -153,7 +153,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param mv
      *            the <code>MethodVisitor</code> to send the resulting inlined
      *            method code to (use <code>null</code> for none).
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -120,7 +120,7 @@
      */
     public LocalVariablesSorter(final int access, final String desc,
             final MethodVisitor mv) {
-        this(Opcodes.ASM5, access, desc, mv);
+        this(Opcodes.ASM6, access, desc, mv);
         if (getClass() != LocalVariablesSorter.class) {
             throw new IllegalStateException();
         }
@@ -131,7 +131,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param access
      *            access flags of the adapted method.
      * @param desc
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/MethodRemapper.java	Thu Nov 02 13:18:23 2017 -0700
@@ -76,7 +76,7 @@
     protected final Remapper remapper;
 
     public MethodRemapper(final MethodVisitor mv, final Remapper remapper) {
-        this(Opcodes.ASM5, mv, remapper);
+        this(Opcodes.ASM6, mv, remapper);
     }
 
     protected MethodRemapper(final int api, final MethodVisitor mv,
@@ -122,18 +122,20 @@
     }
 
     private Object[] remapEntries(int n, Object[] entries) {
-        for (int i = 0; i < n; i++) {
-            if (entries[i] instanceof String) {
-                Object[] newEntries = new Object[n];
-                if (i > 0) {
-                    System.arraycopy(entries, 0, newEntries, 0, i);
+        if (entries != null) {
+            for (int i = 0; i < n; i++) {
+                if (entries[i] instanceof String) {
+                    Object[] newEntries = new Object[n];
+                    if (i > 0) {
+                        System.arraycopy(entries, 0, newEntries, 0, i);
+                    }
+                    do {
+                        Object t = entries[i];
+                        newEntries[i++] = t instanceof String ? remapper
+                                .mapType((String) t) : t;
+                    } while (i < n);
+                    return newEntries;
                 }
-                do {
-                    Object t = entries[i];
-                    newEntries[i++] = t instanceof String ? remapper
-                            .mapType((String) t) : t;
-                } while (i < n);
-                return newEntries;
             }
         }
         return entries;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleHashesAttribute.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,155 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleHashes attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleHashesAttribute extends Attribute {
+    public String algorithm;
+    public List<String> modules;
+    public List<byte[]> hashes;
+
+    /**
+     * Creates an attribute with a hashing algorithm, a list of module names,
+     * and a list of the same length of hashes.
+     * @param algorithm the hashing algorithm name.
+     * @param modules a list of module name
+     * @param hashes a list of hash, one for each module name.
+     */
+    public ModuleHashesAttribute(final String algorithm,
+            final List<String> modules, final List<byte[]> hashes) {
+        super("ModuleHashes");
+        this.algorithm = algorithm;
+        this.modules = modules;
+        this.hashes = hashes;
+    }
+
+    /**
+     * Creates an empty attribute that can be used as prototype
+     * to be passed as argument of the method
+     * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+     */
+    public ModuleHashesAttribute() {
+        this(null, null, null);
+    }
+
+    @Override
+    protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+            int codeOff, Label[] labels) {
+        String hashAlgorithm = cr.readUTF8(off, buf);
+
+        int count = cr.readUnsignedShort(off + 2);
+        ArrayList<String> modules = new ArrayList<String>(count);
+        ArrayList<byte[]> hashes = new ArrayList<byte[]>(count);
+        off += 4;
+
+        for (int i = 0; i < count; i++) {
+            String module = cr.readModule(off, buf);
+            int hashLength = cr.readUnsignedShort(off + 2);
+            off += 4;
+
+            byte[] hash = new byte[hashLength];
+            for (int j = 0; j < hashLength; j++) {
+                hash[j] = (byte) (cr.readByte(off + j) & 0xff);
+            }
+            off += hashLength;
+
+            modules.add(module);
+            hashes.add(hash);
+        }
+        return new ModuleHashesAttribute(hashAlgorithm, modules, hashes);
+    }
+
+    @Override
+    protected ByteVector write(ClassWriter cw, byte[] code, int len,
+            int maxStack, int maxLocals) {
+        ByteVector v = new ByteVector();
+        int index = cw.newUTF8(algorithm);
+        v.putShort(index);
+
+        int count = (modules == null)? 0: modules.size();
+        v.putShort(count);
+
+        for(int i = 0; i < count; i++) {
+            String module = modules.get(i);
+            v.putShort(cw.newModule(module));
+
+            byte[] hash = hashes.get(i);
+            v.putShort(hash.length);
+            for(byte b: hash) {
+                v.putByte(b);
+            }
+        }
+        return v;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleRemapper.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,135 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} adapter for type remapping.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRemapper extends ModuleVisitor {
+    private final Remapper remapper;
+
+    public ModuleRemapper(final ModuleVisitor mv, final Remapper remapper) {
+        this(Opcodes.ASM6, mv, remapper);
+    }
+
+    protected ModuleRemapper(final int api, final ModuleVisitor mv,
+            final Remapper remapper) {
+        super(api, mv);
+        this.remapper = remapper;
+    }
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        super.visitMainClass(remapper.mapType(mainClass));
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        super.visitPackage(remapper.mapPackageName(packaze));
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        super.visitRequire(remapper.mapModuleName(module), access, version);
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        String[] newModules = null;
+        if (modules != null) {
+            newModules = new String[modules.length];
+            for (int i = 0 ; i < modules.length; i++) {
+                newModules[i] = remapper.mapModuleName(modules[i]);
+            }
+        }
+        super.visitExport(remapper.mapPackageName(packaze), access, newModules);
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        String[] newModules = null;
+        if (modules != null) {
+            newModules = new String[modules.length];
+            for (int i = 0 ; i < modules.length; i++) {
+                newModules[i] = remapper.mapModuleName(modules[i]);
+            }
+        }
+        super.visitOpen(remapper.mapPackageName(packaze), access, newModules);
+    }
+
+    @Override
+    public void visitUse(String service) {
+        super.visitUse(remapper.mapType(service));
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        String[] newProviders = new String[providers.length];
+        for (int i = 0 ; i < providers.length; i++) {
+            newProviders[i] = remapper.mapType(providers[i]);
+        }
+        super.visitProvide(remapper.mapType(service), newProviders);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleResolutionAttribute.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,135 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleResolution_attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleResolutionAttribute extends Attribute {
+    /**
+     * Resolution state of a module meaning that the module is not available
+     * from the class-path by default.
+     */
+    public static final int RESOLUTION_DO_NOT_RESOLVE_BY_DEFAULT = 1;
+
+    /**
+     * Resolution state of a module meaning the module is marked as deprecated.
+     */
+    public static final int RESOLUTION_WARN_DEPRECATED = 2;
+
+    /**
+     * Resolution state of a module meaning the module is marked as deprecated
+     * and will be removed in a future release.
+     */
+    public static final int RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL = 4;
+
+    /**
+     * Resolution state of a module meaning the module is not yet standardized,
+     * so in incubating mode.
+     */
+    public static final int RESOLUTION_WARN_INCUBATING = 8;
+
+    public int resolution;
+
+    /**
+     * Creates an attribute with a resolution state value.
+     * @param resolution the resolution state among
+     *        {@link #RESOLUTION_WARN_DEPRECATED},
+     *        {@link #RESOLUTION_WARN_DEPRECATED_FOR_REMOVAL}, and
+     *        {@link #RESOLUTION_WARN_INCUBATING}.
+     */
+    public ModuleResolutionAttribute(final int resolution) {
+        super("ModuleResolution");
+        this.resolution = resolution;
+    }
+
+    /**
+     * Creates an empty attribute that can be used as prototype
+     * to be passed as argument of the method
+     * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+     */
+    public ModuleResolutionAttribute() {
+        this(0);
+    }
+
+    @Override
+    protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+            int codeOff, Label[] labels) {
+        int resolution = cr.readUnsignedShort(off);
+        return new ModuleResolutionAttribute(resolution);
+    }
+
+    @Override
+    protected ByteVector write(ClassWriter cw, byte[] code, int len,
+            int maxStack, int maxLocals) {
+        ByteVector v = new ByteVector();
+        v.putShort(resolution);
+        return v;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/ModuleTargetAttribute.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,110 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package jdk.internal.org.objectweb.asm.commons;
+
+import jdk.internal.org.objectweb.asm.Attribute;
+import jdk.internal.org.objectweb.asm.ByteVector;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+
+/**
+ * ModuleTarget attribute.
+ * This attribute is specific to the OpenJDK and may change in the future.
+ *
+ * @author Remi Forax
+ */
+public final class ModuleTargetAttribute extends Attribute {
+    public String platform;
+
+    /**
+     * Creates an attribute with a platform name.
+     * @param platform the platform name on which the module can run.
+     */
+    public ModuleTargetAttribute(final String platform) {
+        super("ModuleTarget");
+        this.platform = platform;
+    }
+
+    /**
+     * Creates an empty attribute that can be used as prototype
+     * to be passed as argument of the method
+     * {@link ClassReader#accept(org.objectweb.asm.ClassVisitor, Attribute[], int)}.
+     */
+    public ModuleTargetAttribute() {
+        this(null);
+    }
+
+    @Override
+    protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+            int codeOff, Label[] labels) {
+        String platform = cr.readUTF8(off, buf);
+        return new ModuleTargetAttribute(platform);
+    }
+
+    @Override
+    protected ByteVector write(ClassWriter cw, byte[] code, int len,
+            int maxStack, int maxLocals) {
+        ByteVector v = new ByteVector();
+        int index = (platform == null)? 0: cw.newUTF8(platform);
+        v.putShort(index);
+        return v;
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/Remapper.java	Thu Nov 02 13:18:23 2017 -0700
@@ -255,6 +255,28 @@
     }
 
     /**
+     * Map package name to the new name. Subclasses can override.
+     *
+     * @param name name of the package
+     * @return new name of the package
+     */
+    public String mapPackageName(String name) {
+        String fakeName = map(name + ".FakeClassName");
+        int index;
+        return fakeName == null || (index = fakeName.lastIndexOf('.')) == -1 ? name: fakeName.substring(0, index);
+    }
+
+    /**
+     * Map module name to the new name. Subclasses can override.
+     *
+     * @param name name of the module
+     * @return new name of the module
+     */
+    public String mapModuleName(String name) {
+        return name;
+    }
+
+    /**
      * Map type name to the new name. Subclasses can override.
      *
      * @param typeName
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingAnnotationAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -75,7 +75,7 @@
 
     public RemappingAnnotationAdapter(final AnnotationVisitor av,
             final Remapper remapper) {
-        this(Opcodes.ASM5, av, remapper);
+        this(Opcodes.ASM6, av, remapper);
     }
 
     protected RemappingAnnotationAdapter(final int api,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingClassAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -63,6 +63,7 @@
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.TypePath;
 
@@ -80,7 +81,7 @@
     protected String className;
 
     public RemappingClassAdapter(final ClassVisitor cv, final Remapper remapper) {
-        this(Opcodes.ASM5, cv, remapper);
+        this(Opcodes.ASM6, cv, remapper);
     }
 
     protected RemappingClassAdapter(final int api, final ClassVisitor cv,
@@ -99,6 +100,11 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(String name, int flags, String version) {
+        throw new RuntimeException("RemappingClassAdapter is deprecated, use ClassRemapper instead");
+    }
+
+    @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc),
                 visible);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingFieldAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -76,7 +76,7 @@
     private final Remapper remapper;
 
     public RemappingFieldAdapter(final FieldVisitor fv, final Remapper remapper) {
-        this(Opcodes.ASM5, fv, remapper);
+        this(Opcodes.ASM6, fv, remapper);
     }
 
     protected RemappingFieldAdapter(final int api, final FieldVisitor fv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -79,7 +79,7 @@
 
     public RemappingMethodAdapter(final int access, final String desc,
             final MethodVisitor mv, final Remapper remapper) {
-        this(Opcodes.ASM5, access, desc, mv, remapper);
+        this(Opcodes.ASM6, access, desc, mv, remapper);
     }
 
     protected RemappingMethodAdapter(final int api, final int access,
@@ -125,18 +125,20 @@
     }
 
     private Object[] remapEntries(int n, Object[] entries) {
-        for (int i = 0; i < n; i++) {
-            if (entries[i] instanceof String) {
-                Object[] newEntries = new Object[n];
-                if (i > 0) {
-                    System.arraycopy(entries, 0, newEntries, 0, i);
+        if (entries != null) {
+            for (int i = 0; i < n; i++) {
+                if (entries[i] instanceof String) {
+                    Object[] newEntries = new Object[n];
+                    if (i > 0) {
+                        System.arraycopy(entries, 0, newEntries, 0, i);
+                    }
+                    do {
+                        Object t = entries[i];
+                        newEntries[i++] = t instanceof String ? remapper
+                                .mapType((String) t) : t;
+                    } while (i < n);
+                    return newEntries;
                 }
-                do {
-                    Object t = entries[i];
-                    newEntries[i++] = t instanceof String ? remapper
-                            .mapType((String) t) : t;
-                } while (i < n);
-                return newEntries;
             }
         }
         return entries;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingSignatureAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -79,7 +79,7 @@
 
     public RemappingSignatureAdapter(final SignatureVisitor v,
             final Remapper remapper) {
-        this(Opcodes.ASM5, v, remapper);
+        this(Opcodes.ASM6, v, remapper);
     }
 
     protected RemappingSignatureAdapter(final int api,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SerialVersionUIDAdder.java	Thu Nov 02 13:18:23 2017 -0700
@@ -80,7 +80,7 @@
  *   ClassWriter cw = new ClassWriter(...);
  *   ClassVisitor sv = new SerialVersionUIDAdder(cw);
  *   ClassVisitor ca = new MyClassAdapter(sv);
- *   new ClassReader(originalClass).accept(ca, false);
+ *   new ClassReader(orginalClass).accept(ca, false);
  * </pre>
  *
  * The SVUID algorithm can be found <a href=
@@ -199,7 +199,7 @@
      *             If a subclass calls this constructor.
      */
     public SerialVersionUIDAdder(final ClassVisitor cv) {
-        this(Opcodes.ASM5, cv);
+        this(Opcodes.ASM6, cv);
         if (getClass() != SerialVersionUIDAdder.class) {
             throw new IllegalStateException();
         }
@@ -210,7 +210,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param cv
      *            a {@link ClassVisitor} to which this visitor will delegate
      *            calls.
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/SignatureRemapper.java	Thu Nov 02 13:18:23 2017 -0700
@@ -78,7 +78,7 @@
     private Stack<String> classNames = new Stack<String>();
 
     public SignatureRemapper(final SignatureVisitor v, final Remapper remapper) {
-        this(Opcodes.ASM5, v, remapper);
+        this(Opcodes.ASM6, v, remapper);
     }
 
     protected SignatureRemapper(final int api, final SignatureVisitor v,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/StaticInitMerger.java	Thu Nov 02 13:18:23 2017 -0700
@@ -78,7 +78,7 @@
     private int counter;
 
     public StaticInitMerger(final String prefix, final ClassVisitor cv) {
-        this(Opcodes.ASM5, prefix, cv);
+        this(Opcodes.ASM6, prefix, cv);
     }
 
     protected StaticInitMerger(final int api, final String prefix,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/TryCatchBlockSorter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -86,7 +86,7 @@
     public TryCatchBlockSorter(final MethodVisitor mv, final int access,
             final String name, final String desc, final String signature,
             final String[] exceptions) {
-        this(Opcodes.ASM5, mv, access, name, desc, signature, exceptions);
+        this(Opcodes.ASM6, mv, access, name, desc, signature, exceptions);
     }
 
     protected TryCatchBlockSorter(final int api, final MethodVisitor mv,
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -102,7 +102,7 @@
 
     /**
      * The ASM API version implemented by this visitor. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -111,10 +111,10 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public SignatureVisitor(final int api) {
-        if (api != Opcodes.ASM4 && api != Opcodes.ASM5) {
+        if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
             throw new IllegalArgumentException();
         }
         this.api = api;
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/signature/SignatureWriter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -95,7 +95,7 @@
      * Constructs a new {@link SignatureWriter} object.
      */
     public SignatureWriter() {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
     }
 
     // ------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/AnnotationNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -65,7 +65,7 @@
 import jdk.internal.org.objectweb.asm.Opcodes;
 
 /**
- * A node that represents an annotationn.
+ * A node that represents an annotation.
  *
  * @author Eric Bruneton
  */
@@ -81,8 +81,8 @@
      * as two consecutive elements in the list. The name is a {@link String},
      * and the value may be a {@link Byte}, {@link Boolean}, {@link Character},
      * {@link Short}, {@link Integer}, {@link Long}, {@link Float},
-     * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or an
-     * two elements String array (for enumeration values), a
+     * {@link Double}, {@link String} or {@link jdk.internal.org.objectweb.asm.Type}, or a
+     * two elements String array (for enumeration values), an
      * {@link AnnotationNode}, or a {@link List} of values of one of the
      * preceding types. The list may be <tt>null</tt> if there is no name value
      * pair.
@@ -100,7 +100,7 @@
      *             If a subclass calls this constructor.
      */
     public AnnotationNode(final String desc) {
-        this(Opcodes.ASM5, desc);
+        this(Opcodes.ASM6, desc);
         if (getClass() != AnnotationNode.class) {
             throw new IllegalStateException();
         }
@@ -111,7 +111,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param desc
      *            the class descriptor of the annotation class.
      */
@@ -127,7 +127,7 @@
      *            where the visited values must be stored.
      */
     AnnotationNode(final List<Object> values) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         this.values = values;
     }
 
@@ -143,7 +143,65 @@
         if (this.desc != null) {
             values.add(name);
         }
-        values.add(value);
+        if (value instanceof byte[]) {
+            byte[] v = (byte[]) value;
+            ArrayList<Byte> l = new ArrayList<Byte>(v.length);
+            for (byte b : v) {
+                l.add(b);
+            }
+            values.add(l);
+        } else if (value instanceof boolean[]) {
+            boolean[] v = (boolean[]) value;
+            ArrayList<Boolean> l = new ArrayList<Boolean>(v.length);
+            for (boolean b : v) {
+                l.add(b);
+            }
+            values.add(l);
+        } else if (value instanceof short[]) {
+            short[] v = (short[]) value;
+            ArrayList<Short> l = new ArrayList<Short>(v.length);
+            for (short s : v) {
+                l.add(s);
+            }
+            values.add(l);
+        } else if (value instanceof char[]) {
+            char[] v = (char[]) value;
+            ArrayList<Character> l = new ArrayList<Character>(v.length);
+            for (char c : v) {
+                l.add(c);
+            }
+            values.add(l);
+        } else if (value instanceof int[]) {
+            int[] v = (int[]) value;
+            ArrayList<Integer> l = new ArrayList<Integer>(v.length);
+            for (int i : v) {
+                l.add(i);
+            }
+            values.add(l);
+        } else if (value instanceof long[]) {
+            long[] v = (long[]) value;
+            ArrayList<Long> l = new ArrayList<Long>(v.length);
+            for (long lng : v) {
+                l.add(lng);
+            }
+            values.add(l);
+        } else if (value instanceof float[]) {
+            float[] v = (float[]) value;
+            ArrayList<Float> l = new ArrayList<Float>(v.length);
+            for (float f : v) {
+                l.add(f);
+            }
+            values.add(l);
+        } else if (value instanceof double[]) {
+            double[] v = (double[]) value;
+            ArrayList<Double> l = new ArrayList<Double>(v.length);
+            for (double d : v) {
+                l.add(d);
+            }
+            values.add(l);
+        } else {
+            values.add(value);
+        }
     }
 
     @Override
@@ -200,8 +258,8 @@
      * versions of the ASM API than the given version.
      *
      * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
-     *            {@link Opcodes#ASM5}.
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
+     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public void check(final int api) {
         // nothing to do
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ClassNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -67,6 +67,7 @@
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.TypePath;
 
@@ -127,6 +128,11 @@
     public String sourceDebug;
 
     /**
+     * Module information. May be <tt>null</tt>.
+     */
+    public ModuleNode module;
+
+    /**
      * The internal name of the enclosing class of the class. May be
      * <tt>null</tt>.
      */
@@ -221,7 +227,7 @@
      *             If a subclass calls this constructor.
      */
     public ClassNode() {
-        this(Opcodes.ASM5);
+        this(Opcodes.ASM6);
         if (getClass() != ClassNode.class) {
             throw new IllegalStateException();
         }
@@ -232,7 +238,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public ClassNode(final int api) {
         super(api);
@@ -267,6 +273,12 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(final String name, final int access,
+            final String version) {
+        return module = new ModuleNode(name, access, version);
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         outerClass = owner;
@@ -358,11 +370,16 @@
      * API than the given version.
      *
      * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
-     *            {@link Opcodes#ASM5}.
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
+     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public void check(final int api) {
-        if (api == Opcodes.ASM4) {
+        if (api < Opcodes.ASM6) {
+            if (module != null) {
+                throw new RuntimeException();
+            }
+        }
+        if (api < Opcodes.ASM5) {
             if (visibleTypeAnnotations != null
                     && visibleTypeAnnotations.size() > 0) {
                 throw new RuntimeException();
@@ -371,12 +388,31 @@
                     && invisibleTypeAnnotations.size() > 0) {
                 throw new RuntimeException();
             }
-            for (FieldNode f : fields) {
-                f.check(api);
-            }
-            for (MethodNode m : methods) {
-                m.check(api);
-            }
+        }
+        // checks attributes
+        int i, n;
+        n = visibleAnnotations == null ? 0 : visibleAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            visibleAnnotations.get(i).check(api);
+        }
+        n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            invisibleAnnotations.get(i).check(api);
+        }
+        n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size();
+        for (i = 0; i < n; ++i) {
+            visibleTypeAnnotations.get(i).check(api);
+        }
+        n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations
+                .size();
+        for (i = 0; i < n; ++i) {
+            invisibleTypeAnnotations.get(i).check(api);
+        }
+        for (FieldNode f : fields) {
+            f.check(api);
+        }
+        for (MethodNode m : methods) {
+            m.check(api);
         }
     }
 
@@ -395,6 +431,10 @@
         if (sourceFile != null || sourceDebug != null) {
             cv.visitSource(sourceFile, sourceDebug);
         }
+        // visits module
+        if (module != null) {
+            module.accept(cv);
+        }
         // visits outer class
         if (outerClass != null) {
             cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/FieldNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -173,7 +173,7 @@
      */
     public FieldNode(final int access, final String name, final String desc,
             final String signature, final Object value) {
-        this(Opcodes.ASM5, access, name, desc, signature, value);
+        this(Opcodes.ASM6, access, name, desc, signature, value);
         if (getClass() != FieldNode.class) {
             throw new IllegalStateException();
         }
@@ -276,8 +276,8 @@
      * API than the given version.
      *
      * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
-     *            {@link Opcodes#ASM5}.
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
+     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public void check(final int api) {
         if (api == Opcodes.ASM4) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/InsnList.java	Thu Nov 02 13:18:23 2017 -0700
@@ -634,14 +634,28 @@
         }
 
         public void add(Object o) {
-            InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+            if (next != null) {
+                InsnList.this.insertBefore(next, (AbstractInsnNode) o);
+            } else if (prev != null) {
+                InsnList.this.insert(prev, (AbstractInsnNode) o);
+            } else {
+                InsnList.this.add((AbstractInsnNode) o);
+            }
             prev = (AbstractInsnNode) o;
             remove = null;
         }
 
         public void set(Object o) {
-            InsnList.this.set(next.prev, (AbstractInsnNode) o);
-            prev = (AbstractInsnNode) o;
+            if (remove != null) {
+                InsnList.this.set(remove, (AbstractInsnNode) o);
+                if (remove == prev) {
+                    prev = (AbstractInsnNode) o;
+                } else {
+                    next = (AbstractInsnNode) o;
+                }
+            } else {
+                throw new IllegalStateException();
+            }
         }
     }
 }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/LocalVariableAnnotationNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -122,7 +122,7 @@
      */
     public LocalVariableAnnotationNode(int typeRef, TypePath typePath,
             LabelNode[] start, LabelNode[] end, int[] index, String desc) {
-        this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc);
+        this(Opcodes.ASM6, typeRef, typePath, start, end, index, desc);
     }
 
     /**
@@ -130,7 +130,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param typeRef
      *            a reference to the annotated type. See {@link TypeReference}.
      * @param start
@@ -181,6 +181,6 @@
             index[i] = this.index.get(i);
         }
         accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
-                index, desc, true));
+                index, desc, visible));
     }
 }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -249,7 +249,7 @@
      *             If a subclass calls this constructor.
      */
     public MethodNode() {
-        this(Opcodes.ASM5);
+        this(Opcodes.ASM6);
         if (getClass() != MethodNode.class) {
             throw new IllegalStateException();
         }
@@ -260,7 +260,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public MethodNode(final int api) {
         super(api);
@@ -291,7 +291,7 @@
      */
     public MethodNode(final int access, final String name, final String desc,
             final String signature, final String[] exceptions) {
-        this(Opcodes.ASM5, access, name, desc, signature, exceptions);
+        this(Opcodes.ASM6, access, name, desc, signature, exceptions);
         if (getClass() != MethodNode.class) {
             throw new IllegalStateException();
         }
@@ -302,7 +302,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param access
      *            the method's access flags (see {@link Opcodes}). This
      *            parameter also indicates if the method is synthetic and/or
@@ -688,8 +688,8 @@
      * versions of the ASM API than the given version.
      *
      * @param api
-     *            an ASM API version. Must be one of {@link Opcodes#ASM4} or
-     *            {@link Opcodes#ASM5}.
+     *            an ASM API version. Must be one of {@link Opcodes#ASM4},
+     *            {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     public void check(final int api) {
         if (api == Opcodes.ASM4) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleExportNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an exported package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleExportNode {
+    /**
+     * The package name.
+     */
+    public String packaze;
+
+    /**
+     * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+     */
+    public int access;
+
+    /**
+     * A list of modules that can access to this exported package.
+     * May be <tt>null</tt>.
+     */
+    public List<String> modules;
+
+    /**
+     * Constructs a new {@link ModuleExportNode}.
+     *
+     * @param packaze
+     *            the parameter's name.
+     * @param modules
+     *            a list of modules that can access to this exported package.
+     */
+    public ModuleExportNode(final String packaze, final int access, final List<String> modules) {
+        this.packaze = packaze;
+        this.access = access;
+        this.modules = modules;
+    }
+
+    /**
+     * Makes the given module visitor visit this export declaration.
+     *
+     * @param mv
+     *            a module visitor.
+     */
+    public void accept(final ModuleVisitor mv) {
+        mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,280 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A node that represents a module declaration.
+ *
+ * @author Remi Forax
+ */
+public class ModuleNode extends ModuleVisitor {
+    /**
+     * Module name
+     */
+    public String name;
+
+    /**
+     * Module access flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+     *            and {@code ACC_MANDATED}.
+     */
+    public int access;
+
+    /**
+     * Version of the module.
+     * May be <tt>null</tt>.
+     */
+    public String version;
+
+    /**
+     * Name of the main class in internal form
+     * May be <tt>null</tt>.
+     */
+    public String mainClass;
+
+    /**
+     * A list of packages that are declared by the current module.
+     * May be <tt>null</tt>.
+     */
+    public List<String> packages;
+
+    /**
+     * A list of modules can are required by the current module.
+     * May be <tt>null</tt>.
+     */
+    public List<ModuleRequireNode> requires;
+
+    /**
+     * A list of packages that are exported by the current module.
+     * May be <tt>null</tt>.
+     */
+    public List<ModuleExportNode> exports;
+
+    /**
+     * A list of packages that are opened by the current module.
+     * May be <tt>null</tt>.
+     */
+    public List<ModuleOpenNode> opens;
+
+    /**
+     * A list of classes in their internal forms that are used
+     * as a service by the current module. May be <tt>null</tt>.
+     */
+    public List<String> uses;
+
+    /**
+     * A list of services along with their implementations provided
+     * by the current module. May be <tt>null</tt>.
+     */
+    public List<ModuleProvideNode> provides;
+
+    public ModuleNode(final String name, final int access,
+            final String version) {
+        super(Opcodes.ASM6);
+        this.name = name;
+        this.access = access;
+        this.version = version;
+    }
+
+    public ModuleNode(final int api,
+      final String name,
+      final int access,
+      final String version,
+      final List<ModuleRequireNode> requires,
+      final List<ModuleExportNode> exports,
+      final List<ModuleOpenNode> opens,
+      final List<String> uses,
+      final List<ModuleProvideNode> provides) {
+        super(api);
+        this.name = name;
+        this.access = access;
+        this.version = version;
+        this.requires = requires;
+        this.exports = exports;
+        this.opens = opens;
+        this.uses = uses;
+        this.provides = provides;
+        if (getClass() != ModuleNode.class) {
+            throw new IllegalStateException();
+        }
+    }
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        this.mainClass = mainClass;
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        if (packages == null) {
+            packages = new ArrayList<String>(5);
+        }
+        packages.add(packaze);
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        if (requires == null) {
+            requires = new ArrayList<ModuleRequireNode>(5);
+        }
+        requires.add(new ModuleRequireNode(module, access, version));
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        if (exports == null) {
+            exports = new ArrayList<ModuleExportNode>(5);
+        }
+        List<String> moduleList = null;
+        if (modules != null) {
+            moduleList = new ArrayList<String>(modules.length);
+            for (int i = 0; i < modules.length; i++) {
+                moduleList.add(modules[i]);
+            }
+        }
+        exports.add(new ModuleExportNode(packaze, access, moduleList));
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        if (opens == null) {
+            opens = new ArrayList<ModuleOpenNode>(5);
+        }
+        List<String> moduleList = null;
+        if (modules != null) {
+            moduleList = new ArrayList<String>(modules.length);
+            for (int i = 0; i < modules.length; i++) {
+                moduleList.add(modules[i]);
+            }
+        }
+        opens.add(new ModuleOpenNode(packaze, access, moduleList));
+    }
+
+    @Override
+    public void visitUse(String service) {
+        if (uses == null) {
+            uses = new ArrayList<String>(5);
+        }
+        uses.add(service);
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        if (provides == null) {
+            provides = new ArrayList<ModuleProvideNode>(5);
+        }
+        ArrayList<String> providerList =
+                new ArrayList<String>(providers.length);
+        for (int i = 0; i < providers.length; i++) {
+                providerList.add(providers[i]);
+        }
+        provides.add(new ModuleProvideNode(service, providerList));
+    }
+
+    @Override
+    public void visitEnd() {
+    }
+
+    public void accept(final ClassVisitor cv) {
+        ModuleVisitor mv = cv.visitModule(name, access, version);
+        if (mv == null) {
+            return;
+        }
+        if (mainClass != null) {
+            mv.visitMainClass(mainClass);
+        }
+        if (packages != null) {
+            for (int i = 0; i < packages.size(); i++) {
+                mv.visitPackage(packages.get(i));
+            }
+        }
+
+        if (requires != null) {
+            for (int i = 0; i < requires.size(); i++) {
+                requires.get(i).accept(mv);
+            }
+        }
+        if (exports != null) {
+            for (int i = 0; i < exports.size(); i++) {
+                exports.get(i).accept(mv);
+            }
+        }
+        if (opens != null) {
+            for (int i = 0; i < opens.size(); i++) {
+                opens.get(i).accept(mv);
+            }
+        }
+        if (uses != null) {
+            for (int i = 0; i < uses.size(); i++) {
+                mv.visitUse(uses.get(i));
+            }
+        }
+        if (provides != null) {
+            for (int i = 0; i < provides.size(); i++) {
+                provides.get(i).accept(mv);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleOpenNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents an opened package with its name and the module that can access to it.
+ *
+ * @author Remi Forax
+ */
+public class ModuleOpenNode {
+    /**
+     * The package name.
+     */
+    public String packaze;
+
+    /**
+     * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * Valid values are {@code ACC_SYNTHETIC} and {@code ACC_MANDATED}.
+     */
+    public int access;
+
+    /**
+     * A list of modules that can access to this exported package.
+     * May be <tt>null</tt>.
+     */
+    public List<String> modules;
+
+    /**
+     * Constructs a new {@link ModuleOpenNode}.
+     *
+     * @param packaze
+     *            the parameter's name.
+     * @param modules
+     *            a list of modules that can access to this open package.
+     */
+    public ModuleOpenNode(final String packaze, final int access, final List<String> modules) {
+        this.packaze = packaze;
+        this.access = access;
+        this.modules = modules;
+    }
+
+    /**
+     * Makes the given module visitor visit this open declaration.
+     *
+     * @param mv
+     *            a module visitor.
+     */
+    public void accept(final ModuleVisitor mv) {
+        mv.visitExport(packaze, access, (modules == null) ? null : modules.toArray(new String[0]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleProvideNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,103 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import java.util.List;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a service and its implementation provided by the current module.
+ *
+ * @author Remi Forax
+ */
+public class ModuleProvideNode {
+    /**
+     * The service name (in its internal form).
+     */
+    public String service;
+
+    /**
+     * The service provider names (in their internal form).
+     */
+    public List<String> providers;
+
+    /**
+     * Constructs a new {@link ModuleProvideNode}.
+     *
+     * @param service
+     *            the service name (in its internal form).
+     * @param providers
+     *            the service provider names (in their internal form).
+     */
+    public ModuleProvideNode(final String service, final List<String> providers) {
+        this.service = service;
+        this.providers = providers;
+    }
+
+    /**
+     * Makes the given module visitor visit this require declaration.
+     *
+     * @param mv
+     *            a module visitor.
+     */
+    public void accept(final ModuleVisitor mv) {
+        mv.visitProvide(service, providers.toArray(new String[0]));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/ModuleRequireNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,116 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.tree;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+
+/**
+ * A node that represents a required module with its name and access of a module descriptor.
+ *
+ * @author Remi Forax
+ */
+public class ModuleRequireNode {
+    /**
+     * The name of the required module.
+     */
+    public String module;
+
+    /**
+     * The access flags (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * Valid values are <tt>ACC_TRANSITIVE</tt>, <tt>ACC_STATIC_PHASE</tt>,
+     *        <tt>ACC_SYNTHETIC</tt> and <tt>ACC_MANDATED</tt>.
+     */
+    public int access;
+
+    /**
+     * Version at compile time of the required module or null.
+     */
+    public String version;
+
+    /**
+     * Constructs a new {@link ModuleRequireNode}.
+     *
+     * @param module
+     *            the name of the required module.
+     * @param access
+     *            The access flags. Valid values are
+     *            <tt>ACC_TRANSITIVE</tt>, <tt>ACC_STATIC_PHASE</tt>,
+     *            <tt>ACC_SYNTHETIC</tt> and <tt>ACC_MANDATED</tt>
+     *            (see {@link jdk.internal.org.objectweb.asm.Opcodes}).
+     * @param version
+     *            Version of the required module at compile time,
+     *            null if not defined.
+     */
+    public ModuleRequireNode(final String module, final int access,
+            final String version) {
+        this.module = module;
+        this.access = access;
+        this.version = version;
+    }
+
+    /**
+     * Makes the given module visitor visit this require directive.
+     *
+     * @param mv
+     *            a module visitor.
+     */
+    public void accept(final ModuleVisitor mv) {
+        mv.visitRequire(module, access, version);
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/TypeAnnotationNode.java	Thu Nov 02 13:18:23 2017 -0700
@@ -99,7 +99,7 @@
      */
     public TypeAnnotationNode(final int typeRef, final TypePath typePath,
             final String desc) {
-        this(Opcodes.ASM5, typeRef, typePath, desc);
+        this(Opcodes.ASM6, typeRef, typePath, desc);
         if (getClass() != TypeAnnotationNode.class) {
             throw new IllegalStateException();
         }
@@ -110,7 +110,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param typeRef
      *            a reference to the annotated type. See {@link TypeReference}.
      * @param typePath
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicInterpreter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -82,7 +82,7 @@
         Opcodes {
 
     public BasicInterpreter() {
-        super(ASM5);
+        super(ASM6);
     }
 
     protected BasicInterpreter(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/BasicVerifier.java	Thu Nov 02 13:18:23 2017 -0700
@@ -76,7 +76,7 @@
 public class BasicVerifier extends BasicInterpreter {
 
     public BasicVerifier() {
-        super(ASM5);
+        super(ASM6);
     }
 
     protected BasicVerifier(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SimpleVerifier.java	Thu Nov 02 13:18:23 2017 -0700
@@ -136,7 +136,7 @@
     public SimpleVerifier(final Type currentClass,
             final Type currentSuperClass,
             final List<Type> currentClassInterfaces, final boolean isInterface) {
-        this(ASM5, currentClass, currentSuperClass, currentClassInterfaces,
+        this(ASM6, currentClass, currentSuperClass, currentClassInterfaces,
                 isInterface);
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/tree/analysis/SourceInterpreter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -79,7 +79,7 @@
         Opcodes {
 
     public SourceInterpreter() {
-        super(ASM5);
+        super(ASM6);
     }
 
     protected SourceInterpreter(final int api) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java	Thu Nov 02 13:18:23 2017 -0700
@@ -110,6 +110,11 @@
     private static final int ACCESS_INNER = 1048576;
 
     /**
+     * Pseudo access flag used to distinguish module requires/exports flags.
+     */
+    private static final int ACCESS_MODULE = 2097152;
+
+    /**
      * Constructs a new {@link ASMifier}. <i>Subclasses must not use this
      * constructor</i>. Instead, they must use the
      * {@link #ASMifier(int, String, int)} version.
@@ -118,7 +123,7 @@
      *             If a subclass calls this constructor.
      */
     public ASMifier() {
-        this(Opcodes.ASM5, "cw", 0);
+        this(Opcodes.ASM6, "cw", 0);
         if (getClass() != ASMifier.class) {
             throw new IllegalStateException();
         }
@@ -129,7 +134,7 @@
      *
      * @param api
      *            the ASM API version implemented by this class. Must be one of
-     *            {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param name
      *            the name of the visitor variable in the produced code.
      * @param id
@@ -196,13 +201,17 @@
             final String signature, final String superName,
             final String[] interfaces) {
         String simpleName;
-        int n = name.lastIndexOf('/');
-        if (n == -1) {
-            simpleName = name;
+        if (name == null) {
+            simpleName = "module-info";
         } else {
-            text.add("package asm." + name.substring(0, n).replace('/', '.')
-                    + ";\n");
-            simpleName = name.substring(n + 1);
+            int n = name.lastIndexOf('/');
+            if (n == -1) {
+                simpleName = name;
+            } else {
+                text.add("package asm." + name.substring(0, n).replace('/', '.')
+                        + ";\n");
+                simpleName = name.substring(n + 1).replace('-', '_');
+            }
         }
         text.add("import java.util.*;\n");
         text.add("import jdk.internal.org.objectweb.asm.*;\n");
@@ -237,6 +246,12 @@
         case Opcodes.V1_7:
             buf.append("V1_7");
             break;
+        case Opcodes.V1_8:
+            buf.append("V1_8");
+            break;
+        case Opcodes.V9:
+            buf.append("V9");
+            break;
         default:
             buf.append(version);
             break;
@@ -276,6 +291,24 @@
     }
 
     @Override
+    public Printer visitModule(final String name, final int flags,
+            final String version) {
+        buf.setLength(0);
+        buf.append("ModuleVisitor mdv = cw.visitModule(");
+        appendConstant(name);
+        buf.append(", ");
+        appendAccess(flags | ACCESS_MODULE);
+        buf.append(", ");
+        appendConstant(version);
+        buf.append(");\n\n");
+        text.add(buf.toString());
+        ASMifier a = createASMifier("mdv", 0);
+        text.add(a.getText());
+        text.add("}\n");
+        return a;
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         buf.setLength(0);
@@ -386,6 +419,108 @@
     }
 
     // ------------------------------------------------------------------------
+    // Module
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        buf.setLength(0);
+        buf.append("mdv.visitMainClass(");
+        appendConstant(buf, mainClass);
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        buf.setLength(0);
+        buf.append("mdv.visitPackage(");
+        appendConstant(buf, packaze);
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        buf.setLength(0);
+        buf.append("mdv.visitRequire(");
+        appendConstant(buf, module);
+        buf.append(", ");
+        appendAccess(access | ACCESS_MODULE);
+        buf.append(", ");
+        appendConstant(buf, version);
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        buf.setLength(0);
+        buf.append("mdv.visitExport(");
+        appendConstant(buf, packaze);
+        buf.append(", ");
+        appendAccess(access | ACCESS_MODULE);
+        if (modules != null && modules.length > 0) {
+            buf.append(", new String[] {");
+            for (int i = 0; i < modules.length; ++i) {
+                buf.append(i == 0 ? " " : ", ");
+                appendConstant(modules[i]);
+            }
+            buf.append(" }");
+        }
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        buf.setLength(0);
+        buf.append("mdv.visitOpen(");
+        appendConstant(buf, packaze);
+        buf.append(", ");
+        appendAccess(access | ACCESS_MODULE);
+        if (modules != null && modules.length > 0) {
+            buf.append(", new String[] {");
+            for (int i = 0; i < modules.length; ++i) {
+                buf.append(i == 0 ? " " : ", ");
+                appendConstant(modules[i]);
+            }
+            buf.append(" }");
+        }
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitUse(String service) {
+        buf.setLength(0);
+        buf.append("mdv.visitUse(");
+        appendConstant(buf, service);
+        buf.append(");\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        buf.setLength(0);
+        buf.append("mdv.visitProvide(");
+        appendConstant(buf, service);
+        buf.append(",  new String[] {");
+        for (int i = 0; i < providers.length; ++i) {
+            buf.append(i == 0 ? " " : ", ");
+            appendConstant(providers[i]);
+        }
+        buf.append(" });\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitModuleEnd() {
+        text.add("mdv.visitEnd();\n");
+    }
+
+
+    // ------------------------------------------------------------------------
     // Annotations
     // ------------------------------------------------------------------------
 
@@ -972,7 +1107,7 @@
     // ------------------------------------------------------------------------
 
     protected ASMifier createASMifier(final String name, final int id) {
-        return new ASMifier(Opcodes.ASM5, name, id);
+        return new ASMifier(Opcodes.ASM6, name, id);
     }
 
     /**
@@ -1000,7 +1135,11 @@
             if (!first) {
                 buf.append(" + ");
             }
-            buf.append("ACC_FINAL");
+            if ((access & ACCESS_MODULE) == 0) {
+                buf.append("ACC_FINAL");
+            } else {
+                buf.append("ACC_TRANSITIVE");
+            }
             first = false;
         }
         if ((access & Opcodes.ACC_STATIC) != 0) {
@@ -1010,31 +1149,35 @@
             buf.append("ACC_STATIC");
             first = false;
         }
-        if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
+        if ((access & (Opcodes.ACC_SYNCHRONIZED | Opcodes.ACC_SUPER | Opcodes.ACC_TRANSITIVE)) != 0) {
             if (!first) {
                 buf.append(" + ");
             }
             if ((access & ACCESS_CLASS) == 0) {
-                buf.append("ACC_SYNCHRONIZED");
+                if ((access & ACCESS_MODULE) == 0) {
+                    buf.append("ACC_SYNCHRONIZED");
+                } else {
+                    buf.append("ACC_TRANSITIVE");
+                }
             } else {
                 buf.append("ACC_SUPER");
             }
             first = false;
         }
-        if ((access & Opcodes.ACC_VOLATILE) != 0
-                && (access & ACCESS_FIELD) != 0) {
+        if ((access & (Opcodes.ACC_VOLATILE | Opcodes.ACC_BRIDGE | Opcodes.ACC_STATIC_PHASE)) != 0) {
             if (!first) {
                 buf.append(" + ");
             }
-            buf.append("ACC_VOLATILE");
-            first = false;
-        }
-        if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0
-                && (access & ACCESS_FIELD) == 0) {
-            if (!first) {
-                buf.append(" + ");
+            if ((access & ACCESS_FIELD) == 0) {
+                if ((access & ACCESS_MODULE) == 0) {
+                    buf.append("ACC_BRIDGE");
+                } else {
+                    buf.append("ACC_STATIC_PHASE");
+                }
+            } else {
+                buf.append("ACC_VOLATILE");
             }
-            buf.append("ACC_BRIDGE");
+
             first = false;
         }
         if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0
@@ -1113,11 +1256,15 @@
             buf.append("ACC_DEPRECATED");
             first = false;
         }
-        if ((access & Opcodes.ACC_MANDATED) != 0) {
+        if ((access & (Opcodes.ACC_MANDATED | Opcodes.ACC_MODULE)) != 0) {
             if (!first) {
                 buf.append(" + ");
             }
-            buf.append("ACC_MANDATED");
+            if ((access & ACCESS_CLASS) == 0) {
+                buf.append("ACC_MANDATED");
+            } else {
+                buf.append("ACC_MODULE");
+            }
             first = false;
         }
         if (first) {
@@ -1163,7 +1310,8 @@
                     .append(", \"");
             buf.append(h.getOwner()).append("\", \"");
             buf.append(h.getName()).append("\", \"");
-            buf.append(h.getDesc()).append("\")");
+            buf.append(h.getDesc()).append("\", ");
+            buf.append(h.isInterface()).append(")");
         } else if (cst instanceof Byte) {
             buf.append("new Byte((byte)").append(cst).append(')');
         } else if (cst instanceof Boolean) {
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckAnnotationAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -78,7 +78,7 @@
     }
 
     CheckAnnotationAdapter(final AnnotationVisitor av, final boolean named) {
-        super(Opcodes.ASM5, av);
+        super(Opcodes.ASM6, av);
         this.named = named;
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckClassAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -73,6 +73,7 @@
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.Type;
 import jdk.internal.org.objectweb.asm.TypePath;
@@ -181,6 +182,11 @@
     private boolean end;
 
     /**
+     * <tt>true</tt> if the visitModule method has been called.
+     */
+    private boolean module;
+
+    /**
      * The already visited labels. This map associate Integer values to Label
      * keys.
      */
@@ -363,7 +369,7 @@
      *             If a subclass calls this constructor.
      */
     public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow) {
-        this(Opcodes.ASM5, cv, checkDataFlow);
+        this(Opcodes.ASM6, cv, checkDataFlow);
         if (getClass() != CheckClassAdapter.class) {
             throw new IllegalStateException();
         }
@@ -374,7 +380,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param cv
      *            the class visitor to which this adapter must delegate calls.
      * @param checkDataFlow
@@ -407,8 +413,12 @@
                 + Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE
                 + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC
                 + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM
-                + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
-        if (name == null || !name.endsWith("package-info")) {
+                + Opcodes.ACC_DEPRECATED + Opcodes.ACC_MODULE
+                + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE
+        if (name == null) {
+            throw new IllegalArgumentException("Illegal class name (null)");
+        }
+        if (!name.endsWith("package-info")) {
             CheckMethodAdapter.checkInternalName(name, "class name");
         }
         if ("java/lang/Object".equals(name)) {
@@ -450,6 +460,22 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(String name, int access, String version) {
+        checkState();
+        if (module) {
+            throw new IllegalStateException(
+                    "visitModule can be called only once.");
+        }
+        module = true;
+        if (name == null) {
+            throw new IllegalArgumentException("Illegal module name (null)");
+        }
+        checkAccess(access, Opcodes.ACC_OPEN | Opcodes.ACC_SYNTHETIC);
+        return new CheckModuleAdapter(super.visitModule(name, access, version),
+            (access & Opcodes.ACC_OPEN) != 0);
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         checkState();
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckFieldAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -83,7 +83,7 @@
      *             If a subclass calls this constructor.
      */
     public CheckFieldAdapter(final FieldVisitor fv) {
-        this(Opcodes.ASM5, fv);
+        this(Opcodes.ASM6, fv);
         if (getClass() != CheckFieldAdapter.class) {
             throw new IllegalStateException();
         }
@@ -94,7 +94,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param fv
      *            the field visitor to which this adapter must delegate calls.
      */
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -426,7 +426,7 @@
      */
     public CheckMethodAdapter(final MethodVisitor mv,
             final Map<Label, Integer> labels) {
-        this(Opcodes.ASM5, mv, labels);
+        this(Opcodes.ASM6, mv, labels);
         if (getClass() != CheckMethodAdapter.class) {
             throw new IllegalStateException();
         }
@@ -439,7 +439,8 @@
      *
      * @param api
      *            the ASM API version implemented by this CheckMethodAdapter.
-     *            Must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            Must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5}
+     *            or {@link Opcodes#ASM6}.
      * @param mv
      *            the method visitor to which this adapter must delegate calls.
      * @param labels
@@ -756,6 +757,12 @@
             throw new IllegalArgumentException(
                     "INVOKEINTERFACE can't be used with classes");
         }
+        if (opcode == Opcodes.INVOKESPECIAL && itf
+                && (version & 0xFFFF) < Opcodes.V1_8) {
+            throw new IllegalArgumentException(
+                    "INVOKESPECIAL can't be used with interfaces prior to Java 8");
+        }
+
         // Calling super.visitMethodInsn requires to call the correct version
         // depending on this.api (otherwise infinite loops can occur). To
         // simplify and to make it easier to automatically remove the backward
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckModuleAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,180 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.util;
+
+import java.util.HashSet;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * @author Remi Forax
+ */
+public final class CheckModuleAdapter extends ModuleVisitor {
+    private boolean end;
+    private final boolean isOpen;
+
+    private final HashSet<String> requireNames = new HashSet<String>();
+    private final HashSet<String> exportNames = new HashSet<String>();
+    private final HashSet<String> openNames = new HashSet<String>();
+    private final HashSet<String> useNames = new HashSet<String>();
+    private final HashSet<String> provideNames = new HashSet<String>();
+
+    public CheckModuleAdapter(final ModuleVisitor mv, final boolean isOpen) {
+        super(Opcodes.ASM6, mv);
+        this.isOpen = isOpen;
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        checkEnd();
+        if (module == null) {
+            throw new IllegalArgumentException("require cannot be null");
+        }
+        checkDeclared("requires", requireNames, module);
+        CheckClassAdapter.checkAccess(access, Opcodes.ACC_STATIC_PHASE
+                + Opcodes.ACC_TRANSITIVE + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_MANDATED);
+        super.visitRequire(module, access, version);
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        checkEnd();
+        if (packaze == null) {
+            throw new IllegalArgumentException("packaze cannot be null");
+        }
+        CheckMethodAdapter.checkInternalName(packaze, "package name");
+        checkDeclared("exports", exportNames, packaze);
+        CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC
+                + Opcodes.ACC_MANDATED);
+        if (modules != null) {
+            for (int i = 0; i < modules.length; i++) {
+                if (modules[i] == null) {
+                    throw new IllegalArgumentException("module at index " + i + " cannot be null");
+                }
+            }
+        }
+        super.visitExport(packaze, access, modules);
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        checkEnd();
+        if (isOpen) {
+            throw new IllegalArgumentException("an open module can not use open directive");
+        }
+        if (packaze == null) {
+            throw new IllegalArgumentException("packaze cannot be null");
+        }
+        CheckMethodAdapter.checkInternalName(packaze, "package name");
+        checkDeclared("opens", openNames, packaze);
+        CheckClassAdapter.checkAccess(access, Opcodes.ACC_SYNTHETIC
+                + Opcodes.ACC_MANDATED);
+        if (modules != null) {
+            for (int i = 0; i < modules.length; i++) {
+                if (modules[i] == null) {
+                    throw new IllegalArgumentException("module at index " + i + " cannot be null");
+                }
+            }
+        }
+        super.visitOpen(packaze, access, modules);
+    }
+
+    @Override
+    public void visitUse(String service) {
+        checkEnd();
+        CheckMethodAdapter.checkInternalName(service, "service");
+        checkDeclared("uses", useNames, service);
+        super.visitUse(service);
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        checkEnd();
+        CheckMethodAdapter.checkInternalName(service, "service");
+        checkDeclared("provides", provideNames, service);
+        if (providers == null || providers.length == 0) {
+            throw new IllegalArgumentException("providers cannot be null or empty");
+        }
+        for (int i = 0; i < providers.length; i++) {
+            CheckMethodAdapter.checkInternalName(providers[i], "provider");
+        }
+        super.visitProvide(service, providers);
+    }
+
+    @Override
+    public void visitEnd() {
+        checkEnd();
+        end = true;
+        super.visitEnd();
+    }
+
+    private void checkEnd() {
+        if (end) {
+            throw new IllegalStateException(
+                    "Cannot call a visit method after visitEnd has been called");
+        }
+    }
+
+    private static void checkDeclared(String directive, HashSet<String> names, String name) {
+        if (!names.add(name)) {
+            throw new IllegalArgumentException(directive + " " + name + " already declared");
+        }
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/CheckSignatureAdapter.java	Thu Nov 02 13:18:23 2017 -0700
@@ -142,7 +142,7 @@
      *            <tt>null</tt>.
      */
     public CheckSignatureAdapter(final int type, final SignatureVisitor sv) {
-        this(Opcodes.ASM5, type, sv);
+        this(Opcodes.ASM6, type, sv);
     }
 
     /**
@@ -150,7 +150,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      * @param type
      *            the type of signature to be checked. See
      *            {@link #CLASS_SIGNATURE}, {@link #METHOD_SIGNATURE} and
@@ -175,7 +175,7 @@
                 || (state != EMPTY && state != FORMAL && state != BOUND)) {
             throw new IllegalStateException();
         }
-        CheckMethodAdapter.checkIdentifier(name, "formal type parameter");
+        checkIdentifier(name, "formal type parameter");
         state = FORMAL;
         if (sv != null) {
             sv.visitFormalTypeParameter(name);
@@ -284,7 +284,7 @@
         if (type != TYPE_SIGNATURE || state != EMPTY) {
             throw new IllegalStateException();
         }
-        CheckMethodAdapter.checkIdentifier(name, "type variable");
+        checkIdentifier(name, "type variable");
         state = SIMPLE_TYPE;
         if (sv != null) {
             sv.visitTypeVariable(name);
@@ -306,7 +306,7 @@
         if (type != TYPE_SIGNATURE || state != EMPTY) {
             throw new IllegalStateException();
         }
-        CheckMethodAdapter.checkInternalName(name, "class name");
+        checkClassName(name, "class name");
         state = CLASS_TYPE;
         if (sv != null) {
             sv.visitClassType(name);
@@ -318,7 +318,7 @@
         if (state != CLASS_TYPE) {
             throw new IllegalStateException();
         }
-        CheckMethodAdapter.checkIdentifier(name, "inner class name");
+        checkIdentifier(name, "inner class name");
         if (sv != null) {
             sv.visitInnerClassType(name);
         }
@@ -356,4 +356,30 @@
             sv.visitEnd();
         }
     }
+
+    private void checkClassName(final String name, final String msg) {
+        if (name == null || name.length() == 0) {
+            throw new IllegalArgumentException("Invalid " + msg
+                    + " (must not be null or empty)");
+        }
+        for (int i = 0; i < name.length(); ++i) {
+            if (".;[<>:".indexOf(name.charAt(i)) != -1) {
+                throw new IllegalArgumentException("Invalid " + msg
+                        + " (must not contain . ; [ < > or :): " + name);
+            }
+        }
+    }
+
+    private void checkIdentifier(final String name, final String msg) {
+        if (name == null || name.length() == 0) {
+            throw new IllegalArgumentException("Invalid " + msg
+                    + " (must not be null or empty)");
+        }
+        for (int i = 0; i < name.length(); ++i) {
+            if (".;[/<>:".indexOf(name.charAt(i)) != -1) {
+                throw new IllegalArgumentException("Invalid " + msg
+                        + " (must not contain . ; [ / < > or :): " + name);
+            }
+        }
+    }
 }
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java	Thu Nov 02 13:18:23 2017 -0700
@@ -146,7 +146,7 @@
 
     /**
      * The ASM API version implemented by this class. The value of this field
-     * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected final int api;
 
@@ -174,7 +174,7 @@
      *
      * @param api
      *            the ASM API version implemented by this printer. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected Printer(final int api) {
         this.api = api;
@@ -226,6 +226,24 @@
      */
     public abstract void visitSource(final String source, final String debug);
 
+
+    /**
+     * Module.
+     * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitModule(String, int)}.
+     *
+     * @param name
+     *            module name.
+     * @param access
+     *            module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
+     *            and {@code ACC_MANDATED}.
+     * @param version
+     *            module version or null.
+     * @return
+     */
+    public Printer visitModule(String name, int access, String version) {
+        throw new RuntimeException("Must be overriden");
+    }
+
     /**
      * Class outer class.
      * See {@link jdk.internal.org.objectweb.asm.ClassVisitor#visitOuterClass}.
@@ -376,6 +394,45 @@
     public abstract void visitClassEnd();
 
     // ------------------------------------------------------------------------
+    // Module
+    // ------------------------------------------------------------------------
+
+    public void visitMainClass(String mainClass) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitPackage(String packaze) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitRequire(String module, int access, String version) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitExport(String packaze, int access, String... modules) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitOpen(String packaze, int access, String... modules) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitUse(String service) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    public void visitProvide(String service, String... providers) {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    /**
+     * Module end. See {@link jdk.internal.org.objectweb.asm.ModuleVisitor#visitEnd}.
+     */
+    public void visitModuleEnd() {
+        throw new RuntimeException("Must be overriden");
+    }
+
+    // ------------------------------------------------------------------------
     // Annotations
     // ------------------------------------------------------------------------
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java	Thu Nov 02 13:18:23 2017 -0700
@@ -182,7 +182,7 @@
      *             If a subclass calls this constructor.
      */
     public Textifier() {
-        this(Opcodes.ASM5);
+        this(Opcodes.ASM6);
         if (getClass() != Textifier.class) {
             throw new IllegalStateException();
         }
@@ -193,7 +193,7 @@
      *
      * @param api
      *            the ASM API version implemented by this visitor. Must be one
-     *            of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}.
+     *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
      */
     protected Textifier(final int api) {
         super(api);
@@ -250,6 +250,10 @@
     public void visit(final int version, final int access, final String name,
             final String signature, final String superName,
             final String[] interfaces) {
+        if ((access & Opcodes.ACC_MODULE) != 0) {
+            // visitModule will print the module
+            return;
+        }
         this.access = access;
         int major = version & 0xFFFF;
         int minor = version >>> 16;
@@ -271,7 +275,7 @@
                     .append(sv.getDeclaration()).append('\n');
         }
 
-        appendAccess(access & ~Opcodes.ACC_SUPER);
+        appendAccess(access & ~(Opcodes.ACC_SUPER | Opcodes.ACC_MODULE));
         if ((access & Opcodes.ACC_ANNOTATION) != 0) {
             buf.append("@interface ");
         } else if ((access & Opcodes.ACC_INTERFACE) != 0) {
@@ -315,6 +319,24 @@
     }
 
     @Override
+    public Printer visitModule(final String name, final int access,
+            final String version) {
+        buf.setLength(0);
+        if ((access & Opcodes.ACC_OPEN) != 0) {
+            buf.append("open ");
+        }
+        buf.append("module ")
+           .append(name)
+           .append(" { ")
+           .append(version == null ? "" : "// " + version)
+           .append("\n\n");
+        text.add(buf.toString());
+        Textifier t = createTextifier();
+        text.add(t.getText());
+        return t;
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         buf.setLength(0);
@@ -443,7 +465,7 @@
         }
 
         buf.append(tab);
-        appendAccess(access & ~Opcodes.ACC_VOLATILE);
+        appendAccess(access & ~(Opcodes.ACC_VOLATILE | Opcodes.ACC_TRANSIENT));
         if ((access & Opcodes.ACC_NATIVE) != 0) {
             buf.append("native ");
         }
@@ -483,6 +505,118 @@
     }
 
     // ------------------------------------------------------------------------
+    // Module
+    // ------------------------------------------------------------------------
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        buf.setLength(0);
+        buf.append("  // main class ").append(mainClass).append('\n');
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        buf.setLength(0);
+        buf.append("  // package ").append(packaze).append('\n');
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitRequire(String require, int access, String version) {
+        buf.setLength(0);
+        buf.append(tab).append("requires ");
+        if ((access & Opcodes.ACC_TRANSITIVE) != 0) {
+            buf.append("transitive ");
+        }
+        if ((access & Opcodes.ACC_STATIC_PHASE) != 0) {
+            buf.append("static ");
+        }
+        buf.append(require)
+           .append(";  // access flags 0x")
+           .append(Integer.toHexString(access).toUpperCase())
+           .append('\n');
+        if (version != null) {
+            buf.append("  // version ")
+               .append(version)
+               .append('\n');
+        }
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitExport(String export, int access, String... modules) {
+        buf.setLength(0);
+        buf.append(tab).append("exports ");
+        buf.append(export);
+        if (modules != null && modules.length > 0) {
+            buf.append(" to");
+        } else {
+            buf.append(';');
+        }
+        buf.append("  // access flags 0x")
+           .append(Integer.toHexString(access).toUpperCase())
+           .append('\n');
+        if (modules != null && modules.length > 0) {
+            for (int i = 0; i < modules.length; ++i) {
+                buf.append(tab2).append(modules[i]);
+                buf.append(i != modules.length - 1 ? ",\n": ";\n");
+            }
+        }
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitOpen(String export, int access, String... modules) {
+        buf.setLength(0);
+        buf.append(tab).append("opens ");
+        buf.append(export);
+        if (modules != null && modules.length > 0) {
+            buf.append(" to");
+        } else {
+            buf.append(';');
+        }
+        buf.append("  // access flags 0x")
+           .append(Integer.toHexString(access).toUpperCase())
+           .append('\n');
+        if (modules != null && modules.length > 0) {
+            for (int i = 0; i < modules.length; ++i) {
+                buf.append(tab2).append(modules[i]);
+                buf.append(i != modules.length - 1 ? ",\n": ";\n");
+            }
+        }
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitUse(String use) {
+        buf.setLength(0);
+        buf.append(tab).append("uses ");
+        appendDescriptor(INTERNAL_NAME, use);
+        buf.append(";\n");
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitProvide(String provide, String... providers) {
+        buf.setLength(0);
+        buf.append(tab).append("provides ");
+        appendDescriptor(INTERNAL_NAME, provide);
+        buf.append(" with\n");
+        for (int i = 0; i < providers.length; ++i) {
+            buf.append(tab2);
+            appendDescriptor(INTERNAL_NAME, providers[i]);
+            buf.append(i != providers.length - 1 ? ",\n": ";\n");
+        }
+        text.add(buf.toString());
+    }
+
+    @Override
+    public void visitModuleEnd() {
+        // empty
+    }
+
+    // ------------------------------------------------------------------------
     // Annotations
     // ------------------------------------------------------------------------
 
@@ -1296,13 +1430,16 @@
         appendDescriptor(INTERNAL_NAME, h.getOwner());
         buf.append('.');
         buf.append(h.getName());
-        if(!isMethodHandle){
+        if (!isMethodHandle) {
             buf.append('(');
         }
         appendDescriptor(HANDLE_DESCRIPTOR, h.getDesc());
-        if(!isMethodHandle){
+        if (!isMethodHandle) {
             buf.append(')');
         }
+        if (h.isInterface()) {
+            buf.append(" itf");
+        }
     }
 
     /**
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceAnnotationVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -76,7 +76,7 @@
     }
 
     public TraceAnnotationVisitor(final AnnotationVisitor av, final Printer p) {
-        super(Opcodes.ASM5, av);
+        super(Opcodes.ASM6, av);
         this.p = p;
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceClassVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -65,6 +65,7 @@
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
 import jdk.internal.org.objectweb.asm.Opcodes;
 import jdk.internal.org.objectweb.asm.TypePath;
 
@@ -160,7 +161,7 @@
      */
     public TraceClassVisitor(final ClassVisitor cv, final Printer p,
             final PrintWriter pw) {
-        super(Opcodes.ASM5, cv);
+        super(Opcodes.ASM6, cv);
         this.pw = pw;
         this.p = p;
     }
@@ -180,6 +181,14 @@
     }
 
     @Override
+    public ModuleVisitor visitModule(String name, int flags,
+            String version) {
+        Printer p = this.p.visitModule(name, flags, version);
+        ModuleVisitor mv = super.visitModule(name, flags, version);
+        return new TraceModuleVisitor(mv, p);
+    }
+
+    @Override
     public void visitOuterClass(final String owner, final String name,
             final String desc) {
         p.visitOuterClass(owner, name, desc);
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceFieldVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -79,7 +79,7 @@
     }
 
     public TraceFieldVisitor(final FieldVisitor fv, final Printer p) {
-        super(Opcodes.ASM5, fv);
+        super(Opcodes.ASM6, fv);
         this.p = p;
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -81,7 +81,7 @@
     }
 
     public TraceMethodVisitor(final MethodVisitor mv, final Printer p) {
-        super(Opcodes.ASM5, mv);
+        super(Opcodes.ASM6, mv);
         this.p = p;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceModuleVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -0,0 +1,130 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jdk.internal.org.objectweb.asm.util;
+
+import jdk.internal.org.objectweb.asm.ModuleVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+/**
+ * A {@link ModuleVisitor} that prints the fields it visits with a
+ * {@link Printer}.
+ *
+ * @author Remi Forax
+ */
+public final class TraceModuleVisitor extends ModuleVisitor {
+
+    public final Printer p;
+
+    public TraceModuleVisitor(final Printer p) {
+        this(null, p);
+    }
+
+    public TraceModuleVisitor(final ModuleVisitor mv, final Printer p) {
+        super(Opcodes.ASM6, mv);
+        this.p = p;
+    }
+
+    @Override
+    public void visitMainClass(String mainClass) {
+        p.visitMainClass(mainClass);
+        super.visitMainClass(mainClass);
+    }
+
+    @Override
+    public void visitPackage(String packaze) {
+        p.visitPackage(packaze);
+        super.visitPackage(packaze);
+    }
+
+    @Override
+    public void visitRequire(String module, int access, String version) {
+        p.visitRequire(module, access, version);
+        super.visitRequire(module, access, version);
+    }
+
+    @Override
+    public void visitExport(String packaze, int access, String... modules) {
+        p.visitExport(packaze, access, modules);
+        super.visitExport(packaze, access, modules);
+    }
+
+    @Override
+    public void visitOpen(String packaze, int access, String... modules) {
+        p.visitOpen(packaze, access, modules);
+        super.visitOpen(packaze, access, modules);
+    }
+
+    @Override
+    public void visitUse(String use) {
+        p.visitUse(use);
+        super.visitUse(use);
+    }
+
+    @Override
+    public void visitProvide(String service, String... providers) {
+        p.visitProvide(service, providers);
+        super.visitProvide(service, providers);
+    }
+
+    @Override
+    public void visitEnd() {
+        p.visitModuleEnd();
+        super.visitEnd();
+    }
+}
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/util/TraceSignatureVisitor.java	Thu Nov 02 13:18:23 2017 -0700
@@ -104,13 +104,13 @@
     private String separator = "";
 
     public TraceSignatureVisitor(final int access) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         isInterface = (access & Opcodes.ACC_INTERFACE) != 0;
         this.declaration = new StringBuilder();
     }
 
     private TraceSignatureVisitor(final StringBuilder buf) {
-        super(Opcodes.ASM5);
+        super(Opcodes.ASM6);
         this.declaration = buf;
     }
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt	Thu Nov 02 15:09:13 2017 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/version.txt	Thu Nov 02 13:18:23 2017 -0700
@@ -1,12 +1,4 @@
-Path: .
-Working Copy Root Path: /hudson/jobs/objectweb-init/workspace/asm-svn-2016-01-25
-URL: file:///svnroot/asm/trunk/asm
-Repository Root: file:///svnroot/asm
-Repository UUID: 271bd773-ee82-43a6-9b2b-1890ed8ce7f9
-Revision: 1795
-Node Kind: directory
-Schedule: normal
-Last Changed Author: ebruneton
-Last Changed Rev: 1795
-Last Changed Date: 2016-01-24 14:17:10 +0100 (Sun, 24 Jan 2016)
+ASM_6_0-11-gac81f5f
+origin	https://gitlab.ow2.org/asm/asm.git (fetch)
+ac81f5f Merge branch 'add-class-dump-tool-for-unit-tests' into 'master'
 
--- a/test/hotspot/jtreg/runtime/constantPool/ConstModule.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/test/hotspot/jtreg/runtime/constantPool/ConstModule.java	Thu Nov 02 13:18:23 2017 -0700
@@ -47,13 +47,13 @@
 
         // Test that the JVM throws CFE for constant pool CONSTANT_Module type, for
         // class file version 53, when ACC_MODULE is not set in the access_flags.
-        ConstModule.write_and_load(Opcodes.V1_9,
+        ConstModule.write_and_load(Opcodes.V9,
             Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC,
             "jdk.fooMod", "FooMod", MODULE_TEST, CFE_EXCEPTION);
 
         // Test that the JVM throws NCDFE for constant pool CONSTANT_Module type,
         // for class file version 53, when ACC_MODULE is set in the access_flags.
-        ConstModule.write_and_load(Opcodes.V1_9,
+        ConstModule.write_and_load(Opcodes.V9,
             Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
             "jdk.fooModACC", "FooModACC", MODULE_TEST, NCDFE_EXCEPTION);
 
@@ -65,13 +65,13 @@
 
         // Test that the JVM throws CFE for constant pool CONSTANT_Package type, for
         // class file version 53, when ACC_MODULE is not set in the access_flags.
-        ConstModule.write_and_load(Opcodes.V1_9,
+        ConstModule.write_and_load(Opcodes.V9,
             Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC,
             "jdk.fooPkg", "FooPkg", PACKAGE_TEST, CFE_EXCEPTION);
 
         // Test that the JVM throws NCDFE for constant pool CONSTANT_Package type,
         // for class file version 53, when ACC_MODULE is set in the access_flags.
-        ConstModule.write_and_load(Opcodes.V1_9,
+        ConstModule.write_and_load(Opcodes.V9,
             Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC + ACC_MODULE,
             "jdk.fooModACC", "FooModACC", PACKAGE_TEST, NCDFE_EXCEPTION);
 
--- a/test/jdk/java/lang/ModuleTests/AnnotationsTest.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/java/lang/ModuleTests/AnnotationsTest.java	Thu Nov 02 13:18:23 2017 -0700
@@ -34,13 +34,13 @@
 import java.util.List;
 import java.util.Set;
 
-import jdk.internal.module.ClassFileAttributes;
 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
 import jdk.internal.org.objectweb.asm.Attribute;
 import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassVisitor;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.commons.ModuleTargetAttribute;
 
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
@@ -48,6 +48,7 @@
 /**
  * @test
  * @modules java.base/jdk.internal.org.objectweb.asm
+ *          java.base/jdk.internal.org.objectweb.asm.commons
  *          java.base/jdk.internal.module
  *          java.xml
  * @run testng AnnotationsTest
@@ -113,14 +114,11 @@
             ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                              + ClassWriter.COMPUTE_FRAMES);
 
-            ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) { };
+            ClassVisitor cv = new ClassVisitor(Opcodes.ASM6, cw) { };
 
             ClassReader cr = new ClassReader(in);
-
             List<Attribute> attrs = new ArrayList<>();
-            attrs.add(new ClassFileAttributes.ModuleAttribute());
-            attrs.add(new ClassFileAttributes.ModulePackagesAttribute());
-            attrs.add(new ClassFileAttributes.ModuleTargetAttribute());
+            attrs.add(new ModuleTargetAttribute());
             cr.accept(cv, attrs.toArray(new Attribute[0]), 0);
 
             AnnotationVisitor annotationVisitor
--- a/test/jdk/java/lang/invoke/DefineClassTest.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/java/lang/invoke/DefineClassTest.java	Thu Nov 02 13:18:23 2017 -0700
@@ -243,7 +243,7 @@
     byte[] generateClass(String className) {
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(V1_9,
+        cw.visit(V9,
                 ACC_PUBLIC + ACC_SUPER,
                 className.replace(".", "/"),
                 null,
@@ -272,7 +272,7 @@
 
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(V1_9,
+        cw.visit(V9,
                 ACC_PUBLIC + ACC_SUPER,
                 className.replace(".", "/"),
                 null,
@@ -309,7 +309,7 @@
 
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(V1_9,
+        cw.visit(V9,
                 ACC_PUBLIC + ACC_SUPER,
                 className.replace(".", "/"),
                 null,
--- a/test/jdk/java/util/ServiceLoader/BadProvidersTest.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/java/util/ServiceLoader/BadProvidersTest.java	Thu Nov 02 13:18:23 2017 -0700
@@ -209,7 +209,7 @@
 
         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
                                          + ClassWriter.COMPUTE_FRAMES);
-        cw.visit(V1_9,
+        cw.visit(V9,
                 ACC_PUBLIC + ACC_SUPER,
                 "p/ProviderFactory",
                 null,
--- a/test/jdk/lib/testlibrary/ModuleTargetHelper.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/lib/testlibrary/ModuleTargetHelper.java	Thu Nov 02 13:18:23 2017 -0700
@@ -29,13 +29,9 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
 
 public class ModuleTargetHelper {
     private ModuleTargetHelper() {}
@@ -60,29 +56,12 @@
     }
 
     public static ModuleTarget read(InputStream in) throws IOException {
-        ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
-        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
-            @Override
-            public void visitAttribute(Attribute attr) {
-                if (attr instanceof ModuleTargetAttribute) {
-                    modTargets[0] = (ModuleTargetAttribute)attr;
-                }
-            }
-        };
-
-        // prototype of attributes that should be parsed
-        Attribute[] attrs = new Attribute[] {
-            new ModuleTargetAttribute()
-        };
-
-        // parse module-info.class
-        ClassReader cr = new ClassReader(in);
-        cr.accept(cv, attrs, 0);
-        if (modTargets[0] != null) {
-            return new ModuleTarget(modTargets[0].targetPlatform());
+        ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+        if (attrs.target() != null) {
+            return new ModuleTarget(attrs.target().targetPlatform());
+        } else {
+            return null;
         }
-
-        return null;
     }
 
     public static ModuleTarget read(ModuleReference modRef) throws IOException {
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m1/p1/Main.java	Thu Nov 02 13:18:23 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -34,35 +34,13 @@
 import java.util.Collections;
 import java.util.Set;
 
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
 
 public class Main {
     private static boolean hasModuleTarget(InputStream in) throws IOException {
-        ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
-        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
-            @Override
-            public void visitAttribute(Attribute attr) {
-                if (attr instanceof ModuleTargetAttribute) {
-                    modTargets[0] = (ModuleTargetAttribute)attr;
-                }
-            }
-        };
-
-        // prototype of attributes that should be parsed
-        Attribute[] attrs = new Attribute[] {
-            new ModuleTargetAttribute()
-        };
-
-        // parse module-info.class
-        ClassReader cr = new ClassReader(in);
-        cr.accept(cv, attrs, 0);
-        return modTargets[0] != null && modTargets[0].targetPlatform() != null;
+        ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+        return attrs.target() != null;
     }
 
     public static void main(String... args) throws Exception {
--- a/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java	Thu Nov 02 15:09:13 2017 -0700
+++ b/test/jdk/tools/jlink/plugins/SystemModuleDescriptors/src/m4/p4/Main.java	Thu Nov 02 13:18:23 2017 -0700
@@ -35,35 +35,13 @@
 import java.util.Map;
 import java.util.Set;
 
-import jdk.internal.module.ClassFileAttributes;
-import jdk.internal.module.ClassFileAttributes.ModuleTargetAttribute;
-import jdk.internal.module.ClassFileConstants;
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.internal.org.objectweb.asm.ClassVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.module.ModuleInfo;
+import jdk.internal.module.ModuleInfo.Attributes;
 
 public class Main {
     private static boolean hasModuleTarget(InputStream in) throws IOException {
-        ModuleTargetAttribute[] modTargets = new ModuleTargetAttribute[1];
-        ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
-            @Override
-            public void visitAttribute(Attribute attr) {
-                if (attr instanceof ModuleTargetAttribute) {
-                    modTargets[0] = (ModuleTargetAttribute)attr;
-                }
-            }
-        };
-
-        // prototype of attributes that should be parsed
-        Attribute[] attrs = new Attribute[] {
-            new ModuleTargetAttribute()
-        };
-
-        // parse module-info.class
-        ClassReader cr = new ClassReader(in);
-        cr.accept(cv, attrs, 0);
-        return modTargets[0] != null && modTargets[0].targetPlatform() != null;
+        ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
+        return attrs.target() != null;
     }
 
     private static boolean hasModuleTarget(String modName) throws IOException {