changeset 14045:836efde938c1

Add support for species static access. * add support for species static in Model3Converter * add species static support in private copy of classfile library * optimize bootstrap method for dispatching specializable static/species static calls
author mcimadamore
date Fri, 27 May 2016 14:18:22 +0100
parents c82dff06b0d6
children 4aa612ffd864
files src/java.base/share/classes/java/lang/invoke/GenericStaticDispatch.java src/java.base/share/classes/valhalla/model3/Model3Converter.java src/java.base/share/classes/valhalla/model3/classfile/AccessFlags.java
diffstat 3 files changed, 51 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/invoke/GenericStaticDispatch.java	Wed Apr 27 14:49:23 2016 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/GenericStaticDispatch.java	Fri May 27 14:18:22 2016 +0100
@@ -12,7 +12,6 @@
                                        Object... args) throws ReflectiveOperationException {
         DispatchContext dispatchContext = new DispatchContext(invokedName, invokedType, caller, args);
         Class<?> inner = Class.forName(dispatchContext.innerName(dispatchContext.receiverClass), false, dispatchContext.getLoader());
-        Object receiver = inner.newInstance();
-        return new ConstantCallSite(caller.findVirtual(inner, invokedName, invokedType).bindTo(receiver));
+        return new ConstantCallSite(caller.findStatic(inner, invokedName, invokedType));
     }
 }
--- a/src/java.base/share/classes/valhalla/model3/Model3Converter.java	Wed Apr 27 14:49:23 2016 +0200
+++ b/src/java.base/share/classes/valhalla/model3/Model3Converter.java	Fri May 27 14:18:22 2016 +0100
@@ -275,9 +275,14 @@
                     .toArray(Method[]::new);
             Field[] fields = Stream.of(cf.fields)
                     .filter(f -> needsField(erased, f))
+                    .map(m -> mangleField(newCp, m))
                     .toArray(Field[]::new);
+            AccessFlags access = cf.access_flags;
+            if (access.is(AccessFlags.ACC_SPECIES)) {
+                access = access.ignore(AccessFlags.ACC_SPECIES).or(AccessFlags.ACC_STATIC);
+            }
             ClassFile outClass = new ClassFile(cf.magic, 0, cf.major_version,
-                                               newCp, cf.access_flags, cf.this_class, cf.super_class, cf.interfaces,
+                                               newCp, access, cf.this_class, cf.super_class, cf.interfaces,
                                                fields, mangledMethods, cf.attributes);
 
             ClassWriter cw = new ClassWriter();
