Merge
authorchegar
Tue, 18 Jun 2013 09:39:25 +0100
changeset 18276 63b45dc8848c
parent 18275 9e7a5558965d (current diff)
parent 18182 a86f1b828425 (diff)
child 18277 758564251f75
Merge
jdk/src/share/classes/java/lang/Class.java
--- a/jdk/src/share/classes/java/lang/Class.java	Mon Jun 17 14:23:01 2013 +0100
+++ b/jdk/src/share/classes/java/lang/Class.java	Tue Jun 18 09:39:25 2013 +0100
@@ -708,8 +708,9 @@
      */
     @SuppressWarnings("unchecked")
     public TypeVariable<Class<T>>[] getTypeParameters() {
-        if (getGenericSignature() != null)
-            return (TypeVariable<Class<T>>[])getGenericInfo().getTypeParameters();
+        ClassRepository info = getGenericInfo();
+        if (info != null)
+            return (TypeVariable<Class<T>>[])info.getTypeParameters();
         else
             return (TypeVariable<Class<T>>[])new TypeVariable<?>[0];
     }
@@ -759,15 +760,19 @@
      * @since 1.5
      */
     public Type getGenericSuperclass() {
-        if (getGenericSignature() != null) {
-            // Historical irregularity:
-            // Generic signature marks interfaces with superclass = Object
-            // but this API returns null for interfaces
-            if (isInterface())
-                return null;
-            return getGenericInfo().getSuperclass();
-        } else
+        ClassRepository info = getGenericInfo();
+        if (info == null) {
             return getSuperclass();
+        }
+
+        // Historical irregularity:
+        // Generic signature marks interfaces with superclass = Object
+        // but this API returns null for interfaces
+        if (isInterface()) {
+            return null;
+        }
+
+        return info.getSuperclass();
     }
 
     /**
@@ -830,7 +835,23 @@
      *
      * @return an array of interfaces implemented by this class.
      */
-    public native Class<?>[] getInterfaces();
+    public Class<?>[] getInterfaces() {
+        ReflectionData<T> rd = reflectionData();
+        if (rd == null) {
+            // no cloning required
+            return getInterfaces0();
+        } else {
+            Class<?>[] interfaces = rd.interfaces;
+            if (interfaces == null) {
+                interfaces = getInterfaces0();
+                rd.interfaces = interfaces;
+            }
+            // defensively copy before handing over to user code
+            return interfaces.clone();
+        }
+    }
+
+    private native Class<?>[] getInterfaces0();
 
     /**
      * Returns the {@code Type}s representing the interfaces
@@ -882,10 +903,8 @@
      * @since 1.5
      */
     public Type[] getGenericInterfaces() {
-        if (getGenericSignature() != null)
-            return getGenericInfo().getSuperInterfaces();
-        else
-            return getInterfaces();
+        ClassRepository info = getGenericInfo();
+        return (info == null) ?  getInterfaces() : info.getSuperInterfaces();
     }
 
 
@@ -2396,6 +2415,8 @@
         // Intermediate results for getFields and getMethods
         volatile Field[] declaredPublicFields;
         volatile Method[] declaredPublicMethods;
+        volatile Class<?>[] interfaces;
+
         // Value of classRedefinedCount when we created this ReflectionData instance
         final int redefinedCount;
 
@@ -2471,10 +2492,10 @@
     }
 
     // Generic signature handling
-    private native String getGenericSignature();
+    private native String getGenericSignature0();
 
     // Generic info repository; lazily initialized
-    private transient ClassRepository genericInfo;
+    private volatile transient ClassRepository genericInfo;
 
     // accessor for factory
     private GenericsFactory getFactory() {
@@ -2482,15 +2503,20 @@
         return CoreReflectionFactory.make(this, ClassScope.make(this));
     }
 
-    // accessor for generic info repository
+    // accessor for generic info repository;
+    // generic info is lazily initialized
     private ClassRepository getGenericInfo() {
-        // lazily initialize repository if necessary
+        ClassRepository genericInfo = this.genericInfo;
         if (genericInfo == null) {
-            // create and cache generic info repository
-            genericInfo = ClassRepository.make(getGenericSignature(),
-                                               getFactory());
+            String signature = getGenericSignature0();
+            if (signature == null) {
+                genericInfo = ClassRepository.NONE;
+            } else {
+                genericInfo = ClassRepository.make(signature, getFactory());
+            }
+            this.genericInfo = genericInfo;
         }
-        return genericInfo; //return cached repository
+        return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
     }
 
     // Annotations handling
--- a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Mon Jun 17 14:23:01 2013 +0100
+++ b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Tue Jun 18 09:39:25 2013 +0100
@@ -24,14 +24,11 @@
  */
 package java.lang.invoke;
 
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
 import sun.invoke.util.Wrapper;
