changeset 1829:8074ccd57d89

Merge
author chegar
date Wed, 08 May 2013 10:27:52 +0100
parents 27cda5134748 ec434cfd2752
children 9d7d36e6927c
files
diffstat 15 files changed, 1187 insertions(+), 201 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Sun Apr 28 08:16:41 2013 +0100
+++ b/.hgtags	Wed May 08 10:27:52 2013 +0100
@@ -209,3 +209,4 @@
 4a48f31735349782ad13980267358c97076adc66 jdk8-b85
 6ab578e141dfd17c4dc03869bb204aafa490c9f4 jdk8-b86
 1329f9c38d93c8caf339d7687df8371d06fe9e56 jdk8-b87
+a1e10f3adc47c8602a72e43a41403a642e73e0b1 jdk8-b88
--- a/make/build.xml	Sun Apr 28 08:16:41 2013 +0100
+++ b/make/build.xml	Wed May 08 10:27:52 2013 +0100
@@ -717,6 +717,29 @@
     <target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/>
 
     <!--
+    **** crules targets.
+    -->
+
+    <target name="build-crules" depends="-def-compilecrules,-def-build-jar-with-services">
+        <compilecrules/>
+        <build-jar-with-services
+                    name="crules"
+                    includes="crules/* crules/resources/*"
+                    classes.dir="${build.toolclasses.dir}"
+                    lib.dir="${build.toolclasses.dir}"
+                    jarmainclass=""
+                    jarclasspath="crules.jar"
+                    service.type="com.sun.source.util.Plugin"
+                    service.provider="crules.MutableFieldsAnalyzer"/>
+        <build-tool name="crules"/>
+    </target>
+
+    <target name="check-coding-rules" depends="build-bootstrap-javac,-create-import-jdk-stubs,build-crules">
+        <build-classes includes="${javac.includes}"
+            plugin.options="-J-Xbootclasspath/a:${build.toolclasses.dir}/crules.jar -Xplugin:mutable_fields_analyzer" />
+    </target>
+
+    <!--
     **** Create import JDK stubs.
     -->
 
@@ -811,6 +834,31 @@
         </macrodef>
     </target>
 
+    <target name="-def-build-jar-with-services">
+        <macrodef name="build-jar-with-services">
+            <attribute name="name"/>
+            <attribute name="includes"/>
+            <attribute name="classes.dir" default="${build.classes.dir}"/>
+            <attribute name="lib.dir" default="${dist.lib.dir}"/>
+            <attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/>
+            <attribute name="jarclasspath" default=""/>
+            <attribute name="service.type" default=""/>
+            <attribute name="service.provider" default=""/>
+            <sequential>
+                <mkdir dir="${build.toolclasses.dir}"/>
+                <jar destfile="@{lib.dir}/@{name}.jar"
+                     basedir="@{classes.dir}"
+                     includes="@{includes}">
+                    <service type="@{service.type}" provider="@{service.provider}"/>
+                    <manifest>
+                        <attribute name="Main-Class" value="@{jarmainclass}"/>
+                        <attribute name="Class-Path" value="@{jarclasspath}"/>
+                    </manifest>
+                </jar>
+            </sequential>
+        </macrodef>
+    </target>
+
     <target name="-def-build-classes" depends="-def-pcompile">
         <macrodef name="build-classes">
             <attribute name="includes"/>
@@ -826,6 +874,7 @@
             <attribute name="target" default="${javac.target}"/>
             <attribute name="release" default="${release}"/>
             <attribute name="full.version" default="${full.version}"/>
+            <attribute name="plugin.options" default=""/>
             <sequential>
                 <echo level="verbose" message="build-classes: excludes=@{excludes}"/>
                 <echo level="verbose" message="build-classes: bootclasspath.opt=@{bootclasspath.opt}"/>
@@ -868,6 +917,7 @@
                     <compilerarg line="${javac.no.jdk.warnings}"/>
                     <compilerarg line="${javac.version.opt}"/>
                     <compilerarg line="${javac.lint.opts}"/>
+                    <compilerarg line="@{plugin.options}"/>
                 </javac>
                 <copy todir="@{classes.dir}" includeemptydirs="false">
                     <fileset dir="${src.classes.dir}" includes="@{includes}" excludes="@{excludes}">
@@ -935,6 +985,32 @@
                  classpath="${build.toolclasses.dir}/"/>
     </target>
 
