changeset 2993:b91634e5f051

Enhancement: add support for Bridge attribute. Help specializer by emitting a Bridge attribute that points (through a MethodHandle) to the bridged method.
author mcimadamore
date Fri, 29 May 2015 16:51:55 +0100
parents c5b28bea0a2b
children 761d199068c7
files src/jdk.compiler/share/classes/com/sun/tools/classfile/Attribute.java src/jdk.compiler/share/classes/com/sun/tools/classfile/Bridge_attribute.java src/jdk.compiler/share/classes/com/sun/tools/classfile/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javap/AttributeWriter.java test/lib/annotations/annotations/classfile/ClassfileInspector.java test/tools/javac/MethodParameters/AttributeVisitor.java
diffstat 9 files changed, 111 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/classfile/Attribute.java	Thu May 28 12:34:24 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/classfile/Attribute.java	Fri May 29 16:51:55 2015 +0100
@@ -40,6 +40,7 @@
 public abstract class Attribute {
     public static final String AnnotationDefault        = "AnnotationDefault";
     public static final String BootstrapMethods         = "BootstrapMethods";
+    public static final String Bridge                   = "Bridge";
     public static final String CharacterRangeTable      = "CharacterRangeTable";
     public static final String Code                     = "Code";
     public static final String ConstantValue            = "ConstantValue";
@@ -108,6 +109,7 @@
         protected void init() {
             standardAttributes = new HashMap<>();
             standardAttributes.put(AnnotationDefault, AnnotationDefault_attribute.class);
+            standardAttributes.put(Bridge, Bridge_attribute.class);
             standardAttributes.put(BootstrapMethods,  BootstrapMethods_attribute.class);
             standardAttributes.put(CharacterRangeTable, CharacterRangeTable_attribute.class);
             standardAttributes.put(Code,              Code_attribute.class);
@@ -167,6 +169,7 @@
 
     public interface Visitor<R,P> {
         R visitBootstrapMethods(BootstrapMethods_attribute attr, P p);
+        R visitBridge(Bridge_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/jdk.compiler/share/classes/com/sun/tools/classfile/Bridge_attribute.java	Fri May 29 16:51:55 2015 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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;
+
+/**
+ *  <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 Bridge_attribute extends Attribute {
+    Bridge_attribute(ClassReader cr, int name_index, int length) throws IOException {
+        super(name_index, length);
+        bridge_index = cr.readUnsignedShort();
+    }
+
+    public Bridge_attribute(ConstantPool constant_pool, int bridge_index)
+            throws ConstantPoolException {
+        this(constant_pool.getUTF8Index(Attribute.Bridge), bridge_index);
+    }
+
+    public Bridge_attribute(int name_index, int bridge_index) {
+        super(name_index, 2);
+        this.bridge_index = bridge_index;
+    }
+
+    public <R, P> R accept(Visitor<R, P> visitor, P p) {
+        return visitor.visitBridge(this, p);
+    }
+
+    public final int bridge_index;
+}
--- a/src/jdk.compiler/share/classes/com/sun/tools/classfile/ClassWriter.java	Thu May 28 12:34:24 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/classfile/ClassWriter.java	Fri May 29 16:51:55 2015 +0100
@@ -359,6 +359,11 @@
             return null;
         }
 
+        public Void visitBridge(Bridge_attribute attr, ClassOutputStream out) {
+            out.writeShort(attr.bridge_index);
+            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/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Thu May 28 12:34:24 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri May 29 16:51:55 2015 +0100
@@ -269,7 +269,12 @@
         MethodSymbol bridge = new MethodSymbol(flags,
                                                meth.name,
                                                bridgeType,
-                                               origin);
+                                               origin) {
+            @Override
+            public Symbol baseSymbol() {
+                return impl;
+            }
+        };
         /* once JDK-6996415 is solved it should be checked if this approach can
          * be applied to method addOverrideBridgesIfNeeded
          */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Thu May 28 12:34:24 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri May 29 16:51:55 2015 +0100
@@ -1107,7 +1107,7 @@
 
             new AttributeReader(names.Bridge, V49, MEMBER_ATTRIBUTE) {
                 protected void read(Symbol sym, int attrLen) {
-                    sym.flags_field |= BRIDGE;
+                    nextChar(); //skip CP entry
                 }
             },
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Thu May 28 12:34:24 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri May 29 16:51:55 2015 +0100
@@ -595,6 +595,18 @@
         return acount;
     }
 
+    /** Write bridge method attribute
+     */
+    int writeBridgeAttr(Symbol s) {
+        int alenIdx = writeAttr(names.Bridge);
+        Symbol impl = s.baseSymbol();
+        int kind = impl.enclClass().isInterface() ?
+                ClassFile.REF_invokeInterface : ClassFile.REF_invokeVirtual;
+        databuf.appendChar(pool.put(new MethodHandle(kind, impl, types)));
+        endAttr(alenIdx);
+        return 1;
+    }
+
     /** Write member (field or method) attributes;
      *  return number of attributes written.
      */
@@ -1220,6 +1232,9 @@
         if (m.whereClauses != WhereClause.emptyWhereClause) {
             acount += writeMethodWhereClauses(m);
         }
+        if ((m.flags() & BRIDGE) != 0) {
+            acount += writeBridgeAttr(m);
+        }
         acount += writeMemberAttrs(m);
         acount += writeParameterAttrs(m);
         acount += writeTypeVariablesMapIfNeeded(m);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javap/AttributeWriter.java	Thu May 28 12:34:24 2015 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javap/AttributeWriter.java	Fri May 29 16:51:55 2015 +0100
@@ -32,6 +32,7 @@
 import com.sun.tools.classfile.Attribute;
 import com.sun.tools.classfile.Attributes;
 import com.sun.tools.classfile.BootstrapMethods_attribute;
+import com.sun.tools.classfile.Bridge_attribute;
 import com.sun.tools.classfile.BytecodeMapping_attribute;
 import com.sun.tools.classfile.CharacterRangeTable_attribute;
 import com.sun.tools.classfile.Code_attribute;
@@ -182,6 +183,11 @@
         return null;
     }
 
+    public Void visitBridge(Bridge_attribute attr, Void ignore) {
+        println("Bridge: \"" + constantWriter.stringValue(attr.bridge_index) + "\"");
+        return null;
+    }
+
     public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr, Void ignore) {
         println("CharacterRangeTable:");
         indent(+1);
--- a/test/lib/annotations/annotations/classfile/ClassfileInspector.java	Thu May 28 12:34:24 2015 +0100
+++ b/test/lib/annotations/annotations/classfile/ClassfileInspector.java	Fri May 29 16:51:55 2015 +0100
@@ -1181,6 +1181,11 @@
         }
 
         @Override
+        public Void visitBridge(Bridge_attribute attr, ExpectedTypeAnnotation expected) {
+            return null;
+        }
+
+            @Override
         public Void visitDefault(DefaultAttribute attr,
                                  ExpectedTypeAnnotation expected) {
             return null;
@@ -1383,6 +1388,12 @@
             }
 
             @Override
+                public Void visitBridge(Bridge_attribute attr,
+                                        ExpectedAnnotation expected) {
+                return null;
+            }
+
+            @Override
                 public Void visitDefault(DefaultAttribute attr,
                                          ExpectedAnnotation expected) {
                 return null;
@@ -1586,6 +1597,12 @@
             }
 
             @Override
+                public Void visitBridge(Bridge_attribute attr,
+                                        ExpectedParameterAnnotation expected) {
+                return null;
+            }
+
+            @Override
                 public Void visitDefault(DefaultAttribute attr,
                                          ExpectedParameterAnnotation expected) {
                 return null;
--- a/test/tools/javac/MethodParameters/AttributeVisitor.java	Thu May 28 12:34:24 2015 +0100
+++ b/test/tools/javac/MethodParameters/AttributeVisitor.java	Fri May 29 16:51:55 2015 +0100
@@ -29,6 +29,7 @@
  */
 class AttributeVisitor<R, P> implements Attribute.Visitor<R, P> {
     public R visitBootstrapMethods(BootstrapMethods_attribute attr, P p) { return null; }
+    public R visitBridge(Bridge_attribute attr, P p) { return null; }
     public R visitDefault(DefaultAttribute attr, P p) { return null; }
     public R visitAnnotationDefault(AnnotationDefault_attribute attr, P p) { return null; }
     public R visitCharacterRangeTable(CharacterRangeTable_attribute attr, P p) { return null; }