-import static sun.invoke.util.Wrapper.*;
+
+import static sun.invoke.util.Wrapper.forPrimitiveType;
+import static sun.invoke.util.Wrapper.forWrapperType;
+import static sun.invoke.util.Wrapper.isWrapperType;
 
 /**
  * Abstract implementation of a lambda metafactory which provides parameter unrolling and input validation.
@@ -67,34 +64,52 @@
     final MethodType instantiatedMethodType;  // Instantiated erased functional interface method type "(Integer)Object"
     final boolean isSerializable;             // Should the returned instance be serializable
     final Class<?>[] markerInterfaces;        // Additional marker interfaces to be implemented
+    final MethodType[] additionalBridges;     // Signatures of additional methods to bridge
 
 
     /**
      * Meta-factory constructor.
      *
-     * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
-     *               of the caller.
-     * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the
-     *                    expected static type of the returned lambda object, and the static types of the captured
-     *                    arguments for the lambda.  In the event that the implementation method is an instance method,
-     *                    the first argument in the invocation signature will correspond to the receiver.
-     * @param samMethod The primary method in the functional interface to which the lambda or method reference is
-     *                  being converted, represented as a method handle.
-     * @param implMethod The implementation method which should be called (with suitable adaptation of argument
-     *                   types, return types, and adjustment for captured arguments) when methods of the resulting
-     *                   functional interface instance are invoked.
-     * @param instantiatedMethodType The signature of the primary functional interface method after type variables
-     *                               are substituted with their instantiation from the capture site
+     * @param caller Stacked automatically by VM; represents a lookup context
+     *               with the accessibility privileges of the caller.
+     * @param invokedType Stacked automatically by VM; the signature of the
+     *                    invoked method, which includes the expected static
+     *                    type of the returned lambda object, and the static
+     *                    types of the captured arguments for the lambda.  In
+     *                    the event that the implementation method is an
+     *                    instance method, the first argument in the invocation
+     *                    signature will correspond to the receiver.
+     * @param samMethod The primary method in the functional interface to which
+     *                  the lambda or method reference is being converted,
+     *                  represented as a method handle.
+     * @param implMethod The implementation method which should be called
+     *                   (with suitable adaptation of argument types, return
+     *                   types, and adjustment for captured arguments) when
+     *                   methods of the resulting functional interface instance
+     *                   are invoked.
+     * @param instantiatedMethodType The signature of the primary functional
+     *                               interface method after type variables are
+     *                               substituted with their instantiation from
+     *                               the capture site
+     * @param isSerializable Should the lambda be made serializable?  If set,
+     *                       either the target type or one of the additional SAM
+     *                       types must extend {@code Serializable}.
+     * @param markerInterfaces Additional interfaces which the lambda object
+     *                       should implement.
+     * @param additionalBridges Method types for additional signatures to be
+     *                          bridged to the implementation method
      * @throws ReflectiveOperationException
-     * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
+     * @throws LambdaConversionException If any of the meta-factory protocol
+     * invariants are violated
      */
     AbstractValidatingLambdaMetafactory(MethodHandles.Lookup caller,
                                        MethodType invokedType,
                                        MethodHandle samMethod,
                                        MethodHandle implMethod,
                                        MethodType instantiatedMethodType,
-                                       int flags,
-                                       Class<?>[] markerInterfaces)
+                                       boolean isSerializable,
+                                       Class<?>[] markerInterfaces,
+                                       MethodType[] additionalBridges)
             throws ReflectiveOperationException, LambdaConversionException {
         this.targetClass = caller.lookupClass();
         this.invokedType = invokedType;
@@ -118,32 +133,22 @@
                 implKind == MethodHandleInfo.REF_invokeInterface;
         this.implDefiningClass = implInfo.getDeclaringClass();
         this.implMethodType = implInfo.getMethodType();
-
         this.instantiatedMethodType = instantiatedMethodType;
+        this.isSerializable = isSerializable;
+        this.markerInterfaces = markerInterfaces;
+        this.additionalBridges = additionalBridges;
 
         if (!samClass.isInterface()) {
             throw new LambdaConversionException(String.format(
-                    "Functional interface %s is not an interface",
-                    samClass.getName()));
+                    "Functional interface %s is not an interface", samClass.getName()));
         }
 
-        boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(samBase);
         for (Class<?> c : markerInterfaces) {
             if (!c.isInterface()) {
                 throw new LambdaConversionException(String.format(
-                        "Marker interface %s is not an interface",
-                        c.getName()));
+                        "Marker interface %s is not an interface", c.getName()));
             }
-            foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
         }
-        this.isSerializable = ((flags & LambdaMetafactory.FLAG_SERIALIZABLE) != 0)
-                              || foundSerializableSupertype;
-
-        if (isSerializable && !foundSerializableSupertype) {
-            markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1);
-            markerInterfaces[markerInterfaces.length-1] = Serializable.class;
-        }
-        this.markerInterfaces = markerInterfaces;
     }
 
     /**
@@ -265,9 +270,9 @@
      }
 
     /**
-     * Check type adaptability
-     * @param fromType
-     * @param toType
+     * Check type adaptability for parameter types.
+     * @param fromType Type to convert from
+     * @param toType Type to convert to
      * @param strict If true, do strict checks, else allow that fromType may be parameterized
      * @return True if 'fromType' can be passed to an argument of 'toType'
      */
@@ -299,15 +304,14 @@
                 }
             } else {
                 // both are reference types: fromType should be a superclass of toType.
-                return strict? toType.isAssignableFrom(fromType) : true;
+                return !strict || toType.isAssignableFrom(fromType);
             }
         }
     }
 
     /**
-     * Check type adaptability for return types -- special handling of void type) and parameterized fromType
-     * @param fromType
-     * @param toType
+     * Check type adaptability for return types -- special handling of void type)
+     * and parameterized fromType
      * @return True if 'fromType' can be converted to 'toType'
      */
     private boolean isAdaptableToAsReturn(Class<?> fromType, Class<?> toType) {
@@ -338,89 +342,4 @@
     }
     ***********************/
 
-    /**
-     * Find the functional interface method and corresponding abstract methods
-     * which should be bridged. The functional interface method and those to be
-     * bridged will have the same name and number of parameters. Check for
-     * matching default methods (non-abstract), the VM will create bridges for
-     * default methods; We don't have enough readily available type information
-     * to distinguish between where the functional interface method should be
-     * bridged and where the default method should be bridged; This situation is
-     * flagged.
-     */
-    class MethodAnalyzer {
-        private final Method[] methods = samBase.getMethods();
-
-        private Method samMethod = null;
-        private final List<Method> methodsToBridge = new ArrayList<>(methods.length);
-        private boolean conflictFoundBetweenDefaultAndBridge = false;
-
-        MethodAnalyzer() {
-            String samMethodName = samInfo.getName();
-            Class<?>[] samParamTypes = samMethodType.parameterArray();
-            int samParamLength = samParamTypes.length;
-            Class<?> samReturnType = samMethodType.returnType();
-            Class<?> objectClass = Object.class;
-            List<Method> defaultMethods = new ArrayList<>(methods.length);
-
-            for (Method m : methods) {
-                if (m.getName().equals(samMethodName) && m.getDeclaringClass() != objectClass) {
-                    Class<?>[] mParamTypes = m.getParameterTypes();
-                    if (mParamTypes.length == samParamLength) {
-                        // Method matches name and parameter length -- and is not Object
-                        if (Modifier.isAbstract(m.getModifiers())) {
-                            // Method is abstract
-                            if (m.getReturnType().equals(samReturnType)
-                                    && Arrays.equals(mParamTypes, samParamTypes)) {
-                                // Exact match, this is the SAM method signature
-                                samMethod = m;
-                            } else if (!hasMatchingBridgeSignature(m)) {
-                                // Record bridges, exclude methods with duplicate signatures
-                                methodsToBridge.add(m);
-                            }
-                        } else {
-                            // Record default methods for conflict testing
-                            defaultMethods.add(m);
-                        }
-                    }
-                }
-            }
-            for (Method dm : defaultMethods) {
-                if (hasMatchingBridgeSignature(dm)) {
-                    conflictFoundBetweenDefaultAndBridge = true;
-                    break;
-                }
-            }
-        }
-
-        Method getSamMethod() {
-            return samMethod;
-        }
-
-        List<Method> getMethodsToBridge() {
-            return methodsToBridge;
-        }
-
-        boolean conflictFoundBetweenDefaultAndBridge() {
-            return conflictFoundBetweenDefaultAndBridge;
-        }
-
-        /**
-         * Search the list of previously found bridge methods to determine if there is a method with the same signature
-         * (return and parameter types) as the specified method.
-         *
-         * @param m The method to match
-         * @return True if the method was found, False otherwise
-         */
-        private boolean hasMatchingBridgeSignature(Method m) {
-            Class<?>[] ptypes = m.getParameterTypes();
-            Class<?> rtype = m.getReturnType();
-            for (Method md : methodsToBridge) {
-                if (md.getReturnType().equals(rtype) && Arrays.equals(ptypes, md.getParameterTypes())) {
-                    return true;
-                }
-            }
-                    return false;
-                }
-            }
 }