+    <target name="-def-compilecrules">
+        <macrodef name="compilecrules">
+            <sequential>
+                <mkdir dir="${build.toolclasses.dir}"/>
+                <javac fork="true"
+                       source="${boot.javac.source}"
+                       target="${boot.javac.target}"
+                       executable="${boot.java.home}/bin/javac"
+                       srcdir="${make.tools.dir}"
+                       includes="crules/*"
+                       destdir="${build.toolclasses.dir}/"
+                       classpath="${ant.core.lib}"
+                       bootclasspath="${boot.java.home}/jre/lib/rt.jar"
+                       includeantruntime="false">
+                    <compilerarg value="-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
+                    <compilerarg line="${javac.lint.opts}"/>
+                </javac>
+                <copy todir="${build.toolclasses.dir}/" includeemptydirs="false">
+                    <fileset dir="${make.tools.dir}">
+                        <include name="**/*.properties"/>
+                    </fileset>
+                </copy>
+            </sequential>
+        </macrodef>
+    </target>
+
     <target name="-def-genstubs" depends="build-bootstrap-javac" if="require.import.jdk.stubs">
         <mkdir dir="${build.toolclasses.dir}"/>
         <javac fork="true"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/crules/AbstractCodingRulesAnalyzer.java	Wed May 08 10:27:52 2013 +0100
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+
+package crules;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+
+import com.sun.source.tree.Tree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.Plugin;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.BasicJavacTask;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.TreeScanner;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Log;
+
+import static com.sun.source.util.TaskEvent.Kind;
+
+public abstract class AbstractCodingRulesAnalyzer implements Plugin {
+
+    protected Log log;
+    protected Trees trees;
+    protected TreeScanner treeVisitor;
+    protected Kind eventKind;
+    protected Messages messages;
+
+    public void init(JavacTask task, String... args) {
+        BasicJavacTask impl = (BasicJavacTask)task;
+        Context context = impl.getContext();
+        log = Log.instance(context);
+        trees = Trees.instance(task);
+        messages = new Messages();
+        task.addTaskListener(new PostAnalyzeTaskListener());
+    }
+
+    public class PostAnalyzeTaskListener implements TaskListener {
+
+        @Override
+        public void started(TaskEvent taskEvent) {}
+
+        @Override
+        public void finished(TaskEvent taskEvent) {
+            if (taskEvent.getKind().equals(eventKind)) {
+                TypeElement typeElem = taskEvent.getTypeElement();
+                Tree tree = trees.getTree(typeElem);
+                if (tree != null) {
+                    JavaFileObject prevSource = log.currentSourceFile();
+                    try {
+                        log.useSource(taskEvent.getCompilationUnit().getSourceFile());
+                        treeVisitor.scan((JCTree)tree);
+                    } finally {
+                        log.useSource(prevSource);
+                    }
+                }
+            }
+        }
+    }
+
+    class Messages {
+        ResourceBundle bundle;
+
+        Messages() {
+            String name = getClass().getPackage().getName() + ".resources.crules";
+            bundle = ResourceBundle.getBundle(name, Locale.ENGLISH);
+        }
+
+        public void error(JCTree tree, String code, Object... args) {
+            String msg = (code == null) ? (String) args[0] : localize(code, args);
+            log.error(tree, "proc.messager", msg.toString());
+        }
+
+        private String localize(String code, Object... args) {
+            String msg = bundle.getString(code);
+            if (msg == null) {
+                StringBuilder sb = new StringBuilder();
+                sb.append("message file broken: code=").append(code);
+                if (args.length > 0) {
+                    sb.append(" arguments={0}");
+                    for (int i = 1; i < args.length; i++) {
+                        sb.append(", {").append(i).append("}");
+                    }
+                }
+                msg = sb.toString();
+            }
+            return MessageFormat.format(msg, args);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/crules/MutableFieldsAnalyzer.java	Wed May 08 10:27:52 2013 +0100
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+
+package crules;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.tools.javac.code.Kinds;
+import com.sun.tools.javac.tree.TreeScanner;
+
+import static com.sun.source.util.TaskEvent.Kind;
+import static com.sun.tools.javac.code.Flags.*;
+import static com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+
+public class MutableFieldsAnalyzer extends AbstractCodingRulesAnalyzer {
+
+    public MutableFieldsAnalyzer() {
+        treeVisitor = new MutableFieldsVisitor();
+        eventKind = Kind.ANALYZE;
+    }
+
+    public String getName() {
+        return "mutable_fields_analyzer";
+    }
+
+    private boolean ignoreField(String className, String field) {
+        List<String> currentFieldsToIgnore =
+                classFieldsToIgnoreMap.get(className);
+        if (currentFieldsToIgnore != null) {
+            for (String fieldToIgnore : currentFieldsToIgnore) {
+                if (field.equals(fieldToIgnore)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    class MutableFieldsVisitor extends TreeScanner {
+
+        @Override
+        public void visitVarDef(JCVariableDecl tree) {
+            boolean isJavacPack = tree.sym.outermostClass().fullname.toString()
+                    .contains(packageToCheck);
+            if (isJavacPack &&
+                (tree.sym.flags() & SYNTHETIC) == 0 &&
+                tree.sym.owner.kind == Kinds.TYP) {
+                if (!ignoreField(tree.sym.owner.flatName().toString(),
+                        tree.getName().toString())) {
+                    boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0;
+                    boolean nonFinalStaticEnumField =
+                            (tree.sym.flags() & (ENUM | FINAL)) == 0;
+                    boolean nonFinalStaticField =
+                            (tree.sym.flags() & STATIC) != 0 &&
+                            (tree.sym.flags() & FINAL) == 0;
+                    if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) {
+                        messages.error(tree, "crules.err.var.must.be.final", tree);
+                    }
+                }
+            }
+            super.visitVarDef(tree);
+        }
+
+    }
+
+    private static final String packageToCheck = "com.sun.tools.javac";
+
+    private static final Map<String, List<String>> classFieldsToIgnoreMap =
+                new HashMap<String, List<String>>();
+
+    static {
+        classFieldsToIgnoreMap.
+                put("com.sun.tools.javac.util.JCDiagnostic",
+                    Arrays.asList("fragmentFormatter"));
+        classFieldsToIgnoreMap.
+                put("com.sun.tools.javac.util.JavacMessages",
+                    Arrays.asList("defaultBundle", "defaultMessages"));
+        classFieldsToIgnoreMap.
+                put("com.sun.tools.javac.file.ZipFileIndexCache",
+                    Arrays.asList("sharedInstance"));
+        classFieldsToIgnoreMap.
+                put("com.sun.tools.javac.main.JavaCompiler",
+                    Arrays.asList("versionRB"));
+        classFieldsToIgnoreMap.
+                put("com.sun.tools.javac.code.Type",
+                    Arrays.asList("moreInfo"));
+        classFieldsToIgnoreMap.
+                put("com.sun.tools.javac.util.SharedNameTable",
+                    Arrays.asList("freelist"));
+        classFieldsToIgnoreMap.
+                put("com.sun.tools.javac.util.Log",
+                    Arrays.asList("useRawMessages"));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/tools/crules/resources/crules.properties	Wed May 08 10:27:52 2013 +0100
@@ -0,0 +1,28 @@
+#
+# 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.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# 0: symbol
+crules.err.var.must.be.final=\
+    Static variable {0} must be final
--- a/src/share/classes/com/sun/tools/classfile/Dependencies.java	Sun Apr 28 08:16:41 2013 +0100
+++ b/src/share/classes/com/sun/tools/classfile/Dependencies.java	Wed May 08 10:27:52 2013 +0100
@@ -315,7 +315,7 @@
     static class SimpleLocation implements Location {
         public SimpleLocation(String name) {
             this.name = name;
-            this.className = name.replace('/', '.').replace('$', '.');
+            this.className = name.replace('/', '.');
         }
 
         public String getName() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/com/sun/tools/classfile/ReferenceFinder.java	Wed May 08 10:27:52 2013 +0100
@@ -0,0 +1,240 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.classfile;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import com.sun.tools.classfile.Instruction.TypeKind;
+import static com.sun.tools.classfile.ConstantPool.*;
+
+/**
+ * A utility class to find where in a ClassFile references
+ * a {@link CONSTANT_Methodref_info method},
+ * a {@link CONSTANT_InterfaceMethodref_info interface method,
+ * or a {@link CONSTANT_Fieldref_info field}.
+ */
+public final class ReferenceFinder {
+    /**
+     * Filter for ReferenceFinder of what constant pool entries for reference lookup.
+     */
+    public interface Filter {
+        /**
+         * Decides if the given CPRefInfo entry should be accepted or filtered.
+         *
+         * @param cpool  ConstantPool of the ClassFile being parsed
+         * @param cpref  constant pool entry representing a reference to
+         *               a fields method, and interface method.
+         * @return {@code true} if accepted; otherwise {@code false}
+         */
+        boolean accept(ConstantPool cpool, CPRefInfo cpref);
+    }
+
+    /**
+     * Visitor of individual method of a ClassFile that references the
+     * accepted field, method, or interface method references.
+     */
+    public interface Visitor {
+        /**
+         * Invoked for a method containing one or more accepted CPRefInfo entries
+         *
+         * @param cf      ClassFile
+         * @param method  Method that does the references the accepted references
+         * @param refs    Accepted constant pool method/field reference
+         */
+        void visit(ClassFile cf, Method method, List<CPRefInfo> refConstantPool);
+    }
+
+    private final Filter filter;
+    private final Visitor visitor;
+
+    /**
+     * Constructor.
+     */
+    public ReferenceFinder(Filter filter, Visitor visitor) {
+        this.filter = Objects.requireNonNull(filter);
+        this.visitor = Objects.requireNonNull(visitor);
+    }
+
+    /**
+     * Parses a given ClassFile and invoke the visitor if there is any reference
+     * to the constant pool entries referencing field, method, or
+     * interface method that are accepted. This method will return
+     * {@code true} if there is one or more accepted constant pool entries
+     * to lookup; otherwise, it will return {@code false}.
+     *
+     * @param  cf  ClassFile
+     * @return {@code true} if the given class file is processed to lookup
+     *         references
+     * @throws ConstantPoolException if an error of the constant pool
+     */
+    public boolean parse(ClassFile cf) throws ConstantPoolException {
+        List<Integer> cprefs = new ArrayList<Integer>();
+        int index = 1;
+        for (ConstantPool.CPInfo cpInfo : cf.constant_pool.entries()) {
+            if (cpInfo.accept(cpVisitor, cf.constant_pool)) {
+                cprefs.add(index);
+            }
+            index += cpInfo.size();
+        }
+
+        if (cprefs.isEmpty()) {
+            return false;
+        }
+
+        for (Method m : cf.methods) {
+            Set<Integer> ids = new HashSet<Integer>();
+            Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code);
+            if (c_attr != null) {
+                for (Instruction instr : c_attr.getInstructions()) {
+                    int idx = instr.accept(codeVisitor, cprefs);
+                    if (idx > 0) {
+                        ids.add(idx);
+                    }
+                }
+            }
+            if (ids.size() > 0) {
+                List<CPRefInfo> refInfos = new ArrayList<CPRefInfo>(ids.size());
+                for (int id : ids) {
+                    refInfos.add(CPRefInfo.class.cast(cf.constant_pool.get(id)));
+                }
+                visitor.visit(cf, m, refInfos);
+            }
+        }
+        return true;
+    }
+
+    private ConstantPool.Visitor<Boolean,ConstantPool> cpVisitor =
+            new ConstantPool.Visitor<Boolean,ConstantPool>()
+    {
+        public Boolean visitClass(CONSTANT_Class_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, ConstantPool cpool) {
+            return filter.accept(cpool, info);
+        }
+
+        public Boolean visitMethodref(CONSTANT_Methodref_info info, ConstantPool cpool) {
+            return filter.accept(cpool, info);
+        }
+
+        public Boolean visitFieldref(CONSTANT_Fieldref_info info, ConstantPool cpool) {
+            return filter.accept(cpool, info);
+        }
+
+        public Boolean visitDouble(CONSTANT_Double_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitFloat(CONSTANT_Float_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitInteger(CONSTANT_Integer_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitLong(CONSTANT_Long_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitNameAndType(CONSTANT_NameAndType_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitMethodHandle(CONSTANT_MethodHandle_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitMethodType(CONSTANT_MethodType_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitString(CONSTANT_String_info info, ConstantPool cpool) {
+            return false;
+        }
+
+        public Boolean visitUtf8(CONSTANT_Utf8_info info, ConstantPool cpool) {
+            return false;
+        }
+    };
+
+    private Instruction.KindVisitor<Integer, List<Integer>> codeVisitor =
+            new Instruction.KindVisitor<Integer, List<Integer>>()
+    {
+        public Integer visitNoOperands(Instruction instr, List<Integer> p) {
+            return 0;
+        }
+
+        public Integer visitArrayType(Instruction instr, TypeKind kind, List<Integer> p) {
+            return 0;
+        }
+
+        public Integer visitBranch(Instruction instr, int offset, List<Integer> p) {
+            return 0;
+        }
+
+        public Integer visitConstantPoolRef(Instruction instr, int index, List<Integer> p) {
+            return p.contains(index) ? index : 0;
+        }
+
+        public Integer visitConstantPoolRefAndValue(Instruction instr, int index, int value, List<Integer> p) {
+            return p.contains(index) ? index : 0;
+        }
+
+        public Integer visitLocal(Instruction instr, int index, List<Integer> p) {
+            return 0;
+        }
+
+        public Integer visitLocalAndValue(Instruction instr, int index, int value, List<Integer> p) {
+            return 0;
+        }
+
+        public Integer visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, List<Integer> p) {
+            return 0;
+        }
+
+        public Integer visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, List<Integer> p) {
+            return 0;
+        }
+
+        public Integer visitValue(Instruction instr, int value, List<Integer> p) {
+            return 0;
+        }
+
+        public Integer visitUnknown(Instruction instr, List<Integer> p) {
+            return 0;
+        }
+    };
+}
+
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Sun Apr 28 08:16:41 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed May 08 10:27:52 2013 +0100
@@ -1078,7 +1078,8 @@
                 mask = MethodFlags;
             }
             // Imply STRICTFP if owner has STRICTFP set.
-            if (((flags|implicit) & Flags.ABSTRACT) == 0)
+            if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
+                ((flags) & Flags.DEFAULT) != 0)
                 implicit |= sym.owner.flags_field & STRICTFP;
             break;
         case TYP:
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Sun Apr 28 08:16:41 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Wed May 08 10:27:52 2013 +0100
@@ -35,7 +35,6 @@
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
 import com.sun.tools.javac.code.Symbol.*;
-import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.tree.JCTree.*;
 
 import static com.sun.tools.javac.code.Flags.*;
@@ -277,6 +276,15 @@
     }
 
     /**
+     * Utility method to reset several Bits instances.
+     */
+    private void resetBits(Bits... bits) {
+        for (Bits b : bits) {
+            b.reset();
+        }
+    }
+
+    /**
      * Base visitor class for all visitors implementing dataflow analysis logic.
      * This class define the shared logic for handling jumps (break/continue statements).
      */
@@ -1294,11 +1302,11 @@
 
         /** The set of definitely assigned variables.
          */
-        Bits inits;
+        final Bits inits;
 
         /** The set of definitely unassigned variables.
          */
-        Bits uninits;
+        final Bits uninits;
 
         /** The set of variables that are definitely unassigned everywhere
          *  in current try block. This variable is maintained lazily; it is
@@ -1308,15 +1316,15 @@
          *  anywhere in current try block, intersect uninitsTry and
          *  uninits.
          */
-        Bits uninitsTry;
+        final Bits uninitsTry;
 
         /** When analyzing a condition, inits and uninits are null.
          *  Instead we have:
          */
-        Bits initsWhenTrue;
-        Bits initsWhenFalse;
-        Bits uninitsWhenTrue;
-        Bits uninitsWhenFalse;
+        final Bits initsWhenTrue;
+        final Bits initsWhenFalse;
+        final Bits uninitsWhenTrue;
+        final Bits uninitsWhenFalse;
 
         /** A mapping from addresses to variable symbols.
          */
@@ -1348,15 +1356,25 @@
         /** The starting position of the analysed tree */
         int startPos;
 
+        AssignAnalyzer() {
+            inits = new Bits();
+            uninits = new Bits();
+            uninitsTry = new Bits();
+            initsWhenTrue = new Bits(true);
+            initsWhenFalse = new Bits(true);
+            uninitsWhenTrue = new Bits(true);
+            uninitsWhenFalse = new Bits(true);
+        }
+
         class AssignPendingExit extends BaseAnalyzer.PendingExit {
 
-            Bits exit_inits;
-            Bits exit_uninits;
+            final Bits exit_inits = new Bits(true);
+            final Bits exit_uninits = new Bits(true);
 
-            AssignPendingExit(JCTree tree, Bits inits, Bits uninits) {
+            AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) {
                 super(tree);
-                this.exit_inits = inits.dup();
-                this.exit_uninits = uninits.dup();
+                this.exit_inits.assign(inits);
+                this.exit_uninits.assign(uninits);
             }
 
             void resolveJump() {
@@ -1476,19 +1494,20 @@
         /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets
          */
         void split(boolean setToNull) {
-            initsWhenFalse = inits.dup();
-            uninitsWhenFalse = uninits.dup();
-            initsWhenTrue = inits;
-            uninitsWhenTrue = uninits;
-            if (setToNull)
-                inits = uninits = null;
+            initsWhenFalse.assign(inits);
+            uninitsWhenFalse.assign(uninits);
+            initsWhenTrue.assign(inits);
+            uninitsWhenTrue.assign(uninits);
+            if (setToNull) {
+                resetBits(inits, uninits);
+            }
         }
 
         /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
          */
         void merge() {
-            inits = initsWhenFalse.andSet(initsWhenTrue);
-            uninits = uninitsWhenFalse.andSet(uninitsWhenTrue);
+            inits.assign(initsWhenFalse.andSet(initsWhenTrue));
+            uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue));
         }
 
     /* ************************************************************************
@@ -1501,7 +1520,7 @@
         void scanExpr(JCTree tree) {
             if (tree != null) {
                 scan(tree);
-                if (inits == null) merge();
+                if (inits.isReset()) merge();
             }
         }
 
@@ -1518,28 +1537,29 @@
          */
         void scanCond(JCTree tree) {
             if (tree.type.isFalse()) {
-                if (inits == null) merge();
-                initsWhenTrue = inits.dup();
+                if (inits.isReset()) merge();
+                initsWhenTrue.assign(inits);
                 initsWhenTrue.inclRange(firstadr, nextadr);
-                uninitsWhenTrue = uninits.dup();
+                uninitsWhenTrue.assign(uninits);
                 uninitsWhenTrue.inclRange(firstadr, nextadr);
-                initsWhenFalse = inits;
-                uninitsWhenFalse = uninits;
+                initsWhenFalse.assign(inits);
+                uninitsWhenFalse.assign(uninits);
             } else if (tree.type.isTrue()) {
-                if (inits == null) merge();
-                initsWhenFalse = inits.dup();
+                if (inits.isReset()) merge();
+                initsWhenFalse.assign(inits);
                 initsWhenFalse.inclRange(firstadr, nextadr);
-                uninitsWhenFalse = uninits.dup();
+                uninitsWhenFalse.assign(uninits);
                 uninitsWhenFalse.inclRange(firstadr, nextadr);
-                initsWhenTrue = inits;
-                uninitsWhenTrue = uninits;
+                initsWhenTrue.assign(inits);
+                uninitsWhenTrue.assign(uninits);
             } else {
                 scan(tree);
-                if (inits != null)
+                if (!inits.isReset())
                     split(tree.type != syms.unknownType);
             }
-            if (tree.type != syms.unknownType)
-                inits = uninits = null;
+            if (tree.type != syms.unknownType) {
+                resetBits(inits, uninits);
+            }
         }
 
         /* ------------ Visitor methods for various sorts of trees -------------*/
@@ -1619,8 +1639,8 @@
         public void visitMethodDef(JCMethodDecl tree) {
             if (tree.body == null) return;
 
-            Bits initsPrev = inits.dup();
-            Bits uninitsPrev = uninits.dup();
+            final Bits initsPrev = new Bits(inits);
+            final Bits uninitsPrev = new Bits(uninits);
             int nextadrPrev = nextadr;
             int firstadrPrev = firstadr;
             int returnadrPrev = returnadr;
@@ -1658,14 +1678,14 @@
                     exits = exits.tail;
                     Assert.check(exit.tree.hasTag(RETURN), exit.tree);
                     if (isInitialConstructor) {
-                        inits = exit.exit_inits;
+                        inits.assign(exit.exit_inits);
                         for (int i = firstadr; i < nextadr; i++)
                             checkInit(exit.tree.pos(), vars[i]);
                     }
                 }
             } finally {
-                inits = initsPrev;
-                uninits = uninitsPrev;
+                inits.assign(initsPrev);
+                uninits.assign(uninitsPrev);
                 nextadr = nextadrPrev;
                 firstadr = firstadrPrev;
                 returnadr = returnadrPrev;
@@ -1698,31 +1718,31 @@
             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
             FlowKind prevFlowKind = flowKind;
             flowKind = FlowKind.NORMAL;
-            Bits initsSkip = null;
-            Bits uninitsSkip = null;
+            final Bits initsSkip = new Bits(true);
+            final Bits uninitsSkip = new Bits(true);
             pendingExits = new ListBuffer<AssignPendingExit>();
             int prevErrors = log.nerrors;
             do {
-                Bits uninitsEntry = uninits.dup();
+                final Bits uninitsEntry = new Bits(uninits);
                 uninitsEntry.excludeFrom(nextadr);
                 scan(tree.body);
                 resolveContinues(tree);
                 scanCond(tree.cond);
                 if (!flowKind.isFinal()) {
-                    initsSkip = initsWhenFalse;
-                    uninitsSkip = uninitsWhenFalse;
+                    initsSkip.assign(initsWhenFalse);
+                    uninitsSkip.assign(uninitsWhenFalse);
                 }
                 if (log.nerrors !=  prevErrors ||
                     flowKind.isFinal() ||
-                    uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
+                    new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1)
                     break;
-                inits = initsWhenTrue;
-                uninits = uninitsEntry.andSet(uninitsWhenTrue);
+                inits.assign(initsWhenTrue);
+                uninits.assign(uninitsEntry.andSet(uninitsWhenTrue));
                 flowKind = FlowKind.SPECULATIVE_LOOP;
             } while (true);
             flowKind = prevFlowKind;
-            inits = initsSkip;
-            uninits = uninitsSkip;
+            inits.assign(initsSkip);
+            uninits.assign(uninitsSkip);
             resolveBreaks(tree, prevPendingExits);
         }
 
@@ -1730,34 +1750,34 @@
             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
             FlowKind prevFlowKind = flowKind;
             flowKind = FlowKind.NORMAL;
-            Bits initsSkip = null;
-            Bits uninitsSkip = null;
+            final Bits initsSkip = new Bits(true);
+            final Bits uninitsSkip = new Bits(true);
             pendingExits = new ListBuffer<AssignPendingExit>();
             int prevErrors = log.nerrors;
-            Bits uninitsEntry = uninits.dup();
+            final Bits uninitsEntry = new Bits(uninits);
             uninitsEntry.excludeFrom(nextadr);
             do {
                 scanCond(tree.cond);
                 if (!flowKind.isFinal()) {
-                    initsSkip = initsWhenFalse;
-                    uninitsSkip = uninitsWhenFalse;
+                    initsSkip.assign(initsWhenFalse) ;
+                    uninitsSkip.assign(uninitsWhenFalse);
                 }
-                inits = initsWhenTrue;
-                uninits = uninitsWhenTrue;
+                inits.assign(initsWhenTrue);
+                uninits.assign(uninitsWhenTrue);
                 scan(tree.body);
                 resolveContinues(tree);
                 if (log.nerrors != prevErrors ||
                     flowKind.isFinal() ||
-                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
+                    new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
                     break;
-                uninits = uninitsEntry.andSet(uninits);
+                uninits.assign(uninitsEntry.andSet(uninits));
                 flowKind = FlowKind.SPECULATIVE_LOOP;
             } while (true);
             flowKind = prevFlowKind;
             //a variable is DA/DU after the while statement, if it's DA/DU assuming the
             //branch is not taken AND if it's DA/DU before any break statement
-            inits = initsSkip;
-            uninits = uninitsSkip;
+            inits.assign(initsSkip);
+            uninits.assign(uninitsSkip);
             resolveBreaks(tree, prevPendingExits);
         }
 
@@ -1767,25 +1787,25 @@
             flowKind = FlowKind.NORMAL;
             int nextadrPrev = nextadr;
             scan(tree.init);
-            Bits initsSkip = null;
-            Bits uninitsSkip = null;
+            final Bits initsSkip = new Bits(true);
+            final Bits uninitsSkip = new Bits(true);
             pendingExits = new ListBuffer<AssignPendingExit>();
             int prevErrors = log.nerrors;
             do {
-                Bits uninitsEntry = uninits.dup();
+                final Bits uninitsEntry = new Bits(uninits);
                 uninitsEntry.excludeFrom(nextadr);
                 if (tree.cond != null) {
                     scanCond(tree.cond);
                     if (!flowKind.isFinal()) {
-                        initsSkip = initsWhenFalse;
-                        uninitsSkip = uninitsWhenFalse;
+                        initsSkip.assign(initsWhenFalse);
+                        uninitsSkip.assign(uninitsWhenFalse);
                     }
-                    inits = initsWhenTrue;
-                    uninits = uninitsWhenTrue;
+                    inits.assign(initsWhenTrue);
+                    uninits.assign(uninitsWhenTrue);
                 } else if (!flowKind.isFinal()) {
-                    initsSkip = inits.dup();
+                    initsSkip.assign(inits);
                     initsSkip.inclRange(firstadr, nextadr);
-                    uninitsSkip = uninits.dup();
+                    uninitsSkip.assign(uninits);
                     uninitsSkip.inclRange(firstadr, nextadr);
                 }
                 scan(tree.body);
@@ -1793,16 +1813,16 @@
                 scan(tree.step);
                 if (log.nerrors != prevErrors ||
                     flowKind.isFinal() ||
-                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
+                    new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
                     break;
-                uninits = uninitsEntry.andSet(uninits);
+                uninits.assign(uninitsEntry.andSet(uninits));
                 flowKind = FlowKind.SPECULATIVE_LOOP;
             } while (true);
             flowKind = prevFlowKind;
             //a variable is DA/DU after a for loop, if it's DA/DU assuming the
             //branch is not taken AND if it's DA/DU before any break statement
-            inits = initsSkip;
-            uninits = uninitsSkip;
+            inits.assign(initsSkip);
+            uninits.assign(uninitsSkip);
             resolveBreaks(tree, prevPendingExits);
             nextadr = nextadrPrev;
         }
@@ -1815,27 +1835,27 @@
             flowKind = FlowKind.NORMAL;
             int nextadrPrev = nextadr;
             scan(tree.expr);
-            Bits initsStart = inits.dup();
-            Bits uninitsStart = uninits.dup();
+            final Bits initsStart = new Bits(inits);
+            final Bits uninitsStart = new Bits(uninits);
 
             letInit(tree.pos(), tree.var.sym);
             pendingExits = new ListBuffer<AssignPendingExit>();
             int prevErrors = log.nerrors;
             do {
-                Bits uninitsEntry = uninits.dup();
+                final Bits uninitsEntry = new Bits(uninits);
                 uninitsEntry.excludeFrom(nextadr);
                 scan(tree.body);
                 resolveContinues(tree);
                 if (log.nerrors != prevErrors ||
                     flowKind.isFinal() ||
-                    uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1)
+                    new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1)
                     break;
-                uninits = uninitsEntry.andSet(uninits);
+                uninits.assign(uninitsEntry.andSet(uninits));
                 flowKind = FlowKind.SPECULATIVE_LOOP;
             } while (true);
             flowKind = prevFlowKind;
-            inits = initsStart;
-            uninits = uninitsStart.andSet(uninits);
+            inits.assign(initsStart);
+            uninits.assign(uninitsStart.andSet(uninits));
             resolveBreaks(tree, prevPendingExits);
             nextadr = nextadrPrev;
         }
@@ -1852,12 +1872,12 @@
             pendingExits = new ListBuffer<AssignPendingExit>();
             int nextadrPrev = nextadr;
             scanExpr(tree.selector);
-            Bits initsSwitch = inits;
-            Bits uninitsSwitch = uninits.dup();
+            final Bits initsSwitch = new Bits(inits);
+            final Bits uninitsSwitch = new Bits(uninits);
             boolean hasDefault = false;
             for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) {
-                inits = initsSwitch.dup();
-                uninits = uninits.andSet(uninitsSwitch);
+                inits.assign(initsSwitch);
+                uninits.assign(uninits.andSet(uninitsSwitch));
                 JCCase c = l.head;
                 if (c.pat == null)
                     hasDefault = true;
@@ -1875,8 +1895,8 @@
         }
         // where
             /** Add any variables defined in stats to inits and uninits. */
-            private void addVars(List<JCStatement> stats, Bits inits,
-                                        Bits uninits) {
+            private void addVars(List<JCStatement> stats, final Bits inits,
+                                        final Bits uninits) {
                 for (;stats.nonEmpty(); stats = stats.tail) {
                     JCTree stat = stats.head;
                     if (stat.hasTag(VARDEF)) {
@@ -1889,11 +1909,11 @@
 
         public void visitTry(JCTry tree) {
             ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb();
-            Bits uninitsTryPrev = uninitsTry;
+            final Bits uninitsTryPrev = new Bits(uninitsTry);
             ListBuffer<AssignPendingExit> prevPendingExits = pendingExits;
             pendingExits = new ListBuffer<AssignPendingExit>();
-            Bits initsTry = inits.dup();
-            uninitsTry = uninits.dup();
+            final Bits initsTry = new Bits(inits);
+            uninitsTry.assign(uninits);
             for (JCTree resource : tree.resources) {
                 if (resource instanceof JCVariableDecl) {
                     JCVariableDecl vdecl = (JCVariableDecl) resource;
@@ -1908,8 +1928,8 @@
             }
             scan(tree.body);
             uninitsTry.andSet(uninits);
-            Bits initsEnd = inits;
-            Bits uninitsEnd = uninits;
+            final Bits initsEnd = new Bits(inits);
+            final Bits uninitsEnd = new Bits(uninits);
             int nextadrCatch = nextadr;
 
             if (!resourceVarDecls.isEmpty() &&
@@ -1925,8 +1945,8 @@
 
             for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
                 JCVariableDecl param = l.head.param;
-                inits = initsTry.dup();
-                uninits = uninitsTry.dup();
+                inits.assign(initsTry);
+                uninits.assign(uninitsTry);
                 scan(param);
                 inits.incl(param.sym.adr);
                 uninits.excl(param.sym.adr);
@@ -1936,8 +1956,8 @@
                 nextadr = nextadrCatch;
             }
             if (tree.finalizer != null) {
-                inits = initsTry.dup();
-                uninits = uninitsTry.dup();
+                inits.assign(initsTry);
+                uninits.assign(uninitsTry);
                 ListBuffer<AssignPendingExit> exits = pendingExits;
                 pendingExits = prevPendingExits;
                 scan(tree.finalizer);
@@ -1958,8 +1978,8 @@
                     inits.orSet(initsEnd);
                 }
             } else {
-                inits = initsEnd;
-                uninits = uninitsEnd;
+                inits.assign(initsEnd);
+                uninits.assign(uninitsEnd);
                 ListBuffer<AssignPendingExit> exits = pendingExits;
                 pendingExits = prevPendingExits;
                 while (exits.nonEmpty()) pendingExits.append(exits.next());
@@ -1969,10 +1989,10 @@
 
         public void visitConditional(JCConditional tree) {
             scanCond(tree.cond);
-            Bits initsBeforeElse = initsWhenFalse;
-            Bits uninitsBeforeElse = uninitsWhenFalse;
-            inits = initsWhenTrue;
-            uninits = uninitsWhenTrue;
+            final Bits initsBeforeElse = new Bits(initsWhenFalse);
+            final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
+            inits.assign(initsWhenTrue);
+            uninits.assign(uninitsWhenTrue);
             if (tree.truepart.type.hasTag(BOOLEAN) &&
                 tree.falsepart.type.hasTag(BOOLEAN)) {
                 // if b and c are boolean valued, then
@@ -1980,12 +2000,12 @@
                 //    v is (un)assigned after b when true and
                 //    v is (un)assigned after c when true
                 scanCond(tree.truepart);
-                Bits initsAfterThenWhenTrue = initsWhenTrue.dup();
-                Bits initsAfterThenWhenFalse = initsWhenFalse.dup();
-                Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup();
-                Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup();
-                inits = initsBeforeElse;
-                uninits = uninitsBeforeElse;
+                final Bits initsAfterThenWhenTrue = new Bits(initsWhenTrue);
+                final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse);
+                final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue);
+                final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse);
+                inits.assign(initsBeforeElse);
+                uninits.assign(uninitsBeforeElse);
                 scanCond(tree.falsepart);
                 initsWhenTrue.andSet(initsAfterThenWhenTrue);
                 initsWhenFalse.andSet(initsAfterThenWhenFalse);
@@ -1993,10 +2013,10 @@
                 uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
             } else {
                 scanExpr(tree.truepart);
-                Bits initsAfterThen = inits.dup();
-                Bits uninitsAfterThen = uninits.dup();
-                inits = initsBeforeElse;
-                uninits = uninitsBeforeElse;
+                final Bits initsAfterThen = new Bits(inits);
+                final Bits uninitsAfterThen = new Bits(uninits);
+                inits.assign(initsBeforeElse);
+                uninits.assign(uninitsBeforeElse);
                 scanExpr(tree.falsepart);
                 inits.andSet(initsAfterThen);
                 uninits.andSet(uninitsAfterThen);
@@ -2005,16 +2025,16 @@
 
         public void visitIf(JCIf tree) {
             scanCond(tree.cond);
-            Bits initsBeforeElse = initsWhenFalse;
-            Bits uninitsBeforeElse = uninitsWhenFalse;
-            inits = initsWhenTrue;
-            uninits = uninitsWhenTrue;
+            final Bits initsBeforeElse = new Bits(initsWhenFalse);
+            final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse);
+            inits.assign(initsWhenTrue);
+            uninits.assign(uninitsWhenTrue);
             scan(tree.thenpart);
             if (tree.elsepart != null) {
-                Bits initsAfterThen = inits.dup();
-                Bits uninitsAfterThen = uninits.dup();
-                inits = initsBeforeElse;
-                uninits = uninitsBeforeElse;
+                final Bits initsAfterThen = new Bits(inits);
+                final Bits uninitsAfterThen = new Bits(uninits);
+                inits.assign(initsBeforeElse);
+                uninits.assign(uninitsBeforeElse);
                 scan(tree.elsepart);
                 inits.andSet(initsAfterThen);
                 uninits.andSet(uninitsAfterThen);
@@ -2055,8 +2075,8 @@
 
         @Override
         public void visitLambda(JCLambda tree) {
-            Bits prevUninits = uninits;
-            Bits prevInits = inits;
+            final Bits prevUninits = new Bits(uninits);
+            final Bits prevInits = new Bits(inits);
             int returnadrPrev = returnadr;
             ListBuffer<AssignPendingExit> prevPending = pendingExits;
             try {
@@ -2076,8 +2096,8 @@
             }
             finally {
                 returnadr = returnadrPrev;
-                uninits = prevUninits;
-                inits = prevInits;
+                uninits.assign(prevUninits);
+                inits.assign(prevInits);
                 pendingExits = prevPending;
             }
         }
@@ -2088,17 +2108,17 @@
         }
 
         public void visitAssert(JCAssert tree) {
-            Bits initsExit = inits.dup();
-            Bits uninitsExit = uninits.dup();
+            final Bits initsExit = new Bits(inits);
+            final Bits uninitsExit = new Bits(uninits);
             scanCond(tree.cond);
             uninitsExit.andSet(uninitsWhenTrue);
             if (tree.detail != null) {
-                inits = initsWhenFalse;
-                uninits = uninitsWhenFalse;
+                inits.assign(initsWhenFalse);
+                uninits.assign(uninitsWhenFalse);
                 scanExpr(tree.detail);
             }
-            inits = initsExit;
-            uninits = uninitsExit;
+            inits.assign(initsExit);
+            uninits.assign(uninitsExit);
         }
 
         public void visitAssign(JCAssign tree) {
@@ -2120,12 +2140,12 @@
             switch (tree.getTag()) {
             case NOT:
                 scanCond(tree.arg);
-                Bits t = initsWhenFalse;
-                initsWhenFalse = initsWhenTrue;
-                initsWhenTrue = t;
-                t = uninitsWhenFalse;
-                uninitsWhenFalse = uninitsWhenTrue;
-                uninitsWhenTrue = t;
+                final Bits t = new Bits(initsWhenFalse);
+                initsWhenFalse.assign(initsWhenTrue);
+                initsWhenTrue.assign(t);
+                t.assign(uninitsWhenFalse);
+                uninitsWhenFalse.assign(uninitsWhenTrue);
+                uninitsWhenTrue.assign(t);
                 break;
             case PREINC: case POSTINC:
             case PREDEC: case POSTDEC:
@@ -2141,20 +2161,20 @@
             switch (tree.getTag()) {
             case AND:
                 scanCond(tree.lhs);
-                Bits initsWhenFalseLeft = initsWhenFalse;
-                Bits uninitsWhenFalseLeft = uninitsWhenFalse;
-                inits = initsWhenTrue;
-                uninits = uninitsWhenTrue;
+                final Bits initsWhenFalseLeft = new Bits(initsWhenFalse);
+                final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse);
+                inits.assign(initsWhenTrue);
+                uninits.assign(uninitsWhenTrue);
                 scanCond(tree.rhs);
                 initsWhenFalse.andSet(initsWhenFalseLeft);
                 uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
                 break;
             case OR:
                 scanCond(tree.lhs);
-                Bits initsWhenTrueLeft = initsWhenTrue;
-                Bits uninitsWhenTrueLeft = uninitsWhenTrue;
-                inits = initsWhenFalse;
-                uninits = uninitsWhenFalse;
+                final Bits initsWhenTrueLeft = new Bits(initsWhenTrue);
+                final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue);
+                inits.assign(initsWhenFalse);
+                uninits.assign(uninitsWhenFalse);
                 scanCond(tree.rhs);
                 initsWhenTrue.andSet(initsWhenTrueLeft);
                 uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
@@ -2200,11 +2220,7 @@
                 attrEnv = env;
                 Flow.this.make = make;
                 startPos = tree.pos().getStartPosition();
-                inits = new Bits();
-                uninits = new Bits();
-                uninitsTry = new Bits();
-                initsWhenTrue = initsWhenFalse =
-                    uninitsWhenTrue = uninitsWhenFalse = null;
+
                 if (vars == null)
                     vars = new VarSymbol[32];
                 else
@@ -2219,9 +2235,8 @@
             } finally {
                 // note that recursive invocations of this method fail hard
                 startPos = -1;
-                inits = uninits = uninitsTry = null;
-                initsWhenTrue = initsWhenFalse =
-                    uninitsWhenTrue = uninitsWhenFalse = null;
+                resetBits(inits, uninits, uninitsTry, initsWhenTrue,
+                        initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse);
                 if (vars != null) for (int i=0; i<vars.length; i++)
                     vars[i] = null;
                 firstadr = 0;
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Sun Apr 28 08:16:41 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed May 08 10:27:52 2013 +0100
@@ -40,10 +40,9 @@
 import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.code.Type.ClassType;
 import com.sun.tools.javac.code.Type.MethodType;
 import com.sun.tools.javac.code.Types;
-import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzer.*;
+import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*;
 import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
 import com.sun.tools.javac.jvm.*;
 import com.sun.tools.javac.util.*;
@@ -81,7 +80,7 @@
     private Env<AttrContext> attrEnv;
 
     /** the analyzer scanner */
-    private LambdaAnalyzer analyzer;
+    private LambdaAnalyzerPreprocessor analyzer;
 
     /** map from lambda trees to translation contexts */
     private Map<JCTree, TranslationContext<?>> contextMap;
@@ -156,7 +155,7 @@
         make = TreeMaker.instance(context);
         types = Types.instance(context);
         transTypes = TransTypes.instance(context);
-        analyzer = new LambdaAnalyzer();
+        analyzer = new LambdaAnalyzerPreprocessor();
     }
     // </editor-fold>
 
@@ -206,7 +205,7 @@
     public void visitClassDef(JCClassDecl tree) {
         if (tree.sym.owner.kind == PCK) {
             //analyze class
-            analyzer.analyzeClass(tree);
+            tree = analyzer.analyzeAndPreprocessClass(tree);
         }
         KlassInfo prevKlassInfo = kInfo;
         try {
@@ -531,16 +530,25 @@
     /** Make an attributed class instance creation expression.
      *  @param ctype    The class type.
      *  @param args     The constructor arguments.
+     *  @param cons     The constructor symbol
      */
-    JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {
+    JCNewClass makeNewClass(Type ctype, List<JCExpression> args, Symbol cons) {
         JCNewClass tree = make.NewClass(null,
             null, make.QualIdent(ctype.tsym), args, null);
-        tree.constructor = rs.resolveConstructor(
-            null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil());
+        tree.constructor = cons;
         tree.type = ctype;
         return tree;
     }
 
+    /** Make an attributed class instance creation expression.
+     *  @param ctype    The class type.
+     *  @param args     The constructor arguments.
+     */
+    JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {
+        return makeNewClass(ctype, args,
+                rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil()));
+     }
+
     private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym,
             DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) {
         String functionalInterfaceClass = classSig(targetType);
@@ -1019,8 +1027,9 @@
      * This visitor collects information about translation of a lambda expression.
      * More specifically, it keeps track of the enclosing contexts and captured locals
      * accessed by the lambda being translated (as well as other useful info).
+     * It also translates away problems for LambdaToMethod.
      */
-    class LambdaAnalyzer extends TreeScanner {
+    class LambdaAnalyzerPreprocessor extends TreeTranslator {
 
         /** the frame stack - used to reconstruct translation info about enclosing scopes */
         private List<Frame> frameStack;
@@ -1047,10 +1056,10 @@
         private Map<ClassSymbol, Symbol> clinits =
                 new HashMap<ClassSymbol, Symbol>();
 
-        private void analyzeClass(JCClassDecl tree) {
+        private JCClassDecl analyzeAndPreprocessClass(JCClassDecl tree) {
             frameStack = List.nil();
             localClassDefs = new HashMap<Symbol, JCClassDecl>();
-            scan(tree);
+            return translate(tree);
         }
 
         @Override
@@ -1154,7 +1163,7 @@
                     frameStack.head.addLocal(param.sym);
                 }
                 contextMap.put(tree, context);
-                scan(tree.body);
+                super.visitLambda(tree);
                 context.complete();
             }
             finally {
@@ -1220,12 +1229,47 @@
                     };
                     fvc.scan(localCDef);
                 }
-            }
+        }
 
+        /**
+         * Method references to local class constructors, may, if the local
+         * class references local variables, have implicit constructor
+         * parameters added in Lower; As a result, the invokedynamic bootstrap
+         * information added in the LambdaToMethod pass will have the wrong
+         * signature. Hooks between Lower and LambdaToMethod have been added to
+         * handle normal "new" in this case. This visitor converts potentially
+         * effected method references into a lambda containing a normal "new" of
+         * the class.
+         *
+         * @param tree
+         */
         @Override
         public void visitReference(JCMemberReference tree) {
-            scan(tree.getQualifierExpression());
-            contextMap.put(tree, makeReferenceContext(tree));
+            if (tree.getMode() == ReferenceMode.NEW
+                    && tree.kind != ReferenceKind.ARRAY_CTOR
+                    && tree.sym.owner.isLocal()) {
+                MethodSymbol consSym = (MethodSymbol) tree.sym;
+                List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes();
+                Type classType = consSym.owner.type;
+
+                // Make new-class call
+                List<JCVariableDecl> params = make.Params(ptypes, owner());
+                JCNewClass nc = makeNewClass(classType, make.Idents(params));
+                nc.pos = tree.pos;
+
+                // Make lambda holding the new-class call
+                JCLambda slam = make.Lambda(params, nc);
+                slam.descriptorType = tree.descriptorType;
+                slam.targets = tree.targets;
+                slam.type = tree.type;
+                slam.pos = tree.pos;
+
+                // Now it is a lambda, process as such
+                visitLambda(slam);
+            } else {
+                super.visitReference(tree);
+                contextMap.put(tree, makeReferenceContext(tree));
+            }
         }
 
         @Override
@@ -1240,10 +1284,8 @@
                     }
                     localContext = localContext.prev;
                 }
-                scan(tree.selected);
-            } else {
-                super.visitSelect(tree);
             }
+            super.visitSelect(tree);
         }
 
         @Override
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Sun Apr 28 08:16:41 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Wed May 08 10:27:52 2013 +0100
@@ -1647,7 +1647,7 @@
         State dup() {
             try {
                 State state = (State)super.clone();
-                state.defined = defined.dup();
+                state.defined = new Bits(defined);
                 state.stack = stack.clone();
                 if (locks != null) state.locks = locks.clone();
                 if (debugCode) {
@@ -1775,7 +1775,7 @@
         }
 
         State join(State other) {
-            defined = defined.andSet(other.defined);
+            defined.andSet(other.defined);
             Assert.check(stacksize == other.stacksize
                     && nlocks == other.nlocks);
             for (int i=0; i<stacksize; ) {
@@ -1887,7 +1887,7 @@
     /** Set the current variable defined state. */
     public void setDefined(Bits newDefined) {
         if (alive && newDefined != state.defined) {
-            Bits diff = state.defined.dup().xorSet(newDefined);
+            Bits diff = new Bits(state.defined).xorSet(newDefined);
             for (int adr = diff.nextBit(0);
                  adr >= 0;
                  adr = diff.nextBit(adr+1)) {
--- a/src/share/classes/com/sun/tools/javac/util/Bits.java	Sun Apr 28 08:16:41 2013 +0100
+++ b/src/share/classes/com/sun/tools/javac/util/Bits.java	Wed May 08 10:27:52 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -27,6 +27,8 @@
 
 import java.util.Arrays;
 
+import static com.sun.tools.javac.util.Bits.BitsOpKind.*;
+
 /** A class for extensible, mutable bit sets.
  *
  *  <p><b>This is NOT part of any supported API.
@@ -36,31 +38,114 @@
  */
 public class Bits {
 
+    public enum BitsOpKind {
+        INIT,
+        CLEAR,
+        INCL_BIT,
+        EXCL_BIT,
+        ASSIGN,
+        AND_SET,
+        OR_SET,
+        DIFF_SET,
+        XOR_SET,
+        INCL_RANGE,
+        EXCL_RANGE,
+    }
+
+    //       ____________      reset    _________
+    //      /  UNKNOWN   \   <-------- / UNINIT  \
+    //      \____________/       |     \_________/
+    //            |              |          |
+    //            |assign        |          | any
+    //            |        ___________      |
+    //            ------> /  NORMAL   \ <----
+    //                    \___________/     |
+    //                            |         |
+    //                            |         |
+    //                            -----------
+    //                               any
+    private enum BitsState {
+        /*  A Bits instance is in UNKNOWN state if it has been explicitly reset.
+         *  It is possible to get to this state from any other by calling the
+         *  reset method. An instance in the UNKNOWN state can pass to the
+         *  NORMAL state after being assigned another Bits instance.
+         */
+        UNKNOWN,
+        /*  A Bits instance is in UNINIT when it is created with the default
+         *  constructor but it isn't explicitly reset. The main objective of this
+         *  internal state is to save some memory.
+         */
+        UNINIT,
+        /*  The normal state is reached after creating a Bits instance from an
+         *  existing one or after applying any operation to an instance on UNINIT
+         *  or NORMAL state. From this state a bits instance can pass to the
+         *  UNKNOWN state by calling the reset method.
+         */
+        NORMAL;
+
+        static BitsState getState(int[] someBits, boolean reset) {
+            if (reset) {
+                return UNKNOWN;
+            } else {
+                if (someBits != unassignedBits) {
+                    return NORMAL;
+                } else {
+                    return UNINIT;
+                }
+            }
+        }
+
+    }
 
     private final static int wordlen = 32;
     private final static int wordshift = 5;
     private final static int wordmask = wordlen - 1;
 
-    private int[] bits;
+    public int[] bits = null;
+    // This field will store last version of bits after every change.
+    public int[] oldBits = null;
+
+    public BitsOpKind lastOperation = null;
+
+    private static final int[] unassignedBits = new int[0];
+
+    private BitsState currentState;
 
     /** Construct an initially empty set.
      */
     public Bits() {
-        this(new int[1]);
+        this(false);
+    }
+
+    public Bits(Bits someBits) {
+        this(someBits.dup().bits, BitsState.getState(someBits.bits, false));
+    }
+
+    public Bits(boolean reset) {
+        this(unassignedBits, BitsState.getState(unassignedBits, reset));
     }
 
     /** Construct a set consisting initially of given bit vector.
      */
-    public Bits(int[] bits) {
+    private Bits(int[] bits, BitsState initState) {
         this.bits = bits;
+        this.currentState = initState;
+        switch (initState) {
+            case UNKNOWN:
+                reset(); //this will also set current state;
+                break;
+            case NORMAL:
+                Assert.check(bits != unassignedBits);
+                lastOperation = INIT;
+                break;
+        }
     }
 
-    /** Construct a set consisting initially of given range.
+    /** This method will be called after any operation that causes a change to
+     *  the bits. Subclasses can thus override it in order to extract information
+     *  from the changes produced to the bits by the given operation.
      */
-    public Bits(int start, int limit) {
-        this();
-        inclRange(start, limit);
-    }
+    public void changed() {}
 
     private void sizeTo(int len) {
         if (bits.length < len) {
@@ -71,57 +156,110 @@
     /** This set = {}.
      */
     public void clear() {
+        Assert.check(currentState != BitsState.UNKNOWN);
+        oldBits = bits;
+        lastOperation = CLEAR;
         for (int i = 0; i < bits.length; i++) bits[i] = 0;
+        changed();
+        currentState = BitsState.NORMAL;
+    }
+
+    public void reset() {
+        bits = null;
+        oldBits = null;
+        currentState = BitsState.UNKNOWN;
+    }
+
+    public boolean isReset() {
+        return currentState == BitsState.UNKNOWN;
+    }
+
+    public Bits assign(Bits someBits) {
+        lastOperation = ASSIGN;
+        oldBits = bits;
+        bits = someBits.dup().bits;
+        changed();
+        currentState = BitsState.NORMAL;
+        return this;
     }
 
     /** Return a copy of this set.
      */
-    public Bits dup() {
-        int[] newbits = new int[bits.length];
-        System.arraycopy(bits, 0, newbits, 0, bits.length);
-        return new Bits(newbits);
+    private Bits dup() {
+        Assert.check(currentState != BitsState.UNKNOWN);
+        Bits tmp = new Bits();
+        if (currentState != BitsState.NORMAL) {
+            tmp.bits = bits;
+        } else {
+            tmp.bits = new int[bits.length];
+            System.arraycopy(bits, 0, tmp.bits, 0, bits.length);
+        }
+        currentState = BitsState.NORMAL;
+        return tmp;
     }
 
     /** Include x in this set.
      */
     public void incl(int x) {
+        Assert.check(currentState != BitsState.UNKNOWN);
         Assert.check(x >= 0);
+        oldBits = bits;
+        lastOperation = INCL_BIT;
         sizeTo((x >>> wordshift) + 1);
         bits[x >>> wordshift] = bits[x >>> wordshift] |
             (1 << (x & wordmask));
+        changed();
+        currentState = BitsState.NORMAL;
     }
 
 
     /** Include [start..limit) in this set.
      */
     public void inclRange(int start, int limit) {
+        Assert.check(currentState != BitsState.UNKNOWN);
+        oldBits = bits;
+        lastOperation = INCL_RANGE;
         sizeTo((limit >>> wordshift) + 1);
-        for (int x = start; x < limit; x++)
+        for (int x = start; x < limit; x++) {
             bits[x >>> wordshift] = bits[x >>> wordshift] |
                 (1 << (x & wordmask));
+        }
+        changed();
+        currentState = BitsState.NORMAL;
     }
 
     /** Exclude [start...end] from this set.
      */
     public void excludeFrom(int start) {
+        Assert.check(currentState != BitsState.UNKNOWN);
+        oldBits = bits;
+        lastOperation = EXCL_RANGE;
         Bits temp = new Bits();
         temp.sizeTo(bits.length);
         temp.inclRange(0, start);
-        andSet(temp);
+        internalAndSet(temp);
+        changed();
+        currentState = BitsState.NORMAL;
     }
 
     /** Exclude x from this set.
      */
     public void excl(int x) {
+        Assert.check(currentState != BitsState.UNKNOWN);
         Assert.check(x >= 0);
+        oldBits = bits;
+        lastOperation = EXCL_BIT;
         sizeTo((x >>> wordshift) + 1);
         bits[x >>> wordshift] = bits[x >>> wordshift] &
             ~(1 << (x & wordmask));
+        changed();
+        currentState = BitsState.NORMAL;
     }
 
     /** Is x an element of this set?
      */
     public boolean isMember(int x) {
+        Assert.check(currentState != BitsState.UNKNOWN);
         return
             0 <= x && x < (bits.length << wordshift) &&
             (bits[x >>> wordshift] & (1 << (x & wordmask))) != 0;
@@ -130,38 +268,66 @@
     /** {@literal this set = this set & xs}.
      */
     public Bits andSet(Bits xs) {
+        Assert.check(currentState != BitsState.UNKNOWN);
+        oldBits = bits;
+        lastOperation = AND_SET;
+        internalAndSet(xs);
+        changed();
+        currentState = BitsState.NORMAL;
+        return this;
+    }
+
+    private void internalAndSet(Bits xs) {
+        Assert.check(currentState != BitsState.UNKNOWN);
         sizeTo(xs.bits.length);
-        for (int i = 0; i < xs.bits.length; i++)
+        for (int i = 0; i < xs.bits.length; i++) {
             bits[i] = bits[i] & xs.bits[i];
-        return this;
+        }
     }
 
     /** this set = this set | xs.
      */
     public Bits orSet(Bits xs) {
+        Assert.check(currentState != BitsState.UNKNOWN);
+        oldBits = bits;
+        lastOperation = OR_SET;
         sizeTo(xs.bits.length);
-        for (int i = 0; i < xs.bits.length; i++)
+        for (int i = 0; i < xs.bits.length; i++) {
             bits[i] = bits[i] | xs.bits[i];
+        }
+        changed();
+        currentState = BitsState.NORMAL;
         return this;
     }
 
     /** this set = this set \ xs.
      */
     public Bits diffSet(Bits xs) {
+        Assert.check(currentState != BitsState.UNKNOWN);
+        oldBits = bits;
+        lastOperation = DIFF_SET;
         for (int i = 0; i < bits.length; i++) {
             if (i < xs.bits.length) {
                 bits[i] = bits[i] & ~xs.bits[i];
             }
         }
+        changed();
+        currentState = BitsState.NORMAL;
         return this;
     }
 
     /** this set = this set ^ xs.
      */
     public Bits xorSet(Bits xs) {
+        Assert.check(currentState != BitsState.UNKNOWN);
+        oldBits = bits;
+        lastOperation = XOR_SET;
         sizeTo(xs.bits.length);
-        for (int i = 0; i < xs.bits.length; i++)
+        for (int i = 0; i < xs.bits.length; i++) {
             bits[i] = bits[i] ^ xs.bits[i];
+        }
+        changed();
+        currentState = BitsState.NORMAL;
         return this;
     }
 
@@ -187,6 +353,7 @@
      *  }</pre>
      */
     public int nextBit(int x) {
+        Assert.check(currentState != BitsState.UNKNOWN);
         int windex = x >>> wordshift;
         if (windex >= bits.length) return -1;
         int word = bits[windex] & ~((1 << (x & wordmask))-1);
@@ -202,17 +369,20 @@
     /** a string representation of this set.
      */
     public String toString() {
-        char[] digits = new char[bits.length * wordlen];
-        for (int i = 0; i < bits.length * wordlen; i++)
-            digits[i] = isMember(i) ? '1' : '0';
-        return new String(digits);
+        if (bits.length > 0) {
+            char[] digits = new char[bits.length * wordlen];
+            for (int i = 0; i < bits.length * wordlen; i++)
+                digits[i] = isMember(i) ? '1' : '0';
+            return new String(digits);
+        } else {
+            return "[]";
+        }
     }
 
     /** Test Bits.nextBit(int). */
     public static void main(String[] args) {
         java.util.Random r = new java.util.Random();
         Bits bits = new Bits();
-        int dupCount = 0;
         for (int i=0; i<125; i++) {
             int k;
             do {
--- a/test/tools/javac/api/TestJavacTaskScanner.java	Sun Apr 28 08:16:41 2013 +0100
+++ b/test/tools/javac/api/TestJavacTaskScanner.java	Wed May 08 10:27:52 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -93,7 +93,7 @@
         System.out.println("#allMembers: " + numAllMembers);
 
         check(numTokens, "#Tokens", 1222);
-        check(numParseTypeElements, "#parseTypeElements", 136);
+        check(numParseTypeElements, "#parseTypeElements", 158);
         check(numAllMembers, "#allMembers", 52);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java	Wed May 08 10:27:52 2013 +0100
@@ -0,0 +1,96 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8012723
+ * @summary strictfp interface misses strictfp modifer on default method
+ * @run main CheckACC_STRICTFlagOnDefaultMethodTest
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.File;
+import java.io.IOException;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Descriptor;
+import com.sun.tools.classfile.Descriptor.InvalidDescriptor;
+import com.sun.tools.classfile.Method;
+
+import static com.sun.tools.classfile.AccessFlags.ACC_STRICT;
+
+public class CheckACC_STRICTFlagOnDefaultMethodTest {
+    private static final String AssertionErrorMessage =
+        "All methods should have the ACC_STRICT access flag " +
+        "please check output";
+    private static final String offendingMethodErrorMessage =
+        "Method %s of class %s doesn't have the ACC_STRICT access flag";
+
+    private List<String> errors = new ArrayList<>();
+
+    public static void main(String[] args)
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        new CheckACC_STRICTFlagOnDefaultMethodTest().run();
+    }
+
+    private void run()
+            throws IOException, ConstantPoolException, InvalidDescriptor {
+        String testClasses = System.getProperty("test.classes");
+        check(testClasses,
+                "CheckACC_STRICTFlagOnDefaultMethodTest$StrictfpInterface.class");
+        if (errors.size() > 0) {
+            for (String error: errors) {
+                System.err.println(error);
+            }
+            throw new AssertionError(AssertionErrorMessage);
+        }
+    }
+
+    void check(String dir, String... fileNames)
+        throws
+            IOException,
+            ConstantPoolException,
+            Descriptor.InvalidDescriptor {
+        for (String fileName : fileNames) {
+            ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName));
+
+            for (Method method : classFileToCheck.methods) {
+                if ((method.access_flags.flags & ACC_STRICT) == 0) {
+                    errors.add(String.format(offendingMethodErrorMessage,
+                            method.getName(classFileToCheck.constant_pool),
+                            classFileToCheck.getName()));
+                }
+            }
+        }
+    }
+
+    strictfp interface StrictfpInterface {
+        default void default_interface_method() {}
+        static void static_interface_method() {}
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestNewInnerImplicitArgs.java	Wed May 08 10:27:52 2013 +0100
@@ -0,0 +1,82 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8011591
+ * @summary BootstrapMethodError when capturing constructor ref to local classes
+ * @run testng MethodReferenceTestNewInnerImplicitArgs
+ */
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Test the case that a constructor has implicit parameters added to
+ * access local variables and that this constructor is used in a
+ * method reference.
+ * @author Robert Field
+ */
+
+@Test
+public class MethodReferenceTestNewInnerImplicitArgs {
+
+
+    static class S {
+        String b;
+        S(String s, String s2) { b = s + s2; }
+    }
+
+    interface I {
+        S m();
+    }
+
+    interface I2 {
+        S m(int i, int j);
+    }
+
+    public static void testConstructorReferenceImplicitParameters() {
+        String title = "Hey";
+        String a2 = "!!!";
+        class MS extends S {
+            MS() {
+                super(title, a2);
+            }
+        }
+
+        I result = MS::new;
+        assertEquals(result.m().b, "Hey!!!");
+
+        class MS2 extends S {
+            MS2(int x, int y) {
+                super(title+x, a2+y);
+            }
+        }
+
+        I2 result2 = MS2::new;
+        assertEquals(result2.m(8, 4).b, "Hey8!!!4");
+    }
+}