Wed, 08 May 2013 10:27:52 +0100
Merge
1.1 --- a/.hgtags Sun Apr 28 08:16:41 2013 +0100 1.2 +++ b/.hgtags Wed May 08 10:27:52 2013 +0100 1.3 @@ -209,3 +209,4 @@ 1.4 4a48f31735349782ad13980267358c97076adc66 jdk8-b85 1.5 6ab578e141dfd17c4dc03869bb204aafa490c9f4 jdk8-b86 1.6 1329f9c38d93c8caf339d7687df8371d06fe9e56 jdk8-b87 1.7 +a1e10f3adc47c8602a72e43a41403a642e73e0b1 jdk8-b88
2.1 --- a/make/build.xml Sun Apr 28 08:16:41 2013 +0100 2.2 +++ b/make/build.xml Wed May 08 10:27:52 2013 +0100 2.3 @@ -717,6 +717,29 @@ 2.4 <target name="sjavac" depends="build-sjavac,jtreg-sjavac,findbugs-sjavac"/> 2.5 2.6 <!-- 2.7 + **** crules targets. 2.8 + --> 2.9 + 2.10 + <target name="build-crules" depends="-def-compilecrules,-def-build-jar-with-services"> 2.11 + <compilecrules/> 2.12 + <build-jar-with-services 2.13 + name="crules" 2.14 + includes="crules/* crules/resources/*" 2.15 + classes.dir="${build.toolclasses.dir}" 2.16 + lib.dir="${build.toolclasses.dir}" 2.17 + jarmainclass="" 2.18 + jarclasspath="crules.jar" 2.19 + service.type="com.sun.source.util.Plugin" 2.20 + service.provider="crules.MutableFieldsAnalyzer"/> 2.21 + <build-tool name="crules"/> 2.22 + </target> 2.23 + 2.24 + <target name="check-coding-rules" depends="build-bootstrap-javac,-create-import-jdk-stubs,build-crules"> 2.25 + <build-classes includes="${javac.includes}" 2.26 + plugin.options="-J-Xbootclasspath/a:${build.toolclasses.dir}/crules.jar -Xplugin:mutable_fields_analyzer" /> 2.27 + </target> 2.28 + 2.29 + <!-- 2.30 **** Create import JDK stubs. 2.31 --> 2.32 2.33 @@ -811,6 +834,31 @@ 2.34 </macrodef> 2.35 </target> 2.36 2.37 + <target name="-def-build-jar-with-services"> 2.38 + <macrodef name="build-jar-with-services"> 2.39 + <attribute name="name"/> 2.40 + <attribute name="includes"/> 2.41 + <attribute name="classes.dir" default="${build.classes.dir}"/> 2.42 + <attribute name="lib.dir" default="${dist.lib.dir}"/> 2.43 + <attribute name="jarmainclass" default="com.sun.tools.@{name}.Main"/> 2.44 + <attribute name="jarclasspath" default=""/> 2.45 + <attribute name="service.type" default=""/> 2.46 + <attribute name="service.provider" default=""/> 2.47 + <sequential> 2.48 + <mkdir dir="${build.toolclasses.dir}"/> 2.49 + <jar destfile="@{lib.dir}/@{name}.jar" 2.50 + basedir="@{classes.dir}" 2.51 + includes="@{includes}"> 2.52 + <service type="@{service.type}" provider="@{service.provider}"/> 2.53 + <manifest> 2.54 + <attribute name="Main-Class" value="@{jarmainclass}"/> 2.55 + <attribute name="Class-Path" value="@{jarclasspath}"/> 2.56 + </manifest> 2.57 + </jar> 2.58 + </sequential> 2.59 + </macrodef> 2.60 + </target> 2.61 + 2.62 <target name="-def-build-classes" depends="-def-pcompile"> 2.63 <macrodef name="build-classes"> 2.64 <attribute name="includes"/> 2.65 @@ -826,6 +874,7 @@ 2.66 <attribute name="target" default="${javac.target}"/> 2.67 <attribute name="release" default="${release}"/> 2.68 <attribute name="full.version" default="${full.version}"/> 2.69 + <attribute name="plugin.options" default=""/> 2.70 <sequential> 2.71 <echo level="verbose" message="build-classes: excludes=@{excludes}"/> 2.72 <echo level="verbose" message="build-classes: bootclasspath.opt=@{bootclasspath.opt}"/> 2.73 @@ -868,6 +917,7 @@ 2.74 <compilerarg line="${javac.no.jdk.warnings}"/> 2.75 <compilerarg line="${javac.version.opt}"/> 2.76 <compilerarg line="${javac.lint.opts}"/> 2.77 + <compilerarg line="@{plugin.options}"/> 2.78 </javac> 2.79 <copy todir="@{classes.dir}" includeemptydirs="false"> 2.80 <fileset dir="${src.classes.dir}" includes="@{includes}" excludes="@{excludes}"> 2.81 @@ -935,6 +985,32 @@ 2.82 classpath="${build.toolclasses.dir}/"/> 2.83 </target> 2.84 2.85 + <target name="-def-compilecrules"> 2.86 + <macrodef name="compilecrules"> 2.87 + <sequential> 2.88 + <mkdir dir="${build.toolclasses.dir}"/> 2.89 + <javac fork="true" 2.90 + source="${boot.javac.source}" 2.91 + target="${boot.javac.target}" 2.92 + executable="${boot.java.home}/bin/javac" 2.93 + srcdir="${make.tools.dir}" 2.94 + includes="crules/*" 2.95 + destdir="${build.toolclasses.dir}/" 2.96 + classpath="${ant.core.lib}" 2.97 + bootclasspath="${boot.java.home}/jre/lib/rt.jar" 2.98 + includeantruntime="false"> 2.99 + <compilerarg value="-Xbootclasspath/p:${build.bootstrap.dir}/classes"/> 2.100 + <compilerarg line="${javac.lint.opts}"/> 2.101 + </javac> 2.102 + <copy todir="${build.toolclasses.dir}/" includeemptydirs="false"> 2.103 + <fileset dir="${make.tools.dir}"> 2.104 + <include name="**/*.properties"/> 2.105 + </fileset> 2.106 + </copy> 2.107 + </sequential> 2.108 + </macrodef> 2.109 + </target> 2.110 + 2.111 <target name="-def-genstubs" depends="build-bootstrap-javac" if="require.import.jdk.stubs"> 2.112 <mkdir dir="${build.toolclasses.dir}"/> 2.113 <javac fork="true"
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/make/tools/crules/AbstractCodingRulesAnalyzer.java Wed May 08 10:27:52 2013 +0100 3.3 @@ -0,0 +1,117 @@ 3.4 +/* 3.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +package crules; 3.28 + 3.29 +import java.text.MessageFormat; 3.30 +import java.util.Locale; 3.31 +import java.util.ResourceBundle; 3.32 + 3.33 +import javax.lang.model.element.TypeElement; 3.34 +import javax.tools.JavaFileObject; 3.35 + 3.36 +import com.sun.source.tree.Tree; 3.37 +import com.sun.source.util.JavacTask; 3.38 +import com.sun.source.util.Plugin; 3.39 +import com.sun.source.util.TaskEvent; 3.40 +import com.sun.source.util.TaskListener; 3.41 +import com.sun.source.util.Trees; 3.42 +import com.sun.tools.javac.api.BasicJavacTask; 3.43 +import com.sun.tools.javac.tree.JCTree; 3.44 +import com.sun.tools.javac.tree.TreeScanner; 3.45 +import com.sun.tools.javac.util.Context; 3.46 +import com.sun.tools.javac.util.Log; 3.47 + 3.48 +import static com.sun.source.util.TaskEvent.Kind; 3.49 + 3.50 +public abstract class AbstractCodingRulesAnalyzer implements Plugin { 3.51 + 3.52 + protected Log log; 3.53 + protected Trees trees; 3.54 + protected TreeScanner treeVisitor; 3.55 + protected Kind eventKind; 3.56 + protected Messages messages; 3.57 + 3.58 + public void init(JavacTask task, String... args) { 3.59 + BasicJavacTask impl = (BasicJavacTask)task; 3.60 + Context context = impl.getContext(); 3.61 + log = Log.instance(context); 3.62 + trees = Trees.instance(task); 3.63 + messages = new Messages(); 3.64 + task.addTaskListener(new PostAnalyzeTaskListener()); 3.65 + } 3.66 + 3.67 + public class PostAnalyzeTaskListener implements TaskListener { 3.68 + 3.69 + @Override 3.70 + public void started(TaskEvent taskEvent) {} 3.71 + 3.72 + @Override 3.73 + public void finished(TaskEvent taskEvent) { 3.74 + if (taskEvent.getKind().equals(eventKind)) { 3.75 + TypeElement typeElem = taskEvent.getTypeElement(); 3.76 + Tree tree = trees.getTree(typeElem); 3.77 + if (tree != null) { 3.78 + JavaFileObject prevSource = log.currentSourceFile(); 3.79 + try { 3.80 + log.useSource(taskEvent.getCompilationUnit().getSourceFile()); 3.81 + treeVisitor.scan((JCTree)tree); 3.82 + } finally { 3.83 + log.useSource(prevSource); 3.84 + } 3.85 + } 3.86 + } 3.87 + } 3.88 + } 3.89 + 3.90 + class Messages { 3.91 + ResourceBundle bundle; 3.92 + 3.93 + Messages() { 3.94 + String name = getClass().getPackage().getName() + ".resources.crules"; 3.95 + bundle = ResourceBundle.getBundle(name, Locale.ENGLISH); 3.96 + } 3.97 + 3.98 + public void error(JCTree tree, String code, Object... args) { 3.99 + String msg = (code == null) ? (String) args[0] : localize(code, args); 3.100 + log.error(tree, "proc.messager", msg.toString()); 3.101 + } 3.102 + 3.103 + private String localize(String code, Object... args) { 3.104 + String msg = bundle.getString(code); 3.105 + if (msg == null) { 3.106 + StringBuilder sb = new StringBuilder(); 3.107 + sb.append("message file broken: code=").append(code); 3.108 + if (args.length > 0) { 3.109 + sb.append(" arguments={0}"); 3.110 + for (int i = 1; i < args.length; i++) { 3.111 + sb.append(", {").append(i).append("}"); 3.112 + } 3.113 + } 3.114 + msg = sb.toString(); 3.115 + } 3.116 + return MessageFormat.format(msg, args); 3.117 + } 3.118 + } 3.119 + 3.120 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/make/tools/crules/MutableFieldsAnalyzer.java Wed May 08 10:27:52 2013 +0100 4.3 @@ -0,0 +1,118 @@ 4.4 +/* 4.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +package crules; 4.28 + 4.29 +import java.util.Arrays; 4.30 +import java.util.HashMap; 4.31 +import java.util.List; 4.32 +import java.util.Map; 4.33 + 4.34 +import com.sun.tools.javac.code.Kinds; 4.35 +import com.sun.tools.javac.tree.TreeScanner; 4.36 + 4.37 +import static com.sun.source.util.TaskEvent.Kind; 4.38 +import static com.sun.tools.javac.code.Flags.*; 4.39 +import static com.sun.tools.javac.tree.JCTree.JCVariableDecl; 4.40 + 4.41 +public class MutableFieldsAnalyzer extends AbstractCodingRulesAnalyzer { 4.42 + 4.43 + public MutableFieldsAnalyzer() { 4.44 + treeVisitor = new MutableFieldsVisitor(); 4.45 + eventKind = Kind.ANALYZE; 4.46 + } 4.47 + 4.48 + public String getName() { 4.49 + return "mutable_fields_analyzer"; 4.50 + } 4.51 + 4.52 + private boolean ignoreField(String className, String field) { 4.53 + List<String> currentFieldsToIgnore = 4.54 + classFieldsToIgnoreMap.get(className); 4.55 + if (currentFieldsToIgnore != null) { 4.56 + for (String fieldToIgnore : currentFieldsToIgnore) { 4.57 + if (field.equals(fieldToIgnore)) { 4.58 + return true; 4.59 + } 4.60 + } 4.61 + } 4.62 + return false; 4.63 + } 4.64 + 4.65 + class MutableFieldsVisitor extends TreeScanner { 4.66 + 4.67 + @Override 4.68 + public void visitVarDef(JCVariableDecl tree) { 4.69 + boolean isJavacPack = tree.sym.outermostClass().fullname.toString() 4.70 + .contains(packageToCheck); 4.71 + if (isJavacPack && 4.72 + (tree.sym.flags() & SYNTHETIC) == 0 && 4.73 + tree.sym.owner.kind == Kinds.TYP) { 4.74 + if (!ignoreField(tree.sym.owner.flatName().toString(), 4.75 + tree.getName().toString())) { 4.76 + boolean enumClass = (tree.sym.owner.flags() & ENUM) != 0; 4.77 + boolean nonFinalStaticEnumField = 4.78 + (tree.sym.flags() & (ENUM | FINAL)) == 0; 4.79 + boolean nonFinalStaticField = 4.80 + (tree.sym.flags() & STATIC) != 0 && 4.81 + (tree.sym.flags() & FINAL) == 0; 4.82 + if (enumClass ? nonFinalStaticEnumField : nonFinalStaticField) { 4.83 + messages.error(tree, "crules.err.var.must.be.final", tree); 4.84 + } 4.85 + } 4.86 + } 4.87 + super.visitVarDef(tree); 4.88 + } 4.89 + 4.90 + } 4.91 + 4.92 + private static final String packageToCheck = "com.sun.tools.javac"; 4.93 + 4.94 + private static final Map<String, List<String>> classFieldsToIgnoreMap = 4.95 + new HashMap<String, List<String>>(); 4.96 + 4.97 + static { 4.98 + classFieldsToIgnoreMap. 4.99 + put("com.sun.tools.javac.util.JCDiagnostic", 4.100 + Arrays.asList("fragmentFormatter")); 4.101 + classFieldsToIgnoreMap. 4.102 + put("com.sun.tools.javac.util.JavacMessages", 4.103 + Arrays.asList("defaultBundle", "defaultMessages")); 4.104 + classFieldsToIgnoreMap. 4.105 + put("com.sun.tools.javac.file.ZipFileIndexCache", 4.106 + Arrays.asList("sharedInstance")); 4.107 + classFieldsToIgnoreMap. 4.108 + put("com.sun.tools.javac.main.JavaCompiler", 4.109 + Arrays.asList("versionRB")); 4.110 + classFieldsToIgnoreMap. 4.111 + put("com.sun.tools.javac.code.Type", 4.112 + Arrays.asList("moreInfo")); 4.113 + classFieldsToIgnoreMap. 4.114 + put("com.sun.tools.javac.util.SharedNameTable", 4.115 + Arrays.asList("freelist")); 4.116 + classFieldsToIgnoreMap. 4.117 + put("com.sun.tools.javac.util.Log", 4.118 + Arrays.asList("useRawMessages")); 4.119 + } 4.120 + 4.121 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/make/tools/crules/resources/crules.properties Wed May 08 10:27:52 2013 +0100 5.3 @@ -0,0 +1,28 @@ 5.4 +# 5.5 +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 5.6 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 +# 5.8 +# This code is free software; you can redistribute it and/or modify it 5.9 +# under the terms of the GNU General Public License version 2 only, as 5.10 +# published by the Free Software Foundation. Oracle designates this 5.11 +# particular file as subject to the "Classpath" exception as provided 5.12 +# by Oracle in the LICENSE file that accompanied this code. 5.13 +# 5.14 +# This code is distributed in the hope that it will be useful, but WITHOUT 5.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.17 +# version 2 for more details (a copy is included in the LICENSE file that 5.18 +# accompanied this code). 5.19 +# 5.20 +# You should have received a copy of the GNU General Public License version 5.21 +# 2 along with this work; if not, write to the Free Software Foundation, 5.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.23 +# 5.24 +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.25 +# or visit www.oracle.com if you need additional information or have any 5.26 +# questions. 5.27 +# 5.28 + 5.29 +# 0: symbol 5.30 +crules.err.var.must.be.final=\ 5.31 + Static variable {0} must be final
6.1 --- a/src/share/classes/com/sun/tools/classfile/Dependencies.java Sun Apr 28 08:16:41 2013 +0100 6.2 +++ b/src/share/classes/com/sun/tools/classfile/Dependencies.java Wed May 08 10:27:52 2013 +0100 6.3 @@ -315,7 +315,7 @@ 6.4 static class SimpleLocation implements Location { 6.5 public SimpleLocation(String name) { 6.6 this.name = name; 6.7 - this.className = name.replace('/', '.').replace('$', '.'); 6.8 + this.className = name.replace('/', '.'); 6.9 } 6.10 6.11 public String getName() {
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/share/classes/com/sun/tools/classfile/ReferenceFinder.java Wed May 08 10:27:52 2013 +0100 7.3 @@ -0,0 +1,240 @@ 7.4 +/* 7.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. Oracle designates this 7.11 + * particular file as subject to the "Classpath" exception as provided 7.12 + * by Oracle in the LICENSE file that accompanied this code. 7.13 + * 7.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.17 + * version 2 for more details (a copy is included in the LICENSE file that 7.18 + * accompanied this code). 7.19 + * 7.20 + * You should have received a copy of the GNU General Public License version 7.21 + * 2 along with this work; if not, write to the Free Software Foundation, 7.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.23 + * 7.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.25 + * or visit www.oracle.com if you need additional information or have any 7.26 + * questions. 7.27 + */ 7.28 + 7.29 +package com.sun.tools.classfile; 7.30 + 7.31 +import java.util.ArrayList; 7.32 +import java.util.HashSet; 7.33 +import java.util.List; 7.34 +import java.util.Objects; 7.35 +import java.util.Set; 7.36 +import com.sun.tools.classfile.Instruction.TypeKind; 7.37 +import static com.sun.tools.classfile.ConstantPool.*; 7.38 + 7.39 +/** 7.40 + * A utility class to find where in a ClassFile references 7.41 + * a {@link CONSTANT_Methodref_info method}, 7.42 + * a {@link CONSTANT_InterfaceMethodref_info interface method, 7.43 + * or a {@link CONSTANT_Fieldref_info field}. 7.44 + */ 7.45 +public final class ReferenceFinder { 7.46 + /** 7.47 + * Filter for ReferenceFinder of what constant pool entries for reference lookup. 7.48 + */ 7.49 + public interface Filter { 7.50 + /** 7.51 + * Decides if the given CPRefInfo entry should be accepted or filtered. 7.52 + * 7.53 + * @param cpool ConstantPool of the ClassFile being parsed 7.54 + * @param cpref constant pool entry representing a reference to 7.55 + * a fields method, and interface method. 7.56 + * @return {@code true} if accepted; otherwise {@code false} 7.57 + */ 7.58 + boolean accept(ConstantPool cpool, CPRefInfo cpref); 7.59 + } 7.60 + 7.61 + /** 7.62 + * Visitor of individual method of a ClassFile that references the 7.63 + * accepted field, method, or interface method references. 7.64 + */ 7.65 + public interface Visitor { 7.66 + /** 7.67 + * Invoked for a method containing one or more accepted CPRefInfo entries 7.68 + * 7.69 + * @param cf ClassFile 7.70 + * @param method Method that does the references the accepted references 7.71 + * @param refs Accepted constant pool method/field reference 7.72 + */ 7.73 + void visit(ClassFile cf, Method method, List<CPRefInfo> refConstantPool); 7.74 + } 7.75 + 7.76 + private final Filter filter; 7.77 + private final Visitor visitor; 7.78 + 7.79 + /** 7.80 + * Constructor. 7.81 + */ 7.82 + public ReferenceFinder(Filter filter, Visitor visitor) { 7.83 + this.filter = Objects.requireNonNull(filter); 7.84 + this.visitor = Objects.requireNonNull(visitor); 7.85 + } 7.86 + 7.87 + /** 7.88 + * Parses a given ClassFile and invoke the visitor if there is any reference 7.89 + * to the constant pool entries referencing field, method, or 7.90 + * interface method that are accepted. This method will return 7.91 + * {@code true} if there is one or more accepted constant pool entries 7.92 + * to lookup; otherwise, it will return {@code false}. 7.93 + * 7.94 + * @param cf ClassFile 7.95 + * @return {@code true} if the given class file is processed to lookup 7.96 + * references 7.97 + * @throws ConstantPoolException if an error of the constant pool 7.98 + */ 7.99 + public boolean parse(ClassFile cf) throws ConstantPoolException { 7.100 + List<Integer> cprefs = new ArrayList<Integer>(); 7.101 + int index = 1; 7.102 + for (ConstantPool.CPInfo cpInfo : cf.constant_pool.entries()) { 7.103 + if (cpInfo.accept(cpVisitor, cf.constant_pool)) { 7.104 + cprefs.add(index); 7.105 + } 7.106 + index += cpInfo.size(); 7.107 + } 7.108 + 7.109 + if (cprefs.isEmpty()) { 7.110 + return false; 7.111 + } 7.112 + 7.113 + for (Method m : cf.methods) { 7.114 + Set<Integer> ids = new HashSet<Integer>(); 7.115 + Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code); 7.116 + if (c_attr != null) { 7.117 + for (Instruction instr : c_attr.getInstructions()) { 7.118 + int idx = instr.accept(codeVisitor, cprefs); 7.119 + if (idx > 0) { 7.120 + ids.add(idx); 7.121 + } 7.122 + } 7.123 + } 7.124 + if (ids.size() > 0) { 7.125 + List<CPRefInfo> refInfos = new ArrayList<CPRefInfo>(ids.size()); 7.126 + for (int id : ids) { 7.127 + refInfos.add(CPRefInfo.class.cast(cf.constant_pool.get(id))); 7.128 + } 7.129 + visitor.visit(cf, m, refInfos); 7.130 + } 7.131 + } 7.132 + return true; 7.133 + } 7.134 + 7.135 + private ConstantPool.Visitor<Boolean,ConstantPool> cpVisitor = 7.136 + new ConstantPool.Visitor<Boolean,ConstantPool>() 7.137 + { 7.138 + public Boolean visitClass(CONSTANT_Class_info info, ConstantPool cpool) { 7.139 + return false; 7.140 + } 7.141 + 7.142 + public Boolean visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, ConstantPool cpool) { 7.143 + return filter.accept(cpool, info); 7.144 + } 7.145 + 7.146 + public Boolean visitMethodref(CONSTANT_Methodref_info info, ConstantPool cpool) { 7.147 + return filter.accept(cpool, info); 7.148 + } 7.149 + 7.150 + public Boolean visitFieldref(CONSTANT_Fieldref_info info, ConstantPool cpool) { 7.151 + return filter.accept(cpool, info); 7.152 + } 7.153 + 7.154 + public Boolean visitDouble(CONSTANT_Double_info info, ConstantPool cpool) { 7.155 + return false; 7.156 + } 7.157 + 7.158 + public Boolean visitFloat(CONSTANT_Float_info info, ConstantPool cpool) { 7.159 + return false; 7.160 + } 7.161 + 7.162 + public Boolean visitInteger(CONSTANT_Integer_info info, ConstantPool cpool) { 7.163 + return false; 7.164 + } 7.165 + 7.166 + public Boolean visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, ConstantPool cpool) { 7.167 + return false; 7.168 + } 7.169 + 7.170 + public Boolean visitLong(CONSTANT_Long_info info, ConstantPool cpool) { 7.171 + return false; 7.172 + } 7.173 + 7.174 + public Boolean visitNameAndType(CONSTANT_NameAndType_info info, ConstantPool cpool) { 7.175 + return false; 7.176 + } 7.177 + 7.178 + public Boolean visitMethodHandle(CONSTANT_MethodHandle_info info, ConstantPool cpool) { 7.179 + return false; 7.180 + } 7.181 + 7.182 + public Boolean visitMethodType(CONSTANT_MethodType_info info, ConstantPool cpool) { 7.183 + return false; 7.184 + } 7.185 + 7.186 + public Boolean visitString(CONSTANT_String_info info, ConstantPool cpool) { 7.187 + return false; 7.188 + } 7.189 + 7.190 + public Boolean visitUtf8(CONSTANT_Utf8_info info, ConstantPool cpool) { 7.191 + return false; 7.192 + } 7.193 + }; 7.194 + 7.195 + private Instruction.KindVisitor<Integer, List<Integer>> codeVisitor = 7.196 + new Instruction.KindVisitor<Integer, List<Integer>>() 7.197 + { 7.198 + public Integer visitNoOperands(Instruction instr, List<Integer> p) { 7.199 + return 0; 7.200 + } 7.201 + 7.202 + public Integer visitArrayType(Instruction instr, TypeKind kind, List<Integer> p) { 7.203 + return 0; 7.204 + } 7.205 + 7.206 + public Integer visitBranch(Instruction instr, int offset, List<Integer> p) { 7.207 + return 0; 7.208 + } 7.209 + 7.210 + public Integer visitConstantPoolRef(Instruction instr, int index, List<Integer> p) { 7.211 + return p.contains(index) ? index : 0; 7.212 + } 7.213 + 7.214 + public Integer visitConstantPoolRefAndValue(Instruction instr, int index, int value, List<Integer> p) { 7.215 + return p.contains(index) ? index : 0; 7.216 + } 7.217 + 7.218 + public Integer visitLocal(Instruction instr, int index, List<Integer> p) { 7.219 + return 0; 7.220 + } 7.221 + 7.222 + public Integer visitLocalAndValue(Instruction instr, int index, int value, List<Integer> p) { 7.223 + return 0; 7.224 + } 7.225 + 7.226 + public Integer visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, List<Integer> p) { 7.227 + return 0; 7.228 + } 7.229 + 7.230 + public Integer visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, List<Integer> p) { 7.231 + return 0; 7.232 + } 7.233 + 7.234 + public Integer visitValue(Instruction instr, int value, List<Integer> p) { 7.235 + return 0; 7.236 + } 7.237 + 7.238 + public Integer visitUnknown(Instruction instr, List<Integer> p) { 7.239 + return 0; 7.240 + } 7.241 + }; 7.242 +} 7.243 +
8.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Sun Apr 28 08:16:41 2013 +0100 8.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Wed May 08 10:27:52 2013 +0100 8.3 @@ -1078,7 +1078,8 @@ 8.4 mask = MethodFlags; 8.5 } 8.6 // Imply STRICTFP if owner has STRICTFP set. 8.7 - if (((flags|implicit) & Flags.ABSTRACT) == 0) 8.8 + if (((flags|implicit) & Flags.ABSTRACT) == 0 || 8.9 + ((flags) & Flags.DEFAULT) != 0) 8.10 implicit |= sym.owner.flags_field & STRICTFP; 8.11 break; 8.12 case TYP:
9.1 --- a/src/share/classes/com/sun/tools/javac/comp/Flow.java Sun Apr 28 08:16:41 2013 +0100 9.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java Wed May 08 10:27:52 2013 +0100 9.3 @@ -35,7 +35,6 @@ 9.4 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 9.5 9.6 import com.sun.tools.javac.code.Symbol.*; 9.7 -import com.sun.tools.javac.comp.Resolve; 9.8 import com.sun.tools.javac.tree.JCTree.*; 9.9 9.10 import static com.sun.tools.javac.code.Flags.*; 9.11 @@ -277,6 +276,15 @@ 9.12 } 9.13 9.14 /** 9.15 + * Utility method to reset several Bits instances. 9.16 + */ 9.17 + private void resetBits(Bits... bits) { 9.18 + for (Bits b : bits) { 9.19 + b.reset(); 9.20 + } 9.21 + } 9.22 + 9.23 + /** 9.24 * Base visitor class for all visitors implementing dataflow analysis logic. 9.25 * This class define the shared logic for handling jumps (break/continue statements). 9.26 */ 9.27 @@ -1294,11 +1302,11 @@ 9.28 9.29 /** The set of definitely assigned variables. 9.30 */ 9.31 - Bits inits; 9.32 + final Bits inits; 9.33 9.34 /** The set of definitely unassigned variables. 9.35 */ 9.36 - Bits uninits; 9.37 + final Bits uninits; 9.38 9.39 /** The set of variables that are definitely unassigned everywhere 9.40 * in current try block. This variable is maintained lazily; it is 9.41 @@ -1308,15 +1316,15 @@ 9.42 * anywhere in current try block, intersect uninitsTry and 9.43 * uninits. 9.44 */ 9.45 - Bits uninitsTry; 9.46 + final Bits uninitsTry; 9.47 9.48 /** When analyzing a condition, inits and uninits are null. 9.49 * Instead we have: 9.50 */ 9.51 - Bits initsWhenTrue; 9.52 - Bits initsWhenFalse; 9.53 - Bits uninitsWhenTrue; 9.54 - Bits uninitsWhenFalse; 9.55 + final Bits initsWhenTrue; 9.56 + final Bits initsWhenFalse; 9.57 + final Bits uninitsWhenTrue; 9.58 + final Bits uninitsWhenFalse; 9.59 9.60 /** A mapping from addresses to variable symbols. 9.61 */ 9.62 @@ -1348,15 +1356,25 @@ 9.63 /** The starting position of the analysed tree */ 9.64 int startPos; 9.65 9.66 + AssignAnalyzer() { 9.67 + inits = new Bits(); 9.68 + uninits = new Bits(); 9.69 + uninitsTry = new Bits(); 9.70 + initsWhenTrue = new Bits(true); 9.71 + initsWhenFalse = new Bits(true); 9.72 + uninitsWhenTrue = new Bits(true); 9.73 + uninitsWhenFalse = new Bits(true); 9.74 + } 9.75 + 9.76 class AssignPendingExit extends BaseAnalyzer.PendingExit { 9.77 9.78 - Bits exit_inits; 9.79 - Bits exit_uninits; 9.80 + final Bits exit_inits = new Bits(true); 9.81 + final Bits exit_uninits = new Bits(true); 9.82 9.83 - AssignPendingExit(JCTree tree, Bits inits, Bits uninits) { 9.84 + AssignPendingExit(JCTree tree, final Bits inits, final Bits uninits) { 9.85 super(tree); 9.86 - this.exit_inits = inits.dup(); 9.87 - this.exit_uninits = uninits.dup(); 9.88 + this.exit_inits.assign(inits); 9.89 + this.exit_uninits.assign(uninits); 9.90 } 9.91 9.92 void resolveJump() { 9.93 @@ -1476,19 +1494,20 @@ 9.94 /** Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets 9.95 */ 9.96 void split(boolean setToNull) { 9.97 - initsWhenFalse = inits.dup(); 9.98 - uninitsWhenFalse = uninits.dup(); 9.99 - initsWhenTrue = inits; 9.100 - uninitsWhenTrue = uninits; 9.101 - if (setToNull) 9.102 - inits = uninits = null; 9.103 + initsWhenFalse.assign(inits); 9.104 + uninitsWhenFalse.assign(uninits); 9.105 + initsWhenTrue.assign(inits); 9.106 + uninitsWhenTrue.assign(uninits); 9.107 + if (setToNull) { 9.108 + resetBits(inits, uninits); 9.109 + } 9.110 } 9.111 9.112 /** Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets. 9.113 */ 9.114 void merge() { 9.115 - inits = initsWhenFalse.andSet(initsWhenTrue); 9.116 - uninits = uninitsWhenFalse.andSet(uninitsWhenTrue); 9.117 + inits.assign(initsWhenFalse.andSet(initsWhenTrue)); 9.118 + uninits.assign(uninitsWhenFalse.andSet(uninitsWhenTrue)); 9.119 } 9.120 9.121 /* ************************************************************************ 9.122 @@ -1501,7 +1520,7 @@ 9.123 void scanExpr(JCTree tree) { 9.124 if (tree != null) { 9.125 scan(tree); 9.126 - if (inits == null) merge(); 9.127 + if (inits.isReset()) merge(); 9.128 } 9.129 } 9.130 9.131 @@ -1518,28 +1537,29 @@ 9.132 */ 9.133 void scanCond(JCTree tree) { 9.134 if (tree.type.isFalse()) { 9.135 - if (inits == null) merge(); 9.136 - initsWhenTrue = inits.dup(); 9.137 + if (inits.isReset()) merge(); 9.138 + initsWhenTrue.assign(inits); 9.139 initsWhenTrue.inclRange(firstadr, nextadr); 9.140 - uninitsWhenTrue = uninits.dup(); 9.141 + uninitsWhenTrue.assign(uninits); 9.142 uninitsWhenTrue.inclRange(firstadr, nextadr); 9.143 - initsWhenFalse = inits; 9.144 - uninitsWhenFalse = uninits; 9.145 + initsWhenFalse.assign(inits); 9.146 + uninitsWhenFalse.assign(uninits); 9.147 } else if (tree.type.isTrue()) { 9.148 - if (inits == null) merge(); 9.149 - initsWhenFalse = inits.dup(); 9.150 + if (inits.isReset()) merge(); 9.151 + initsWhenFalse.assign(inits); 9.152 initsWhenFalse.inclRange(firstadr, nextadr); 9.153 - uninitsWhenFalse = uninits.dup(); 9.154 + uninitsWhenFalse.assign(uninits); 9.155 uninitsWhenFalse.inclRange(firstadr, nextadr); 9.156 - initsWhenTrue = inits; 9.157 - uninitsWhenTrue = uninits; 9.158 + initsWhenTrue.assign(inits); 9.159 + uninitsWhenTrue.assign(uninits); 9.160 } else { 9.161 scan(tree); 9.162 - if (inits != null) 9.163 + if (!inits.isReset()) 9.164 split(tree.type != syms.unknownType); 9.165 } 9.166 - if (tree.type != syms.unknownType) 9.167 - inits = uninits = null; 9.168 + if (tree.type != syms.unknownType) { 9.169 + resetBits(inits, uninits); 9.170 + } 9.171 } 9.172 9.173 /* ------------ Visitor methods for various sorts of trees -------------*/ 9.174 @@ -1619,8 +1639,8 @@ 9.175 public void visitMethodDef(JCMethodDecl tree) { 9.176 if (tree.body == null) return; 9.177 9.178 - Bits initsPrev = inits.dup(); 9.179 - Bits uninitsPrev = uninits.dup(); 9.180 + final Bits initsPrev = new Bits(inits); 9.181 + final Bits uninitsPrev = new Bits(uninits); 9.182 int nextadrPrev = nextadr; 9.183 int firstadrPrev = firstadr; 9.184 int returnadrPrev = returnadr; 9.185 @@ -1658,14 +1678,14 @@ 9.186 exits = exits.tail; 9.187 Assert.check(exit.tree.hasTag(RETURN), exit.tree); 9.188 if (isInitialConstructor) { 9.189 - inits = exit.exit_inits; 9.190 + inits.assign(exit.exit_inits); 9.191 for (int i = firstadr; i < nextadr; i++) 9.192 checkInit(exit.tree.pos(), vars[i]); 9.193 } 9.194 } 9.195 } finally { 9.196 - inits = initsPrev; 9.197 - uninits = uninitsPrev; 9.198 + inits.assign(initsPrev); 9.199 + uninits.assign(uninitsPrev); 9.200 nextadr = nextadrPrev; 9.201 firstadr = firstadrPrev; 9.202 returnadr = returnadrPrev; 9.203 @@ -1698,31 +1718,31 @@ 9.204 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; 9.205 FlowKind prevFlowKind = flowKind; 9.206 flowKind = FlowKind.NORMAL; 9.207 - Bits initsSkip = null; 9.208 - Bits uninitsSkip = null; 9.209 + final Bits initsSkip = new Bits(true); 9.210 + final Bits uninitsSkip = new Bits(true); 9.211 pendingExits = new ListBuffer<AssignPendingExit>(); 9.212 int prevErrors = log.nerrors; 9.213 do { 9.214 - Bits uninitsEntry = uninits.dup(); 9.215 + final Bits uninitsEntry = new Bits(uninits); 9.216 uninitsEntry.excludeFrom(nextadr); 9.217 scan(tree.body); 9.218 resolveContinues(tree); 9.219 scanCond(tree.cond); 9.220 if (!flowKind.isFinal()) { 9.221 - initsSkip = initsWhenFalse; 9.222 - uninitsSkip = uninitsWhenFalse; 9.223 + initsSkip.assign(initsWhenFalse); 9.224 + uninitsSkip.assign(uninitsWhenFalse); 9.225 } 9.226 if (log.nerrors != prevErrors || 9.227 flowKind.isFinal() || 9.228 - uninitsEntry.dup().diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) 9.229 + new Bits(uninitsEntry).diffSet(uninitsWhenTrue).nextBit(firstadr)==-1) 9.230 break; 9.231 - inits = initsWhenTrue; 9.232 - uninits = uninitsEntry.andSet(uninitsWhenTrue); 9.233 + inits.assign(initsWhenTrue); 9.234 + uninits.assign(uninitsEntry.andSet(uninitsWhenTrue)); 9.235 flowKind = FlowKind.SPECULATIVE_LOOP; 9.236 } while (true); 9.237 flowKind = prevFlowKind; 9.238 - inits = initsSkip; 9.239 - uninits = uninitsSkip; 9.240 + inits.assign(initsSkip); 9.241 + uninits.assign(uninitsSkip); 9.242 resolveBreaks(tree, prevPendingExits); 9.243 } 9.244 9.245 @@ -1730,34 +1750,34 @@ 9.246 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; 9.247 FlowKind prevFlowKind = flowKind; 9.248 flowKind = FlowKind.NORMAL; 9.249 - Bits initsSkip = null; 9.250 - Bits uninitsSkip = null; 9.251 + final Bits initsSkip = new Bits(true); 9.252 + final Bits uninitsSkip = new Bits(true); 9.253 pendingExits = new ListBuffer<AssignPendingExit>(); 9.254 int prevErrors = log.nerrors; 9.255 - Bits uninitsEntry = uninits.dup(); 9.256 + final Bits uninitsEntry = new Bits(uninits); 9.257 uninitsEntry.excludeFrom(nextadr); 9.258 do { 9.259 scanCond(tree.cond); 9.260 if (!flowKind.isFinal()) { 9.261 - initsSkip = initsWhenFalse; 9.262 - uninitsSkip = uninitsWhenFalse; 9.263 + initsSkip.assign(initsWhenFalse) ; 9.264 + uninitsSkip.assign(uninitsWhenFalse); 9.265 } 9.266 - inits = initsWhenTrue; 9.267 - uninits = uninitsWhenTrue; 9.268 + inits.assign(initsWhenTrue); 9.269 + uninits.assign(uninitsWhenTrue); 9.270 scan(tree.body); 9.271 resolveContinues(tree); 9.272 if (log.nerrors != prevErrors || 9.273 flowKind.isFinal() || 9.274 - uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) 9.275 + new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) 9.276 break; 9.277 - uninits = uninitsEntry.andSet(uninits); 9.278 + uninits.assign(uninitsEntry.andSet(uninits)); 9.279 flowKind = FlowKind.SPECULATIVE_LOOP; 9.280 } while (true); 9.281 flowKind = prevFlowKind; 9.282 //a variable is DA/DU after the while statement, if it's DA/DU assuming the 9.283 //branch is not taken AND if it's DA/DU before any break statement 9.284 - inits = initsSkip; 9.285 - uninits = uninitsSkip; 9.286 + inits.assign(initsSkip); 9.287 + uninits.assign(uninitsSkip); 9.288 resolveBreaks(tree, prevPendingExits); 9.289 } 9.290 9.291 @@ -1767,25 +1787,25 @@ 9.292 flowKind = FlowKind.NORMAL; 9.293 int nextadrPrev = nextadr; 9.294 scan(tree.init); 9.295 - Bits initsSkip = null; 9.296 - Bits uninitsSkip = null; 9.297 + final Bits initsSkip = new Bits(true); 9.298 + final Bits uninitsSkip = new Bits(true); 9.299 pendingExits = new ListBuffer<AssignPendingExit>(); 9.300 int prevErrors = log.nerrors; 9.301 do { 9.302 - Bits uninitsEntry = uninits.dup(); 9.303 + final Bits uninitsEntry = new Bits(uninits); 9.304 uninitsEntry.excludeFrom(nextadr); 9.305 if (tree.cond != null) { 9.306 scanCond(tree.cond); 9.307 if (!flowKind.isFinal()) { 9.308 - initsSkip = initsWhenFalse; 9.309 - uninitsSkip = uninitsWhenFalse; 9.310 + initsSkip.assign(initsWhenFalse); 9.311 + uninitsSkip.assign(uninitsWhenFalse); 9.312 } 9.313 - inits = initsWhenTrue; 9.314 - uninits = uninitsWhenTrue; 9.315 + inits.assign(initsWhenTrue); 9.316 + uninits.assign(uninitsWhenTrue); 9.317 } else if (!flowKind.isFinal()) { 9.318 - initsSkip = inits.dup(); 9.319 + initsSkip.assign(inits); 9.320 initsSkip.inclRange(firstadr, nextadr); 9.321 - uninitsSkip = uninits.dup(); 9.322 + uninitsSkip.assign(uninits); 9.323 uninitsSkip.inclRange(firstadr, nextadr); 9.324 } 9.325 scan(tree.body); 9.326 @@ -1793,16 +1813,16 @@ 9.327 scan(tree.step); 9.328 if (log.nerrors != prevErrors || 9.329 flowKind.isFinal() || 9.330 - uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) 9.331 + new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) 9.332 break; 9.333 - uninits = uninitsEntry.andSet(uninits); 9.334 + uninits.assign(uninitsEntry.andSet(uninits)); 9.335 flowKind = FlowKind.SPECULATIVE_LOOP; 9.336 } while (true); 9.337 flowKind = prevFlowKind; 9.338 //a variable is DA/DU after a for loop, if it's DA/DU assuming the 9.339 //branch is not taken AND if it's DA/DU before any break statement 9.340 - inits = initsSkip; 9.341 - uninits = uninitsSkip; 9.342 + inits.assign(initsSkip); 9.343 + uninits.assign(uninitsSkip); 9.344 resolveBreaks(tree, prevPendingExits); 9.345 nextadr = nextadrPrev; 9.346 } 9.347 @@ -1815,27 +1835,27 @@ 9.348 flowKind = FlowKind.NORMAL; 9.349 int nextadrPrev = nextadr; 9.350 scan(tree.expr); 9.351 - Bits initsStart = inits.dup(); 9.352 - Bits uninitsStart = uninits.dup(); 9.353 + final Bits initsStart = new Bits(inits); 9.354 + final Bits uninitsStart = new Bits(uninits); 9.355 9.356 letInit(tree.pos(), tree.var.sym); 9.357 pendingExits = new ListBuffer<AssignPendingExit>(); 9.358 int prevErrors = log.nerrors; 9.359 do { 9.360 - Bits uninitsEntry = uninits.dup(); 9.361 + final Bits uninitsEntry = new Bits(uninits); 9.362 uninitsEntry.excludeFrom(nextadr); 9.363 scan(tree.body); 9.364 resolveContinues(tree); 9.365 if (log.nerrors != prevErrors || 9.366 flowKind.isFinal() || 9.367 - uninitsEntry.dup().diffSet(uninits).nextBit(firstadr) == -1) 9.368 + new Bits(uninitsEntry).diffSet(uninits).nextBit(firstadr) == -1) 9.369 break; 9.370 - uninits = uninitsEntry.andSet(uninits); 9.371 + uninits.assign(uninitsEntry.andSet(uninits)); 9.372 flowKind = FlowKind.SPECULATIVE_LOOP; 9.373 } while (true); 9.374 flowKind = prevFlowKind; 9.375 - inits = initsStart; 9.376 - uninits = uninitsStart.andSet(uninits); 9.377 + inits.assign(initsStart); 9.378 + uninits.assign(uninitsStart.andSet(uninits)); 9.379 resolveBreaks(tree, prevPendingExits); 9.380 nextadr = nextadrPrev; 9.381 } 9.382 @@ -1852,12 +1872,12 @@ 9.383 pendingExits = new ListBuffer<AssignPendingExit>(); 9.384 int nextadrPrev = nextadr; 9.385 scanExpr(tree.selector); 9.386 - Bits initsSwitch = inits; 9.387 - Bits uninitsSwitch = uninits.dup(); 9.388 + final Bits initsSwitch = new Bits(inits); 9.389 + final Bits uninitsSwitch = new Bits(uninits); 9.390 boolean hasDefault = false; 9.391 for (List<JCCase> l = tree.cases; l.nonEmpty(); l = l.tail) { 9.392 - inits = initsSwitch.dup(); 9.393 - uninits = uninits.andSet(uninitsSwitch); 9.394 + inits.assign(initsSwitch); 9.395 + uninits.assign(uninits.andSet(uninitsSwitch)); 9.396 JCCase c = l.head; 9.397 if (c.pat == null) 9.398 hasDefault = true; 9.399 @@ -1875,8 +1895,8 @@ 9.400 } 9.401 // where 9.402 /** Add any variables defined in stats to inits and uninits. */ 9.403 - private void addVars(List<JCStatement> stats, Bits inits, 9.404 - Bits uninits) { 9.405 + private void addVars(List<JCStatement> stats, final Bits inits, 9.406 + final Bits uninits) { 9.407 for (;stats.nonEmpty(); stats = stats.tail) { 9.408 JCTree stat = stats.head; 9.409 if (stat.hasTag(VARDEF)) { 9.410 @@ -1889,11 +1909,11 @@ 9.411 9.412 public void visitTry(JCTry tree) { 9.413 ListBuffer<JCVariableDecl> resourceVarDecls = ListBuffer.lb(); 9.414 - Bits uninitsTryPrev = uninitsTry; 9.415 + final Bits uninitsTryPrev = new Bits(uninitsTry); 9.416 ListBuffer<AssignPendingExit> prevPendingExits = pendingExits; 9.417 pendingExits = new ListBuffer<AssignPendingExit>(); 9.418 - Bits initsTry = inits.dup(); 9.419 - uninitsTry = uninits.dup(); 9.420 + final Bits initsTry = new Bits(inits); 9.421 + uninitsTry.assign(uninits); 9.422 for (JCTree resource : tree.resources) { 9.423 if (resource instanceof JCVariableDecl) { 9.424 JCVariableDecl vdecl = (JCVariableDecl) resource; 9.425 @@ -1908,8 +1928,8 @@ 9.426 } 9.427 scan(tree.body); 9.428 uninitsTry.andSet(uninits); 9.429 - Bits initsEnd = inits; 9.430 - Bits uninitsEnd = uninits; 9.431 + final Bits initsEnd = new Bits(inits); 9.432 + final Bits uninitsEnd = new Bits(uninits); 9.433 int nextadrCatch = nextadr; 9.434 9.435 if (!resourceVarDecls.isEmpty() && 9.436 @@ -1925,8 +1945,8 @@ 9.437 9.438 for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) { 9.439 JCVariableDecl param = l.head.param; 9.440 - inits = initsTry.dup(); 9.441 - uninits = uninitsTry.dup(); 9.442 + inits.assign(initsTry); 9.443 + uninits.assign(uninitsTry); 9.444 scan(param); 9.445 inits.incl(param.sym.adr); 9.446 uninits.excl(param.sym.adr); 9.447 @@ -1936,8 +1956,8 @@ 9.448 nextadr = nextadrCatch; 9.449 } 9.450 if (tree.finalizer != null) { 9.451 - inits = initsTry.dup(); 9.452 - uninits = uninitsTry.dup(); 9.453 + inits.assign(initsTry); 9.454 + uninits.assign(uninitsTry); 9.455 ListBuffer<AssignPendingExit> exits = pendingExits; 9.456 pendingExits = prevPendingExits; 9.457 scan(tree.finalizer); 9.458 @@ -1958,8 +1978,8 @@ 9.459 inits.orSet(initsEnd); 9.460 } 9.461 } else { 9.462 - inits = initsEnd; 9.463 - uninits = uninitsEnd; 9.464 + inits.assign(initsEnd); 9.465 + uninits.assign(uninitsEnd); 9.466 ListBuffer<AssignPendingExit> exits = pendingExits; 9.467 pendingExits = prevPendingExits; 9.468 while (exits.nonEmpty()) pendingExits.append(exits.next()); 9.469 @@ -1969,10 +1989,10 @@ 9.470 9.471 public void visitConditional(JCConditional tree) { 9.472 scanCond(tree.cond); 9.473 - Bits initsBeforeElse = initsWhenFalse; 9.474 - Bits uninitsBeforeElse = uninitsWhenFalse; 9.475 - inits = initsWhenTrue; 9.476 - uninits = uninitsWhenTrue; 9.477 + final Bits initsBeforeElse = new Bits(initsWhenFalse); 9.478 + final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); 9.479 + inits.assign(initsWhenTrue); 9.480 + uninits.assign(uninitsWhenTrue); 9.481 if (tree.truepart.type.hasTag(BOOLEAN) && 9.482 tree.falsepart.type.hasTag(BOOLEAN)) { 9.483 // if b and c are boolean valued, then 9.484 @@ -1980,12 +2000,12 @@ 9.485 // v is (un)assigned after b when true and 9.486 // v is (un)assigned after c when true 9.487 scanCond(tree.truepart); 9.488 - Bits initsAfterThenWhenTrue = initsWhenTrue.dup(); 9.489 - Bits initsAfterThenWhenFalse = initsWhenFalse.dup(); 9.490 - Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup(); 9.491 - Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup(); 9.492 - inits = initsBeforeElse; 9.493 - uninits = uninitsBeforeElse; 9.494 + final Bits initsAfterThenWhenTrue = new Bits(initsWhenTrue); 9.495 + final Bits initsAfterThenWhenFalse = new Bits(initsWhenFalse); 9.496 + final Bits uninitsAfterThenWhenTrue = new Bits(uninitsWhenTrue); 9.497 + final Bits uninitsAfterThenWhenFalse = new Bits(uninitsWhenFalse); 9.498 + inits.assign(initsBeforeElse); 9.499 + uninits.assign(uninitsBeforeElse); 9.500 scanCond(tree.falsepart); 9.501 initsWhenTrue.andSet(initsAfterThenWhenTrue); 9.502 initsWhenFalse.andSet(initsAfterThenWhenFalse); 9.503 @@ -1993,10 +2013,10 @@ 9.504 uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse); 9.505 } else { 9.506 scanExpr(tree.truepart); 9.507 - Bits initsAfterThen = inits.dup(); 9.508 - Bits uninitsAfterThen = uninits.dup(); 9.509 - inits = initsBeforeElse; 9.510 - uninits = uninitsBeforeElse; 9.511 + final Bits initsAfterThen = new Bits(inits); 9.512 + final Bits uninitsAfterThen = new Bits(uninits); 9.513 + inits.assign(initsBeforeElse); 9.514 + uninits.assign(uninitsBeforeElse); 9.515 scanExpr(tree.falsepart); 9.516 inits.andSet(initsAfterThen); 9.517 uninits.andSet(uninitsAfterThen); 9.518 @@ -2005,16 +2025,16 @@ 9.519 9.520 public void visitIf(JCIf tree) { 9.521 scanCond(tree.cond); 9.522 - Bits initsBeforeElse = initsWhenFalse; 9.523 - Bits uninitsBeforeElse = uninitsWhenFalse; 9.524 - inits = initsWhenTrue; 9.525 - uninits = uninitsWhenTrue; 9.526 + final Bits initsBeforeElse = new Bits(initsWhenFalse); 9.527 + final Bits uninitsBeforeElse = new Bits(uninitsWhenFalse); 9.528 + inits.assign(initsWhenTrue); 9.529 + uninits.assign(uninitsWhenTrue); 9.530 scan(tree.thenpart); 9.531 if (tree.elsepart != null) { 9.532 - Bits initsAfterThen = inits.dup(); 9.533 - Bits uninitsAfterThen = uninits.dup(); 9.534 - inits = initsBeforeElse; 9.535 - uninits = uninitsBeforeElse; 9.536 + final Bits initsAfterThen = new Bits(inits); 9.537 + final Bits uninitsAfterThen = new Bits(uninits); 9.538 + inits.assign(initsBeforeElse); 9.539 + uninits.assign(uninitsBeforeElse); 9.540 scan(tree.elsepart); 9.541 inits.andSet(initsAfterThen); 9.542 uninits.andSet(uninitsAfterThen); 9.543 @@ -2055,8 +2075,8 @@ 9.544 9.545 @Override 9.546 public void visitLambda(JCLambda tree) { 9.547 - Bits prevUninits = uninits; 9.548 - Bits prevInits = inits; 9.549 + final Bits prevUninits = new Bits(uninits); 9.550 + final Bits prevInits = new Bits(inits); 9.551 int returnadrPrev = returnadr; 9.552 ListBuffer<AssignPendingExit> prevPending = pendingExits; 9.553 try { 9.554 @@ -2076,8 +2096,8 @@ 9.555 } 9.556 finally { 9.557 returnadr = returnadrPrev; 9.558 - uninits = prevUninits; 9.559 - inits = prevInits; 9.560 + uninits.assign(prevUninits); 9.561 + inits.assign(prevInits); 9.562 pendingExits = prevPending; 9.563 } 9.564 } 9.565 @@ -2088,17 +2108,17 @@ 9.566 } 9.567 9.568 public void visitAssert(JCAssert tree) { 9.569 - Bits initsExit = inits.dup(); 9.570 - Bits uninitsExit = uninits.dup(); 9.571 + final Bits initsExit = new Bits(inits); 9.572 + final Bits uninitsExit = new Bits(uninits); 9.573 scanCond(tree.cond); 9.574 uninitsExit.andSet(uninitsWhenTrue); 9.575 if (tree.detail != null) { 9.576 - inits = initsWhenFalse; 9.577 - uninits = uninitsWhenFalse; 9.578 + inits.assign(initsWhenFalse); 9.579 + uninits.assign(uninitsWhenFalse); 9.580 scanExpr(tree.detail); 9.581 } 9.582 - inits = initsExit; 9.583 - uninits = uninitsExit; 9.584 + inits.assign(initsExit); 9.585 + uninits.assign(uninitsExit); 9.586 } 9.587 9.588 public void visitAssign(JCAssign tree) { 9.589 @@ -2120,12 +2140,12 @@ 9.590 switch (tree.getTag()) { 9.591 case NOT: 9.592 scanCond(tree.arg); 9.593 - Bits t = initsWhenFalse; 9.594 - initsWhenFalse = initsWhenTrue; 9.595 - initsWhenTrue = t; 9.596 - t = uninitsWhenFalse; 9.597 - uninitsWhenFalse = uninitsWhenTrue; 9.598 - uninitsWhenTrue = t; 9.599 + final Bits t = new Bits(initsWhenFalse); 9.600 + initsWhenFalse.assign(initsWhenTrue); 9.601 + initsWhenTrue.assign(t); 9.602 + t.assign(uninitsWhenFalse); 9.603 + uninitsWhenFalse.assign(uninitsWhenTrue); 9.604 + uninitsWhenTrue.assign(t); 9.605 break; 9.606 case PREINC: case POSTINC: 9.607 case PREDEC: case POSTDEC: 9.608 @@ -2141,20 +2161,20 @@ 9.609 switch (tree.getTag()) { 9.610 case AND: 9.611 scanCond(tree.lhs); 9.612 - Bits initsWhenFalseLeft = initsWhenFalse; 9.613 - Bits uninitsWhenFalseLeft = uninitsWhenFalse; 9.614 - inits = initsWhenTrue; 9.615 - uninits = uninitsWhenTrue; 9.616 + final Bits initsWhenFalseLeft = new Bits(initsWhenFalse); 9.617 + final Bits uninitsWhenFalseLeft = new Bits(uninitsWhenFalse); 9.618 + inits.assign(initsWhenTrue); 9.619 + uninits.assign(uninitsWhenTrue); 9.620 scanCond(tree.rhs); 9.621 initsWhenFalse.andSet(initsWhenFalseLeft); 9.622 uninitsWhenFalse.andSet(uninitsWhenFalseLeft); 9.623 break; 9.624 case OR: 9.625 scanCond(tree.lhs); 9.626 - Bits initsWhenTrueLeft = initsWhenTrue; 9.627 - Bits uninitsWhenTrueLeft = uninitsWhenTrue; 9.628 - inits = initsWhenFalse; 9.629 - uninits = uninitsWhenFalse; 9.630 + final Bits initsWhenTrueLeft = new Bits(initsWhenTrue); 9.631 + final Bits uninitsWhenTrueLeft = new Bits(uninitsWhenTrue); 9.632 + inits.assign(initsWhenFalse); 9.633 + uninits.assign(uninitsWhenFalse); 9.634 scanCond(tree.rhs); 9.635 initsWhenTrue.andSet(initsWhenTrueLeft); 9.636 uninitsWhenTrue.andSet(uninitsWhenTrueLeft); 9.637 @@ -2200,11 +2220,7 @@ 9.638 attrEnv = env; 9.639 Flow.this.make = make; 9.640 startPos = tree.pos().getStartPosition(); 9.641 - inits = new Bits(); 9.642 - uninits = new Bits(); 9.643 - uninitsTry = new Bits(); 9.644 - initsWhenTrue = initsWhenFalse = 9.645 - uninitsWhenTrue = uninitsWhenFalse = null; 9.646 + 9.647 if (vars == null) 9.648 vars = new VarSymbol[32]; 9.649 else 9.650 @@ -2219,9 +2235,8 @@ 9.651 } finally { 9.652 // note that recursive invocations of this method fail hard 9.653 startPos = -1; 9.654 - inits = uninits = uninitsTry = null; 9.655 - initsWhenTrue = initsWhenFalse = 9.656 - uninitsWhenTrue = uninitsWhenFalse = null; 9.657 + resetBits(inits, uninits, uninitsTry, initsWhenTrue, 9.658 + initsWhenFalse, uninitsWhenTrue, uninitsWhenFalse); 9.659 if (vars != null) for (int i=0; i<vars.length; i++) 9.660 vars[i] = null; 9.661 firstadr = 0;
10.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Sun Apr 28 08:16:41 2013 +0100 10.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed May 08 10:27:52 2013 +0100 10.3 @@ -40,10 +40,9 @@ 10.4 import com.sun.tools.javac.code.Symbol.VarSymbol; 10.5 import com.sun.tools.javac.code.Symtab; 10.6 import com.sun.tools.javac.code.Type; 10.7 -import com.sun.tools.javac.code.Type.ClassType; 10.8 import com.sun.tools.javac.code.Type.MethodType; 10.9 import com.sun.tools.javac.code.Types; 10.10 -import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzer.*; 10.11 +import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*; 10.12 import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector; 10.13 import com.sun.tools.javac.jvm.*; 10.14 import com.sun.tools.javac.util.*; 10.15 @@ -81,7 +80,7 @@ 10.16 private Env<AttrContext> attrEnv; 10.17 10.18 /** the analyzer scanner */ 10.19 - private LambdaAnalyzer analyzer; 10.20 + private LambdaAnalyzerPreprocessor analyzer; 10.21 10.22 /** map from lambda trees to translation contexts */ 10.23 private Map<JCTree, TranslationContext<?>> contextMap; 10.24 @@ -156,7 +155,7 @@ 10.25 make = TreeMaker.instance(context); 10.26 types = Types.instance(context); 10.27 transTypes = TransTypes.instance(context); 10.28 - analyzer = new LambdaAnalyzer(); 10.29 + analyzer = new LambdaAnalyzerPreprocessor(); 10.30 } 10.31 // </editor-fold> 10.32 10.33 @@ -206,7 +205,7 @@ 10.34 public void visitClassDef(JCClassDecl tree) { 10.35 if (tree.sym.owner.kind == PCK) { 10.36 //analyze class 10.37 - analyzer.analyzeClass(tree); 10.38 + tree = analyzer.analyzeAndPreprocessClass(tree); 10.39 } 10.40 KlassInfo prevKlassInfo = kInfo; 10.41 try { 10.42 @@ -531,16 +530,25 @@ 10.43 /** Make an attributed class instance creation expression. 10.44 * @param ctype The class type. 10.45 * @param args The constructor arguments. 10.46 + * @param cons The constructor symbol 10.47 */ 10.48 - JCNewClass makeNewClass(Type ctype, List<JCExpression> args) { 10.49 + JCNewClass makeNewClass(Type ctype, List<JCExpression> args, Symbol cons) { 10.50 JCNewClass tree = make.NewClass(null, 10.51 null, make.QualIdent(ctype.tsym), args, null); 10.52 - tree.constructor = rs.resolveConstructor( 10.53 - null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil()); 10.54 + tree.constructor = cons; 10.55 tree.type = ctype; 10.56 return tree; 10.57 } 10.58 10.59 + /** Make an attributed class instance creation expression. 10.60 + * @param ctype The class type. 10.61 + * @param args The constructor arguments. 10.62 + */ 10.63 + JCNewClass makeNewClass(Type ctype, List<JCExpression> args) { 10.64 + return makeNewClass(ctype, args, 10.65 + rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil())); 10.66 + } 10.67 + 10.68 private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym, 10.69 DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) { 10.70 String functionalInterfaceClass = classSig(targetType); 10.71 @@ -1019,8 +1027,9 @@ 10.72 * This visitor collects information about translation of a lambda expression. 10.73 * More specifically, it keeps track of the enclosing contexts and captured locals 10.74 * accessed by the lambda being translated (as well as other useful info). 10.75 + * It also translates away problems for LambdaToMethod. 10.76 */ 10.77 - class LambdaAnalyzer extends TreeScanner { 10.78 + class LambdaAnalyzerPreprocessor extends TreeTranslator { 10.79 10.80 /** the frame stack - used to reconstruct translation info about enclosing scopes */ 10.81 private List<Frame> frameStack; 10.82 @@ -1047,10 +1056,10 @@ 10.83 private Map<ClassSymbol, Symbol> clinits = 10.84 new HashMap<ClassSymbol, Symbol>(); 10.85 10.86 - private void analyzeClass(JCClassDecl tree) { 10.87 + private JCClassDecl analyzeAndPreprocessClass(JCClassDecl tree) { 10.88 frameStack = List.nil(); 10.89 localClassDefs = new HashMap<Symbol, JCClassDecl>(); 10.90 - scan(tree); 10.91 + return translate(tree); 10.92 } 10.93 10.94 @Override 10.95 @@ -1154,7 +1163,7 @@ 10.96 frameStack.head.addLocal(param.sym); 10.97 } 10.98 contextMap.put(tree, context); 10.99 - scan(tree.body); 10.100 + super.visitLambda(tree); 10.101 context.complete(); 10.102 } 10.103 finally { 10.104 @@ -1220,12 +1229,47 @@ 10.105 }; 10.106 fvc.scan(localCDef); 10.107 } 10.108 - } 10.109 + } 10.110 10.111 + /** 10.112 + * Method references to local class constructors, may, if the local 10.113 + * class references local variables, have implicit constructor 10.114 + * parameters added in Lower; As a result, the invokedynamic bootstrap 10.115 + * information added in the LambdaToMethod pass will have the wrong 10.116 + * signature. Hooks between Lower and LambdaToMethod have been added to 10.117 + * handle normal "new" in this case. This visitor converts potentially 10.118 + * effected method references into a lambda containing a normal "new" of 10.119 + * the class. 10.120 + * 10.121 + * @param tree 10.122 + */ 10.123 @Override 10.124 public void visitReference(JCMemberReference tree) { 10.125 - scan(tree.getQualifierExpression()); 10.126 - contextMap.put(tree, makeReferenceContext(tree)); 10.127 + if (tree.getMode() == ReferenceMode.NEW 10.128 + && tree.kind != ReferenceKind.ARRAY_CTOR 10.129 + && tree.sym.owner.isLocal()) { 10.130 + MethodSymbol consSym = (MethodSymbol) tree.sym; 10.131 + List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes(); 10.132 + Type classType = consSym.owner.type; 10.133 + 10.134 + // Make new-class call 10.135 + List<JCVariableDecl> params = make.Params(ptypes, owner()); 10.136 + JCNewClass nc = makeNewClass(classType, make.Idents(params)); 10.137 + nc.pos = tree.pos; 10.138 + 10.139 + // Make lambda holding the new-class call 10.140 + JCLambda slam = make.Lambda(params, nc); 10.141 + slam.descriptorType = tree.descriptorType; 10.142 + slam.targets = tree.targets; 10.143 + slam.type = tree.type; 10.144 + slam.pos = tree.pos; 10.145 + 10.146 + // Now it is a lambda, process as such 10.147 + visitLambda(slam); 10.148 + } else { 10.149 + super.visitReference(tree); 10.150 + contextMap.put(tree, makeReferenceContext(tree)); 10.151 + } 10.152 } 10.153 10.154 @Override 10.155 @@ -1240,10 +1284,8 @@ 10.156 } 10.157 localContext = localContext.prev; 10.158 } 10.159 - scan(tree.selected); 10.160 - } else { 10.161 - super.visitSelect(tree); 10.162 } 10.163 + super.visitSelect(tree); 10.164 } 10.165 10.166 @Override
11.1 --- a/src/share/classes/com/sun/tools/javac/jvm/Code.java Sun Apr 28 08:16:41 2013 +0100 11.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java Wed May 08 10:27:52 2013 +0100 11.3 @@ -1647,7 +1647,7 @@ 11.4 State dup() { 11.5 try { 11.6 State state = (State)super.clone(); 11.7 - state.defined = defined.dup(); 11.8 + state.defined = new Bits(defined); 11.9 state.stack = stack.clone(); 11.10 if (locks != null) state.locks = locks.clone(); 11.11 if (debugCode) { 11.12 @@ -1775,7 +1775,7 @@ 11.13 } 11.14 11.15 State join(State other) { 11.16 - defined = defined.andSet(other.defined); 11.17 + defined.andSet(other.defined); 11.18 Assert.check(stacksize == other.stacksize 11.19 && nlocks == other.nlocks); 11.20 for (int i=0; i<stacksize; ) { 11.21 @@ -1887,7 +1887,7 @@ 11.22 /** Set the current variable defined state. */ 11.23 public void setDefined(Bits newDefined) { 11.24 if (alive && newDefined != state.defined) { 11.25 - Bits diff = state.defined.dup().xorSet(newDefined); 11.26 + Bits diff = new Bits(state.defined).xorSet(newDefined); 11.27 for (int adr = diff.nextBit(0); 11.28 adr >= 0; 11.29 adr = diff.nextBit(adr+1)) {
12.1 --- a/src/share/classes/com/sun/tools/javac/util/Bits.java Sun Apr 28 08:16:41 2013 +0100 12.2 +++ b/src/share/classes/com/sun/tools/javac/util/Bits.java Wed May 08 10:27:52 2013 +0100 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -27,6 +27,8 @@ 12.11 12.12 import java.util.Arrays; 12.13 12.14 +import static com.sun.tools.javac.util.Bits.BitsOpKind.*; 12.15 + 12.16 /** A class for extensible, mutable bit sets. 12.17 * 12.18 * <p><b>This is NOT part of any supported API. 12.19 @@ -36,31 +38,114 @@ 12.20 */ 12.21 public class Bits { 12.22 12.23 + public enum BitsOpKind { 12.24 + INIT, 12.25 + CLEAR, 12.26 + INCL_BIT, 12.27 + EXCL_BIT, 12.28 + ASSIGN, 12.29 + AND_SET, 12.30 + OR_SET, 12.31 + DIFF_SET, 12.32 + XOR_SET, 12.33 + INCL_RANGE, 12.34 + EXCL_RANGE, 12.35 + } 12.36 + 12.37 + // ____________ reset _________ 12.38 + // / UNKNOWN \ <-------- / UNINIT \ 12.39 + // \____________/ | \_________/ 12.40 + // | | | 12.41 + // |assign | | any 12.42 + // | ___________ | 12.43 + // ------> / NORMAL \ <---- 12.44 + // \___________/ | 12.45 + // | | 12.46 + // | | 12.47 + // ----------- 12.48 + // any 12.49 + private enum BitsState { 12.50 + /* A Bits instance is in UNKNOWN state if it has been explicitly reset. 12.51 + * It is possible to get to this state from any other by calling the 12.52 + * reset method. An instance in the UNKNOWN state can pass to the 12.53 + * NORMAL state after being assigned another Bits instance. 12.54 + */ 12.55 + UNKNOWN, 12.56 + /* A Bits instance is in UNINIT when it is created with the default 12.57 + * constructor but it isn't explicitly reset. The main objective of this 12.58 + * internal state is to save some memory. 12.59 + */ 12.60 + UNINIT, 12.61 + /* The normal state is reached after creating a Bits instance from an 12.62 + * existing one or after applying any operation to an instance on UNINIT 12.63 + * or NORMAL state. From this state a bits instance can pass to the 12.64 + * UNKNOWN state by calling the reset method. 12.65 + */ 12.66 + NORMAL; 12.67 + 12.68 + static BitsState getState(int[] someBits, boolean reset) { 12.69 + if (reset) { 12.70 + return UNKNOWN; 12.71 + } else { 12.72 + if (someBits != unassignedBits) { 12.73 + return NORMAL; 12.74 + } else { 12.75 + return UNINIT; 12.76 + } 12.77 + } 12.78 + } 12.79 + 12.80 + } 12.81 12.82 private final static int wordlen = 32; 12.83 private final static int wordshift = 5; 12.84 private final static int wordmask = wordlen - 1; 12.85 12.86 - private int[] bits; 12.87 + public int[] bits = null; 12.88 + // This field will store last version of bits after every change. 12.89 + public int[] oldBits = null; 12.90 + 12.91 + public BitsOpKind lastOperation = null; 12.92 + 12.93 + private static final int[] unassignedBits = new int[0]; 12.94 + 12.95 + private BitsState currentState; 12.96 12.97 /** Construct an initially empty set. 12.98 */ 12.99 public Bits() { 12.100 - this(new int[1]); 12.101 + this(false); 12.102 + } 12.103 + 12.104 + public Bits(Bits someBits) { 12.105 + this(someBits.dup().bits, BitsState.getState(someBits.bits, false)); 12.106 + } 12.107 + 12.108 + public Bits(boolean reset) { 12.109 + this(unassignedBits, BitsState.getState(unassignedBits, reset)); 12.110 } 12.111 12.112 /** Construct a set consisting initially of given bit vector. 12.113 */ 12.114 - public Bits(int[] bits) { 12.115 + private Bits(int[] bits, BitsState initState) { 12.116 this.bits = bits; 12.117 + this.currentState = initState; 12.118 + switch (initState) { 12.119 + case UNKNOWN: 12.120 + reset(); //this will also set current state; 12.121 + break; 12.122 + case NORMAL: 12.123 + Assert.check(bits != unassignedBits); 12.124 + lastOperation = INIT; 12.125 + break; 12.126 + } 12.127 } 12.128 12.129 - /** Construct a set consisting initially of given range. 12.130 + /** This method will be called after any operation that causes a change to 12.131 + * the bits. Subclasses can thus override it in order to extract information 12.132 + * from the changes produced to the bits by the given operation. 12.133 */ 12.134 - public Bits(int start, int limit) { 12.135 - this(); 12.136 - inclRange(start, limit); 12.137 - } 12.138 + public void changed() {} 12.139 12.140 private void sizeTo(int len) { 12.141 if (bits.length < len) { 12.142 @@ -71,57 +156,110 @@ 12.143 /** This set = {}. 12.144 */ 12.145 public void clear() { 12.146 + Assert.check(currentState != BitsState.UNKNOWN); 12.147 + oldBits = bits; 12.148 + lastOperation = CLEAR; 12.149 for (int i = 0; i < bits.length; i++) bits[i] = 0; 12.150 + changed(); 12.151 + currentState = BitsState.NORMAL; 12.152 + } 12.153 + 12.154 + public void reset() { 12.155 + bits = null; 12.156 + oldBits = null; 12.157 + currentState = BitsState.UNKNOWN; 12.158 + } 12.159 + 12.160 + public boolean isReset() { 12.161 + return currentState == BitsState.UNKNOWN; 12.162 + } 12.163 + 12.164 + public Bits assign(Bits someBits) { 12.165 + lastOperation = ASSIGN; 12.166 + oldBits = bits; 12.167 + bits = someBits.dup().bits; 12.168 + changed(); 12.169 + currentState = BitsState.NORMAL; 12.170 + return this; 12.171 } 12.172 12.173 /** Return a copy of this set. 12.174 */ 12.175 - public Bits dup() { 12.176 - int[] newbits = new int[bits.length]; 12.177 - System.arraycopy(bits, 0, newbits, 0, bits.length); 12.178 - return new Bits(newbits); 12.179 + private Bits dup() { 12.180 + Assert.check(currentState != BitsState.UNKNOWN); 12.181 + Bits tmp = new Bits(); 12.182 + if (currentState != BitsState.NORMAL) { 12.183 + tmp.bits = bits; 12.184 + } else { 12.185 + tmp.bits = new int[bits.length]; 12.186 + System.arraycopy(bits, 0, tmp.bits, 0, bits.length); 12.187 + } 12.188 + currentState = BitsState.NORMAL; 12.189 + return tmp; 12.190 } 12.191 12.192 /** Include x in this set. 12.193 */ 12.194 public void incl(int x) { 12.195 + Assert.check(currentState != BitsState.UNKNOWN); 12.196 Assert.check(x >= 0); 12.197 + oldBits = bits; 12.198 + lastOperation = INCL_BIT; 12.199 sizeTo((x >>> wordshift) + 1); 12.200 bits[x >>> wordshift] = bits[x >>> wordshift] | 12.201 (1 << (x & wordmask)); 12.202 + changed(); 12.203 + currentState = BitsState.NORMAL; 12.204 } 12.205 12.206 12.207 /** Include [start..limit) in this set. 12.208 */ 12.209 public void inclRange(int start, int limit) { 12.210 + Assert.check(currentState != BitsState.UNKNOWN); 12.211 + oldBits = bits; 12.212 + lastOperation = INCL_RANGE; 12.213 sizeTo((limit >>> wordshift) + 1); 12.214 - for (int x = start; x < limit; x++) 12.215 + for (int x = start; x < limit; x++) { 12.216 bits[x >>> wordshift] = bits[x >>> wordshift] | 12.217 (1 << (x & wordmask)); 12.218 + } 12.219 + changed(); 12.220 + currentState = BitsState.NORMAL; 12.221 } 12.222 12.223 /** Exclude [start...end] from this set. 12.224 */ 12.225 public void excludeFrom(int start) { 12.226 + Assert.check(currentState != BitsState.UNKNOWN); 12.227 + oldBits = bits; 12.228 + lastOperation = EXCL_RANGE; 12.229 Bits temp = new Bits(); 12.230 temp.sizeTo(bits.length); 12.231 temp.inclRange(0, start); 12.232 - andSet(temp); 12.233 + internalAndSet(temp); 12.234 + changed(); 12.235 + currentState = BitsState.NORMAL; 12.236 } 12.237 12.238 /** Exclude x from this set. 12.239 */ 12.240 public void excl(int x) { 12.241 + Assert.check(currentState != BitsState.UNKNOWN); 12.242 Assert.check(x >= 0); 12.243 + oldBits = bits; 12.244 + lastOperation = EXCL_BIT; 12.245 sizeTo((x >>> wordshift) + 1); 12.246 bits[x >>> wordshift] = bits[x >>> wordshift] & 12.247 ~(1 << (x & wordmask)); 12.248 + changed(); 12.249 + currentState = BitsState.NORMAL; 12.250 } 12.251 12.252 /** Is x an element of this set? 12.253 */ 12.254 public boolean isMember(int x) { 12.255 + Assert.check(currentState != BitsState.UNKNOWN); 12.256 return 12.257 0 <= x && x < (bits.length << wordshift) && 12.258 (bits[x >>> wordshift] & (1 << (x & wordmask))) != 0; 12.259 @@ -130,38 +268,66 @@ 12.260 /** {@literal this set = this set & xs}. 12.261 */ 12.262 public Bits andSet(Bits xs) { 12.263 + Assert.check(currentState != BitsState.UNKNOWN); 12.264 + oldBits = bits; 12.265 + lastOperation = AND_SET; 12.266 + internalAndSet(xs); 12.267 + changed(); 12.268 + currentState = BitsState.NORMAL; 12.269 + return this; 12.270 + } 12.271 + 12.272 + private void internalAndSet(Bits xs) { 12.273 + Assert.check(currentState != BitsState.UNKNOWN); 12.274 sizeTo(xs.bits.length); 12.275 - for (int i = 0; i < xs.bits.length; i++) 12.276 + for (int i = 0; i < xs.bits.length; i++) { 12.277 bits[i] = bits[i] & xs.bits[i]; 12.278 - return this; 12.279 + } 12.280 } 12.281 12.282 /** this set = this set | xs. 12.283 */ 12.284 public Bits orSet(Bits xs) { 12.285 + Assert.check(currentState != BitsState.UNKNOWN); 12.286 + oldBits = bits; 12.287 + lastOperation = OR_SET; 12.288 sizeTo(xs.bits.length); 12.289 - for (int i = 0; i < xs.bits.length; i++) 12.290 + for (int i = 0; i < xs.bits.length; i++) { 12.291 bits[i] = bits[i] | xs.bits[i]; 12.292 + } 12.293 + changed(); 12.294 + currentState = BitsState.NORMAL; 12.295 return this; 12.296 } 12.297 12.298 /** this set = this set \ xs. 12.299 */ 12.300 public Bits diffSet(Bits xs) { 12.301 + Assert.check(currentState != BitsState.UNKNOWN); 12.302 + oldBits = bits; 12.303 + lastOperation = DIFF_SET; 12.304 for (int i = 0; i < bits.length; i++) { 12.305 if (i < xs.bits.length) { 12.306 bits[i] = bits[i] & ~xs.bits[i]; 12.307 } 12.308 } 12.309 + changed(); 12.310 + currentState = BitsState.NORMAL; 12.311 return this; 12.312 } 12.313 12.314 /** this set = this set ^ xs. 12.315 */ 12.316 public Bits xorSet(Bits xs) { 12.317 + Assert.check(currentState != BitsState.UNKNOWN); 12.318 + oldBits = bits; 12.319 + lastOperation = XOR_SET; 12.320 sizeTo(xs.bits.length); 12.321 - for (int i = 0; i < xs.bits.length; i++) 12.322 + for (int i = 0; i < xs.bits.length; i++) { 12.323 bits[i] = bits[i] ^ xs.bits[i]; 12.324 + } 12.325 + changed(); 12.326 + currentState = BitsState.NORMAL; 12.327 return this; 12.328 } 12.329 12.330 @@ -187,6 +353,7 @@ 12.331 * }</pre> 12.332 */ 12.333 public int nextBit(int x) { 12.334 + Assert.check(currentState != BitsState.UNKNOWN); 12.335 int windex = x >>> wordshift; 12.336 if (windex >= bits.length) return -1; 12.337 int word = bits[windex] & ~((1 << (x & wordmask))-1); 12.338 @@ -202,17 +369,20 @@ 12.339 /** a string representation of this set. 12.340 */ 12.341 public String toString() { 12.342 - char[] digits = new char[bits.length * wordlen]; 12.343 - for (int i = 0; i < bits.length * wordlen; i++) 12.344 - digits[i] = isMember(i) ? '1' : '0'; 12.345 - return new String(digits); 12.346 + if (bits.length > 0) { 12.347 + char[] digits = new char[bits.length * wordlen]; 12.348 + for (int i = 0; i < bits.length * wordlen; i++) 12.349 + digits[i] = isMember(i) ? '1' : '0'; 12.350 + return new String(digits); 12.351 + } else { 12.352 + return "[]"; 12.353 + } 12.354 } 12.355 12.356 /** Test Bits.nextBit(int). */ 12.357 public static void main(String[] args) { 12.358 java.util.Random r = new java.util.Random(); 12.359 Bits bits = new Bits(); 12.360 - int dupCount = 0; 12.361 for (int i=0; i<125; i++) { 12.362 int k; 12.363 do {
13.1 --- a/test/tools/javac/api/TestJavacTaskScanner.java Sun Apr 28 08:16:41 2013 +0100 13.2 +++ b/test/tools/javac/api/TestJavacTaskScanner.java Wed May 08 10:27:52 2013 +0100 13.3 @@ -1,5 +1,5 @@ 13.4 /* 13.5 - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 13.6 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 * 13.9 * This code is free software; you can redistribute it and/or modify it 13.10 @@ -93,7 +93,7 @@ 13.11 System.out.println("#allMembers: " + numAllMembers); 13.12 13.13 check(numTokens, "#Tokens", 1222); 13.14 - check(numParseTypeElements, "#parseTypeElements", 136); 13.15 + check(numParseTypeElements, "#parseTypeElements", 158); 13.16 check(numAllMembers, "#allMembers", 52); 13.17 } 13.18
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/test/tools/javac/defaultMethods/CheckACC_STRICTFlagOnDefaultMethodTest.java Wed May 08 10:27:52 2013 +0100 14.3 @@ -0,0 +1,96 @@ 14.4 +/* 14.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.7 + * 14.8 + * This code is free software; you can redistribute it and/or modify it 14.9 + * under the terms of the GNU General Public License version 2 only, as 14.10 + * published by the Free Software Foundation. Oracle designates this 14.11 + * particular file as subject to the "Classpath" exception as provided 14.12 + * by Oracle in the LICENSE file that accompanied this code. 14.13 + * 14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14.17 + * version 2 for more details (a copy is included in the LICENSE file that 14.18 + * accompanied this code). 14.19 + * 14.20 + * You should have received a copy of the GNU General Public License version 14.21 + * 2 along with this work; if not, write to the Free Software Foundation, 14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 14.23 + * 14.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 14.25 + * or visit www.oracle.com if you need additional information or have any 14.26 + * questions. 14.27 + */ 14.28 + 14.29 +/* 14.30 + * @test 14.31 + * @bug 8012723 14.32 + * @summary strictfp interface misses strictfp modifer on default method 14.33 + * @run main CheckACC_STRICTFlagOnDefaultMethodTest 14.34 + */ 14.35 + 14.36 +import java.util.ArrayList; 14.37 +import java.util.List; 14.38 +import java.io.File; 14.39 +import java.io.IOException; 14.40 + 14.41 +import com.sun.tools.classfile.ClassFile; 14.42 +import com.sun.tools.classfile.ConstantPoolException; 14.43 +import com.sun.tools.classfile.Descriptor; 14.44 +import com.sun.tools.classfile.Descriptor.InvalidDescriptor; 14.45 +import com.sun.tools.classfile.Method; 14.46 + 14.47 +import static com.sun.tools.classfile.AccessFlags.ACC_STRICT; 14.48 + 14.49 +public class CheckACC_STRICTFlagOnDefaultMethodTest { 14.50 + private static final String AssertionErrorMessage = 14.51 + "All methods should have the ACC_STRICT access flag " + 14.52 + "please check output"; 14.53 + private static final String offendingMethodErrorMessage = 14.54 + "Method %s of class %s doesn't have the ACC_STRICT access flag"; 14.55 + 14.56 + private List<String> errors = new ArrayList<>(); 14.57 + 14.58 + public static void main(String[] args) 14.59 + throws IOException, ConstantPoolException, InvalidDescriptor { 14.60 + new CheckACC_STRICTFlagOnDefaultMethodTest().run(); 14.61 + } 14.62 + 14.63 + private void run() 14.64 + throws IOException, ConstantPoolException, InvalidDescriptor { 14.65 + String testClasses = System.getProperty("test.classes"); 14.66 + check(testClasses, 14.67 + "CheckACC_STRICTFlagOnDefaultMethodTest$StrictfpInterface.class"); 14.68 + if (errors.size() > 0) { 14.69 + for (String error: errors) { 14.70 + System.err.println(error); 14.71 + } 14.72 + throw new AssertionError(AssertionErrorMessage); 14.73 + } 14.74 + } 14.75 + 14.76 + void check(String dir, String... fileNames) 14.77 + throws 14.78 + IOException, 14.79 + ConstantPoolException, 14.80 + Descriptor.InvalidDescriptor { 14.81 + for (String fileName : fileNames) { 14.82 + ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); 14.83 + 14.84 + for (Method method : classFileToCheck.methods) { 14.85 + if ((method.access_flags.flags & ACC_STRICT) == 0) { 14.86 + errors.add(String.format(offendingMethodErrorMessage, 14.87 + method.getName(classFileToCheck.constant_pool), 14.88 + classFileToCheck.getName())); 14.89 + } 14.90 + } 14.91 + } 14.92 + } 14.93 + 14.94 + strictfp interface StrictfpInterface { 14.95 + default void default_interface_method() {} 14.96 + static void static_interface_method() {} 14.97 + } 14.98 + 14.99 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestNewInnerImplicitArgs.java Wed May 08 10:27:52 2013 +0100 15.3 @@ -0,0 +1,82 @@ 15.4 +/* 15.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.7 + * 15.8 + * This code is free software; you can redistribute it and/or modify it 15.9 + * under the terms of the GNU General Public License version 2 only, as 15.10 + * published by the Free Software Foundation. Oracle designates this 15.11 + * particular file as subject to the "Classpath" exception as provided 15.12 + * by Oracle in the LICENSE file that accompanied this code. 15.13 + * 15.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 15.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15.17 + * version 2 for more details (a copy is included in the LICENSE file that 15.18 + * accompanied this code). 15.19 + * 15.20 + * You should have received a copy of the GNU General Public License version 15.21 + * 2 along with this work; if not, write to the Free Software Foundation, 15.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 15.23 + * 15.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 15.25 + * or visit www.oracle.com if you need additional information or have any 15.26 + * questions. 15.27 + */ 15.28 + 15.29 +/** 15.30 + * @test 15.31 + * @bug 8011591 15.32 + * @summary BootstrapMethodError when capturing constructor ref to local classes 15.33 + * @run testng MethodReferenceTestNewInnerImplicitArgs 15.34 + */ 15.35 + 15.36 +import org.testng.annotations.Test; 15.37 + 15.38 +import static org.testng.Assert.assertEquals; 15.39 + 15.40 +/** 15.41 + * Test the case that a constructor has implicit parameters added to 15.42 + * access local variables and that this constructor is used in a 15.43 + * method reference. 15.44 + * @author Robert Field 15.45 + */ 15.46 + 15.47 +@Test 15.48 +public class MethodReferenceTestNewInnerImplicitArgs { 15.49 + 15.50 + 15.51 + static class S { 15.52 + String b; 15.53 + S(String s, String s2) { b = s + s2; } 15.54 + } 15.55 + 15.56 + interface I { 15.57 + S m(); 15.58 + } 15.59 + 15.60 + interface I2 { 15.61 + S m(int i, int j); 15.62 + } 15.63 + 15.64 + public static void testConstructorReferenceImplicitParameters() { 15.65 + String title = "Hey"; 15.66 + String a2 = "!!!"; 15.67 + class MS extends S { 15.68 + MS() { 15.69 + super(title, a2); 15.70 + } 15.71 + } 15.72 + 15.73 + I result = MS::new; 15.74 + assertEquals(result.m().b, "Hey!!!"); 15.75 + 15.76 + class MS2 extends S { 15.77 + MS2(int x, int y) { 15.78 + super(title+x, a2+y); 15.79 + } 15.80 + } 15.81 + 15.82 + I2 result2 = MS2::new; 15.83 + assertEquals(result2.m(8, 4).b, "Hey8!!!4"); 15.84 + } 15.85 +}