--- a/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Mon Jun 17 14:23:01 2013 +0100
+++ b/jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Tue Jun 18 09:39:25 2013 +0100
@@ -25,15 +25,16 @@
 
 package java.lang.invoke;
 
+import jdk.internal.org.objectweb.asm.*;
+import sun.misc.Unsafe;
+
 import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.security.ProtectionDomain;
 import java.util.concurrent.atomic.AtomicInteger;
-import jdk.internal.org.objectweb.asm.*;
+
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
-import sun.misc.Unsafe;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
 
 /**
  * Lambda metafactory implementation which dynamically creates an inner-class-like class per lambda callsite.
@@ -41,6 +42,8 @@
  * @see LambdaMetafactory
  */
 /* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
     private static final int CLASSFILE_VERSION = 51;
     private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
     private static final String NAME_MAGIC_ACCESSOR_IMPL = "java/lang/invoke/MagicLambdaImpl";
@@ -77,36 +80,51 @@
     private final Type[] instantiatedArgumentTypes;  // ASM types for the functional interface arguments
 
     /**
-     * General meta-factory constructor, standard cases and allowing for uncommon options such as serialization.
+     * General meta-factory constructor, supporting both standard cases and
+     * allowing for uncommon options such as serialization or bridging.
      *
-     * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
-     *               of the caller.
-     * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the
-     *                    expected static type of the returned lambda object, and the static types of the captured
-     *                    arguments for the lambda.  In the event that the implementation method is an instance method,
-     *                    the first argument in the invocation signature will correspond to the receiver.
-     * @param samMethod The primary method in the functional interface to which the lambda or method reference is
-     *                  being converted, represented as a method handle.
-     * @param implMethod The implementation method which should be called (with suitable adaptation of argument
-     *                   types, return types, and adjustment for captured arguments) when methods of the resulting
-     *                   functional interface instance are invoked.
-     * @param instantiatedMethodType The signature of the primary functional interface method after type variables
-     *                               are substituted with their instantiation from the capture site
-     * @param flags A bitmask containing flags that may influence the translation of this lambda expression.  Defined
-     *              fields include FLAG_SERIALIZABLE.
-     * @param markerInterfaces Additional interfaces which the lambda object should implement.
+     * @param caller Stacked automatically by VM; represents a lookup context
+     *               with the accessibility privileges of the caller.
+     * @param invokedType Stacked automatically by VM; the signature of the
+     *                    invoked method, which includes the expected static
+     *                    type of the returned lambda object, and the static
+     *                    types of the captured arguments for the lambda.  In
+     *                    the event that the implementation method is an
+     *                    instance method, the first argument in the invocation
+     *                    signature will correspond to the receiver.
+     * @param samMethod The primary method in the functional interface to which
+     *                  the lambda or method reference is being converted,
+     *                  represented as a method handle.
+     * @param implMethod The implementation method which should be called (with
+     *                   suitable adaptation of argument types, return types,
+     *                   and adjustment for captured arguments) when methods of
+     *                   the resulting functional interface instance are invoked.
+     * @param instantiatedMethodType The signature of the primary functional
+     *                               interface method after type variables are
+     *                               substituted with their instantiation from
+     *                               the capture site
+     * @param isSerializable Should the lambda be made serializable?  If set,
+     *                       either the target type or one of the additional SAM
+     *                       types must extend {@code Serializable}.
+     * @param markerInterfaces Additional interfaces which the lambda object
+     *                       should implement.
+     * @param additionalBridges Method types for additional signatures to be
+     *                          bridged to the implementation method
      * @throws ReflectiveOperationException
-     * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
+     * @throws LambdaConversionException If any of the meta-factory protocol
+     * invariants are violated
      */
     public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
                                        MethodType invokedType,
                                        MethodHandle samMethod,
                                        MethodHandle implMethod,
                                        MethodType instantiatedMethodType,
