changeset 6011:1ebaa3f08ed1

Merge
author mduigou
date Fri, 14 Sep 2012 09:09:24 -0700
parents 257bb5320a2b 5e95936891d2
children 9fffedf7ed04
files src/share/classes/java/util/streams/ops/AbstractTask.java src/share/classes/java/util/streams/ops/TreeUtils.java
diffstat 22 files changed, 349 insertions(+), 244 deletions(-) [+]
line wrap: on
line diff
--- a/combo-tests/build.xml	Thu Sep 13 21:40:37 2012 -0700
+++ b/combo-tests/build.xml	Fri Sep 14 09:09:24 2012 -0700
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project name="jdk" default="test">
 
-    <property name="build.dir" value="build" />
-    <property name="gen.dir" value="gen" />
+    <property name="build.dir" value="../../build/combo-tests" />
+    <property name="gen.dir" value="${build.dir}/gen" />
     <property name="test.classes.dir" value="${build.dir}/test-classes"/>
     <property name="test.reports.dir" value="${build.dir}/test-reports"/>
     <property name="test.src.dir" value="tests"/>
--- a/combo-tests/tests/tools/javac/lambda/DefaultMethodAddTest.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/combo-tests/tests/tools/javac/lambda/DefaultMethodAddTest.java	Fri Sep 14 09:09:24 2012 -0700
@@ -33,19 +33,16 @@
     @DimensionVar("ADD") AddType addType;
         
     @SourceFile(value="B.java", group="A")
-    String interfaceBModified = "interface B #{SHAPE.EXTEND} { #{ADD} }";
+    String interfaceBModified = "interface B #{SHAPE.B_DECL} { #{ADD} }";
     
     @SourceFile(value="B.java", group="B")
-    String interfaceB = "interface B #{SHAPE.EXTEND} {}";
+    String interfaceB =         "interface B #{SHAPE.B_DECL} {}";
     
     @SourceFile(value="A.java", group="B")
-    String interfaceA = "interface A { String m() default { return \"A\"; } }";
-    
-    @SourceFile(value="AB.java", group="B")
-    String interfaceAB = "#{SHAPE.COMMENT}interface AB extends A, B {}";
+    String interfaceA =         "interface A { String m() default { return \"A\"; } }";
     
     @SourceFile(value="C.java", group="B")
-    String classC = "class C implements #{SHAPE.IMPLEMENT} {}";
+    String classC = "#{SHAPE.C}";
     
     @SourceFile(value="Main.java", group="B")
     String classMain = "public class Main {\n" +
@@ -67,42 +64,59 @@
         } catch (InvocationTargetException ex) {
             output = ex.getCause().getMessage();          
         }        