@@ -295,9 +300,10 @@
     }
 
     boolean needsMethod(boolean erased, String[] bindings, ConstantPool cp, Method m) {
-        if (!erased && m.access_flags.is(AccessFlags.ACC_STATIC)) {
-            //check for static specializable methods (species statics)
-            return m.attributes.get(Attribute.SpecializerSignature) != null;
+        if (erased && getUTF8(m.name_index, cp).equals("<sclinit>")) {
+            return false;
+        } else if (!erased && m.access_flags.is(AccessFlags.ACC_STATIC)) {
+            return false;
         } else {
             Where_attribute where_attribute = (Where_attribute)m.attributes.get(Attribute.Where);
             if (where_attribute != null) {
@@ -412,6 +418,14 @@
         }
     }
 
+    private Field mangleField(ConstantPool cp, Field f) {
+        AccessFlags access = f.access_flags;
+        if (access.is(AccessFlags.ACC_SPECIES)) {
+            access = access.ignore(AccessFlags.ACC_SPECIES).or(AccessFlags.ACC_STATIC);
+        }
+        return new Field(access, f.name_index, f.descriptor, f.attributes);
+    }
+
     private Method mangleMethod(ConstantPool cp, Method m) {
         Attribute[] attrs = m.attributes.attrs.clone();
         boolean changed = false;
@@ -425,7 +439,20 @@
         if (!changed)
             return m;
 
-        return new Method(m.access_flags, m.name_index, m.descriptor, new Attributes(cp, attrs));
+        int name_index = m.name_index;
+        if (getUTF8(name_index, cp).equals("<sclinit>")) {
+            try {
+                name_index = cp.getUTF8Index("<clinit>");
+            } catch (Throwable ex) { }
+        }
+
+        AccessFlags access = m.access_flags;
+        if (access.is(AccessFlags.ACC_SPECIES)) {
+            access = access.ignore(AccessFlags.ACC_SPECIES).or(AccessFlags.ACC_STATIC);
+        }
+
+
+        return new Method(access, name_index, m.descriptor, new Attributes(cp, attrs));
     }
 
     private Code_attribute mangleCode(Code_attribute old, ConstantPool cp) {
--- a/src/java.base/share/classes/valhalla/model3/classfile/AccessFlags.java	Wed Apr 27 14:49:23 2016 +0200
+++ b/src/java.base/share/classes/valhalla/model3/classfile/AccessFlags.java	Fri May 27 14:18:22 2016 +0100
@@ -60,7 +60,8 @@
     public static final int ACC_ANNOTATION    = 0x2000; // class, inner
     public static final int ACC_VALUEFACTORY  = 0x2000; //                      method
     public static final int ACC_ENUM          = 0x4000; // class, inner, field
-    public static final int ACC_MANDATED      = 0x8000; // class, inner, field, method
+    public static final int ACC_MANDATED      = 0x8000; // method parameters
+    public static final int ACC_SPECIES       = 0x8000; // class, inner, field, method
 
     public static enum Kind { Class, InnerClass, Field, Method}
 
@@ -72,8 +73,12 @@
         this.flags = flags;
     }
 
-    public valhalla.model3.classfile.AccessFlags ignore(int mask) {
-        return new valhalla.model3.classfile.AccessFlags(flags & ~mask);
+    public AccessFlags ignore(int mask) {
+        return new AccessFlags(flags & ~mask);
+    }
+
+    public AccessFlags or(int mask) {
+        return new AccessFlags(flags | mask);
     }
 
     public boolean is(int mask) {
@@ -104,12 +109,12 @@
 
     private static final int[] innerClassModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_ABSTRACT, ACC_VALUE
+        ACC_ABSTRACT, ACC_VALUE, ACC_SPECIES
     };
 
     private static final int[] innerClassFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER,
-        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_VALUE
+        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_VALUE, ACC_SPECIES
     };
 
     public Set<String> getInnerClassModifiers() {
@@ -123,12 +128,12 @@
 
     private static final int[] fieldModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_VOLATILE, ACC_TRANSIENT
+        ACC_VOLATILE, ACC_TRANSIENT, ACC_SPECIES
     };
 
     private static final int[] fieldFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM
+        ACC_VOLATILE, ACC_TRANSIENT, ACC_SYNTHETIC, ACC_ENUM, ACC_SPECIES
     };
 
     public Set<String> getFieldModifiers() {
@@ -141,13 +146,13 @@
 
     private static final int[] methodModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT
+        ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT, ACC_SPECIES
     };
 
     private static final int[] methodFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
         ACC_SYNCHRONIZED, ACC_BRIDGE, ACC_VARARGS, ACC_NATIVE, ACC_ABSTRACT,
-        ACC_STRICT, ACC_SYNTHETIC, ACC_VALUEFACTORY
+        ACC_STRICT, ACC_SYNTHETIC, ACC_VALUEFACTORY, ACC_SPECIES
     };
 
     public Set<String> getMethodModifiers() {
@@ -212,8 +217,8 @@
                 return "abstract";
             case ACC_STRICT:
                 return "strictfp";
-            case ACC_MANDATED:
-                return "mandated";
+            case ACC_SPECIES:
+                return "species";
             default:
                 return null;
         }
@@ -251,8 +256,8 @@
             return (t == Kind.Method ? "ACC_VALUEFACTORY" : "ACC_ANNOTATION");
         case ACC_ENUM:
             return "ACC_ENUM";
-        case ACC_MANDATED:
-            return "ACC_MANDATED";
+        case ACC_SPECIES:
+            return "ACC_SPECIES";
         default:
             return null;
         }