-                                       int flags,
-                                       Class<?>[] markerInterfaces)
+                                       boolean isSerializable,
+                                       Class<?>[] markerInterfaces,
+                                       MethodType[] additionalBridges)
             throws ReflectiveOperationException, LambdaConversionException {
-        super(caller, invokedType, samMethod, implMethod, instantiatedMethodType, flags, markerInterfaces);
+        super(caller, invokedType, samMethod, implMethod, instantiatedMethodType,
+              isSerializable, markerInterfaces, additionalBridges);
         implMethodClassName = implDefiningClass.getName().replace('.', '/');
         implMethodName = implInfo.getName();
         implMethodDesc = implMethodType.toMethodDescriptorString();
@@ -134,7 +152,8 @@
      * @return a CallSite, which, when invoked, will return an instance of the
      * functional interface
      * @throws ReflectiveOperationException
-     * @throws LambdaConversionException If properly formed functional interface is not found
+     * @throws LambdaConversionException If properly formed functional interface
+     * is not found
      */
     @Override
     CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException {
@@ -174,8 +193,16 @@
      * Generate a class file which implements the functional
      * interface, define and return the class.
      *
+     * @implNote The class that is generated does not include signature
+     * information for exceptions that may be present on the SAM method.
+     * This is to reduce classfile size, and is harmless as checked exceptions
+     * are erased anyway, no one will ever compile against this classfile,
+     * and we make no guarantees about the reflective properties of lambda
+     * objects.
+     *
      * @return a Class which implements the functional interface
-     * @throws LambdaConversionException If properly formed functional interface is not found
+     * @throws LambdaConversionException If properly formed functional interface
+     * is not found
      */
     private Class<?> spinInnerClass() throws LambdaConversionException {
         String samName = samBase.getName().replace('.', '/');
@@ -197,28 +224,22 @@
 
         generateConstructor();
 
-        MethodAnalyzer ma = new MethodAnalyzer();
-
         // Forward the SAM method
-        if (ma.getSamMethod() == null) {
-            throw new LambdaConversionException(String.format("Functional interface method not found: %s", samMethodType));
-        } else {
-            generateForwardingMethod(ma.getSamMethod(), false);
-        }
+        String methodDescriptor = samMethodType.toMethodDescriptorString();
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samInfo.getName(), methodDescriptor, null, null);
+        new ForwardingMethodGenerator(mv).generate(methodDescriptor);
 
         // Forward the bridges
-        // @@@ The commented-out code is temporary, pending the VM's ability to bridge all methods on request
-        // @@@ Once the VM can do fail-over, uncomment the !ma.wasDefaultMethodFound() test, and emit the appropriate
-        // @@@ classfile attribute to request custom bridging.  See 8002092.
-        if (!ma.getMethodsToBridge().isEmpty() /* && !ma.conflictFoundBetweenDefaultAndBridge() */ ) {
-            for (Method m : ma.getMethodsToBridge()) {
-                generateForwardingMethod(m, true);
+        if (additionalBridges != null) {
+            for (MethodType mt : additionalBridges) {
+                methodDescriptor = mt.toMethodDescriptorString();
+                mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samInfo.getName(), methodDescriptor, null, null);
+                new ForwardingMethodGenerator(mv).generate(methodDescriptor);
             }
         }
 
-        if (isSerializable) {
+        if (isSerializable)
             generateWriteReplace();
-        }
 
         cw.visitEnd();
 
@@ -247,8 +268,8 @@
             }
         );
 
-        return (Class<?>) Unsafe.getUnsafe().defineClass(lambdaClassName, classBytes, 0, classBytes.length,
-                                                                   loader, pd);
+        return UNSAFE.defineClass(lambdaClassName, classBytes, 0, classBytes.length,
+                                  loader, pd);
     }
 
     /**
@@ -265,7 +286,8 @@
             ctor.visitVarInsn(ALOAD, 0);
             ctor.visitVarInsn(argTypes[i].getOpcode(ILOAD), lvIndex + 1);
             lvIndex += argTypes[i].getSize();
-            ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor());
+            ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i],
+                                argTypes[i].getDescriptor());
         }
         ctor.visitInsn(RETURN);
         ctor.visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
@@ -283,7 +305,7 @@
 
         mv.visitCode();
         mv.visitTypeInsn(NEW, NAME_SERIALIZED_LAMBDA);
-        mv.visitInsn(DUP);;
+        mv.visitInsn(DUP);
         mv.visitLdcInsn(Type.getType(targetClass));
         mv.visitLdcInsn(samInfo.getReferenceKind());
         mv.visitLdcInsn(invokedType.returnType().getName().replace('.', '/'));
@@ -313,24 +335,6 @@
     }
 
     /**
-     * Generate a method which calls the lambda implementation method,
-     * converting arguments, as needed.
-     * @param m The method whose signature should be generated
-     * @param isBridge True if this methods should be flagged as a bridge
-     */
-    private void generateForwardingMethod(Method m, boolean isBridge) {
-        Class<?>[] exceptionTypes = m.getExceptionTypes();
-        String[] exceptionNames = new String[exceptionTypes.length];
-        for (int i = 0; i < exceptionTypes.length; i++) {
-            exceptionNames[i] = exceptionTypes[i].getName().replace('.', '/');
-        }
-        String methodDescriptor = Type.getMethodDescriptor(m);
-        int access = isBridge? ACC_PUBLIC | ACC_BRIDGE : ACC_PUBLIC;
-        MethodVisitor mv = cw.visitMethod(access, m.getName(), methodDescriptor, null, exceptionNames);
-        new ForwardingMethodGenerator(mv).generate(m);
-    }
-
-    /**
      * This class generates a method body which calls the lambda implementation
      * method, converting arguments, as needed.
      */
@@ -340,26 +344,26 @@
             super(mv);
         }
 
