changeset 889:5cf6c432ef2f

6982999: tools must support -target 7 bytecodes Reviewed-by: jjg, jrose
author ksrini
date Tue, 18 Jan 2011 08:37:05 -0800
parents 19f9b6548c70
children b6f95173e769
files src/share/classes/com/sun/tools/classfile/Attribute.java src/share/classes/com/sun/tools/classfile/BootstrapMethods_attribute.java src/share/classes/com/sun/tools/classfile/ClassTranslator.java src/share/classes/com/sun/tools/classfile/ClassWriter.java src/share/classes/com/sun/tools/classfile/ConstantPool.java src/share/classes/com/sun/tools/classfile/Dependencies.java src/share/classes/com/sun/tools/javac/jvm/ClassFile.java src/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/share/classes/com/sun/tools/javap/AttributeWriter.java src/share/classes/com/sun/tools/javap/ConstantWriter.java
diffstat 10 files changed, 468 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/classfile/Attribute.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/classfile/Attribute.java	Tue Jan 18 08:37:05 2011 -0800
@@ -39,6 +39,7 @@
 
 public abstract class Attribute {
     public static final String AnnotationDefault        = "AnnotationDefault";
+    public static final String BootstrapMethods         = "BootstrapMethods";
     public static final String CharacterRangeTable      = "CharacterRangeTable";
     public static final String Code                     = "Code";
     public static final String ConstantValue            = "ConstantValue";
@@ -99,6 +100,7 @@
         protected void init() {
             standardAttributes = new HashMap<String,Class<? extends Attribute>>();
             standardAttributes.put(AnnotationDefault, AnnotationDefault_attribute.class);
+            standardAttributes.put(BootstrapMethods, BootstrapMethods_attribute.class);
             standardAttributes.put(CharacterRangeTable, CharacterRangeTable_attribute.class);
             standardAttributes.put(Code,              Code_attribute.class);
             standardAttributes.put(ConstantValue,     ConstantValue_attribute.class);
@@ -155,6 +157,7 @@
 
 
     public interface Visitor<R,P> {
+        R visitBootstrapMethods(BootstrapMethods_attribute attr, P p);
         R visitDefault(DefaultAttribute attr, P p);
         R visitAnnotationDefault(AnnotationDefault_attribute attr, P p);
         R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/BootstrapMethods_attribute.java	Tue Jan 18 08:37:05 2011 -0800
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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.
+ */
+
+package com.sun.tools.classfile;
+
+import java.io.IOException;
+
+/**
+ * See JVMS3 <TBD>
+ * http://cr.openjdk.java.net/~jrose/pres/indy-javadoc-mlvm/
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class BootstrapMethods_attribute extends Attribute {
+    public final BootstrapMethodSpecifier[] bootstrap_method_specifiers;
+
+    BootstrapMethods_attribute(ClassReader cr, int name_index, int length)
+            throws IOException, AttributeException {
+        super(name_index, length);
+        int bootstrap_method_count = cr.readUnsignedShort();
+        bootstrap_method_specifiers = new BootstrapMethodSpecifier[bootstrap_method_count];
+        for (int i = 0; i < bootstrap_method_specifiers.length; i++)
+            bootstrap_method_specifiers[i] = new BootstrapMethodSpecifier(cr);
+    }
+
+    public  BootstrapMethods_attribute(int name_index, BootstrapMethodSpecifier[] bootstrap_method_specifiers) {
+        super(name_index, length(bootstrap_method_specifiers));
+        this.bootstrap_method_specifiers = bootstrap_method_specifiers;
+    }
+
+    public static int length(BootstrapMethodSpecifier[] bootstrap_method_specifiers) {
+        int n = 2;
+        for (BootstrapMethodSpecifier b : bootstrap_method_specifiers)
+            n += b.length();
+        return n;
+    }
+
+    @Override
+    public <R, P> R accept(Visitor<R, P> visitor, P p) {
+        return visitor.visitBootstrapMethods(this, p);
+    }
+
+    public static class BootstrapMethodSpecifier {
+        public int bootstrap_method_ref;
+        public int[] bootstrap_arguments;
+
+        public BootstrapMethodSpecifier(int bootstrap_method_ref, int[] bootstrap_arguments) {
+            this.bootstrap_method_ref = bootstrap_method_ref;
+            this.bootstrap_arguments = bootstrap_arguments;
+        }
+        BootstrapMethodSpecifier(ClassReader cr) throws IOException {
+            bootstrap_method_ref = cr.readUnsignedShort();
+            int method_count = cr.readUnsignedShort();
+            bootstrap_arguments = new int[method_count];
+            for (int i = 0; i < bootstrap_arguments.length; i++) {
+                bootstrap_arguments[i] = cr.readUnsignedShort();
+            }
+        }
+
+        int length() {
+            // u2 (method_ref) + u2 (argc) + u2 * argc
+            return 2 + 2 + (bootstrap_arguments.length * 2);
+        }
+    }
+}
--- a/src/share/classes/com/sun/tools/classfile/ClassTranslator.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/classfile/ClassTranslator.java	Tue Jan 18 08:37:05 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2011 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
@@ -31,7 +31,10 @@
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Float_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Integer_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_InterfaceMethodref_info;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_InvokeDynamic_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Long_info;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodHandle_info;
+import com.sun.tools.classfile.ConstantPool.CONSTANT_MethodType_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_Methodref_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_NameAndType_info;
 import com.sun.tools.classfile.ConstantPool.CONSTANT_String_info;
@@ -304,6 +307,20 @@
         return info;
     }
 
+    public CPInfo visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Map<Object, Object> translations) {
+        CONSTANT_InvokeDynamic_info info2 = (CONSTANT_InvokeDynamic_info) translations.get(info);
+        if (info2 == null) {
+            ConstantPool cp2 = translate(info.cp, translations);
+            if (cp2 == info.cp) {
+                info2 = info;
+            } else {
+                info2 = new CONSTANT_InvokeDynamic_info(cp2, info.bootstrap_method_attr_index, info.name_and_type_index);
+            }
+            translations.put(info, info2);
+        }
+        return info;
+    }
+
     public CPInfo visitLong(CONSTANT_Long_info info, Map<Object, Object> translations) {
         CONSTANT_Long_info info2 = (CONSTANT_Long_info) translations.get(info);
         if (info2 == null) {
@@ -339,6 +356,34 @@
         return info;
     }
 
+    public CPInfo visitMethodHandle(CONSTANT_MethodHandle_info info, Map<Object, Object> translations) {
+        CONSTANT_MethodHandle_info info2 = (CONSTANT_MethodHandle_info) translations.get(info);
+        if (info2 == null) {
+            ConstantPool cp2 = translate(info.cp, translations);
+            if (cp2 == info.cp) {
+                info2 = info;
+            } else {
+                info2 = new CONSTANT_MethodHandle_info(cp2, info.reference_kind, info.reference_index);
+            }
+            translations.put(info, info2);
+        }
+        return info;
+    }
+
+    public CPInfo visitMethodType(CONSTANT_MethodType_info info, Map<Object, Object> translations) {
+        CONSTANT_MethodType_info info2 = (CONSTANT_MethodType_info) translations.get(info);
+        if (info2 == null) {
+            ConstantPool cp2 = translate(info.cp, translations);
+            if (cp2 == info.cp) {
+                info2 = info;
+            } else {
+                info2 = new CONSTANT_MethodType_info(cp2, info.descriptor_index);
+            }
+            translations.put(info, info2);
+        }
+        return info;
+    }
+
     public CPInfo visitString(CONSTANT_String_info info, Map<Object, Object> translations) {
         CONSTANT_String_info info2 = (CONSTANT_String_info) translations.get(info);
         if (info2 == null) {
--- a/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Tue Jan 18 08:37:05 2011 -0800
@@ -267,6 +267,12 @@
             return 1;
         }
 
+        public Integer visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, ClassOutputStream out) {
+            out.writeShort(info.bootstrap_method_attr_index);
+            out.writeShort(info.name_and_type_index);
+            return 1;
+        }
+
         public Integer visitLong(CONSTANT_Long_info info, ClassOutputStream out) {
             out.writeLong(info.value);
             return 2;
@@ -278,6 +284,17 @@
             return 1;
         }
 
+        public Integer visitMethodHandle(CONSTANT_MethodHandle_info info, ClassOutputStream out) {
+            out.writeByte(info.reference_kind.tag);
+            out.writeShort(info.reference_index);
+            return 1;
+        }
+
+        public Integer visitMethodType(CONSTANT_MethodType_info info, ClassOutputStream out) {
+            out.writeShort(info.descriptor_index);
+            return 1;
+        }
+
         public Integer visitMethodref(CONSTANT_Methodref_info info, ClassOutputStream out) {
             return writeRef(info, out);
         }
@@ -332,6 +349,19 @@
             return null;
         }
 
+        public Void visitBootstrapMethods(BootstrapMethods_attribute attr, ClassOutputStream out) {
+            out.writeShort(attr.bootstrap_method_specifiers.length);
+            for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsm : attr.bootstrap_method_specifiers) {
+                out.writeShort(bsm.bootstrap_method_ref);
+                int bsm_args_count = bsm.bootstrap_arguments.length;
+                out.writeShort(bsm_args_count);
+                for (int i : bsm.bootstrap_arguments) {
+                    out.writeShort(i);
+                }
+            }
+            return null;
+        }
+
         public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, ClassOutputStream out) {
             out.writeShort(attr.character_range_table.length);
             for (CharacterRangeTable_attribute.Entry e: attr.character_range_table)
--- a/src/share/classes/com/sun/tools/classfile/ConstantPool.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/classfile/ConstantPool.java	Tue Jan 18 08:37:05 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2011, 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
@@ -114,6 +114,54 @@
     public static final int CONSTANT_Methodref = 10;
     public static final int CONSTANT_InterfaceMethodref = 11;
     public static final int CONSTANT_NameAndType = 12;
+    public static final int CONSTANT_MethodHandle = 15;
+    public static final int CONSTANT_MethodType = 16;
+    public static final int CONSTANT_InvokeDynamic = 18;
+
+    public static enum RefKind {
+        REF_getField(1, "getfield"),
+        REF_getStatic(2, "getstatic"),
+        REF_putField(3, "putfield"),
+        REF_putStatic(4, "putstatic"),
+        REF_invokeVirtual(5, "invokevirtual"),
+        REF_invokeStatic(6, "invokestatic"),
+        REF_invokeSpecial(7, "invokespecial"),
+        REF_newInvokeSpecial(8, "newinvokespecial"),
+        REF_invokeInterface(9, "invokeinterface");
+
+        public final int tag;
+        public final String name;
+
+        RefKind(int tag, String name) {
+            this.tag = tag;
+            this.name = name;
+        }
+
+        static RefKind getRefkind(int tag) {
+            switch(tag) {
+                case 1:
+                    return REF_getField;
+                case 2:
+                    return REF_getStatic;
+                case 3:
+                    return REF_putField;
+                case 4:
+                    return REF_putStatic;
+                case 5:
+                    return REF_invokeVirtual;
+                case 6:
+                    return REF_invokeStatic;
+                case 7:
+                    return REF_invokeSpecial;
+                case 8:
+                    return REF_newInvokeSpecial;
+                case 9:
+                    return REF_invokeInterface;
+                default:
+                    return null;
+            }
+        }
+    }
 
     ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
         int count = cr.readUnsignedShort();
@@ -146,11 +194,23 @@
                 pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
                 break;
 
+            case CONSTANT_InvokeDynamic:
+                pool[i] = new CONSTANT_InvokeDynamic_info(this, cr);
+                break;
+
             case CONSTANT_Long:
                 pool[i] = new CONSTANT_Long_info(cr);
                 i++;
                 break;
 
+            case CONSTANT_MethodHandle:
+                pool[i] = new CONSTANT_MethodHandle_info(this, cr);
+                break;
+
+            case CONSTANT_MethodType:
+                pool[i] = new CONSTANT_MethodType_info(this, cr);
+                break;
+
             case CONSTANT_Methodref:
                 pool[i] = new CONSTANT_Methodref_info(this, cr);
                 break;
@@ -279,9 +339,12 @@
         R visitFloat(CONSTANT_Float_info info, P p);
         R visitInteger(CONSTANT_Integer_info info, P p);
         R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
+        R visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, P p);
         R visitLong(CONSTANT_Long_info info, P p);
         R visitNameAndType(CONSTANT_NameAndType_info info, P p);
         R visitMethodref(CONSTANT_Methodref_info info, P p);
+        R visitMethodHandle(CONSTANT_MethodHandle_info info, P p);
+        R visitMethodType(CONSTANT_MethodType_info info, P p);
         R visitString(CONSTANT_String_info info, P p);
         R visitUtf8(CONSTANT_Utf8_info info, P p);
     }
@@ -548,6 +611,44 @@
         }
     }
 
+    public static class CONSTANT_InvokeDynamic_info extends CPInfo {
+        CONSTANT_InvokeDynamic_info(ConstantPool cp, ClassReader cr) throws IOException {
+            super(cp);
+            bootstrap_method_attr_index = cr.readUnsignedShort();
+            name_and_type_index = cr.readUnsignedShort();
+        }
+
+        public CONSTANT_InvokeDynamic_info(ConstantPool cp, int bootstrap_method_index, int name_and_type_index) {
+            super(cp);
+            this.bootstrap_method_attr_index = bootstrap_method_index;
+            this.name_and_type_index = name_and_type_index;
+        }
+
+        public int getTag() {
+            return CONSTANT_InvokeDynamic;
+        }
+
+        public int byteLength() {
+            return 5;
+        }
+
+        @Override
+        public String toString() {
+            return "CONSTANT_InvokeDynamic_info[bootstrap_method_index: " + bootstrap_method_attr_index + ", name_and_type_index: " + name_and_type_index + "]";
+        }
+
+        public <R, D> R accept(Visitor<R, D> visitor, D data) {
+            return visitor.visitInvokeDynamic(this, data);
+        }
+
+        public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
+            return cp.getNameAndTypeInfo(name_and_type_index);
+        }
+
+        public final int bootstrap_method_attr_index;
+        public final int name_and_type_index;
+    }
+
     public static class CONSTANT_Long_info extends CPInfo {
         CONSTANT_Long_info(ClassReader cr) throws IOException {
             value = cr.readLong();
@@ -582,6 +683,87 @@
         public final long value;
     }
 
+    public static class CONSTANT_MethodHandle_info extends CPInfo {
+        CONSTANT_MethodHandle_info(ConstantPool cp, ClassReader cr) throws IOException {
+            super(cp);
+            reference_kind =  RefKind.getRefkind(cr.readUnsignedByte());
+            reference_index = cr.readUnsignedShort();
+        }
+
+        public CONSTANT_MethodHandle_info(ConstantPool cp, RefKind ref_kind, int member_index) {
+            super(cp);
+            this.reference_kind = ref_kind;
+            this.reference_index = member_index;
+        }
+
+        public int getTag() {
+            return CONSTANT_MethodHandle;
+        }
+
+        public int byteLength() {
+            return 4;
+        }
+
+        @Override
+        public String toString() {
+            return "CONSTANT_MethodHandle_info[ref_kind: " + reference_kind + ", member_index: " + reference_index + "]";
+        }
+
+        public <R, D> R accept(Visitor<R, D> visitor, D data) {
+            return visitor.visitMethodHandle(this, data);
+        }
+
+        public CPRefInfo getCPRefInfo() throws ConstantPoolException {
+            int expected = CONSTANT_Methodref;
+            int actual = cp.get(reference_index).getTag();
+            // allow these tag types also:
+            switch (actual) {
+                case CONSTANT_Fieldref:
+                case CONSTANT_InterfaceMethodref:
+                    expected = actual;
+            }
+            return (CPRefInfo) cp.get(reference_index, expected);
+        }
+
+        public final RefKind reference_kind;
+        public final int reference_index;
+    }
+
+    public static class CONSTANT_MethodType_info extends CPInfo {
+        CONSTANT_MethodType_info(ConstantPool cp, ClassReader cr) throws IOException {
+            super(cp);
+            descriptor_index = cr.readUnsignedShort();
+        }
+
+        public CONSTANT_MethodType_info(ConstantPool cp, int signature_index) {
+            super(cp);
+            this.descriptor_index = signature_index;
+        }
+
+        public int getTag() {
+            return CONSTANT_MethodType;
+        }
+
+        public int byteLength() {
+            return 3;
+        }
+
+        @Override
+        public String toString() {
+            return "CONSTANT_MethodType_info[signature_index: " + descriptor_index + "]";
+        }
+
+        public <R, D> R accept(Visitor<R, D> visitor, D data) {
+            return visitor.visitMethodType(this, data);
+        }
+
+        public String getType() throws ConstantPoolException {
+            return cp.getUTF8Value(descriptor_index);
+        }
+
+        public final int descriptor_index;
+    }
+
     public static class CONSTANT_Methodref_info extends CPRefInfo {
         CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
             super(cp, cr, CONSTANT_Methodref);
@@ -729,5 +911,4 @@
         public final String value;
     }
 
-
 }
--- a/src/share/classes/com/sun/tools/classfile/Dependencies.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/classfile/Dependencies.java	Tue Jan 18 08:37:05 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011 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
@@ -626,10 +626,26 @@
                 return visitRef(info, p);
             }
 
+            public Void visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
+                return null;
+            }
+
             public Void visitLong(CONSTANT_Long_info info, Void p) {
                 return null;
             }
 
+            public Void visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
+                return null;
+            }
+
+            public Void visitMethodType(CONSTANT_MethodType_info info, Void p) {
+                return null;
+            }
+
+            public Void visitMethodref(CONSTANT_Methodref_info info, Void p) {
+                return visitRef(info, p);
+            }
+
             public Void visitNameAndType(CONSTANT_NameAndType_info info, Void p) {
                 try {
                     new Signature(info.type_index).getType(constant_pool).accept(this, null);
@@ -639,10 +655,6 @@
                 }
             }
 
-            public Void visitMethodref(CONSTANT_Methodref_info info, Void p) {
-                return visitRef(info, p);
-            }
-
             public Void visitString(CONSTANT_String_info info, Void p) {
                 return null;
             }
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassFile.java	Tue Jan 18 08:37:05 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, 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
@@ -80,6 +80,9 @@
     public final static int CONSTANT_Methodref = 10;
     public final static int CONSTANT_InterfaceMethodref = 11;
     public final static int CONSTANT_NameandType = 12;
+    public final static int CONSTANT_MethodHandle = 15;
+    public final static int CONSTANT_MethodType = 16;
+    public final static int CONSTANT_InvokeDynamic = 18;
 
     public final static int MAX_PARAMETERS = 0xff;
     public final static int MAX_DIMENSIONS = 0xff;
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Jan 18 08:37:05 2011 -0800
@@ -434,14 +434,19 @@
             }
             case CONSTANT_Class:
             case CONSTANT_String:
+            case CONSTANT_MethodType:
                 bp = bp + 2;
                 break;
+            case CONSTANT_MethodHandle:
+                bp = bp + 3;
+                break;
             case CONSTANT_Fieldref:
             case CONSTANT_Methodref:
             case CONSTANT_InterfaceMethodref:
             case CONSTANT_NameandType:
             case CONSTANT_Integer:
             case CONSTANT_Float:
+            case CONSTANT_InvokeDynamic:
                 bp = bp + 4;
                 break;
             case CONSTANT_Long:
@@ -510,6 +515,15 @@
         case CONSTANT_Double:
             poolObj[i] = new Double(getDouble(index + 1));
             break;
+        case CONSTANT_MethodHandle:
+            skipBytes(4);
+            break;
+        case CONSTANT_MethodType:
+            skipBytes(3);
+            break;
+        case CONSTANT_InvokeDynamic:
+            skipBytes(5);
+            break;
         default:
             throw badClassFile("bad.const.pool.tag", Byte.toString(tag));
         }
@@ -1821,6 +1835,13 @@
         sym.savedParameterNames = paramNames.reverse();
     }
 
+    /**
+     * skip n bytes
+     */
+    void skipBytes(int n) {
+        bp = bp + n;
+    }
+
     /** Skip a field or method
      */
     void skipMember() {
--- a/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Tue Jan 18 08:37:05 2011 -0800
@@ -31,6 +31,7 @@
 import com.sun.tools.classfile.AnnotationDefault_attribute;
 import com.sun.tools.classfile.Attribute;
 import com.sun.tools.classfile.Attributes;
+import com.sun.tools.classfile.BootstrapMethods_attribute;
 import com.sun.tools.classfile.CharacterRangeTable_attribute;
 import com.sun.tools.classfile.Code_attribute;
 import com.sun.tools.classfile.CompilationID_attribute;
@@ -151,6 +152,25 @@
         return null;
     }
 
+    public Void visitBootstrapMethods(BootstrapMethods_attribute attr, Void p) {
+        println(Attribute.BootstrapMethods + ":");
+        for (int i = 0; i < attr.bootstrap_method_specifiers.length ; i++) {
+            BootstrapMethods_attribute.BootstrapMethodSpecifier bsm = attr.bootstrap_method_specifiers[i];
+            indent(+1);
+            print(i + ": #" + bsm.bootstrap_method_ref + " ");
+            println(constantWriter.stringValue(bsm.bootstrap_method_ref));
+            indent(+1);
+            println("Method arguments:");
+            indent(+1);
+            for (int j = 0; j < bsm.bootstrap_arguments.length; j++) {
+                print("#" + bsm.bootstrap_arguments[j] + " ");
+                println(constantWriter.stringValue(bsm.bootstrap_arguments[j]));
+            }
+            indent(-3);
+        }
+        return null;
+    }
+
     public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
         println("CharacterRangeTable:");
         indent(+1);
--- a/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Fri Jan 14 13:59:18 2011 -0800
+++ b/src/share/classes/com/sun/tools/javap/ConstantWriter.java	Tue Jan 18 08:37:05 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2011, 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
@@ -97,6 +97,13 @@
                 return 1;
             }
 
+            public Integer visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
+                print("#" + info.bootstrap_method_attr_index + ":#" + info.name_and_type_index);
+                tab();
+                println("//  " + stringValue(info));
+                return 1;
+            }
+
             public Integer visitLong(CONSTANT_Long_info info, Void p) {
                 println(stringValue(info));
                 return 2;
@@ -116,6 +123,20 @@
                 return 1;
             }
 
+            public Integer visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
+                print("#" + info.reference_kind.tag + ":#" + info.reference_index);
+                tab();
+                println("//  " + stringValue(info));
+                return 1;
+            }
+
+            public Integer visitMethodType(CONSTANT_MethodType_info info, Void p) {
+                print("#" + info.descriptor_index);
+                tab();
+                println("//  " + stringValue(info));
+                return 1;
+            }
+
             public Integer visitString(CONSTANT_String_info info, Void p) {
                 print("#" + info.string_index);
                 tab();
@@ -201,14 +222,20 @@
                 return "String";
             case CONSTANT_Fieldref:
                 return "Field";
+            case CONSTANT_MethodHandle:
+                return "MethodHandle";
+            case CONSTANT_MethodType:
+                return "MethodType";
             case CONSTANT_Methodref:
                 return "Method";
             case CONSTANT_InterfaceMethodref:
                 return "InterfaceMethod";
+            case CONSTANT_InvokeDynamic:
+                return "InvokeDynamic";
             case CONSTANT_NameAndType:
                 return "NameAndType";
             default:
-                return "(unknown tag)";
+                return "(unknown tag " + tag + ")";
         }
     }
 
@@ -264,6 +291,15 @@
             return visitRef(info, p);
         }
 
+        public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) {
+            try {
+                String callee = stringValue(info.getNameAndTypeInfo());
+                return "#" + info.bootstrap_method_attr_index + ":" + callee;
+            } catch (ConstantPoolException e) {
+                return report(e);
+            }
+        }
+
         public String visitLong(CONSTANT_Long_info info, Void p) {
             return info.value + "l";
         }
@@ -288,6 +324,22 @@
             }
         }
 
+        public String visitMethodHandle(CONSTANT_MethodHandle_info info, Void p) {
+            try {
+                return info.reference_kind.name + " " + stringValue(info.getCPRefInfo());
+            } catch (ConstantPoolException e) {
+                return report(e);
+            }
+        }
+
+        public String visitMethodType(CONSTANT_MethodType_info info, Void p) {
+            try {
+                return info.getType();
+            } catch (ConstantPoolException e) {
+                return report(e);
+            }
+        }
+
         public String visitMethodref(CONSTANT_Methodref_info info, Void p) {
             return visitRef(info, p);
         }
@@ -347,7 +399,6 @@
         }
     }
 
-
     /* If name is a valid binary name, return it; otherwise quote it. */
     private static String checkName(String name) {
         if (name == null)