-        if(shapeType == CShapes.C_B_A){
+        if(shapeType == CShapes.C_B_A) {
             if(addType == AddType.ADD)
                 assertEquals(result, "B");
             else //redeclare
-                assertEquals(result, "A");
-        } else {
-            if(addType == AddType.ADD)
-                assertTrue(output.matches("Conflicting default methods: .+[.]m .+[.]m"));                    
-            else //redeclare
-                assertEquals(result, "A");        
+                assertEquals(output, "Method B.m()Ljava/lang/String; is abstract");
         }
+        else if(shapeType == CShapes.C_I_AB2)
+        	assertEquals(result, "A");
+        else if(shapeType == CShapes.C_CI)
+        	assertEquals(result, "D");
+        else if(shapeType == CShapes.C_I_AB3)
+        	assertEquals(result, "AB");
+        else            
+            assertTrue(output.matches("Conflicting default methods: .+[.]m .+[.]m"));        
     }
     
     enum CShapes implements Template { //shapes of class hirarchy
         //class C implements interface A, B
-        C_AB("", "A, B", "//"), 
+        C_AB("", 
+	       "class C implements A, B {}"), 
         //class C implments interface B, B extends interface A
-        C_B_A("extends A", "B", "//"),         
+        C_B_A("extends A", 
+	       "class C implements B {}"),         
+
         //class C implments interface AB, AB extends interface A, B
-        C_I_AB("", "AB", "");        
+        C_I_AB("", 
+	       "interface AB extends A, B {  }\n" + 
+	       "class C implements AB {}"),
+        //class C implments interface AB, AB extends interface A, B and explicitly inherits the default method in A
+        C_I_AB2("", 
+		"interface AB extends A, B { String m() default { return A.super.m(); } }\n" + 
+		"class C implements AB {}"),
+        //class C implments interface AB, AB extends interface A, B and overrides the default method inherited
+        C_I_AB3("", 
+		"interface AB extends A, B { String m() default { return \"AB\"; } }\n" + 
+		"class C implements AB {}"),
+        //class C extends Class D implements Interface B
+        C_CI("", 
+	        "class D { public String m() { return \"D\"; } }\n" + 
+	        "class C extends D implements B {}");
         
-        private final String extend;
-        private final String implement;
-        private final String commentSign;
+        private final String sB_DECL;
+        private final String sC;
         
-        CShapes(String extend, String implement, String commentSign) {
-            this.extend = extend;
-            this.implement = implement;
-            this.commentSign = commentSign;            
+        CShapes(String sB_DECL, String sC) {
+            this.sB_DECL = sB_DECL;
+            this.sC = sC;
         }
         
         public String expand(String selector) {
             switch(selector) {
-                case "EXTEND": return extend;
-                case "IMPLEMENT": return implement;
-                case "COMMENT": return commentSign;
+                case "B_DECL": return sB_DECL;
+                case "C": return sC;
                 default: return toString();
             }            
         }        
--- a/combo-tests/tests/tools/javac/lambda/DefaultMethodRemoveTest.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/combo-tests/tests/tools/javac/lambda/DefaultMethodRemoveTest.java	Fri Sep 14 09:09:24 2012 -0700
@@ -32,19 +32,16 @@
     @DimensionVar("REMOVE") RemoveType removeType;
     
     @SourceFile(value="B.java", group="A")
-    String interfaceBModified = "interface B #{SHAPE.EXTENDS} { #{REMOVE} }";
+    String interfaceBModified = "interface B #{SHAPE.B_DECL} { #{REMOVE} }";
       
     @SourceFile(value="A.java", group="B")
     String interfaceA = "interface A { String m() default { return \"A\"; } }";
     
     @SourceFile(value="B.java", group="B")
-    String interfaceB = "interface B #{SHAPE.EXTENDS} { String m() default { return \"B\"; } }";
-    
-    @SourceFile(value="D.java", group="B")
-    String interfaceD = "#{SHAPE.COMMENT}interface D { String m() default { return \"D\"; } }";
-    
+    String interfaceB = "interface B #{SHAPE.B_DECL} { String m() default { return \"B\"; } }";
+        
     @SourceFile(value="C.java", group="B")
-    String classC = "class C implements B {}";
+    String classC = "#{SHAPE.C}";
     
     @SourceFile(value="Main.java", group="B")
     String classMain = "public class Main {\n" +
@@ -72,40 +69,56 @@
         } catch (InvocationTargetException ex) {
             output = ex.getCause().getMessage();
         }
-        if(shapeType == CShapes.C_B_A)
-            assertEquals(result, "A");
-        else if(shapeType == CShapes.C_B)
-            assertEquals(output, "C.m()Ljava/lang/String;");
-        else if (shapeType == CShapes.C_B_AD)                        
-            assertTrue(output.matches("Conflicting default methods: .+[.]m .+[.]m"));
+        if(shapeType == CShapes.C_B_A) {
+            if(removeType == RemoveType.REMOVE)
+                assertEquals(result, "A");
+            else
+                assertEquals(output, "Method B.m()Ljava/lang/String; is abstract");
+        }
+        else if(shapeType == CShapes.C_CI)
+            assertEquals(result, "D");
+        else {
+            if(shapeType == CShapes.C_B_AD && removeType == RemoveType.REDECLARE)
+                assertEquals(output, "Method B.m()Ljava/lang/String; is abstract");
+            else
+                assertEquals(output, "C.m()Ljava/lang/String;");
+        }
     }
     
     enum CShapes implements Template { //shapes of class hirarchy
         //class C implements interface B
-        C_B("", "//"), 
+        C_B("", 
+            "class C implements B {}"), 
         //class C implments interface B, B extends interface A
-        C_B_A("extends A", "//"),
+        C_B_A("extends A", 
+              "class C implements B {}"),
         //class C implments interface B, B extends interface A, D
-        C_B_AD("extends A, D", ""); 
+        C_B_AD("extends A, D", 
+               "interface D { String m() default { return \"D\"; } }\n" + 
+               "class C implements B {}"),
+        //class C extends Class D implements Interface B
+        C_CI("", 
+             "class D { public String m() { return \"D\"; } }\n" + 
+              "class C extends D implements B {}");
         
-        private final String extend;
-        private final String commentSign;
+        private final String sB_DECL;
+        private final String sC;
         
-        CShapes(String extend, String commentSign) {
-            this.extend = extend;
-            this.commentSign = commentSign;
+        CShapes(String sB_DECL, String sC) {
+            this.sB_DECL = sB_DECL;
+            this.sC = sC;            
         }
         
         public String expand(String selector) {
             switch(selector) {
-                case "EXTENDS": return extend;
-                case "COMMENT": return commentSign;                
+                case "B_DECL": return sB_DECL;
+                case "C": return sC;                
                 default: return toString();
             }
         }        
     }
     
-    enum RemoveType implements Template { // remove by removing default method code or redeclaring the interface method
+    enum RemoveType implements Template { //remove by removing default method code or redeclaring the interface method
         REMOVE(""),
         REDECLARE("String m();");
         
--- a/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java	Fri Sep 14 09:09:24 2012 -0700
@@ -25,11 +25,17 @@
 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.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
 
 /**
  * Abstract implementation of a meta-factory which provides parameter unrolling and input validation.
@@ -63,6 +69,9 @@
     final MethodType implMethodType;          // Type of the implementation method "(int)String"
     final MethodType instantiatedMethodType;  // Instantiated erased functional interface method type "(Integer)Object"
 
+    static final Executor logPool = Executors.newSingleThreadExecutor(); // @@@ For debugging only
+
+
     /**
      * Meta-factory constructor.
      *
@@ -304,4 +313,101 @@
                || !fromType.equals(void.class) && isAdaptableTo(fromType, toType, false);
     }
 
+    // @@@ Logging support -- for debugging only -- delete before shipping
+    protected static void log(final String s) {
+        MethodHandleProxyLambdaMetafactory.logPool.execute(new Runnable() {
+            @Override
+            public void run() {
+                System.out.println(s);
+            }
+        });
+    }
+
+    protected static void log(final String s, final Throwable e) {
+        MethodHandleProxyLambdaMetafactory.logPool.execute(new Runnable() {
+            @Override
+            public void run() {
+                System.out.println(s);
+                e.printStackTrace(System.out);
+            }
+        });
+    }
+
+    /**
+     * Find the SAM method and corresponding methods which should be bridged. SAM method and those to be bridged
+     * will have the same name and number of parameters. Check for matching default methods (non-abstract), they
+     * should not be bridged-over and indicate a complex bridging situation.
+     */
+    class MethodAnalyzer {
+        private final Method[] methods = samBase.getMethods();
+        private final List<Method> methodsFound = new ArrayList<>(methods.length);
+
+        private Method samMethod = null;
+        private final List<Method> methodsToBridge = new ArrayList<>(methods.length);
+        private boolean defaultMethodFound = false;
+
+        MethodAnalyzer() {
+            String samMethodName = samInfo.getName();
+            Class<?>[] samParamTypes = samMethodType.parameterArray();
+            int samParamLength = samParamTypes.length;
+            Class<?> samReturnType = samMethodType.returnType();
+            Class<?> objectClass = Object.class;
+
+            for (Method m : methods) {
+                if (m.getName().equals(samMethodName) && m.getDeclaringClass() != objectClass) {
+                    Class<?>[] mParamTypes = m.getParameterTypes();
+                    if (mParamTypes.length == samParamLength) {
+                        if (Modifier.isAbstract(m.getModifiers())) {
+                            // Exclude methods with duplicate signatures
+                            if (methodUnique(m)) {
+                                if (m.getReturnType().equals(samReturnType) && Arrays.equals(mParamTypes, samParamTypes)) {
+                                    // Exact match, this is the SAM method signature
+                                    samMethod = m;
+                                } else {
+                                    methodsToBridge.add(m);
+                                }
+                            }
+                        } else {
+                            // This is a default method, flag for special processing
+                            defaultMethodFound = true;
+                            // Ignore future matching abstracts.
+                            // Note, due to reabstraction, this is really a punt, hence pass-off to VM
+                            methodUnique(m);
+                        }
+                    }
+                }
+            }
+        }
+
+        Method getSamMethod() {
+            return samMethod;
+        }
+
+        List<Method> getMethodsToBridge() {
+            return methodsToBridge;
+        }
+
+        boolean wasDefaultMethodFound() {
+            return defaultMethodFound;
+        }
+
+        /**
+         * Search the list of previously found methods to determine if there is a method with the same signature
+         * (return and parameter types) as the specified method. If it wasn't found before, add to the found list.
+         *
+         * @param m The method to match
+         * @return False if the method was found, True otherwise
+         */
+        private boolean methodUnique(Method m) {
+            Class<?>[] ptypes = m.getParameterTypes();
+            Class<?> rtype = m.getReturnType();
+            for (Method md : methodsFound) {
+                if (md.getReturnType().equals(rtype) && Arrays.equals(ptypes, md.getParameterTypes())) {
+                    return false;
+                }
+            }
+            methodsFound.add(m);
+            return true;
+        }
+    }
 }
--- a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Fri Sep 14 09:09:24 2012 -0700
@@ -147,7 +147,6 @@
     private <T> Class<? extends T> spinInnerClass() {
         String samMethodName = samInfo.getName();
 
-        Method[] methods = samBase.getMethods();
         String samName = samBase.getName().replace('.', '/');
         Type samType = Type.getType(samBase);
 
@@ -162,65 +161,28 @@
         
         generateConstructor();
 
-        // Generate methods
-        Class<?>[] samParamTypes = samMethodType.parameterArray();
-        int samParamLength = samParamTypes.length;
-        Class<?> samReturnType = samMethodType.returnType();
-        boolean defaultMethodFound = false;
-        Method samMethod = null;
-        List<Method> methodsFound = new ArrayList<>(methods.length);
-        List<Method> methodsToBridge = new ArrayList<>(methods.length);
-        Class<?> objectClass = Object.class;
-
-        // Find the SAM method and corresponding methods which should be bridged.
-        // SAM method and those to be bridged will have the same name and number of parameters.
-        // Check for default methods (non-abstract), they should not be bridged-over and indicate a complex bridging situation.
-        for (Method m : methods) {
-            if (m.getName().equals(samMethodName) && m.getDeclaringClass() != objectClass) {
-                Class<?>[] mParamTypes = m.getParameterTypes();
-                if (mParamTypes.length == samParamLength) {
-                    if (Modifier.isAbstract(m.getModifiers())) {
-                        // Exclude methods with duplicate signatures
-                        if (!matchesAnyMethod(m, methodsFound)) {
-                            methodsFound.add(m);
-                            if (m.getReturnType().equals(samReturnType) && Arrays.equals(mParamTypes, samParamTypes)) {
-                                // Exact match, this is the SAM method signature
-                                samMethod = m;
-                            } else {
-                                methodsToBridge.add(m);
-                            }
-                        }
-                    } else {
-                        // This is a default method, flag for special processing
-                        defaultMethodFound = true;
-                        // Ignore future matching abstracts.
-                        // Note, due to reabstraction, this is really a punt, hence pass-off to VM
-                        if (!matchesAnyMethod(m, methodsFound)) {
-                            methodsFound.add(m);
-                        }
-                    }
-                }
-            }
-        }
+        MethodAnalyzer ma = new MethodAnalyzer();
 
         // Forward the SAM method
-        if (samMethod == null) {
+        if (ma.getSamMethod() == null) {
             throw new LambdaConversionException(String.format("SAM method not found: %s", samMethodType));
         } else {
-            generateForwardingMethod(samMethod, false);
+            generateForwardingMethod(ma.getSamMethod(), false);
         }
 
         // Forward the bridges
         // @@@ Once the VM can do fail-over, uncomment the default method test
-        if (!methodsToBridge.isEmpty() /* && !defaultMethodFound*/) {
-            for (Method m : methodsToBridge) {
+        if (!ma.getMethodsToBridge().isEmpty() /* && !ma.wasDefaultMethodFound() */) {
+            for (Method m : ma.getMethodsToBridge()) {
                 generateForwardingMethod(m, true);
             }
         }
 
+        /***** Serialization not yet supported
         if (isSerializable) {
             generateSerializationMethod(samType, samMethodName);
         }
+        ******/
 
         cw.visitEnd();
 
@@ -243,23 +205,6 @@
     }
 
     /**
-     * Search the specified list of 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
-     * @param methods The list of methods to search
-     * @return True if a method was found in 'methods' which the same signature as 'm', False otherwise
-     */
-    private static boolean matchesAnyMethod(Method m, List<Method> methods) {
-        Class<?>[] ptypes = m.getParameterTypes();
-        Class<?> rtype = m.getReturnType();
-        for (Method md : methods) {
-            if (md.getReturnType().equals(rtype) && Arrays.equals(ptypes, md.getParameterTypes())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * Generate the constructor for the class
      */
     private void generateConstructor() {
@@ -283,6 +228,7 @@
     /**
      * Generate the serialization method (if needed)
      */
+    /****** This code is out of date -- known to be wrong -- and not currently used ******
     private void generateSerializationMethod(Type samType, String samMethodName) {
         String samMethodDesc = samMethodType.toMethodDescriptorString();
         TypeConvertingMethodAdapter mv = new TypeConvertingMethodAdapter(cw.visitMethod(ACC_PRIVATE + ACC_FINAL, NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE, null, null));
@@ -313,6 +259,7 @@
         mv.visitMaxs(-1, -1); // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
         mv.visitEnd();
     }
+    ********/
 
     /**
      * Generate a method which calls the lambda implementation method,
--- a/src/share/classes/java/lang/invoke/LambdaMetafactory.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/lang/invoke/LambdaMetafactory.java	Fri Sep 14 09:09:24 2012 -0700
@@ -69,8 +69,9 @@
  * as well as a method signature describing the number and static types (but not the values) of the dynamic
  * arguments, and the static return type of the invokedynamic site.
  *
- * <p>The implementation method can, in theory, be anything representable with a method handle. Currently supported
- * are method handles representing invocation of virtual, interface, constructor and static methods.
+ * <p>The implementation method is described with a method handle. In theory, any method handle could be used.
+ * Currently supported are method handles representing invocation of virtual, interface, constructor and static
+ * methods.
  *
  * <p>Assume:
  * <ul>
@@ -86,7 +87,8 @@
  * <ul>
  *     <li>Rd is a subtype of F</li>
  *     <li>For i=1..N, Ti is a subtype of Ui</li>
- *     <li>Rt is a subtype of Ru</li>
+ *     <li>Either Rt and Ru are primitive and are the same type, or both are reference types and
+ *         Rt is a subtype of Ru</li>
  *     <li>If the implementation method is a static method:
  *     <ul>
  *         <li>K + N = M</li>
@@ -106,8 +108,8 @@
  * <p>Note that the potentially parameterized implementation return type provides the value for the SAM. Whereas
  * the completely known instantiated return type is adapted to the implementation arguments. Because the
  * instantiated type of the implementation method is not available, the adaptability of return types cannot be
- * checked as precisely at link-time as arguments. Thus a loose version of link-time checking is done on return
- * type, while a strict version is applied to arguments.
+ * checked as precisely at link-time as the arguments can be checked. Thus a loose version of link-time checking is
+ * done on return type, while a strict version is applied to arguments.
  *
  * <p>A type Q is considered adaptable to S as follows:
  * <table>
--- a/src/share/classes/java/lang/invoke/MethodHandleInfo.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandleInfo.java	Fri Sep 14 09:09:24 2012 -0700
@@ -79,21 +79,21 @@
     private String getReferenceKindString() {
         switch (referenceKind) {
             case REF_NONE: return "REF_NONE";
-            case REF_getField: return "getField";
-            case REF_getStatic: return "getStatic";
-            case REF_putField: return "putField";
-            case REF_putStatic: return "putStatic";
-            case REF_invokeVirtual: return "invokeVirtual";
-            case REF_invokeStatic: return "invokeStatic";
-            case REF_invokeSpecial: return "invokeSpecial";
-            case REF_newInvokeSpecial: return "newInvokeSpecial";
-            case REF_invokeInterface: return "invokeInterface";
+            case REF_getField: return "getfield";
+            case REF_getStatic: return "getstatic";
+            case REF_putField: return "putfield";
+            case REF_putStatic: return "putstatic";
+            case REF_invokeVirtual: return "invokevirtual";
+            case REF_invokeStatic: return "invokestatic";
+            case REF_invokeSpecial: return "invokespecial";
+            case REF_newInvokeSpecial: return "newinvokespecial";
+            case REF_invokeInterface: return "invokeinterface";
             default: return "UNKNOWN_REFENCE_KIND";
         }
     }
 
     @Override
     public String toString() {
-        return String.format("MethodHandleInfo[%s %s.%s%s]", getReferenceKindString(), declaringClass.getName(), name, methodType);
+        return String.format("%s %s.%s:%s", getReferenceKindString(), declaringClass.getName(), name, methodType);
     }
 }
--- a/src/share/classes/java/lang/invoke/MethodHandleProxyLambdaMetafactory.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandleProxyLambdaMetafactory.java	Fri Sep 14 09:09:24 2012 -0700
@@ -25,8 +25,6 @@
 package java.lang.invoke;
 
 import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
 
 /**
  * MethodHandleProxyLambdaMetafactory
@@ -37,27 +35,6 @@
 
     private final MethodHandle implMethod;
 
-    // @@@ For debugging only -- delete before shipping
-    static Executor logPool = Executors.newSingleThreadExecutor();
-    private static void log(final String s) {
-        logPool.execute(new Runnable() {
-            @Override
-            public void run() {
-                System.out.println(s);
-            }
-        });
-    }
-    private static void log(final String s, final Throwable e) {
-        logPool.execute(new Runnable() {
-            @Override
-            public void run() {
-                System.out.println(s);
-                e.printStackTrace(System.out);
-            }
-        });
-    }
-    // -- dev-only --
-
     /**
      * Meta-factory constructor.
      *
--- a/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/lang/invoke/TypeConvertingMethodAdapter.java	Fri Sep 14 09:09:24 2012 -0700
@@ -180,8 +180,13 @@
                 boxingDescriptor(sort));
     }
 
-    void unbox(Type sType, Type tType) {
-        int sSort = sType.getSort();
+    /**
+     * Convert types by unboxing. The source type is known to be a primitive wrapper.
+     * @param spType A primitive type corresponding to wrapped reference source type
+     * @param tType A primitive type being converted to
+     */
+    void unbox(Type spType, Type tType) {
+        int sSort = spType.getSort();
         int tSort = tType.getSort();
         visitMethodInsn(INVOKEVIRTUAL,
                 NAME_PRIMITIVE_WRAPPER[sSort],
@@ -189,6 +194,12 @@
                 unboxingDescriptor(tSort));
     }
 
+    /**
+     * Convert types by unboxing.  Use the base wrapper (for example, Number for int, short, etc) to go directly
+     * to the desired type.
+     * @param sType A reference type being converted from
+     * @param tType A primitive type being converted to
+     */
     void looseUnbox(Type sType, Type tType) {
         int tSort = tType.getSort();
         String baseWrapper = NAME_PRIMITIVE_BASE_WRAPPER[tSort];
@@ -230,6 +241,13 @@
         return NAME_PRIMITIVE_WRAPPER[type.getSort()];
     }
 
+    /**
+     * Convert an argument of type 'argType' to be passed to 'targetType' assuring that it is 'functionalType'.
+     * Insert the needed conversion instructions in the method code.
+     * @param argType
+     * @param targetType
+     * @param functionalType
+     */
     void convertType(Type argType, Type targetType, Type functionalType) {
         if (argType.equals(targetType) || argType.equals(VOID_TYPE)) {
             return;
--- a/src/share/classes/java/util/streams/AbstractPipeline.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/AbstractPipeline.java	Fri Sep 14 09:09:24 2012 -0700
@@ -185,16 +185,20 @@
             }
 
             @Override
-            public Sink<T, ?, ?> sink(Sink sink) {
-                return wrapSink(ops, sink);
+            public Sink<T, ?, ?> wrapSink(Sink sink) {
+                return AbstractPipeline.wrapSink(ops, sink);
+            }
+
+            @Override
+            public Iterator wrapIterator(Iterator it) {
+                for (IntermediateOp op : ops)
+                    it = op.wrapIterator(it);
+                return it;
             }
 
             @Override
             public Iterator iterator() {
-                Iterator it = source.iterator();
-                for (IntermediateOp op : ops)
-                    it = op.wrapIterator(it);
-                return it;
+                return wrapIterator(source.iterator());
             }
 
             @Override
--- a/src/share/classes/java/util/streams/ops/AbstractTask.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/AbstractTask.java	Fri Sep 14 09:09:24 2012 -0700
@@ -44,7 +44,7 @@
     protected T children;
     protected T nextSibling;
     protected boolean isLeaf;
-    protected R result;
+    private R rawResult;
 
     protected AbstractTask(Spliterator<E> spliterator, long targetSize) {
         super(null);
@@ -62,17 +62,42 @@
 
     protected abstract R doLeaf();
 
+    @Override
+    public R getRawResult() {
+        return rawResult;
+    }
+
+    @Override
+    protected void setRawResult(R r) {
+        rawResult = r;
+    }
+
     protected T getParent() {
         return (T) getCompleter();
     }
 
+    protected T getRoot() {
+        T result = (T) this;
+        while (true) {
+            T parent = result.getParent();
+            if (parent == null)
+                return result;
+            else
+                result = parent;
+        }
+    }
+
+    protected void completeRoot(R result) {
+        getRoot().complete(result);
+    }
+
     @Override
     public void compute() {
         int remaining = spliterator.getRemainingSizeIfKnown();
         int naturalSplits = spliterator.getNaturalSplitArity();
         isLeaf = ((remaining <= targetSize) && (remaining >= 0)) || (naturalSplits == 0);
         if (isLeaf) {
-            result = doLeaf();
+            setRawResult(doLeaf());
             tryComplete();
         }
         else {
--- a/src/share/classes/java/util/streams/ops/CumulateOp.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/CumulateOp.java	Fri Sep 14 09:09:24 2012 -0700
@@ -180,7 +180,7 @@
                     else {
                         leafData = StreamBuilders.make();
                         TerminalSink<T, T> terminalSink = wrapSink(leafData);
-                        source.into(problem.helper.sink(terminalSink));
+                        source.into(problem.helper.wrapSink(terminalSink));
                         upward = terminalSink.getAndClearState();
                         // Special case -- if problem.depth == 0, just wrap the result and be done
                         if (isRoot())
--- a/src/share/classes/java/util/streams/ops/FoldOp.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/FoldOp.java	Fri Sep 14 09:09:24 2012 -0700
@@ -91,7 +91,7 @@
     public <V> U computeParallel(ParallelOpHelper<T, V> helper) {
         ReduceTask<T, U, V> task = new ReduceTask<>(helper.spliterator(), helper.suggestTargetSize(), helper, this);
         helper.invoke(task);
-        return task.result;
+        return task.getRawResult();
     }
 
     private static class ReduceTask<T, U, V> extends AbstractTask<V, U, ReduceTask<T,U,V>> {
@@ -118,7 +118,7 @@
         @Override
         protected U doLeaf() {
             final TerminalSink<T, U> reduceStage = op.sink();
-            spliterator.into(helper.sink(reduceStage));
+            spliterator.into(helper.wrapSink(reduceStage));
             return reduceStage.getAndClearState();
         }
 
@@ -126,10 +126,11 @@
         public void onCompletion(CountedCompleter caller) {
             if (!isLeaf) {
                 ReduceTask<T,U,V> child = children;
-                result = child.result;
+                U result = child.getRawResult();
                 child = child.nextSibling;
                 for (; child != null; child = child.nextSibling)
-                    result = op.combiner.operate(result, child.result);
+                    result = op.combiner.operate(result, child.getRawResult());
+                setRawResult(result);
             }
         }
     }
--- a/src/share/classes/java/util/streams/ops/ForEachOp.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/ForEachOp.java	Fri Sep 14 09:09:24 2012 -0700
@@ -96,7 +96,7 @@
     @Override
     public <V> Void computeParallel(ParallelOpHelper<T, V> helper) {
         long targetSize = helper.suggestTargetSize();
-        Sink<V, ?, ?> compoundSink = helper.sink(sink);
+        Sink<V, ?, ?> compoundSink = helper.wrapSink(sink);
         Spliterator<V> spliterator = helper.spliterator();
         if (helper.suggestDepth() == 0) {
             spliterator.into(compoundSink);
--- a/src/share/classes/java/util/streams/ops/MatchOp.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/MatchOp.java	Fri Sep 14 09:09:24 2012 -0700
@@ -26,6 +26,7 @@
 
 import java.util.Iterator;
 import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.functions.Predicate;
 import java.util.streams.Spliterator;
 
@@ -48,93 +49,82 @@
         return matchKind.match(iterator, predicate);
     }
 
-    // Code sketch for parallel implementation:
-    // - Decompose as per usual
-    // - run match on leaf chunks, returns b
-    // - if b == matchKind.shortCircuitOn, complete early and return b
-    // - else if we complete normally, return !shortCircuitOn
+    @Override
+    public <V> Boolean computeParallel(ParallelOpHelper<T, V> helper) {
+        // Approach for parallel implementation:
+        // - Decompose as per usual
+        // - run match on leaf chunks, call result "b"
+        // - if b == matchKind.shortCircuitOn, complete early and return b
+        // - else if we complete normally, return !shortCircuitOn
 
-    private static class MatchTask<T> extends AbstractTask<T, Boolean, MatchTask<T>> {
+        MatchTask<T, V> task = new MatchTask<>(helper.spliterator(), helper.suggestTargetSize(), this, helper);
+        helper.invoke(task);
+        return task.answer.get();
+    }
+
+    private static class MatchTask<T, V> extends AbstractTask<V, Boolean, MatchTask<T, V>> {
         private final MatchOp<T> op;
-        private final ParallelOpHelper<T, Boolean> helper;
+        private final ParallelOpHelper<T, V> helper;
+        private final AtomicReference<Boolean> answer;
 
-        private MatchTask(Spliterator<T> spliterator, long targetSize, MatchOp<T> op, ParallelOpHelper<T, Boolean> helper) {
+        private MatchTask(Spliterator<V> spliterator, long targetSize, MatchOp<T> op, ParallelOpHelper<T, V> helper) {
             super(spliterator, targetSize);
             this.op = op;
             this.helper = helper;
+            this.answer = new AtomicReference<>(null);
         }
 
-        private MatchTask(MatchTask<T> parent, Spliterator<T> spliterator) {
+        private MatchTask(MatchTask<T, V> parent, Spliterator<V> spliterator) {
             super(parent, spliterator);
             this.op = parent.op;
             this.helper = parent.helper;
+            this.answer = parent.answer;
         }
 
         @Override
-        protected MatchTask<T> makeChild(Spliterator<T> spliterator) {
+        protected MatchTask<T, V> makeChild(Spliterator<V> spliterator) {
             return new MatchTask<>(this, spliterator);
         }
 
         @Override
         protected Boolean doLeaf() {
-            boolean b = op.evaluate(helper.iterator());
-            if (b == op.matchKind.shortCircuitOn)
-                complete(null); // @@@ Should be complete(b);
-            return null;
+            boolean b = op.matchKind.match(helper.wrapIterator(spliterator.iterator()), op.predicate);
+            if (b == op.matchKind.shortCircuitResult) {
+                answer.compareAndSet(null, b);
+                completeRoot(b);
+            }
+            return b;
         }
 
         @Override
         public void onCompletion(CountedCompleter caller) {
-            // if getRawValue() returns non-null, then complete the parent with that
-            // if we have no parent, then complete with !shortCircuitOn
+            if (getParent() == null)
+                answer.compareAndSet(null, !op.matchKind.shortCircuitResult);
         }
     }
 
     public enum MatchKind {
-        ANY(true) {
-            @Override
-            <T> boolean match(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
-                while (iterator.hasNext()) {
-                    if(predicate.test(iterator.next())) {
-                        return true;
-                    }
-                }
+        ANY(true, true),
+        ALL(false, false),
+        NONE(true, false);
 
-                return false;
-            }
-        },
-        ALL(false) {
-            @Override
-            <T> boolean match(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
-                while (iterator.hasNext()) {
-                    if(!predicate.test(iterator.next())) {
-                        return false;
-                    }
-                }
+        private final boolean stopOnPredicateMatches;
+        private final boolean shortCircuitResult;
 
-                return true;
-            }
-        },
-        NONE(false) {
-            @Override
-            <T> boolean match(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
-                while (iterator.hasNext()) {
-                    if(predicate.test(iterator.next())) {
-                        return false;
-                    }
-                }
-
-                return true;
-            }
-        };
-
-        private final boolean shortCircuitOn;
-
-        MatchKind(boolean shortCircuitOn) {
-            this.shortCircuitOn = shortCircuitOn;
+        MatchKind(boolean stopOnPredicateMatches, boolean shortCircuitResult) {
+            this.stopOnPredicateMatches = stopOnPredicateMatches;
+            this.shortCircuitResult = shortCircuitResult;
         }
 
-        abstract<T> boolean match(Iterator<? extends T> iterator, Predicate<? super T> predicate);
+        <T> boolean match(Iterator<? extends T> iterator, Predicate<? super T> predicate) {
+            while (iterator.hasNext()) {
+                if(predicate.test(iterator.next()) == stopOnPredicateMatches) {
+                    return shortCircuitResult;
+                }
+            }
+
+            return !shortCircuitResult;
+        }
     }
 
 }
--- a/src/share/classes/java/util/streams/ops/ParallelOp.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/ParallelOp.java	Fri Sep 14 09:09:24 2012 -0700
@@ -43,7 +43,8 @@
         public int suggestDepth();
         public long suggestTargetSize();
         public Spliterator<V> spliterator();
-        public Sink<V, ?, ?> sink(Sink sink);
+        public Sink<V, ?, ?> wrapSink(Sink sink);
+        public Iterator wrapIterator(Iterator it);
         public Iterator<T> iterator();
         public<Z> Z invoke(ForkJoinTask<Z> task);
     }
--- a/src/share/classes/java/util/streams/ops/StatefulOp.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/StatefulOp.java	Fri Sep 14 09:09:24 2012 -0700
@@ -24,7 +24,7 @@
     <Z> TreeUtils.Node<U> computeParallel(ParallelOpHelper<T, Z> helper) default {
         // dumb default serial implementation
         final StreamBuilder<U> sb = StreamBuilders.make();
-        helper.spliterator().into(helper.sink(wrapSink(sb)));
+        helper.spliterator().into(helper.wrapSink(wrapSink(sb)));
         return TreeUtils.node(sb);
     }
 }
--- a/src/share/classes/java/util/streams/ops/TerminalOp.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/TerminalOp.java	Fri Sep 14 09:09:24 2012 -0700
@@ -58,7 +58,7 @@
     <V> U computeParallel(ParallelOpHelper<T, V> helper) default {
         // dumb default serial version
         TerminalSink<T, U> toArraySink = sink();
-        helper.spliterator().into(helper.sink(toArraySink));
+        helper.spliterator().into(helper.wrapSink(toArraySink));
         return toArraySink.getAndClearState();
     }
 
--- a/src/share/classes/java/util/streams/ops/TreeUtils.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/src/share/classes/java/util/streams/ops/TreeUtils.java	Fri Sep 14 09:09:24 2012 -0700
@@ -52,12 +52,12 @@
             // Need to account for SIZED flag from pipeline
             if (size != -1 && splitSizesKnown) {
                 builder = StreamBuilders.makeFixed(size);
-                spliterator.into(helper.sink(builder));
+                spliterator.into(helper.wrapSink(builder));
                 return node((T[]) builder.toArray());
             }
             else {
                 builder = StreamBuilders.make();
-                spliterator.into(helper.sink(builder));
+                spliterator.into(helper.wrapSink(builder));
                 return node(builder);
             }
         }
@@ -72,7 +72,7 @@
             else {
                 CollectorTask<U, T> task = new CollectorTask<>(spliterator, helper.suggestTargetSize(), helper);
                 helper.invoke(task);
-                Node<T> node = task.result;
+                Node<T> node = task.getRawResult();
                 if (flattenTree) {
                     T[] array = (T[]) new Object[node.size()];
                     helper.invoke(new ToArrayTask<>(node, array, 0));
@@ -123,7 +123,7 @@
         protected Node<U> doLeaf() {
             // @@@ Usual comment about using fixed stream builders if we know enough to do so
             StreamBuilder<U> builder = StreamBuilders.make();
-            spliterator.into(helper.sink(builder));
+            spliterator.into(helper.wrapSink(builder));
             return node(builder);
         }
 
@@ -134,13 +134,13 @@
                 Node<U>[] nodes = (Node<U>[]) new Node[numChildren];
                 int idx = 0;
                 for (CollectorTask<T, U> cur = children; cur != null; cur = cur.nextSibling)
-                    nodes[idx++] = cur.result;
-                result = node(nodes);
+                    nodes[idx++] = cur.getRawResult();
+                setRawResult(node(nodes));
             }
         }
     }
 
-    private static class SizedCollectorTask<T, U> extends CountedCompleter {
+    private static class SizedCollectorTask<T, U> extends CountedCompleter<Void> {
         private final Spliterator<T> spliterator;
         private final ParallelOp.ParallelOpHelper<U, T> helper;
         private final long targetSize;
@@ -173,7 +173,7 @@
             int naturalSplits = spliterator.getNaturalSplitArity();
             boolean isLeaf = ((remaining <= targetSize) && (remaining >= 0)) || (naturalSplits == 0);
             if (isLeaf) {
-                spliterator.into(helper.sink(Arrays.sink(array, offset, length)));
+                spliterator.into(helper.wrapSink(Arrays.sink(array, offset, length)));
                 tryComplete();
             }
             else {
@@ -195,7 +195,7 @@
         }
     }
 
-    private static class ToArrayTask<T> extends CountedCompleter {
+    private static class ToArrayTask<T> extends CountedCompleter<Void> {
         private final T[] array;
         private final Node<T> node;
         private final int offset;
--- a/test-ng/tests/org/openjdk/tests/java/util/streams/MapStreamTestDataProvider.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/test-ng/tests/org/openjdk/tests/java/util/streams/MapStreamTestDataProvider.java	Fri Sep 14 09:09:24 2012 -0700
@@ -91,7 +91,7 @@
 
                 list.add(new Object[]{
                             String.format("%s%s%s", name, "<Integer,Integer>", range),
-                            new StreamOpTestCase.MapTestData(makeIntegerIntegerMap((Class<? extends Map<Integer,Integer>>) type, size))
+                            new StreamOpTestCase.MapTestData<>(makeIntegerIntegerMap((Class<? extends Map<Integer,Integer>>) type, size))
                       });
                 list.add(new Object[]{
                             String.format("%s%s%s", name, "<Integer,String>", range),
--- a/test-ng/tests/org/openjdk/tests/java/util/streams/ops/MatchOpTest.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/MatchOpTest.java	Fri Sep 14 09:09:24 2012 -0700
@@ -61,7 +61,7 @@
         ALL {
             @Override
             <T> boolean match(Stream<T> stream, Predicate<T> predicate) {
-                return stream.anyMatch(predicate);
+                return stream.allMatch(predicate);
             }
 
             @Override
@@ -72,7 +72,7 @@
         NONE {
             @Override
             <T> boolean match(Stream<T> stream, Predicate<T> predicate) {
-                return stream.anyMatch(predicate);
+                return stream.noneMatch(predicate);
             }
 
             @Override
@@ -86,11 +86,12 @@
     }
 
     private<T> void assertPredicates(Streamable<T> source, MatchKind matchKind, Predicate<T>[] predicates, boolean... answers) {
-        for (int i=0; i<predicates.length; i++)
+        for (int i=0; i<predicates.length; i++) {
             assertEquals(answers[i], matchKind.match(source.stream(), predicates[i]), matchKind.toString() + predicates[i].toString());
+        }
     }
 
-    void testMatches() {
+    public void testMatches() {
         assertPredicates(countTo(0), MatchKind.ANY, INTEGER_PREDICATES, false, false, false, false);
         assertPredicates(countTo(0), MatchKind.ALL, INTEGER_PREDICATES, true, true, true, true);
         assertPredicates(countTo(0), MatchKind.NONE, INTEGER_PREDICATES, true, true, true, true);
@@ -107,7 +108,8 @@
     @Test(dataProvider = "opArrays", dataProviderClass = StreamTestDataProvider.class)
     public void testOps(String name, TestData<Integer> data) {
         for (Predicate<Integer> p : INTEGER_PREDICATES)
-            for (MatchKind matchKind : MatchKind.values())
+            for (MatchKind matchKind : MatchKind.values()) {
                 exerciseOps(data, matchKind.op(p));
+            }
     }
 }
--- a/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java	Thu Sep 13 21:40:37 2012 -0700
+++ b/test-ng/tests/org/openjdk/tests/java/util/streams/ops/StreamOpTestCase.java	Fri Sep 14 09:09:24 2012 -0700
@@ -321,11 +321,16 @@
 
         @Override
         @SuppressWarnings({ "raw", "unchecked" })
-        public Sink<T, ?, ?> sink(Sink sink) {
+        public Sink<T, ?, ?> wrapSink(Sink sink) {
             return sink;
         }
 
         @Override
+        public Iterator wrapIterator(Iterator it) {
+            return it;
+        }
+
+        @Override
         public Iterator<T> iterator() {
             return data.iterator();
         }