-        void generate(Method m) throws InternalError {
+        void generate(String methodDescriptor) {
             visitCode();
 
             if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
                 visitTypeInsn(NEW, implMethodClassName);
-                visitInsn(DUP);;
+                visitInsn(DUP);
             }
             for (int i = 0; i < argTypes.length; i++) {
                 visitVarInsn(ALOAD, 0);
                 visitFieldInsn(GETFIELD, lambdaClassName, argNames[i], argTypes[i].getDescriptor());
             }
 
-            convertArgumentTypes(Type.getArgumentTypes(m));
+            convertArgumentTypes(Type.getArgumentTypes(methodDescriptor));
 
             // Invoke the method we want to forward to
             visitMethodInsn(invocationOpcode(), implMethodClassName, implMethodName, implMethodDesc);
 
             // Convert the return value (if any) and return it
             // Note: if adapting from non-void to void, the 'return' instruction will pop the unneeded result
-            Type samReturnType = Type.getReturnType(m);
+            Type samReturnType = Type.getReturnType(methodDescriptor);
             convertType(implMethodReturnType, samReturnType, samReturnType);
             visitInsn(samReturnType.getOpcode(Opcodes.IRETURN));
 
--- a/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java	Mon Jun 17 14:23:01 2013 +0100
+++ b/jdk/src/share/classes/java/lang/invoke/LambdaMetafactory.java	Tue Jun 18 09:39:25 2013 +0100
@@ -25,6 +25,9 @@
 
 package java.lang.invoke;
 
+import java.io.Serializable;
+import java.util.Arrays;
+
 /**
  * <p>Bootstrap methods for converting lambda expressions and method references to functional interface objects.</p>
  *
@@ -44,16 +47,11 @@
  *
  * <p>When parameterized types are used, the instantiated type of the functional interface method may be different
  * from that in the functional interface. For example, consider
- * <code>interface I&lt;T&gt; { int m(T x); }</code> if this functional interface type is used in a lambda
- * <code>I&lt;Byte&gt; v = ...</code>, we need both the actual functional interface method which has the signature
- * <code>(Object)int</code> and the erased instantiated type of the functional interface method (or simply
+ * {@code interface I<T> { int m(T x); }} if this functional interface type is used in a lambda
+ * {@code I<Byte>; v = ...}, we need both the actual functional interface method which has the signature
+ * {@code (Object)int} and the erased instantiated type of the functional interface method (or simply
  * <I>instantiated method type</I>), which has signature
- * <code>(Byte)int</code>.
- *
- * <p>While functional interfaces only have a single abstract method from the language perspective (concrete
- * methods in Object are and default methods may be present), at the bytecode level they may actually have multiple
- * methods because of the need for bridge methods. Invoking any of these methods on the lambda object will result
- * in invoking the implementation method.
+ * {@code (Byte)int}.
  *
  * <p>The argument list of the implementation method and the argument list of the functional interface method(s)
  * may differ in several ways.  The implementation methods may have additional arguments to accommodate arguments
@@ -144,38 +142,59 @@
  */
 public class LambdaMetafactory {
 
-    /** Flag for alternate metafactories indicating the lambda object is must to be serializable */
+    /** Flag for alternate metafactories indicating the lambda object is
+     * must to be serializable */
     public static final int FLAG_SERIALIZABLE = 1 << 0;
 
     /**
-     * Flag for alternate metafactories indicating the lambda object implements other marker interfaces
+     * Flag for alternate metafactories indicating the lambda object implements
+     * other marker interfaces
      * besides Serializable
      */
     public static final int FLAG_MARKERS = 1 << 1;
 
+    /**
+     * Flag for alternate metafactories indicating the lambda object requires
+     * additional bridge methods
+     */
+    public static final int FLAG_BRIDGES = 1 << 2;
+
     private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
+    private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
 
-/**
-     * Standard meta-factory for conversion of lambda expressions or method references to functional interfaces.
+    /**
+     * Standard meta-factory for conversion of lambda expressions or method
+     * references to functional interfaces.
      *
-     * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
-     *               of the caller.
-     * @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site.
+     * @param caller Stacked automatically by VM; represents a lookup context
+     *                   with the accessibility privileges of the caller.
+     * @param invokedName Stacked automatically by VM; the name of the invoked
+     *                    method as it appears at the call site.
      *                    Currently unused.
-     * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes the
-     *                    expected static type of the returned lambda object, and the static types of the captured
-     *                    arguments for the lambda.  In the event that the implementation method is an instance method,
-     *                    the first argument in the invocation signature will correspond to the receiver.
-     * @param samMethod The primary method in the functional interface to which the lambda or method reference is
-     *                  being converted, represented as a method handle.
-     * @param implMethod The implementation method which should be called (with suitable adaptation of argument
-     *                   types, return types, and adjustment for captured arguments) when methods of the resulting
-     *                   functional interface instance are invoked.
-     * @param instantiatedMethodType The signature of the primary functional interface method after type variables
-     *                               are substituted with their instantiation from the capture site
-     * @return a CallSite, which, when invoked, will return an instance of the functional interface
+     * @param invokedType Stacked automatically by VM; the signature of the
+     *                    invoked method, which includes the expected static
+     *                    type of the returned lambda object, and the static
+     *                    types of the captured arguments for the lambda.
+     *                    In the event that the implementation method is an
+     *                    instance method, the first argument in the invocation
+     *                    signature will correspond to the receiver.
+     * @param samMethod The primary method in the functional interface to which
+     *                  the lambda or method reference is being converted,
+     *                  represented as a method handle.
+     * @param implMethod The implementation method which should be called
+     *                   (with suitable adaptation of argument types, return
+     *                   types, and adjustment for captured arguments) when
+     *                   methods of the resulting functional interface instance
+     *                   are invoked.
+     * @param instantiatedMethodType The signature of the primary functional
+     *                               interface method after type variables
+     *                               are substituted with their instantiation
+     *                               from the capture site
+     * @return a CallSite, which, when invoked, will return an instance of the
+     * functional interface
      * @throws ReflectiveOperationException
-     * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
+     * @throws LambdaConversionException If any of the meta-factory protocol
+     * invariants are violated
      */
     public static CallSite metaFactory(MethodHandles.Lookup caller,
                                        String invokedName,
@@ -185,15 +204,17 @@
                                        MethodType instantiatedMethodType)
                    throws ReflectiveOperationException, LambdaConversionException {
         AbstractValidatingLambdaMetafactory mf;
-        mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType,
-                0, EMPTY_CLASS_ARRAY);
+        mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod,
+                                             implMethod, instantiatedMethodType,
+                                             false, EMPTY_CLASS_ARRAY, EMPTY_MT_ARRAY);
         mf.validateMetafactoryArgs();
         return mf.buildCallSite();
     }
 
     /**
-     * Alternate meta-factory for conversion of lambda expressions or method references to functional interfaces,
-     * which supports serialization and other uncommon options.
+     * Alternate meta-factory for conversion of lambda expressions or method
+     * references to functional interfaces, which supports serialization and
+     * other uncommon options.
      *
      * The declared argument list for this method is:
      *
@@ -213,21 +234,28 @@
      *                          int flags,
      *                          int markerInterfaceCount, // IF flags has MARKERS set
      *                          Class... markerInterfaces // IF flags has MARKERS set
+     *                          int bridgeCount,          // IF flags has BRIDGES set
+     *                          MethodType... bridges     // IF flags has BRIDGES set
      *                          )
      *
      *
-     * @param caller Stacked automatically by VM; represents a lookup context with the accessibility privileges
-     *               of the caller.
-     * @param invokedName Stacked automatically by VM; the name of the invoked method as it appears at the call site.
-     *                    Currently unused.
-     * @param invokedType Stacked automatically by VM; the signature of the invoked method, which includes thefu
-     *                    expected static type of the returned lambda object, and the static types of the captured
-     *                    arguments for the lambda.  In the event that the implementation method is an instance method,
-     *                    the first argument in the invocation signature will correspond to the receiver.
-     * @param  args       argument to pass, flags, marker interface count, and marker interfaces as described above
-     * @return a CallSite, which, when invoked, will return an instance of the functional interface
+     * @param caller Stacked automatically by VM; represents a lookup context
+     *               with the accessibility privileges of the caller.
+     * @param invokedName Stacked automatically by VM; the name of the invoked
+     *                    method as it appears at the call site. Currently unused.
+     * @param invokedType Stacked automatically by VM; the signature of the
+     *                    invoked method, which includes the expected static
+     *                    type of the returned lambda object, and the static
+     *                    types of the captured arguments for the lambda.
+     *                    In the event that the implementation method is an
+     *                    instance method, the first argument in the invocation
+     *                    signature will correspond to the receiver.
+     * @param  args       flags and optional arguments, as described above
+     * @return a CallSite, which, when invoked, will return an instance of the
+     * functional interface
      * @throws ReflectiveOperationException
-     * @throws LambdaConversionException If any of the meta-factory protocol invariants are violated
+     * @throws LambdaConversionException If any of the meta-factory protocol
+     * invariants are violated
      */
     public static CallSite altMetaFactory(MethodHandles.Lookup caller,
                                           String invokedName,
@@ -239,6 +267,7 @@
         MethodType instantiatedMethodType = (MethodType)args[2];
         int flags = (Integer) args[3];
         Class<?>[] markerInterfaces;
+        MethodType[] bridges;
         int argIndex = 4;
         if ((flags & FLAG_MARKERS) != 0) {
             int markerCount = (Integer) args[argIndex++];
@@ -248,9 +277,30 @@
         }
         else
             markerInterfaces = EMPTY_CLASS_ARRAY;
-        AbstractValidatingLambdaMetafactory mf;
-        mf = new InnerClassLambdaMetafactory(caller, invokedType, samMethod, implMethod, instantiatedMethodType,
-                                             flags, markerInterfaces);
+        if ((flags & FLAG_BRIDGES) != 0) {
+            int bridgeCount = (Integer) args[argIndex++];
+            bridges = new MethodType[bridgeCount];
+            System.arraycopy(args, argIndex, bridges, 0, bridgeCount);
+            argIndex += bridgeCount;
+        }
+        else
+            bridges = EMPTY_MT_ARRAY;
+
+        boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType());
+        for (Class<?> c : markerInterfaces)
+            foundSerializableSupertype |= Serializable.class.isAssignableFrom(c);
+        boolean isSerializable = ((flags & LambdaMetafactory.FLAG_SERIALIZABLE) != 0)
+                                 || foundSerializableSupertype;
+
+        if (isSerializable && !foundSerializableSupertype) {
+            markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1);
+            markerInterfaces[markerInterfaces.length-1] = Serializable.class;
+        }
+
+        AbstractValidatingLambdaMetafactory mf
+                = new InnerClassLambdaMetafactory(caller, invokedType, samMethod,
+                                                  implMethod, instantiatedMethodType,
+                                                  isSerializable, markerInterfaces, bridges);
         mf.validateMetafactoryArgs();
         return mf.buildCallSite();
     }
--- a/jdk/src/share/classes/java/lang/invoke/MethodType.java	Mon Jun 17 14:23:01 2013 +0100
+++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java	Tue Jun 18 09:39:25 2013 +0100
@@ -27,10 +27,13 @@
 
 import sun.invoke.util.Wrapper;
 import java.lang.ref.WeakReference;
+import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
 import sun.invoke.util.BytecodeDescriptor;
 import static java.lang.invoke.MethodHandleStatics.*;
 import sun.invoke.util.VerifyType;
@@ -171,7 +174,7 @@
         return new IndexOutOfBoundsException(num.toString());
     }
 
-    static final WeakInternSet internTable = new WeakInternSet();
+    static final ConcurrentWeakInternSet<MethodType> internTable = new ConcurrentWeakInternSet<>();
 
     static final Class<?>[] NO_PTYPES = {};
 
@@ -1013,267 +1016,104 @@
     }
 
     /**
-     * Weak intern set based on implementation of the <tt>HashSet</tt> and
-     * <tt>WeakHashMap</tt>, with <em>weak values</em>.  Note: <tt>null</tt>
-     * values will yield <tt>NullPointerException</tt>
-     * Refer to implementation of WeakInternSet for details.
+     * Simple implementation of weak concurrent intern set.
      *
-     * @see         java.util.HashMap
-     * @see         java.util.HashSet
-     * @see         java.util.WeakHashMap
-     * @see         java.lang.ref.WeakReference
+     * @param <T> interned type
      */
-    private static class WeakInternSet {
-        // The default initial capacity -- MUST be a power of two.
-        private static final int DEFAULT_INITIAL_CAPACITY = 16;
-
-        // The maximum capacity, used if a higher value is implicitly specified
-        // by either of the constructors with arguments.
-        // MUST be a power of two <= 1<<30.
-        private static final int MAXIMUM_CAPACITY = 1 << 30;
-
-        // The load factor used when none specified in constructor.
-        private static final float DEFAULT_LOAD_FACTOR = 0.75f;
-
-        // The table, resized as necessary. Length MUST Always be a power of two.
-        private Entry[] table;
-
-        // The number of entries contained in this set.
-        private int size;
-
-        // The next size value at which to resize (capacity * load factor).
-        private int threshold;
+    private static class ConcurrentWeakInternSet<T> {
 
-        // The load factor for the hash table.
-        private final float loadFactor;
-
-        // Reference queue for cleared WeakEntries
-        private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
-
-        private Entry[] newTable(int n) {
-            return new Entry[n];
-        }
+        private final ConcurrentMap<WeakEntry<T>, WeakEntry<T>> map;
+        private final ReferenceQueue<T> stale;
 
-        /**
-         * Constructs a new, empty <tt>WeakInternSet</tt> with the default initial
-         * capacity (16) and load factor (0.75).
-         */
-        WeakInternSet() {
-            this.loadFactor = DEFAULT_LOAD_FACTOR;
-            threshold = DEFAULT_INITIAL_CAPACITY;
-            table = newTable(DEFAULT_INITIAL_CAPACITY);
-        }
-
-        /**
-         * Applies a supplemental hash function to a given hashCode, which
-         * defends against poor quality hash functions.  This is critical
-         * because hashing uses power-of-two length hash tables, that
-         * otherwise encounter collisions for hashCodes that do not differ
-         * in lower bits.
-         * @param h preliminary hash code value
-         * @return supplemental hash code value
-         */
-        private static int hash(int h) {
-            // This function ensures that hashCodes that differ only by
-            // constant multiples at each bit position have a bounded
-            // number of collisions (approximately 8 at default load factor).
-            h ^= (h >>> 20) ^ (h >>> 12);
-            return h ^ (h >>> 7) ^ (h >>> 4);
+        public ConcurrentWeakInternSet() {
+            this.map = new ConcurrentHashMap<>();
+            this.stale = new ReferenceQueue<>();
         }
 
         /**
-         * Checks for equality of non-null reference x and possibly-null y.  By
-         * default uses Object.equals.
-         * @param x first object to compare
-         * @param y second object to compare
-         * @return <tt>true</tt> if objects are equal
-         */
-        private static boolean eq(Object x, Object y) {
-            return x == y || x.equals(y);
-        }
-
-        /**
-         * Returns index for hash code h.
-         * @param h      raw hash code
-         * @param length length of table (power of 2)
-         * @return index in table
-         */
-        private static int indexFor(int h, int length) {
-            return h & (length-1);
-        }
-
-        /**
-         * Expunges stale entries from the table.
+         * Get the existing interned element.
+         * This method returns null if no element is interned.
+         *
+         * @param elem element to look up
+         * @return the interned element
          */
-        private void expungeStaleEntries() {
-            for (Object x; (x = queue.poll()) != null; ) {
-                synchronized (queue) {
-                    Entry entry = (Entry) x;
-                    int i = indexFor(entry.hash, table.length);
-                    Entry prev = table[i];
-                    Entry p = prev;
-                    while (p != null) {
-                        Entry next = p.next;
-                        if (p == entry) {
-                            if (prev == entry)
-                                table[i] = next;
-                            else
-                                prev.next = next;
-                            entry.next = null;
-                            size--;
-                            break;
-                        }
-                        prev = p;
-                        p = next;
-                    }
-                }
-            }
-        }
+        public T get(T elem) {
+            if (elem == null) throw new NullPointerException();
+            expungeStaleElements();
 
-        /**
-         * Returns the table after first expunging stale entries.
-         * @return an expunged hash table
-         */
-        private Entry[] getTable() {
-            expungeStaleEntries();
-            return table;
-        }
-
-        /**
-         * Returns the entry to which the specified value is mapped,
-         * or {@code null} if this set contains no entry for the value.
-         *
-         * <p>More formally, if this set contains an entry for value
-         * {@code entry} to a value {@code value} such that
-         * {@code entry.equals(value)}, then this method returns {@code entry};
-         * otherwise it returns {@code null}.
-         *
-         * @param value value to search for in set
-         * @return interned value if in set, otherwise <tt>null</tt>
-         */
-        synchronized MethodType get(MethodType value) {
-            int h = hash(value.hashCode());
-            Entry[] tab = getTable();
-            int index = indexFor(h, tab.length);
-            Entry e = tab[index];
-            MethodType g;
-            while (e != null) {
-                if (e.hash == h && eq(value, g = e.get()))
-                    return g;
-                e = e.next;
+            WeakEntry<T> value = map.get(new WeakEntry<>(elem));
+            if (value != null) {
+                T res = value.get();
+                if (res != null) {
+                    return res;
+                }
             }
             return null;
         }
 
         /**
-         * Attempts to add the specified value to the set and returns same value.
-         * If the set previously contained an entry for this value, the old
-         * value is left untouched and returned as the result.
+         * Interns the element.
+         * Always returns non-null element, matching the one in the intern set.
+         * Under the race against another add(), it can return <i>different</i>
+         * element, if another thread beats us to interning it.
          *
-         * @param value value to be added
-         * @return the previous entry associated with <tt>value</tt>, or
-         *         <tt>value</tt> if there was no previous entry found
+         * @param elem element to add
+         * @return element that was actually added
          */
-        synchronized MethodType add(MethodType value) {
-            int h = hash(value.hashCode());
-            Entry[] tab = getTable();
-            int i = indexFor(h, tab.length);
-            MethodType g;
-            for (Entry e = tab[i]; e != null; e = e.next) {
-                if (h == e.hash && eq(value, g = e.get())) {
-                    return g;
-                }
-            }
-            Entry e = tab[i];
-            tab[i] = new Entry(value, queue, h, e);
-            if (++size >= threshold)
-                resize(tab.length * 2);
-            return value;
+        public T add(T elem) {
+            if (elem == null) throw new NullPointerException();
+
+            // Playing double race here, and so spinloop is required.
+            // First race is with two concurrent updaters.
+            // Second race is with GC purging weak ref under our feet.
+            // Hopefully, we almost always end up with a single pass.
+            T interned;
+            WeakEntry<T> e = new WeakEntry<>(elem, stale);
+            do {
+                expungeStaleElements();
+                WeakEntry<T> exist = map.putIfAbsent(e, e);
+                interned = (exist == null) ? elem : exist.get();
+            } while (interned == null);
+            return interned;
         }
 
-        /**
-         * Rehashes the contents of this set into a new array with a
-         * larger capacity.  This method is called automatically when the
-         * number of keys in this set reaches its threshold.
-         *
-         * If current capacity is MAXIMUM_CAPACITY, this method does not
-         * resize the set, but sets threshold to Integer.MAX_VALUE.
-         * This has the effect of preventing future calls.
-         *
-         * @param newCapacity the new capacity, MUST be a power of two;
-         *        must be greater than current capacity unless current
-         *        capacity is MAXIMUM_CAPACITY (in which case value
-         *        is irrelevant)
-         */
-        private void resize(int newCapacity) {
-            Entry[] oldTable = getTable();
-            int oldCapacity = oldTable.length;
-            if (oldCapacity == MAXIMUM_CAPACITY) {
-                threshold = Integer.MAX_VALUE;
-                return;
-            }
-
-            Entry[] newTable = newTable(newCapacity);
-            transfer(oldTable, newTable);
-            table = newTable;
-
-            /*
-             * If ignoring null elements and processing ref queue caused massive
-             * shrinkage, then restore old table.  This should be rare, but avoids
-             * unbounded expansion of garbage-filled tables.
-             */
-            if (size >= threshold / 2) {
-                threshold = (int)(newCapacity * loadFactor);
-            } else {
-                expungeStaleEntries();
-                transfer(newTable, oldTable);
-                table = oldTable;
+        private void expungeStaleElements() {
+            Reference<? extends T> reference;
+            while ((reference = stale.poll()) != null) {
+                map.remove(reference);
             }
         }
 
-        /**
-         * Transfers all entries from src to dest tables
-         * @param src  original table
-         * @param dest new table
-         */
-        private void transfer(Entry[] src, Entry[] dest) {
-            for (int j = 0; j < src.length; ++j) {
-                Entry e = src[j];
-                src[j] = null;
-                while (e != null) {
-                    Entry next = e.next;
-                    MethodType key = e.get();
-                    if (key == null) {
-                        e.next = null;  // Help GC
-                        size--;
-                    } else {
-                        int i = indexFor(e.hash, dest.length);
-                        e.next = dest[i];
-                        dest[i] = e;
-                    }
-                    e = next;
+        private static class WeakEntry<T> extends WeakReference<T> {
+
+            public final int hashcode;
+
+            public WeakEntry(T key, ReferenceQueue<T> queue) {
+                super(key, queue);
+                hashcode = key.hashCode();
+            }
+
+            public WeakEntry(T key) {
+                super(key);
+                hashcode = key.hashCode();
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                if (obj instanceof WeakEntry) {
+                    Object that = ((WeakEntry) obj).get();
+                    Object mine = get();
+                    return (that == null || mine == null) ? (this == obj) : mine.equals(that);
                 }
+                return false;
             }
-        }
-
-        /**
-         * The entries in this hash table extend WeakReference, using its main ref
-         * field as the key.
-         */
-        private static class Entry extends WeakReference<MethodType> {
-            final int hash;
-            Entry next;
 
-            /**
-             * Creates new entry.
-             */
-            Entry(MethodType key,
-                  ReferenceQueue<Object> queue,
-                  int hash, Entry next) {
-                super(key, queue);
-                this.hash  = hash;
-                this.next  = next;
+            @Override
+            public int hashCode() {
+                return hashcode;
             }
+
         }
     }
+
 }
--- a/jdk/src/share/classes/java/security/Signature.java	Mon Jun 17 14:23:01 2013 +0100
+++ b/jdk/src/share/classes/java/security/Signature.java	Tue Jun 18 09:39:25 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -248,6 +248,7 @@
         Signature sig;
         if (instance.impl instanceof Signature) {
             sig = (Signature)instance.impl;
+            sig.algorithm = algorithm;
         } else {
             SignatureSpi spi = (SignatureSpi)instance.impl;
             sig = new Delegate(spi, algorithm);
--- a/jdk/src/share/classes/sun/reflect/generics/repository/ClassRepository.java	Mon Jun 17 14:23:01 2013 +0100
+++ b/jdk/src/share/classes/sun/reflect/generics/repository/ClassRepository.java	Tue Jun 18 09:39:25 2013 +0100
@@ -40,6 +40,8 @@
  */
 public class ClassRepository extends GenericDeclRepository<ClassSignature> {
 
+    public static final ClassRepository NONE = ClassRepository.make("Ljava/lang/Object;", null);
+
     private Type superclass; // caches the generic superclass info
     private Type[] superInterfaces; // caches the generic superinterface info
 
--- a/jdk/src/share/native/java/lang/Class.c	Mon Jun 17 14:23:01 2013 +0100
+++ b/jdk/src/share/native/java/lang/Class.c	Tue Jun 18 09:39:25 2013 +0100
@@ -55,7 +55,7 @@
 static JNINativeMethod methods[] = {
     {"getName0",         "()" STR,          (void *)&JVM_GetClassName},
     {"getSuperclass",    "()" CLS,          NULL},
-    {"getInterfaces",    "()[" CLS,         (void *)&JVM_GetClassInterfaces},
+    {"getInterfaces0",   "()[" CLS,         (void *)&JVM_GetClassInterfaces},
     {"getClassLoader0",  "()" JCL,          (void *)&JVM_GetClassLoader},
     {"isInterface",      "()Z",             (void *)&JVM_IsInterface},
     {"getSigners",       "()[" OBJ,         (void *)&JVM_GetClassSigners},
@@ -70,7 +70,7 @@
     {"getProtectionDomain0", "()" PD,       (void *)&JVM_GetProtectionDomain},
     {"getDeclaredClasses0",  "()[" CLS,      (void *)&JVM_GetDeclaredClasses},
     {"getDeclaringClass",   "()" CLS,      (void *)&JVM_GetDeclaringClass},
-    {"getGenericSignature", "()" STR,       (void *)&JVM_GetClassSignature},
+    {"getGenericSignature0", "()" STR,      (void *)&JVM_GetClassSignature},
     {"getRawAnnotations",      "()" BA,        (void *)&JVM_GetClassAnnotations},
     {"getConstantPool",     "()" CPL,       (void *)&JVM_GetClassConstantPool},
     {"desiredAssertionStatus0","("CLS")Z",(void *)&JVM_DesiredAssertionStatus},
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/Signature/SignatureGetAlgorithm.java	Tue Jun 18 09:39:25 2013 +0100
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Portions Copyright (c) 2013 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 8014620
+ * @summary Signature.getAlgorithm return null in special case
+ * @run main/othervm SignatureGetAlgorithm
+ * @author youdwei
+ */
+import java.security.*;
+
+public class SignatureGetAlgorithm {
+
+    public static void main(String[] args) throws Exception {
+        Provider testProvider = new TestProvider();
+        Security.addProvider(testProvider);
+        Signature sig = Signature.getInstance("MySignatureAlg");
+        String algorithm = sig.getAlgorithm();
+        System.out.println("Algorithm Name: " + algorithm);
+        if (algorithm == null) {
+            throw new Exception("algorithm name should be 'MySignatureAlg'");
+        }
+    }
+
+    public static class TestProvider extends Provider {
+        TestProvider() {
+            super("test", 1.0, "test");
+            put("Signature.MySignatureAlg",
+                "SignatureGetAlgorithm$MySignatureAlg");
+        }
+    }
+
+    public static class MySignatureAlg extends Signature {
+
+        public MySignatureAlg() {
+            super(null);
+        }
+
+        MySignatureAlg(String s) {
+            super(s);
+        }
+
+        @Override
+        protected void engineInitVerify(PublicKey publicKey)
+                throws InvalidKeyException {
+        }
+
+        @Override
+        protected void engineInitSign(PrivateKey privateKey)
+                throws InvalidKeyException {
+        }
+
+        @Override
+        protected void engineUpdate(byte b) throws SignatureException {
+        }
+
+        @Override
+        protected void engineUpdate(byte[] b, int off, int len)
+                throws SignatureException {
+        }
+
+        @Override
+        protected byte[] engineSign()
+                throws SignatureException {
+            return new byte[0];
+        }
+
+        @Override
+        protected boolean engineVerify(byte[] sigBytes)
+                throws SignatureException {
+            return false;
+        }
+
+        @Override
+        @Deprecated
+        protected void engineSetParameter(String param, Object value)
+                throws InvalidParameterException {
+        }
+
+        @Override
+        @Deprecated
+        protected Object engineGetParameter(String param)
+                throws InvalidParameterException {
+            return null;
+        }
+    }
+}