OpenJDK / portola / portola
changeset 20543:298a19a1a1f6
Merge
author | lana |
---|---|
date | Fri, 11 Oct 2013 03:06:10 -0700 |
parents | 351f3c15b63e a7dcd7811f02 |
children | 8518304d2097 5b63cde6a6a1 a6cbbedabed7 a1e6716bbcbe |
files | jdk/makefiles/CreateJars.gmk jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java jdk/src/share/classes/java/time/chrono/ChronoDateImpl.java jdk/test/java/time/tck/java/time/chrono/TCKChronologySerialization.java |
diffstat | 699 files changed, 17970 insertions(+), 5782 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/make/docs/Makefile Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/make/docs/Makefile Fri Oct 11 03:06:10 2013 -0700 @@ -50,6 +50,7 @@ DEV_DOCS_URL-5 = http://java.sun.com/j2se/1.5.0/docs/index.html DEV_DOCS_URL-6 = http://download.oracle.com/javase/6/docs/index.html DEV_DOCS_URL-7 = http://download.oracle.com/javase/7/docs/index.html +DEV_DOCS_URL-8 = http://download.oracle.com/javase/8/docs/index.html DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION)) DOCS_BASE_URL = http://download.oracle.com/javase/7/docs
--- a/jdk/make/java/java/FILES_c.gmk Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/make/java/java/FILES_c.gmk Fri Oct 11 03:06:10 2013 -0700 @@ -33,6 +33,7 @@ Console_md.c \ Double.c \ Executable.c \ + Field.c \ FileDescriptor_md.c \ FileInputStream.c \ FileInputStream_md.c \
--- a/jdk/make/java/java/mapfile-vers Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/make/java/java/mapfile-vers Fri Oct 11 03:06:10 2013 -0700 @@ -190,6 +190,8 @@ Java_java_lang_reflect_Array_setLong; Java_java_lang_reflect_Array_setShort; Java_java_lang_reflect_Executable_getParameters0; + Java_java_lang_reflect_Executable_getTypeAnnotationBytes0; + Java_java_lang_reflect_Field_getTypeAnnotationBytes0; Java_java_lang_Runtime_freeMemory; Java_java_lang_Runtime_maxMemory; Java_java_lang_Runtime_gc;
--- a/jdk/make/netbeans/common/java-data-native.ent Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/make/netbeans/common/java-data-native.ent Fri Oct 11 03:06:10 2013 -0700 @@ -31,14 +31,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> -<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3"> +<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4"> <compilation-unit> <package-root>${root}/src/share/classes</package-root> <package-root>${root}/src/macosx/classes</package-root> <package-root>${root}/src/solaris/classes</package-root> <package-root>${root}/src/windows/classes</package-root> <classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath> - <built-to>${root}/build/${platform}-${arch}/classes</built-to> + <built-to>${root}/../build/${platform}-${arch}/jdk/classes</built-to> <javadoc-built-to>${root}/build/${platform}-${arch}/docs/api</javadoc-built-to> <source-level>1.8</source-level> </compilation-unit>
--- a/jdk/make/netbeans/common/java-data-no-native.ent Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/make/netbeans/common/java-data-no-native.ent Fri Oct 11 03:06:10 2013 -0700 @@ -31,11 +31,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> -<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/3"> +<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4"> <compilation-unit> <package-root>${root}/src/share/classes</package-root> <classpath mode="boot">${bootstrap.jdk}/jre/lib/rt.jar</classpath> - <built-to>${root}/build/${platform}-${arch}/classes</built-to> + <built-to>${root}/../build/${platform}-${arch}/jdk/classes</built-to> <javadoc-built-to>${root}/build/${platform}-${arch}/docs/api</javadoc-built-to> <source-level>1.8</source-level> </compilation-unit>
--- a/jdk/make/tools/src/build/tools/buildmetaindex/BuildMetaIndex.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/make/tools/src/build/tools/buildmetaindex/BuildMetaIndex.java Fri Oct 11 03:06:10 2013 -0700 @@ -174,6 +174,44 @@ private HashMap<String, HashSet<String>> knownPrefixMap = new HashMap<>(); /* + * A class for mapping package prefixes to the number of + * levels of package elements to include. + */ + static class ExtraLevel { + public ExtraLevel(String prefix, int levels) { + this.prefix = prefix; + this.levels = levels; + } + String prefix; + int levels; + } + + /* + * A list of the special-cased package names. + */ + private static ArrayList<ExtraLevel> extraLevels = new ArrayList<>(); + + static { + // The order of these statements is significant, + // since we stop looking after the first match. + + // Need more precise information to disambiguate + // (illegal) references from applications to + // obsolete backported collections classes in + // com/sun/java/util + extraLevels.add(new ExtraLevel("com/sun/java/util/", Integer.MAX_VALUE)); + extraLevels.add(new ExtraLevel("com/sun/java/", 4)); + // Need more information than just first two package + // name elements to determine that classes in + // deploy.jar are not in rt.jar + extraLevels.add(new ExtraLevel("com/sun/", 3)); + // Need to make sure things in jfr.jar aren't + // confused with other com/oracle/** packages + extraLevels.add(new ExtraLevel("com/oracle/jrockit", 3)); + } + + + /* * We add maximum 5 second level entries to "sun", "java" and * "javax" entries. Tune this parameter to get a balance on the * cold start and footprint. @@ -237,39 +275,25 @@ String[] pkgElements = name.split("/"); // Last one is the class name; definitely ignoring that if (pkgElements.length > 2) { - String meta = null; - // Need more information than just first two package - // name elements to determine that classes in - // deploy.jar are not in rt.jar - if (pkgElements.length > 3 && - pkgElements[0].equals("com") && - pkgElements[1].equals("sun")) { - // Need more precise information to disambiguate - // (illegal) references from applications to - // obsolete backported collections classes in - // com/sun/java/util - if (pkgElements.length > 4 && - pkgElements[2].equals("java")) { - int bound = 0; - if (pkgElements[3].equals("util")) { - // Take all of the packages - bound = pkgElements.length - 1; - } else { - // Trim it somewhat more - bound = 4; - } - meta = ""; - for (int j = 0; j < bound; j++) { - meta += pkgElements[j] + "/"; - } - } else { - meta = pkgElements[0] + "/" + pkgElements[1] - + "/" + pkgElements[2] + "/"; + String meta = ""; + + // Default is 2 levels of package elements + int levels = 2; + + // But for some packages we add more elements + for(ExtraLevel el : extraLevels) { + if (name.startsWith(el.prefix)) { + levels = el.levels; + break; } - } else { - meta = pkgElements[0] + "/" + pkgElements[1] + "/"; + } + for (int i = 0; i < levels && i < pkgElements.length - 1; i++) { + meta += pkgElements[i] + "/"; } - indexSet.add(meta); + + if (!meta.equals("")) { + indexSet.add(meta); + } } } // end of "while" loop;
--- a/jdk/makefiles/CompileJavaClasses.gmk Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/makefiles/CompileJavaClasses.gmk Fri Oct 11 03:06:10 2013 -0700 @@ -237,10 +237,10 @@ # These files do not appear in the build result of the old build. This # is because they are generated sources, but the AUTO_JAVA_FILES won't -# pick them up since they aren't generated when the source dirs are +# pick them up since they aren't generated when the source dirs are # searched and they aren't referenced by any other classes so they won't # be picked up by implicit compilation. On a rebuild, they are picked up -# and compiled. Exclude them here to produce the same rt.jar as the old +# and compiled. Exclude them here to produce the same rt.jar as the old # build does when building just once. EXFILES+=javax/swing/plaf/nimbus/InternalFrameTitlePanePainter.java \ javax/swing/plaf/nimbus/OptionPaneMessageAreaPainter.java \ @@ -308,19 +308,6 @@ ########################################################################################## -ifndef OPENJDK - - $(eval $(call SetupJavaCompilation,BUILD_ALTCLASSES,\ - SETUP:=GENERATE_JDKBYTECODE,\ - SRC:=$(JDK_TOPDIR)/src/closed/share/altclasses, \ - BIN:=$(JDK_OUTPUTDIR)/altclasses_classes)) - - $(BUILD_ALTCLASSES): $(BUILD_JDK) - -endif - -########################################################################################## - $(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin: $(MKDIR) -p $(@D) $(TOUCH) $@ @@ -403,7 +390,7 @@ ########################################################################################## -all: $(BUILD_JDK) $(BUILD_ALTCLASSES) $(BUILD_JOBJC) $(BUILD_JOBJC_HEADERS) $(COPY_EXTRA) \ +all: $(BUILD_JDK) $(BUILD_JOBJC) $(BUILD_JOBJC_HEADERS) $(COPY_EXTRA) \ $(JDK_OUTPUTDIR)/classes/META-INF/services/com.sun.tools.xjc.Plugin \ $(BUILD_ACCESSBRIDGE_32) $(BUILD_ACCESSBRIDGE_64) \ $(BUILD_ACCESSBRIDGE_LEGACY)
--- a/jdk/makefiles/CreateJars.gmk Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/makefiles/CreateJars.gmk Fri Oct 11 03:06:10 2013 -0700 @@ -990,15 +990,6 @@ ########################################################################################## -ifndef OPENJDK - $(eval $(call SetupArchive,BUILD_ALT_RT_JAR,,\ - SRCS:=$(JDK_OUTPUTDIR)/altclasses_classes,\ - JAR:=$(IMAGES_OUTPUTDIR)/lib/alt-rt.jar)) - -endif - -########################################################################################## - # This file is imported from hotspot in Import.gmk. Copying it into images/lib so that # all jars can be found in one place when creating images in Images.gmk. It needs to be # done here so that clean targets can be simple and accurate.
--- a/jdk/makefiles/Profiles.gmk Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/makefiles/Profiles.gmk Fri Oct 11 03:06:10 2013 -0700 @@ -40,8 +40,8 @@ # imported (signed jars) rather than built. # # The incoming lists, eg PROFILE_1_JRE_JARS_FILES, are the jars to be -# included in this profile. They have the jar name relative to the lib -# directory. We have to turn these into targets by adding the +# included in this profile. They have the jar name relative to the lib +# directory. We have to turn these into targets by adding the # $(IMAGES_OUTPUTDIR)/lib prefix # # Note that some jars may be optional depending on the type of build (jdk vs. @@ -69,10 +69,6 @@ $(addprefix $(IMAGES_OUTPUTDIR)/lib/, $(PROFILE_3_JRE_JAR_FILES)) \ $(PROFILE_2_JARS) -ifdef OPENJDK - FULL_JRE_JAR_FILES := $(filter-out alt-rt.jar, $(FULL_JRE_JAR_FILES)) -endif - ifneq ($(ENABLE_JFR), true) FULL_JRE_JAR_FILES := $(filter-out jfr.jar, $(FULL_JRE_JAR_FILES)) endif @@ -107,7 +103,7 @@ ifeq ($(OPENJDK_TARGET_OS),windows) ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/ext/sunmscapi.jar -endif +endif ifeq ($(OPENJDK_TARGET_OS),macosx) ALL_JARS += $(IMAGES_OUTPUTDIR)/lib/JObjC.jar @@ -142,7 +138,7 @@ $(PROFILE_1_JRE_BIN_FILES) \ $(PROFILE_2_JRE_BIN_FILES) \ $(PROFILE_3_JRE_BIN_FILES) \ - $(FULL_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) NOT_JRE_BIN_FILES := $(filter-out $(ALL_JRE_BIN_FILES), $(NEW_ALL_BIN_LIST)) @@ -151,18 +147,18 @@ NOT_JRE_BIN_FILES += \ $(PROFILE_2_JRE_BIN_FILES) \ $(PROFILE_3_JRE_BIN_FILES) \ - $(FULL_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif ifeq ($(PROFILE), profile_2) NOT_JRE_BIN_FILES += \ $(PROFILE_3_JRE_BIN_FILES) \ - $(FULL_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif ifeq ($(PROFILE), profile_3) NOT_JRE_BIN_FILES += \ - $(FULL_JRE_BIN_FILES) + $(FULL_JRE_BIN_FILES) endif NOT_JRE_BIN_FILES := $(addprefix $(JDK_OUTPUTDIR)/bin/, $(NOT_JRE_BIN_FILES)) @@ -175,7 +171,7 @@ $(PROFILE_1_JRE_LIB_FILES) \ $(PROFILE_2_JRE_LIB_FILES) \ $(PROFILE_3_JRE_LIB_FILES) \ - $(FULL_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) NOT_JRE_LIB_FILES := $(filter-out $(ALL_JRE_LIB_FILES), $(NEW_ALL_LIB_LIST)) @@ -191,18 +187,18 @@ NOT_JRE_LIB_FILES += \ $(PROFILE_2_JRE_LIB_FILES) \ $(PROFILE_3_JRE_LIB_FILES) \ - $(FULL_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif ifeq ($(PROFILE), profile_2) NOT_JRE_LIB_FILES += \ $(PROFILE_3_JRE_LIB_FILES) \ - $(FULL_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif ifeq ($(PROFILE), profile_3) NOT_JRE_LIB_FILES += \ - $(FULL_JRE_LIB_FILES) + $(FULL_JRE_LIB_FILES) endif # Exclude the custom jar files as these will be added back via a special rule @@ -210,7 +206,7 @@ ############################################################################### # Customization of rt.jar file contents -# These are expressed as exclusions from everything found in the +# These are expressed as exclusions from everything found in the # JDK_OUTPUTDIR/classes directory ############################################################################### @@ -231,8 +227,8 @@ # # These are specific types that must be included within a package. # There are two cases: -# - individual types in a package that is otherwise excluded at this -# profile level. The only arises if there are split packages. +# - individual types in a package that is otherwise excluded at this +# profile level. The only arises if there are split packages. # # - A higher-level package is included in a high profile where a subpackage # is included in a lower profile. Including the package in the high profile @@ -247,7 +243,7 @@ # containing package is include. Again this occurs with split packges. # # So the exclude list for each profile consists of the include lists -# for all profiles above it, together with any explicitly excluded types. +# for all profiles above it, together with any explicitly excluded types. # This is then combined with the overall RT_JAR_EXCLUDES list (which covers # things that go into other jar files). # @@ -257,7 +253,7 @@ # profile 3 includes the entire package, but it is harmless to add them # explicitly, and complex to determine if we still need to include them. # -# Need a way to express: +# Need a way to express: # for (int i = profile+1; i < 4; i++) # RT_JAR_EXCLUDES += PROFILE_$i_RTJAR_INCLUDE_PACKAGES # @@ -267,7 +263,7 @@ # # These are META-INF/services/ entries found in resources.jar. Together # resources.jar and rt.jar hold the contents of the classes directory, (the -# classes in rt.jar and everything else in resources.jar).Hence the +# classes in rt.jar and everything else in resources.jar).Hence the # include/exclude information for resources.jar is tied to that of rt.jar include profile-rtjar-includes.txt @@ -324,7 +320,7 @@ # Filter out non-OpenJDK services ifdef OPENJDK - EXCLUDED_SERVICES := META-INF/services/javax.script.ScriptEngineFactory + EXCLUDED_SERVICES := META-INF/services/javax.script.ScriptEngineFactory PROFILE_INCLUDE_METAINF_SERVICES := $(filter-out $(EXCLUDED_SERVICES),$(PROFILE_INCLUDE_METAINF_SERVICES)) endif
--- a/jdk/makefiles/mapfiles/libjava/mapfile-vers Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/makefiles/mapfiles/libjava/mapfile-vers Fri Oct 11 03:06:10 2013 -0700 @@ -190,6 +190,8 @@ Java_java_lang_reflect_Array_setLong; Java_java_lang_reflect_Array_setShort; Java_java_lang_reflect_Executable_getParameters0; + Java_java_lang_reflect_Executable_getTypeAnnotationBytes0; + Java_java_lang_reflect_Field_getTypeAnnotationBytes0; Java_java_lang_Runtime_freeMemory; Java_java_lang_Runtime_maxMemory; Java_java_lang_Runtime_gc;
--- a/jdk/makefiles/profile-includes.txt Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/makefiles/profile-includes.txt Fri Oct 11 03:06:10 2013 -0700 @@ -107,14 +107,14 @@ rmid$(EXE_SUFFIX) \ rmiregistry$(EXE_SUFFIX) -PROFILE_2_JRE_LIB_FILES := +PROFILE_2_JRE_LIB_FILES := -PROFILE_2_JRE_OTHER_FILES := +PROFILE_2_JRE_OTHER_FILES := -PROFILE_2_JRE_JAR_FILES := +PROFILE_2_JRE_JAR_FILES := -PROFILE_3_JRE_BIN_FILES := +PROFILE_3_JRE_BIN_FILES := PROFILE_3_JRE_LIB_FILES := \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)hprof$(SHARED_LIBRARY_SUFFIX) \ @@ -138,7 +138,7 @@ management/management.properties \ management/snmp.acl.template -PROFILE_3_JRE_OTHER_FILES := +PROFILE_3_JRE_OTHER_FILES := PROFILE_3_JRE_JAR_FILES := \ management-agent.jar @@ -171,7 +171,6 @@ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)splashscreen$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \ - alt-rt.jar \ charsets.jar \ cmm/CIEXYZ.pf \ cmm/GRAY.pf \ @@ -248,7 +247,6 @@ man/man1/unpack200.1 FULL_JRE_JAR_FILES := \ - alt-rt.jar \ charsets.jar \ ext/cldrdata.jar \ ext/dnsns.jar \
--- a/jdk/src/macosx/classes/apple/applescript/AppleScriptEngine.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/apple/applescript/AppleScriptEngine.java Fri Oct 11 03:06:10 2013 -0700 @@ -155,7 +155,7 @@ TRACE("init()"); // set up our context /* TODO -- name of current executable? bad java documentation at: - * http://java.sun.com/javase/6/docs/api/javax/script/ScriptEngine.html#FILENAME */ + * http://docs.oracle.com/javase/6/docs/api/javax/script/ScriptEngine.html#FILENAME */ put(ScriptEngine.FILENAME, ""); put(ScriptEngine.ENGINE, getEngine()); put(ScriptEngine.ENGINE_VERSION, getEngineVersion());
--- a/jdk/src/macosx/classes/apple/security/AppleProvider.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/apple/security/AppleProvider.java Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -43,7 +43,7 @@ public AppleProvider() { /* We are the Apple provider */ - super("Apple", 1.1, info); + super("Apple", 1.8d, info); AccessController.<Object>doPrivileged(new java.security.PrivilegedAction<Object>() { public Object run() {
--- a/jdk/src/macosx/classes/com/apple/eawt/_AppEventLegacyHandler.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/com/apple/eawt/_AppEventLegacyHandler.java Fri Oct 11 03:06:10 2013 -0700 @@ -31,10 +31,6 @@ import com.apple.eawt.AppEvent.*; -interface _OpenAppHandler { - void handleOpenApp(); -} - @SuppressWarnings("deprecation") class _AppEventLegacyHandler implements AboutHandler, PreferencesHandler, _OpenAppHandler, AppReOpenedListener, OpenFilesHandler, PrintFilesHandler, QuitHandler { final _AppEventHandler parent;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/macosx/classes/com/apple/eawt/_OpenAppHandler.java Fri Oct 11 03:06:10 2013 -0700 @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2011, 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.apple.eawt; + +interface _OpenAppHandler { + void handleOpenApp(); +} \ No newline at end of file
--- a/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxRenderer.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxRenderer.java Fri Oct 11 03:06:10 2013 -0700 @@ -25,141 +25,11 @@ package com.apple.laf; -import java.awt.*; - import javax.swing.*; import javax.swing.plaf.UIResource; -import sun.swing.SwingUtilities2; - class AquaComboBoxRenderer extends AquaComboBoxRendererInternal implements UIResource { public AquaComboBoxRenderer(final JComboBox comboBox) { super(comboBox); } } - -class AquaComboBoxRendererInternal extends JLabel implements ListCellRenderer { - final JComboBox fComboBox; - boolean fSelected; - boolean fChecked; - boolean fInList; - boolean fEditable; - boolean fDrawCheckedItem = true; - - // Provides space for a checkbox, and is translucent - public AquaComboBoxRendererInternal(final JComboBox comboBox) { - super(); - fComboBox = comboBox; - } - - // Don't include checkIcon space, because this is also used for button size calculations - // - the popup-size calc will get checkIcon space from getInsets - public Dimension getPreferredSize() { - // From BasicComboBoxRenderer - trick to avoid zero-height items - final Dimension size; - - final String text = getText(); - if ((text == null) || ("".equals(text))) { - setText(" "); - size = super.getPreferredSize(); - setText(""); - } else { - size = super.getPreferredSize(); - } - return size; - } - - // Don't paint the border here, it gets painted by the UI - protected void paintBorder(final Graphics g) { - - } - - public int getBaseline(int width, int height) { - return super.getBaseline(width, height) - 1; - } - - // Really means is the one with the mouse over it - public Component getListCellRendererComponent(final JList list, final Object value, int index, final boolean isSelected, final boolean cellHasFocus) { - fInList = (index >= 0); // When the button wants the item painted, it passes in -1 - fSelected = isSelected; - if (index < 0) { - index = fComboBox.getSelectedIndex(); - } - - // changed this to not ask for selected index but directly compare the current item and selected item - // different from basic because basic has no concept of checked, just has the last one selected, - // and the user changes selection. We have selection and a check mark. - // we used to call fComboBox.getSelectedIndex which ends up being a very bad call for large checkboxes - // it does a linear compare of every object in the checkbox until it finds the selected one, so if - // we have a 5000 element list we will 5000 * (selected index) .equals() of objects. - // See Radar #3141307 - - // Fix for Radar # 3204287 where we ask for an item at a negative index! - if (index >= 0) { - final Object item = fComboBox.getItemAt(index); - fChecked = fInList && item != null && item.equals(fComboBox.getSelectedItem()); - } else { - fChecked = false; - } - - fEditable = fComboBox.isEditable(); - if (isSelected) { - if (fEditable) { - setBackground(UIManager.getColor("List.selectionBackground")); - setForeground(UIManager.getColor("List.selectionForeground")); - } else { - setBackground(list.getSelectionBackground()); - setForeground(list.getSelectionForeground()); - } - } else { - if (fEditable) { - setBackground(UIManager.getColor("List.background")); - setForeground(UIManager.getColor("List.foreground")); - } else { - setBackground(list.getBackground()); - setForeground(list.getForeground()); - } - } - - setFont(list.getFont()); - - if (value instanceof Icon) { - setIcon((Icon)value); - } else { - setText((value == null) ? " " : value.toString()); - } - return this; - } - - public Insets getInsets(Insets insets) { - if (insets == null) insets = new Insets(0, 0, 0, 0); - insets.top = 1; - insets.bottom = 1; - insets.right = 5; - insets.left = (fInList && !fEditable ? 16 + 7 : 5); - return insets; - } - - protected void setDrawCheckedItem(final boolean drawCheckedItem) { - this.fDrawCheckedItem = drawCheckedItem; - } - - // Paint this component, and a checkbox if it's the selected item and not in the button - protected void paintComponent(final Graphics g) { - if (fInList) { - if (fSelected && !fEditable) { - AquaMenuPainter.instance().paintSelectedMenuItemBackground(g, getWidth(), getHeight()); - } else { - g.setColor(getBackground()); - g.fillRect(0, 0, getWidth(), getHeight()); - } - - if (fChecked && !fEditable && fDrawCheckedItem) { - final int y = getHeight() - 4; - g.setColor(getForeground()); - SwingUtilities2.drawString(fComboBox, g, "\u2713", 6, y); - } - } - super.paintComponent(g); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxRendererInternal.java Fri Oct 11 03:06:10 2013 -0700 @@ -0,0 +1,157 @@ +/* + * 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.apple.laf; + +import sun.swing.SwingUtilities2; + +import javax.swing.*; +import java.awt.*; + +class AquaComboBoxRendererInternal extends JLabel implements ListCellRenderer { + final JComboBox fComboBox; + boolean fSelected; + boolean fChecked; + boolean fInList; + boolean fEditable; + boolean fDrawCheckedItem = true; + + // Provides space for a checkbox, and is translucent + public AquaComboBoxRendererInternal(final JComboBox comboBox) { + super(); + fComboBox = comboBox; + } + + // Don't include checkIcon space, because this is also used for button size calculations + // - the popup-size calc will get checkIcon space from getInsets + public Dimension getPreferredSize() { + // From BasicComboBoxRenderer - trick to avoid zero-height items + final Dimension size; + + final String text = getText(); + if ((text == null) || ("".equals(text))) { + setText(" "); + size = super.getPreferredSize(); + setText(""); + } else { + size = super.getPreferredSize(); + } + return size; + } + + // Don't paint the border here, it gets painted by the UI + protected void paintBorder(final Graphics g) { + + } + + public int getBaseline(int width, int height) { + return super.getBaseline(width, height) - 1; + } + + // Really means is the one with the mouse over it + public Component getListCellRendererComponent(final JList list, final Object value, int index, final boolean isSelected, final boolean cellHasFocus) { + fInList = (index >= 0); // When the button wants the item painted, it passes in -1 + fSelected = isSelected; + if (index < 0) { + index = fComboBox.getSelectedIndex(); + } + + // changed this to not ask for selected index but directly compare the current item and selected item + // different from basic because basic has no concept of checked, just has the last one selected, + // and the user changes selection. We have selection and a check mark. + // we used to call fComboBox.getSelectedIndex which ends up being a very bad call for large checkboxes + // it does a linear compare of every object in the checkbox until it finds the selected one, so if + // we have a 5000 element list we will 5000 * (selected index) .equals() of objects. + // See Radar #3141307 + + // Fix for Radar # 3204287 where we ask for an item at a negative index! + if (index >= 0) { + final Object item = fComboBox.getItemAt(index); + fChecked = fInList && item != null && item.equals(fComboBox.getSelectedItem()); + } else { + fChecked = false; + } + + fEditable = fComboBox.isEditable(); + if (isSelected) { + if (fEditable) { + setBackground(UIManager.getColor("List.selectionBackground")); + setForeground(UIManager.getColor("List.selectionForeground")); + } else { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } + } else { + if (fEditable) { + setBackground(UIManager.getColor("List.background")); + setForeground(UIManager.getColor("List.foreground")); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + } + + setFont(list.getFont()); + + if (value instanceof Icon) { + setIcon((Icon)value); + } else { + setText((value == null) ? " " : value.toString()); + } + return this; + } + + public Insets getInsets(Insets insets) { + if (insets == null) insets = new Insets(0, 0, 0, 0); + insets.top = 1; + insets.bottom = 1; + insets.right = 5; + insets.left = (fInList && !fEditable ? 16 + 7 : 5); + return insets; + } + + protected void setDrawCheckedItem(final boolean drawCheckedItem) { + this.fDrawCheckedItem = drawCheckedItem; + } + + // Paint this component, and a checkbox if it's the selected item and not in the button + protected void paintComponent(final Graphics g) { + if (fInList) { + if (fSelected && !fEditable) { + AquaMenuPainter.instance().paintSelectedMenuItemBackground(g, getWidth(), getHeight()); + } else { + g.setColor(getBackground()); + g.fillRect(0, 0, getWidth(), getHeight()); + } + + if (fChecked && !fEditable && fDrawCheckedItem) { + final int y = getHeight() - 4; + g.setColor(getForeground()); + SwingUtilities2.drawString(fComboBox, g, "\u2713", 6, y); + } + } + super.paintComponent(g); + } +}
--- a/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/com/apple/laf/AquaComboBoxUI.java Fri Oct 11 03:06:10 2013 -0700 @@ -281,12 +281,16 @@ actionMap.put("aquaSelectPageUp", highlightPageUpAction); actionMap.put("aquaSelectPageDown", highlightPageDownAction); + actionMap.put("aquaHidePopup", hideAction); + SwingUtilities.replaceUIActionMap(comboBox, actionMap); } - abstract class ComboBoxAction extends AbstractAction { + private abstract class ComboBoxAction extends AbstractAction { public void actionPerformed(final ActionEvent e) { - if (!comboBox.isEnabled() || !comboBox.isShowing()) return; + if (!comboBox.isEnabled() || !comboBox.isShowing()) { + return; + } if (comboBox.isPopupVisible()) { final AquaComboBoxUI ui = (AquaComboBoxUI)comboBox.getUI(); @@ -302,7 +306,7 @@ /** * Hilight _but do not select_ the next item in the list. */ - Action highlightNextAction = new ComboBoxAction() { + private Action highlightNextAction = new ComboBoxAction() { @Override public void performComboBoxAction(AquaComboBoxUI ui) { final int si = listBox.getSelectedIndex(); @@ -318,7 +322,7 @@ /** * Hilight _but do not select_ the previous item in the list. */ - Action highlightPreviousAction = new ComboBoxAction() { + private Action highlightPreviousAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { final int si = listBox.getSelectedIndex(); @@ -330,7 +334,7 @@ } }; - Action highlightFirstAction = new ComboBoxAction() { + private Action highlightFirstAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { listBox.setSelectedIndex(0); @@ -338,7 +342,7 @@ } }; - Action highlightLastAction = new ComboBoxAction() { + private Action highlightLastAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { final int size = listBox.getModel().getSize(); @@ -347,7 +351,7 @@ } }; - Action highlightPageUpAction = new ComboBoxAction() { + private Action highlightPageUpAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { final int current = listBox.getSelectedIndex(); @@ -367,7 +371,7 @@ } }; - Action highlightPageDownAction = new ComboBoxAction() { + private Action highlightPageDownAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { final int current = listBox.getSelectedIndex(); @@ -482,13 +486,13 @@ // This is somewhat messy. The difference here from BasicComboBoxUI.EnterAction is that // arrow up or down does not automatically select the - static final Action triggerSelectionAction = new AbstractAction() { + private static final Action triggerSelectionAction = new AbstractAction() { public void actionPerformed(final ActionEvent e) { triggerSelectionEvent((JComboBox)e.getSource(), e); } }; - static final Action toggleSelectionAction = new AbstractAction() { + private static final Action toggleSelectionAction = new AbstractAction() { public void actionPerformed(final ActionEvent e) { final JComboBox comboBox = (JComboBox)e.getSource(); if (!comboBox.isEnabled()) return; @@ -506,6 +510,18 @@ } }; + private static Action hideAction = new AbstractAction() { + @Override + public void actionPerformed(final ActionEvent e) { + final JComboBox comboBox = (JComboBox)e.getSource(); + + if (comboBox.isPopupVisible()) { + comboBox.firePopupMenuCanceled(); + comboBox.setPopupVisible(false); + } + } + }; + public void applySizeFor(final JComponent c, final Size size) { if (arrowButton == null) return; final Border border = arrowButton.getBorder();
--- a/jdk/src/macosx/classes/com/apple/laf/AquaKeyBindings.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/com/apple/laf/AquaKeyBindings.java Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -209,7 +209,7 @@ LateBoundInputMap getComboBoxInputMap() { return new LateBoundInputMap(new SimpleBinding(new String[] { - "ESCAPE", "hidePopup", + "ESCAPE", "aquaHidePopup", "PAGE_UP", "aquaSelectPageUp", "PAGE_DOWN", "aquaSelectPageDown", "HOME", "aquaSelectHome",
--- a/jdk/src/macosx/classes/com/apple/laf/AquaMenuBarUI.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/com/apple/laf/AquaMenuBarUI.java Fri Oct 11 03:06:10 2013 -0700 @@ -73,8 +73,9 @@ public Dimension getPreferredSize(final JComponent c) { if (isScreenMenuBar((JMenuBar)c)) { - if (setScreenMenuBar((JFrame)(c.getTopLevelAncestor()))) ; - return new Dimension(0, 0); + if (setScreenMenuBar((JFrame)(c.getTopLevelAncestor()))) { + return new Dimension(0, 0); + } } return null; }
--- a/jdk/src/macosx/classes/sun/awt/CGraphicsEnvironment.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/sun/awt/CGraphicsEnvironment.java Fri Oct 11 03:06:10 2013 -0700 @@ -181,6 +181,9 @@ initDevices(); d = devices.get(mainDisplayID); + if (d == null) { + throw new AWTError("no screen devices"); + } } return d; }
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Fri Oct 11 03:06:10 2013 -0700 @@ -385,11 +385,6 @@ // ---- PEER METHODS ---- // - @Override - public Toolkit getToolkit() { - return LWToolkit.getLWToolkit(); - } - // Just a helper method public LWToolkit getLWToolkit() { return LWToolkit.getLWToolkit(); @@ -1010,13 +1005,13 @@ @Override public boolean prepareImage(Image img, int w, int h, ImageObserver o) { // TODO: is it a right/complete implementation? - return getToolkit().prepareImage(img, w, h, o); + return Toolkit.getDefaultToolkit().prepareImage(img, w, h, o); } @Override public int checkImage(Image img, int w, int h, ImageObserver o) { // TODO: is it a right/complete implementation? - return getToolkit().checkImage(img, w, h, o); + return Toolkit.getDefaultToolkit().checkImage(img, w, h, o); } @Override
--- a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java Fri Oct 11 03:06:10 2013 -0700 @@ -71,13 +71,14 @@ } setEditable(getTarget().isEditable()); setText(getTarget().getText()); + setCaretPosition(getTarget().getCaretPosition()); getTarget().addInputMethodListener(this); final int start = getTarget().getSelectionStart(); final int end = getTarget().getSelectionEnd(); if (end > start) { + // Should be called after setText() and setCaretPosition() select(start, end); } - setCaretPosition(getTarget().getCaretPosition()); firstChangeSkipped = true; } @@ -122,7 +123,7 @@ } @Override - public final void setText(final String l) { + public final void setText(final String text) { synchronized (getDelegateLock()) { // JTextArea.setText() posts two different events (remove & insert). // Since we make no differences between text events, @@ -130,7 +131,7 @@ // JTextArea.setText() is called. final Document document = getTextComponent().getDocument(); document.removeDocumentListener(this); - getTextComponent().setText(l); + getTextComponent().setText(text); revalidate(); if (firstChangeSkipped) { postEvent(new TextEvent(getTarget(),
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Oct 11 03:06:10 2013 -0700 @@ -317,9 +317,25 @@ op |= SET_SIZE; } + // Don't post ComponentMoved/Resized and Paint events + // until we've got a notification from the delegate + Rectangle cb = constrainBounds(x, y, w, h); + setBounds(cb.x, cb.y, cb.width, cb.height, op, false, false); + // Get updated bounds, so we don't have to handle 'op' here manually + Rectangle r = getBounds(); + platformWindow.setBounds(r.x, r.y, r.width, r.height); + } + + public Rectangle constrainBounds(Rectangle bounds) { + return constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height); + } + + public Rectangle constrainBounds(int x, int y, int w, int h) { + if (w < MINIMUM_WIDTH) { w = MINIMUM_WIDTH; } + if (h < MINIMUM_HEIGHT) { h = MINIMUM_HEIGHT; } @@ -334,12 +350,7 @@ h = maxH; } - // Don't post ComponentMoved/Resized and Paint events - // until we've got a notification from the delegate - setBounds(x, y, w, h, op, false, false); - // Get updated bounds, so we don't have to handle 'op' here manually - Rectangle r = getBounds(); - platformWindow.setBounds(r.x, r.y, r.width, r.height); + return new Rectangle(x, y, w, h); } @Override @@ -393,8 +404,12 @@ @Override public void setModalBlocked(Dialog blocker, boolean blocked) { synchronized (getPeerTreeLock()) { - this.blocker = !blocked ? null : - (LWWindowPeer) AWTAccessor.getComponentAccessor().getPeer(blocker); + ComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(blocker); + if (blocked && (peer instanceof LWWindowPeer)) { + this.blocker = (LWWindowPeer) peer; + } else { + this.blocker = null; + } } platformWindow.setModalBlocked(blocked); @@ -1146,8 +1161,11 @@ return false; } - Window currentActive = KeyboardFocusManager. - getCurrentKeyboardFocusManager().getActiveWindow(); + AppContext targetAppContext = AWTAccessor.getComponentAccessor().getAppContext(getTarget()); + KeyboardFocusManager kfm = AWTAccessor.getKeyboardFocusManagerAccessor() + .getCurrentKeyboardFocusManager(targetAppContext); + Window currentActive = kfm.getActiveWindow(); + Window opposite = LWKeyboardFocusManagerPeer.getInstance(). getCurrentFocusedWindow();
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java Fri Oct 11 03:06:10 2013 -0700 @@ -26,6 +26,7 @@ package sun.lwawt.macosx; import java.awt.*; +import java.awt.dnd.DropTarget; import sun.awt.dnd.SunDropTargetContextPeer; import sun.awt.dnd.SunDropTargetEvent; @@ -38,7 +39,7 @@ private long fNativeDropTransfer = 0; private long fNativeDataAvailable = 0; private Object fNativeData = null; - private boolean insideTarget = true; + private DropTarget insideTarget = null; Object awtLockAccess = new Object(); @@ -88,26 +89,19 @@ return fNativeData; } - // We need to take care of dragExit message because for some reason it is not being - // generated for lightweight components + // We need to take care of dragEnter and dragExit messages because + // native system generates them only for heavyweights @Override protected void processMotionMessage(SunDropTargetEvent event, boolean operationChanged) { - Component eventSource = (Component)event.getComponent(); - Point screenPoint = event.getPoint(); - SwingUtilities.convertPointToScreen(screenPoint, eventSource); - Rectangle screenBounds = new Rectangle(eventSource.getLocationOnScreen().x, - eventSource.getLocationOnScreen().y, - eventSource.getWidth(), eventSource.getHeight()); - if(insideTarget) { - if(!screenBounds.contains(screenPoint)) { + boolean eventInsideTarget = isEventInsideTarget(event); + if (event.getComponent().getDropTarget() == insideTarget) { + if (!eventInsideTarget) { processExitMessage(event); - insideTarget = false; return; } } else { - if(screenBounds.contains(screenPoint)) { + if (eventInsideTarget) { processEnterMessage(event); - insideTarget = true; } else { return; } @@ -115,17 +109,52 @@ super.processMotionMessage(event, operationChanged); } + /** + * Could be called when DnD enters a heavyweight or synthesized in processMotionMessage + */ + @Override + protected void processEnterMessage(SunDropTargetEvent event) { + Component c = event.getComponent(); + DropTarget dt = event.getComponent().getDropTarget(); + if (isEventInsideTarget(event) + && dt != insideTarget + && c.isShowing() + && dt != null + && dt.isActive()) { + insideTarget = dt; + super.processEnterMessage(event); + } + } + + /** + * Could be called when DnD exits a heavyweight or synthesized in processMotionMessage + */ + @Override + protected void processExitMessage(SunDropTargetEvent event) { + if (event.getComponent().getDropTarget() == insideTarget) { + insideTarget = null; + super.processExitMessage(event); + } + } + @Override protected void processDropMessage(SunDropTargetEvent event) { - Component eventSource = (Component)event.getComponent(); + if (isEventInsideTarget(event)) { + super.processDropMessage(event); + insideTarget = null; + } + } + + private boolean isEventInsideTarget(SunDropTargetEvent event) { + Component eventSource = event.getComponent(); Point screenPoint = event.getPoint(); SwingUtilities.convertPointToScreen(screenPoint, eventSource); - Rectangle screenBounds = new Rectangle(eventSource.getLocationOnScreen().x, - eventSource.getLocationOnScreen().y, - eventSource.getWidth(), eventSource.getHeight()); - if(screenBounds.contains(screenPoint)) { - super.processDropMessage(event); - } + Point locationOnScreen = eventSource.getLocationOnScreen(); + Rectangle screenBounds = new Rectangle(locationOnScreen.x, + locationOnScreen.y, + eventSource.getWidth(), + eventSource.getHeight()); + return screenBounds.contains(screenPoint); } @Override
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java Fri Oct 11 03:06:10 2013 -0700 @@ -327,11 +327,6 @@ } @Override - public Toolkit getToolkit() { - return Toolkit.getDefaultToolkit(); - } - - @Override public void handleEvent(AWTEvent e) { }
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Oct 11 03:06:10 2013 -0700 @@ -210,7 +210,6 @@ private boolean undecorated; // initialized in getInitialStyleBits() private Rectangle normalBounds = null; // not-null only for undecorated maximized windows private CPlatformResponder responder; - private volatile boolean zoomed = false; // from native perspective public CPlatformWindow() { super(0, true); @@ -231,7 +230,9 @@ contentView.initialize(peer, responder); final long ownerPtr = owner != null ? owner.getNSWindowPtr() : 0L; - final long nativeWindowPtr = nativeCreateNSWindow(contentView.getAWTView(), ownerPtr, styleBits, 0, 0, 0, 0); + Rectangle bounds = _peer.constrainBounds(_target.getBounds()); + final long nativeWindowPtr = nativeCreateNSWindow(contentView.getAWTView(), + ownerPtr, styleBits, bounds.x, bounds.y, bounds.width, bounds.height); setPtr(nativeWindowPtr); if (target instanceof javax.swing.RootPaneContainer) { @@ -466,7 +467,8 @@ } private boolean isMaximized() { - return undecorated ? this.normalBounds != null : zoomed; + return undecorated ? this.normalBounds != null + : CWrapper.NSWindow.isZoomed(getNSWindowPtr()); } private void maximize() { @@ -474,7 +476,6 @@ return; } if (!undecorated) { - zoomed = true; CWrapper.NSWindow.zoom(getNSWindowPtr()); } else { deliverZoom(true); @@ -496,7 +497,6 @@ return; } if (!undecorated) { - zoomed = false; CWrapper.NSWindow.zoom(getNSWindowPtr()); } else { deliverZoom(false);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java Fri Oct 11 03:06:10 2013 -0700 @@ -68,6 +68,7 @@ public static native void miniaturize(long window); public static native void deminiaturize(long window); + public static native boolean isZoomed(long window); public static native void zoom(long window); public static native void makeFirstResponder(long window, long responder);
--- a/jdk/src/macosx/lib/flavormap.properties Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/lib/flavormap.properties Fri Oct 11 03:06:10 2013 -0700 @@ -76,5 +76,6 @@ text/uri-list=application/x-java-file-list;class=java.util.List PNG=image/x-java-image;class=java.awt.Image JFIF=image/x-java-image;class=java.awt.Image +TIFF=image/x-java-image;class=java.awt.Image RICH_TEXT=text/rtf HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Oct 11 03:06:10 2013 -0700 @@ -366,7 +366,7 @@ - (BOOL) canBecomeMainWindow { AWT_ASSERT_APPKIT_THREAD; - if(!self.isEnabled){ + if (!self.isEnabled) { // Native system can bring up the NSWindow to // the top even if the window is not main. // We should bring up the modal dialog manually @@ -377,7 +377,7 @@ if (platformWindow != NULL) { static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow, "checkBlockingAndOrder", "()Z"); - JNFCallVoidMethod(env, platformWindow, jm_checkBlockingAndOrder); + JNFCallBooleanMethod(env, platformWindow, jm_checkBlockingAndOrder); (*env)->DeleteLocalRef(env, platformWindow); } }
--- a/jdk/src/macosx/native/sun/awt/CDropTarget.m Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/native/sun/awt/CDropTarget.m Fri Oct 11 03:06:10 2013 -0700 @@ -477,6 +477,8 @@ sDraggingExited = FALSE; sDraggingLocation = [sender draggingLocation]; NSPoint javaLocation = [fView convertPoint:sDraggingLocation fromView:nil]; + javaLocation.y = fView.window.frame.size.height - javaLocation.y; + DLog5(@"+ dragEnter: loc native %f, %f, java %f, %f\n", sDraggingLocation.x, sDraggingLocation.y, javaLocation.x, javaLocation.y); ////////// BEGIN Calculate the current drag actions ////////// @@ -570,8 +572,7 @@ // Should we notify Java things have changed? if (sDraggingError == FALSE && notifyJava) { NSPoint javaLocation = [fView convertPoint:sDraggingLocation fromView:nil]; - // For some reason even after the convertPoint drag events come with the y coordinate reverted - javaLocation.y = fView.window.frame.size.height - javaLocation.y; + javaLocation.y = fView.window.frame.size.height - javaLocation.y; //DLog5(@" : dragMoved: loc native %f, %f, java %f, %f\n", sDraggingLocation.x, sDraggingLocation.y, javaLocation.x, javaLocation.y); jlongArray formats = sDraggingFormats;
--- a/jdk/src/macosx/native/sun/awt/CFileDialog.m Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/native/sun/awt/CFileDialog.m Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,6 +93,14 @@ - (void)safeSaveOrLoad { NSSavePanel *thePanel = nil; + /* + * 8013553: turns off extension hiding for the native file dialog. + * This way is used because setExtensionHidden(NO) doesn't work + * as expected. + */ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setBool:NO forKey:@"NSNavLastUserSetHideExtensionButtonState"]; + if (fMode == java_awt_FileDialog_SAVE) { thePanel = [NSSavePanel savePanel]; [thePanel setAllowsOtherFileTypes:YES]; @@ -110,7 +118,7 @@ if (fMode == java_awt_FileDialog_LOAD) { NSOpenPanel *openPanel = (NSOpenPanel *)thePanel; [openPanel setAllowsMultipleSelection:fMultipleMode]; - [openPanel setCanChooseFiles:YES]; + [openPanel setCanChooseFiles:!fChooseDirectories]; [openPanel setCanChooseDirectories:fChooseDirectories]; [openPanel setCanCreateDirectories:YES]; }
--- a/jdk/src/macosx/native/sun/awt/CWrapper.m Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/native/sun/awt/CWrapper.m Fri Oct 11 03:06:10 2013 -0700 @@ -437,6 +437,29 @@ /* * Class: sun_lwawt_macosx_CWrapper$NSWindow + * Method: isZoomed + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL +Java_sun_lwawt_macosx_CWrapper_00024NSWindow_isZoomed +(JNIEnv *env, jclass cls, jlong windowPtr) +{ + __block jboolean isZoomed = JNI_FALSE; + +JNF_COCOA_ENTER(env); + + NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr); + [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ + isZoomed = [window isZoomed]; + }]; + +JNF_COCOA_EXIT(env); + + return isZoomed; +} + +/* + * Class: sun_lwawt_macosx_CWrapper$NSWindow * Method: zoom * Signature: (J)V */
--- a/jdk/src/macosx/native/sun/awt/awt.m Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/macosx/native/sun/awt/awt.m Fri Oct 11 03:06:10 2013 -0700 @@ -227,7 +227,7 @@ id jrsAppKitAWTClass = objc_getClass("JRSAppKitAWT"); SEL markAppSel = @selector(markAppIsDaemon); if (![jrsAppKitAWTClass respondsToSelector:markAppSel]) return NO; - return (BOOL)[jrsAppKitAWTClass performSelector:markAppSel]; + return [jrsAppKitAWTClass performSelector:markAppSel] ? YES : NO; } + (void)appKitIsRunning:(id)arg { @@ -337,6 +337,8 @@ // Headless mode trumps either ordinary AWT or SWT-in-AWT mode. Declare us a daemon and return. if (headless) { + // Note that we don't install run loop observers in headless mode + // because we don't need them (see 7174704) if (!forceEmbeddedMode) { setUpAppKitThreadName(); }
--- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java Fri Oct 11 03:06:10 2013 -0700 @@ -104,7 +104,7 @@ public SunJCE() { /* We are the "SunJCE" provider */ - super("SunJCE", 1.7d, info); + super("SunJCE", 1.8d, info); final String BLOCK_MODES = "ECB|CBC|PCBC|CTR|CTS|CFB|OFB" + "|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64" +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPCompressionTypes.java Fri Oct 11 03:06:10 2013 -0700 @@ -0,0 +1,47 @@ +/* + * 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.imageio.plugins.bmp; + +public class BMPCompressionTypes { + + private static final String[] compressionTypeNames = + {"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"}; + + static int getType(String typeString) { + for (int i = 0; i < compressionTypeNames.length; i++) + if (compressionTypeNames[i].equals(typeString)) + return i; + return 0; + } + + static String getName(int type) { + return compressionTypeNames[type]; + } + + public static String[] getCompressionTypes() { + return compressionTypeNames.clone(); + } +}
--- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java Fri Oct 11 03:06:10 2013 -0700 @@ -47,7 +47,4 @@ static final int BI_BITFIELDS = 3; static final int BI_JPEG = 4; static final int BI_PNG = 5; - - static final String[] compressionTypeNames = - {"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"}; }
--- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java Fri Oct 11 03:06:10 2013 -0700 @@ -25,7 +25,6 @@ package com.sun.imageio.plugins.bmp; -import java.awt.Point; import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.ComponentSampleModel; @@ -42,7 +41,6 @@ import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; -import java.awt.image.WritableRaster; import java.awt.image.BufferedImage; import java.io.IOException; @@ -51,22 +49,16 @@ import java.util.Iterator; import javax.imageio.IIOImage; -import javax.imageio.IIOException; import javax.imageio.ImageIO; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataNode; -import javax.imageio.metadata.IIOMetadataFormatImpl; -import javax.imageio.metadata.IIOInvalidTreeException; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.stream.ImageOutputStream; import javax.imageio.event.IIOWriteProgressListener; import javax.imageio.event.IIOWriteWarningListener; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; import javax.imageio.plugins.bmp.BMPImageWriteParam; import com.sun.imageio.plugins.common.ImageUtil; @@ -129,7 +121,7 @@ meta.compression = getPreferredCompressionType(imageType); if (param != null && param.getCompressionMode() == ImageWriteParam.MODE_EXPLICIT) { - meta.compression = getCompressionType(param.getCompressionType()); + meta.compression = BMPCompressionTypes.getType(param.getCompressionType()); } meta.bitsPerPixel = (short)imageType.getColorModel().getPixelSize(); return meta; @@ -308,7 +300,7 @@ switch(bmpParam.getCompressionMode()) { case ImageWriteParam.MODE_EXPLICIT: - compressionType = getCompressionType(bmpParam.getCompressionType()); + compressionType = BMPCompressionTypes.getType(bmpParam.getCompressionType()); break; case ImageWriteParam.MODE_COPY_FROM_METADATA: compressionType = bmpImageMetadata.compression; @@ -323,12 +315,12 @@ if (!canEncodeImage(compressionType, colorModel, sampleModel)) { throw new IOException("Image can not be encoded with compression type " - + compressionTypeNames[compressionType]); + + BMPCompressionTypes.getName(compressionType)); } byte r[] = null, g[] = null, b[] = null, a[] = null; - if (compressionType == BMPConstants.BI_BITFIELDS) { + if (compressionType == BI_BITFIELDS) { bitsPerPixel = DataBuffer.getDataTypeSize(sampleModel.getDataType()); @@ -372,7 +364,7 @@ // an exception related to unsupported image format throw new IOException("Image can not be encoded with " + "compression type " + - compressionTypeNames[compressionType]); + BMPCompressionTypes.getName(compressionType)); } } writeMaskToPalette(rmask, 0, r, g, b, a); @@ -511,8 +503,8 @@ * Images with any other compression type must be wrote in the * bottom-up layout. */ - if (compressionType == BMPConstants.BI_RGB || - compressionType == BMPConstants.BI_BITFIELDS) + if (compressionType == BI_RGB || + compressionType == BI_BITFIELDS) { isTopDown = bmpParam.isTopDown(); } else { @@ -543,7 +535,7 @@ if (isPalette == true) { // write palette - if (compressionType == BMPConstants.BI_BITFIELDS) { + if (compressionType == BI_BITFIELDS) { // write masks for red, green and blue components. for (int i=0; i<3; i++) { int mask = (a[i]&0xFF) + ((r[i]&0xFF)*0x100) + ((g[i]&0xFF)*0x10000) + ((b[i]&0xFF)*0x1000000); @@ -571,8 +563,8 @@ int l; - if (compressionType == BMPConstants.BI_JPEG || - compressionType == BMPConstants.BI_PNG) { + if (compressionType == BI_JPEG || + compressionType == BI_PNG) { // prepare embedded buffer embedded_stream = new ByteArrayOutputStream(); @@ -657,7 +649,7 @@ pos = sppsm.getOffset(startX, startY); } - if (compressionType == BMPConstants.BI_RGB || compressionType == BMPConstants.BI_BITFIELDS){ + if (compressionType == BI_RGB || compressionType == BI_BITFIELDS){ switch(dataType) { case DataBuffer.TYPE_BYTE: byte[] bdata = @@ -687,7 +679,7 @@ for(int k=0; k<padding; k++) { stream.writeByte(0); } - } else if (compressionType == BMPConstants.BI_RLE4) { + } else if (compressionType == BI_RLE4) { if (bpixels == null || bpixels.length < scanlineBytes) bpixels = new byte[scanlineBytes]; src.getPixels(srcRect.x, srcRect.y, @@ -696,7 +688,7 @@ bpixels[h] = (byte)pixels[h]; } encodeRLE4(bpixels, scanlineBytes); - } else if (compressionType == BMPConstants.BI_RLE8) { + } else if (compressionType == BI_RLE8) { //byte[] bdata = // ((DataBufferByte)src.getDataBuffer()).getData(); //System.out.println("bdata.length="+bdata.length); @@ -734,8 +726,8 @@ processImageProgress(100.0f * (((float)i) / ((float)h))); } - if (compressionType == BMPConstants.BI_RLE4 || - compressionType == BMPConstants.BI_RLE8) { + if (compressionType == BI_RLE4 || + compressionType == BI_RLE8) { // Write the RLE EOF marker and stream.writeByte(0); stream.writeByte(1); @@ -793,7 +785,7 @@ break; case 4: - if (compressionType == BMPConstants.BI_RLE4){ + if (compressionType == BI_RLE4){ byte[] bipixels = new byte[scanlineBytes]; for (int h=0; h<scanlineBytes; h++) { bipixels[h] = (byte)pixels[l++]; @@ -814,7 +806,7 @@ break; case 8: - if(compressionType == BMPConstants.BI_RLE8) { + if(compressionType == BI_RLE8) { for (int h=0; h<scanlineBytes; h++) { bpixels[h] = (byte)pixels[l++]; } @@ -841,7 +833,7 @@ */ for (int j = 0, m = 0; j < scanlineBytes; m++) { spixels[m] = 0; - if (compressionType == BMPConstants.BI_RGB) { + if (compressionType == BI_RGB) { /* * please note that despite other cases, * the 16bpp BI_RGB requires the RGB data order @@ -910,7 +902,7 @@ */ for (int j = 0, m = 0; j < scanlineBytes; m++) { ipixels[m] = 0; - if (compressionType == BMPConstants.BI_RGB) { + if (compressionType == BI_RGB) { ipixels[m] = ((0xff & pixels[j + 2]) << 16) | ((0xff & pixels[j + 1]) << 8) | @@ -945,8 +937,8 @@ } // Write out the padding - if (compressionType == BMPConstants.BI_RGB || - compressionType == BMPConstants.BI_BITFIELDS) + if (compressionType == BI_RGB || + compressionType == BI_BITFIELDS) { for(k=0; k<padding; k++) { stream.writeByte(0); @@ -1329,17 +1321,10 @@ stream = null; } - private int getCompressionType(String typeString) { - for (int i = 0; i < BMPConstants.compressionTypeNames.length; i++) - if (BMPConstants.compressionTypeNames[i].equals(typeString)) - return i; - return 0; - } - private void writeEmbedded(IIOImage image, ImageWriteParam bmpParam) throws IOException { String format = - compressionType == BMPConstants.BI_JPEG ? "jpeg" : "png"; + compressionType == BI_JPEG ? "jpeg" : "png"; Iterator iterator = ImageIO.getImageWritersByFormatName(format); ImageWriter writer = null; if (iterator.hasNext())
--- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPMetadata.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPMetadata.java Fri Oct 11 03:06:10 2013 -0700 @@ -219,7 +219,7 @@ // CompressionTypeName IIOMetadataNode subNode = new IIOMetadataNode("CompressionTypeName"); - subNode.setAttribute("value", compressionTypeNames[compression]); + subNode.setAttribute("value", BMPCompressionTypes.getName(compression)); node.appendChild(subNode); return node; }
--- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFStreamMetadata.java Fri Oct 11 03:06:10 2013 -0700 @@ -25,11 +25,8 @@ package com.sun.imageio.plugins.gif; -import javax.imageio.ImageTypeSpecifier; import javax.imageio.metadata.IIOInvalidTreeException; -import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataNode; -import javax.imageio.metadata.IIOMetadataFormat; import javax.imageio.metadata.IIOMetadataFormatImpl; import org.w3c.dom.Node; @@ -41,7 +38,7 @@ static final String nativeMetadataFormatName = "javax_imageio_gif_stream_1.0"; - public static final String[] versionStrings = { "87a", "89a" }; + static final String[] versionStrings = { "87a", "89a" }; public String version; // 87a or 89a public int logicalScreenWidth; @@ -52,7 +49,7 @@ public int backgroundColorIndex; // Valid if globalColorTable != null public boolean sortFlag; // Valid if globalColorTable != null - public static final String[] colorTableSizes = { + static final String[] colorTableSizes = { "2", "4", "8", "16", "32", "64", "128", "256" };
--- a/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JPEG.java Fri Oct 11 03:06:10 2013 -0700 @@ -25,14 +25,11 @@ package com.sun.imageio.plugins.jpeg; -import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.imageio.ImageTypeSpecifier; import javax.imageio.plugins.jpeg.JPEGQTable; import javax.imageio.plugins.jpeg.JPEGHuffmanTable; import java.awt.image.ColorModel; -import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; import java.awt.color.ColorSpace; import java.awt.color.ICC_ColorSpace; @@ -172,9 +169,9 @@ public static final String vendor = "Oracle Corporation"; public static final String version = "0.5"; // Names of the formats we can read or write - public static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"}; - public static final String [] suffixes = {"jpg", "jpeg"}; - public static final String [] MIMETypes = {"image/jpeg"}; + static final String [] names = {"JPEG", "jpeg", "JPG", "jpg"}; + static final String [] suffixes = {"jpg", "jpeg"}; + static final String [] MIMETypes = {"image/jpeg"}; public static final String nativeImageMetadataFormatName = "javax_imageio_jpeg_image_1.0"; public static final String nativeImageMetadataFormatClassName = @@ -201,12 +198,12 @@ public static final int NUM_JCS_CODES = JCS_YCCK+1; /** IJG can handle up to 4-channel JPEGs */ - public static final int [] [] bandOffsets = {{0}, + static final int [] [] bandOffsets = {{0}, {0, 1}, {0, 1, 2}, {0, 1, 2, 3}}; - public static final int [] bOffsRGB = { 2, 1, 0 }; + static final int [] bOffsRGB = { 2, 1, 0 }; /* These are kept in the inner class to avoid static initialization * of the CMM class until someone actually needs it.
--- a/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/png/PNGMetadata.java Fri Oct 11 03:06:10 2013 -0700 @@ -29,12 +29,10 @@ import java.awt.image.IndexColorModel; import java.awt.image.SampleModel; import java.util.ArrayList; -import java.util.Iterator; import java.util.StringTokenizer; import javax.imageio.ImageTypeSpecifier; import javax.imageio.metadata.IIOInvalidTreeException; import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataFormat; import javax.imageio.metadata.IIOMetadataFormatImpl; import javax.imageio.metadata.IIOMetadataNode; import org.w3c.dom.Node; @@ -49,42 +47,42 @@ = "com.sun.imageio.plugins.png.PNGMetadataFormat"; // Color types for IHDR chunk - public static final String[] IHDR_colorTypeNames = { + static final String[] IHDR_colorTypeNames = { "Grayscale", null, "RGB", "Palette", "GrayAlpha", null, "RGBAlpha" }; - public static final int[] IHDR_numChannels = { + static final int[] IHDR_numChannels = { 1, 0, 3, 3, 2, 0, 4 }; // Bit depths for IHDR chunk - public static final String[] IHDR_bitDepths = { + static final String[] IHDR_bitDepths = { "1", "2", "4", "8", "16" }; // Compression methods for IHDR chunk - public static final String[] IHDR_compressionMethodNames = { + static final String[] IHDR_compressionMethodNames = { "deflate" }; // Filter methods for IHDR chunk - public static final String[] IHDR_filterMethodNames = { + static final String[] IHDR_filterMethodNames = { "adaptive" }; // Interlace methods for IHDR chunk - public static final String[] IHDR_interlaceMethodNames = { + static final String[] IHDR_interlaceMethodNames = { "none", "adam7" }; // Compression methods for iCCP chunk - public static final String[] iCCP_compressionMethodNames = { + static final String[] iCCP_compressionMethodNames = { "deflate" }; // Compression methods for zTXt chunk - public static final String[] zTXt_compressionMethodNames = { + static final String[] zTXt_compressionMethodNames = { "deflate" }; @@ -95,12 +93,12 @@ public static final int PHYS_UNIT_METER = 1; // Unit specifiers for pHYs chunk - public static final String[] unitSpecifierNames = { + static final String[] unitSpecifierNames = { "unknown", "meter" }; // Rendering intents for sRGB chunk - public static final String[] renderingIntentNames = { + static final String[] renderingIntentNames = { "Perceptual", // 0 "Relative colorimetric", // 1 "Saturation", // 2 @@ -109,7 +107,7 @@ }; // Color space types for Chroma->ColorSpaceType node - public static final String[] colorSpaceTypeNames = { + static final String[] colorSpaceTypeNames = { "GRAY", null, "RGB", "RGB", "GRAY", null, "RGB" };
--- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java Fri Oct 11 03:06:10 2013 -0700 @@ -85,42 +85,42 @@ ImageInputStream stream = (ImageInputStream)source; stream.mark(); - int type = stream.readByte(); // TypeField - int fixHeaderField = stream.readByte(); - // check WBMP "header" - if (type != 0 || fixHeaderField != 0) { - // while WBMP reader does not support ext WBMP headers - stream.reset(); - return false; - } + try { + int type = stream.readByte(); // TypeField + int fixHeaderField = stream.readByte(); + // check WBMP "header" + if (type != 0 || fixHeaderField != 0) { + // while WBMP reader does not support ext WBMP headers + return false; + } - int width = ReaderUtil.readMultiByteInteger(stream); - int height = ReaderUtil.readMultiByteInteger(stream); - // check image dimension - if (width <= 0 || height <= 0) { - stream.reset(); - return false; - } + int width = ReaderUtil.readMultiByteInteger(stream); + int height = ReaderUtil.readMultiByteInteger(stream); + // check image dimension + if (width <= 0 || height <= 0) { + return false; + } - long dataLength = stream.length(); - if (dataLength == -1) { - // We can't verify that amount of data in the stream - // corresponds to image dimension because we do not know - // the length of the data stream. - // Assuming that wbmp image are used for mobile devices, - // let's introduce an upper limit for image dimension. - // In case if exact amount of raster data is unknown, - // let's reject images with dimension above the limit. + long dataLength = stream.length(); + if (dataLength == -1) { + // We can't verify that amount of data in the stream + // corresponds to image dimension because we do not know + // the length of the data stream. + // Assuming that wbmp image are used for mobile devices, + // let's introduce an upper limit for image dimension. + // In case if exact amount of raster data is unknown, + // let's reject images with dimension above the limit. + return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT); + } + + dataLength -= stream.getStreamPosition(); + + long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1); + + return (dataLength == scanSize * height); + } finally { stream.reset(); - return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT); } - - dataLength -= stream.getStreamPosition(); - stream.reset(); - - long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1); - - return (dataLength == scanSize * height); } public ImageReader createReaderInstance(Object extension)
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/Driver.java Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -303,7 +303,7 @@ } else { if (!packfile.toLowerCase().endsWith(".pack") && !packfile.toLowerCase().endsWith(".pac")) { - System.err.println(MessageFormat.format(RESOURCE.getString(DriverResource.WIRTE_PACKGZ_FILE),packfile)); + System.err.println(MessageFormat.format(RESOURCE.getString(DriverResource.WRITE_PACKGZ_FILE),packfile)); printUsage(doPack, false, System.err); System.exit(2); }
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/DriverResource.java Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 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 @@ -22,110 +22,99 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package com.sun.java.util.jar.pack; import java.util.ListResourceBundle; public class DriverResource extends ListResourceBundle { - public static final String VERSION ="VERSION"; - public static final String BAD_ARGUMENT ="BAD_ARGUMENT"; - public static final String BAD_OPTION ="BAD_OPTION"; - public static final String BAD_REPACK_OUTPUT="BAD_REPACK_OUTPUT"; - public static final String DETECTED_ZIP_COMMENT="DETECTED_ZIP_COMMENT"; - public static final String SKIP_FOR_REPACKED ="SKIP_FOR_REPACKED"; - public static final String WRITE_PACK_FILE ="WRITE_PACK_FILE"; - public static final String WIRTE_PACKGZ_FILE="WIRTE_PACKGZ_FILE"; - public static final String SKIP_FOR_MOVE_FAILED="SKIP_FOR_MOVE_FAILED"; - public static final String PACK_HELP="PACK_HELP"; - public static final String UNPACK_HELP ="UNPACK_HELP"; - public static final String MORE_INFO = "MORE_INFO"; - public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION"; - public static final String BAD_SPEC = "BAD_SPEC"; - //The following string is duplicate in PACK and UNPACK comment,which was draw out to ruduce translation work. - private static final String PARAMETER_V = " -v, --verbose increase program verbosity"; - private static final String PARAMETER_Q = " -q, --quiet set verbosity to lowest level"; - private static final String PARAMETER_LF = " -l{F}, --log-file={F} output to the given log file, or '-' for System.out"; - private static final String PARAMETER_H = " -?, -h, --help print this message"; - private static final String PARAMETER_VER = " -V, --version print program version"; - private static final String PARAMETER_J = " -J{X} pass option X to underlying Java VM"; - + public static final String VERSION = "VERSION"; + public static final String BAD_ARGUMENT = "BAD_ARGUMENT"; + public static final String BAD_OPTION = "BAD_OPTION"; + public static final String BAD_REPACK_OUTPUT = "BAD_REPACK_OUTPUT"; + public static final String DETECTED_ZIP_COMMENT = "DETECTED_ZIP_COMMENT"; + public static final String SKIP_FOR_REPACKED = "SKIP_FOR_REPACKED"; + public static final String WRITE_PACK_FILE = "WRITE_PACK_FILE"; + public static final String WRITE_PACKGZ_FILE = "WRITE_PACKGZ_FILE"; + public static final String SKIP_FOR_MOVE_FAILED = "SKIP_FOR_MOVE_FAILED"; + public static final String PACK_HELP = "PACK_HELP"; + public static final String UNPACK_HELP = "UNPACK_HELP"; + public static final String MORE_INFO = "MORE_INFO"; + public static final String DUPLICATE_OPTION = "DUPLICATE_OPTION"; + public static final String BAD_SPEC = "BAD_SPEC"; - //The following are outputs of command 'pack200' and 'unpack200'. - //Don't translate command arguments ,words with a prefix of '-' or '--'. - // - private static final Object[][] resource= { - {VERSION,"{0} version {1}"},//parameter 0:class name;parameter 1: version value - {BAD_ARGUMENT,"Bad argument: {0}"}, - {BAD_OPTION,"Bad option: {0}={1}"},//parameter 0:option name;parameter 1:option value - {BAD_REPACK_OUTPUT,"Bad --repack output: {0}"},//parameter 0:filename - {DETECTED_ZIP_COMMENT,"Detected ZIP comment: {0}"},//parameter 0:comment - {SKIP_FOR_REPACKED,"Skipping because already repacked: {0}"},//parameter 0:filename - {WRITE_PACK_FILE,"To write a *.pack file, specify --no-gzip: {0}"},//parameter 0:filename - {WIRTE_PACKGZ_FILE,"To write a *.pack.gz file, specify --gzip: {0}"},//parameter 0:filename - {SKIP_FOR_MOVE_FAILED,"Skipping unpack because move failed: {0}"},//parameter 0:filename - {PACK_HELP,new String[]{ - "Usage: pack200 [-opt... | --option=value]... x.pack[.gz] y.jar", - "", - "Packing Options", - " -g, --no-gzip output a plain *.pack file with no zipping", - " --gzip (default) post-process the pack output with gzip", - " -G, --strip-debug remove debugging attributes while packing", - " -O, --no-keep-file-order do not transmit file ordering information", - " --keep-file-order (default) preserve input file ordering", - " -S{N}, --segment-limit={N} output segment limit (default N=1Mb)", - " -E{N}, --effort={N} packing effort (default N=5)", - " -H{h}, --deflate-hint={h} transmit deflate hint: true, false, or keep (default)", - " -m{V}, --modification-time={V} transmit modtimes: latest or keep (default)", - " -P{F}, --pass-file={F} transmit the given input element(s) uncompressed", - " -U{a}, --unknown-attribute={a} unknown attribute action: error, strip, or pass (default)", - " -C{N}={L}, --class-attribute={N}={L} (user-defined attribute)", - " -F{N}={L}, --field-attribute={N}={L} (user-defined attribute)", - " -M{N}={L}, --method-attribute={N}={L} (user-defined attribute)", - " -D{N}={L}, --code-attribute={N}={L} (user-defined attribute)", - " -f{F}, --config-file={F} read file F for Pack200.Packer properties", - PARAMETER_V , - PARAMETER_Q , - PARAMETER_LF , - PARAMETER_H , - PARAMETER_VER , - PARAMETER_J, - "", - "Notes:", - " The -P, -C, -F, -M, and -D options accumulate.", - " Example attribute definition: -C SourceFile=RUH .", - " Config. file properties are defined by the Pack200 API.", - " For meaning of -S, -E, -H-, -m, -U values, see Pack200 API.", - " Layout definitions (like RUH) are defined by JSR 200.", - "", - "Repacking mode updates the JAR file with a pack/unpack cycle:", - " pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n" - } - }, - {UNPACK_HELP,new String[]{ - "Usage: unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n", - "", - "Unpacking Options", - " -H{h}, --deflate-hint={h} override transmitted deflate hint: true, false, or keep (default)", - " -r, --remove-pack-file remove input file after unpacking", - PARAMETER_V , - PARAMETER_Q , - PARAMETER_LF , - PARAMETER_H , - PARAMETER_VER , - PARAMETER_J, - } - }, + /* + * The following are the output of 'pack200' and 'unpack200' commands. + * Do not translate command arguments and words with a prefix of '-' or '--'. + */ + private static final Object[][] resource = { + {VERSION, "{0} version {1}"}, // parameter 0:class name;parameter 1: version value + {BAD_ARGUMENT, "Bad argument: {0}"}, + {BAD_OPTION, "Bad option: {0}={1}"}, // parameter 0:option name;parameter 1:option value + {BAD_REPACK_OUTPUT, "Bad --repack output: {0}"}, // parameter 0:filename + {DETECTED_ZIP_COMMENT, "Detected ZIP comment: {0}"}, // parameter 0:comment + {SKIP_FOR_REPACKED, "Skipping because already repacked: {0}"}, // parameter 0:filename + {WRITE_PACK_FILE, "To write a *.pack file, specify --no-gzip: {0}"}, // parameter 0:filename + {WRITE_PACKGZ_FILE, "To write a *.pack.gz file, specify --gzip: {0}"}, // parameter 0:filename + {SKIP_FOR_MOVE_FAILED, "Skipping unpack because move failed: {0}"}, // parameter 0:filename + {PACK_HELP, new String[] { + "Usage: pack200 [-opt... | --option=value]... x.pack[.gz] y.jar", + "", + "Packing Options", + " -g, --no-gzip output a plain *.pack file with no zipping", + " --gzip (default) post-process the pack output with gzip", + " -G, --strip-debug remove debugging attributes while packing", + " -O, --no-keep-file-order do not transmit file ordering information", + " --keep-file-order (default) preserve input file ordering", + " -S{N}, --segment-limit={N} output segment limit (default N=1Mb)", + " -E{N}, --effort={N} packing effort (default N=5)", + " -H{h}, --deflate-hint={h} transmit deflate hint: true, false, or keep (default)", + " -m{V}, --modification-time={V} transmit modtimes: latest or keep (default)", + " -P{F}, --pass-file={F} transmit the given input element(s) uncompressed", + " -U{a}, --unknown-attribute={a} unknown attribute action: error, strip, or pass (default)", + " -C{N}={L}, --class-attribute={N}={L} (user-defined attribute)", + " -F{N}={L}, --field-attribute={N}={L} (user-defined attribute)", + " -M{N}={L}, --method-attribute={N}={L} (user-defined attribute)", + " -D{N}={L}, --code-attribute={N}={L} (user-defined attribute)", + " -f{F}, --config-file={F} read file F for Pack200.Packer properties", + " -v, --verbose increase program verbosity", + " -q, --quiet set verbosity to lowest level", + " -l{F}, --log-file={F} output to the given log file, or '-' for System.out", + " -?, -h, --help print this message", + " -V, --version print program version", + " -J{X} pass option X to underlying Java VM", + "", + "Notes:", + " The -P, -C, -F, -M, and -D options accumulate.", + " Example attribute definition: -C SourceFile=RUH .", + " Config. file properties are defined by the Pack200 API.", + " For meaning of -S, -E, -H-, -m, -U values, see Pack200 API.", + " Layout definitions (like RUH) are defined by JSR 200.", + "", + "Repacking mode updates the JAR file with a pack/unpack cycle:", + " pack200 [-r|--repack] [-opt | --option=value]... [repackedy.jar] y.jar\n" + } + }, + {UNPACK_HELP, new String[] { + "Usage: unpack200 [-opt... | --option=value]... x.pack[.gz] y.jar\n", + "", + "Unpacking Options", + " -H{h}, --deflate-hint={h} override transmitted deflate hint: true, false, or keep (default)", + " -r, --remove-pack-file remove input file after unpacking", + " -v, --verbose increase program verbosity", + " -q, --quiet set verbosity to lowest level", + " -l{F}, --log-file={F} output to the given log file, or '-' for System.out", + " -?, -h, --help print this message", + " -V, --version print program version", + " -J{X} pass option X to underlying Java VM" + } + }, + {MORE_INFO, "(For more information, run {0} --help .)"}, // parameter 0:command name + {DUPLICATE_OPTION, "duplicate option: {0}"}, // parameter 0:option + {BAD_SPEC, "bad spec for {0}: {1}"}, // parameter 0:option;parameter 1:specifier + }; - {MORE_INFO,"(For more information, run {0} --help .)"},//parameter 0:command name - {DUPLICATE_OPTION,"duplicate option: {0}"},//parameter 0:option - {BAD_SPEC,"bad spec for {0}: {1}"},//parameter 0:option;parameter 1:specifier - }; - - protected Object[][] getContents() { - return resource; - } - - + protected Object[][] getContents() { + return resource; + } }
--- a/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/media/sound/JSSecurityManager.java Fri Oct 11 03:06:10 2013 -0700 @@ -187,9 +187,18 @@ static <T> List<T> getProviders(final Class<T> providerClass) { List<T> p = new ArrayList<>(); - // ServiceLoader creates "lazy" iterator instance, so it doesn't, - // require do be called from privileged section - final Iterator<T> ps = ServiceLoader.load(providerClass).iterator(); + // ServiceLoader creates "lazy" iterator instance, but it ensures that + // next/hasNext run with permissions that are restricted by whatever + // creates the ServiceLoader instance, so it requires to be called from + // privileged section + final PrivilegedAction<Iterator<T>> psAction = + new PrivilegedAction<Iterator<T>>() { + @Override + public Iterator<T> run() { + return ServiceLoader.load(providerClass).iterator(); + } + }; + final Iterator<T> ps = AccessController.doPrivileged(psAction); // the iterator's hasNext() method looks through classpath for // the provider class names, so it requires read permissions
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java Fri Oct 11 03:06:10 2013 -0700 @@ -35,7 +35,7 @@ /** * Handles SubjectKeyIdentifier (SKI) for X.509v3. * - * @see <A HREF="http://java.sun.com/j2se/1.5.0/docs/api/java/security/cert/X509Extension.html"> + * @see <A HREF="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/cert/X509Extension.html"> * Interface X509Extension</A> */ public class XMLX509SKI extends SignatureElementProxy implements XMLX509DataContent {
--- a/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java Fri Oct 11 03:06:10 2013 -0700 @@ -56,7 +56,7 @@ * </PRE> * * @see <A HREF="http://www.javaworld.com/javaworld/javatips/jw-javatip42_p.html">Java Tip 42: Write Java apps that work with proxy-based firewalls</A> - * @see <A HREF="http://java.sun.com/j2se/1.4/docs/guide/net/properties.html">SUN J2SE docs for network properties</A> + * @see <A HREF="http://docs.oracle.com/javase/1.4.2/docs/guide/net/properties.html">SUN J2SE docs for network properties</A> * @see <A HREF="http://metalab.unc.edu/javafaq/javafaq.html#proxy">The JAVA FAQ Question 9.5: How do I make Java work with a proxy server?</A> */ public class ResolverDirectHTTP extends ResourceResolverSpi {
--- a/jdk/src/share/classes/com/sun/security/sasl/Provider.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/com/sun/security/sasl/Provider.java Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -53,7 +53,7 @@ " server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)"; public Provider() { - super("SunSASL", 1.7d, info); + super("SunSASL", 1.8d, info); AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() {
--- a/jdk/src/share/classes/java/applet/Applet.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/applet/Applet.java Fri Oct 11 03:06:10 2013 -0700 @@ -143,11 +143,11 @@ * For example, suppose an applet is contained * within the document: * <blockquote><pre> - * http://java.sun.com/products/jdk/1.2/index.html + * http://www.oracle.com/technetwork/java/index.html * </pre></blockquote> * The document base is: * <blockquote><pre> - * http://java.sun.com/products/jdk/1.2/index.html + * http://www.oracle.com/technetwork/java/index.html * </pre></blockquote> * * @return the {@link java.net.URL} of the document that contains this
--- a/jdk/src/share/classes/java/applet/AppletStub.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/applet/AppletStub.java Fri Oct 11 03:06:10 2013 -0700 @@ -54,11 +54,11 @@ * For example, suppose an applet is contained * within the document: * <blockquote><pre> - * http://java.sun.com/products/jdk/1.2/index.html + * http://www.oracle.com/technetwork/java/index.html * </pre></blockquote> * The document base is: * <blockquote><pre> - * http://java.sun.com/products/jdk/1.2/index.html + * http://www.oracle.com/technetwork/java/index.html * </pre></blockquote> * * @return the {@link java.net.URL} of the document that contains the
--- a/jdk/src/share/classes/java/awt/BorderLayout.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/BorderLayout.java Fri Oct 11 03:06:10 2013 -0700 @@ -96,7 +96,7 @@ * alt="Diagram of an applet demonstrating BorderLayout. * Each section of the BorderLayout contains a Button corresponding to its position in the layout, one of: * North, West, Center, East, or South." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * The code for this applet is as follows: * <p>
--- a/jdk/src/share/classes/java/awt/Button.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Button.java Fri Oct 11 03:06:10 2013 -0700 @@ -40,7 +40,7 @@ * under the Solaris operating system: * <p> * <img src="doc-files/Button-1.gif" alt="The following context describes the graphic" - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * The first view shows the button as it appears normally. * The second view shows the button
--- a/jdk/src/share/classes/java/awt/Checkbox.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Checkbox.java Fri Oct 11 03:06:10 2013 -0700 @@ -53,7 +53,7 @@ * created by this code example: * <p> * <img src="doc-files/Checkbox-1.gif" alt="The following context describes the graphic." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * The button labeled <code>one</code> is in the "on" state, and the * other two are in the "off" state. In this example, which uses the
--- a/jdk/src/share/classes/java/awt/CheckboxGroup.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/CheckboxGroup.java Fri Oct 11 03:06:10 2013 -0700 @@ -48,7 +48,7 @@ * <p> * <img src="doc-files/CheckboxGroup-1.gif" * alt="Shows three checkboxes, arranged vertically, labeled one, two, and three. Checkbox one is in the on state." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * @author Sami Shaio * @see java.awt.Checkbox
--- a/jdk/src/share/classes/java/awt/CheckboxMenuItem.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/CheckboxMenuItem.java Fri Oct 11 03:06:10 2013 -0700 @@ -44,7 +44,7 @@ * <p> * <img src="doc-files/MenuBar-1.gif" * alt="Menu labeled Examples, containing items Basic, Simple, Check, and More Examples. The Check item is a CheckBoxMenuItem instance, in the off state." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * The item labeled <code>Check</code> shows a check box menu item * in its "off" state.
--- a/jdk/src/share/classes/java/awt/Choice.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Choice.java Fri Oct 11 03:06:10 2013 -0700 @@ -52,7 +52,7 @@ * it appears as follows in its normal state: * <p> * <img src="doc-files/Choice-1.gif" alt="The following text describes the graphic" - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * In the picture, <code>"Green"</code> is the current choice. * Pushing the mouse button down on the object causes a menu to
--- a/jdk/src/share/classes/java/awt/Color.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Color.java Fri Oct 11 03:06:10 2013 -0700 @@ -823,7 +823,7 @@ * <p> * The integer that is returned by <code>HSBtoRGB</code> encodes the * value of a color in bits 0-23 of an integer value that is the same - * format used by the method {@link #getRGB() <code>getRGB</code>}. + * format used by the method {@link #getRGB() getRGB}. * This integer can be supplied as an argument to the * <code>Color</code> constructor that takes a single integer argument. * @param hue the hue component of the color
--- a/jdk/src/share/classes/java/awt/Component.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Component.java Fri Oct 11 03:06:10 2013 -0700 @@ -173,10 +173,10 @@ * <b>Note</b>: For more information on the paint mechanisms utilitized * by AWT and Swing, including information on how to write the most * efficient painting code, see - * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>. + * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. * <p> * For details on the focus subsystem, see - * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html"> + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> * How to Use the Focus Subsystem</a>, * a section in <em>The Java Tutorial</em>, and the * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a> @@ -1223,10 +1223,6 @@ * be called on the toolkit thread. */ final Toolkit getToolkitImpl() { - ComponentPeer peer = this.peer; - if ((peer != null) && ! (peer instanceof LightweightPeer)){ - return peer.getToolkit(); - } Container parent = this.parent; if (parent != null) { return parent.getToolkitImpl(); @@ -3205,7 +3201,7 @@ * <b>Note</b>: For more information on the paint mechanisms utilitized * by AWT and Swing, including information on how to write the most * efficient painting code, see - * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>. + * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. * * @param g the graphics context to use for painting * @see #update @@ -3240,7 +3236,7 @@ * <b>Note</b>: For more information on the paint mechanisms utilitized * by AWT and Swing, including information on how to write the most * efficient painting code, see - * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>. + * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. * * @param g the specified context to use for updating * @see #paint @@ -3301,7 +3297,7 @@ * <b>Note</b>: For more information on the paint mechanisms utilitized * by AWT and Swing, including information on how to write the most * efficient painting code, see - * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>. + * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. * * @see #update(Graphics) @@ -3319,7 +3315,7 @@ * <b>Note</b>: For more information on the paint mechanisms utilitized * by AWT and Swing, including information on how to write the most * efficient painting code, see - * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>. + * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. * * @param tm maximum time in milliseconds before update * @see #paint @@ -3341,7 +3337,7 @@ * <b>Note</b>: For more information on the paint mechanisms utilitized * by AWT and Swing, including information on how to write the most * efficient painting code, see - * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>. + * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. * * @param x the <i>x</i> coordinate * @param y the <i>y</i> coordinate @@ -3366,7 +3362,7 @@ * <b>Note</b>: For more information on the paint mechanisms utilitized * by AWT and Swing, including information on how to write the most * efficient painting code, see - * <a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html">Painting in AWT and Swing</a>. + * <a href="http://www.oracle.com/technetwork/java/painting-140037.html">Painting in AWT and Swing</a>. * * @param tm maximum time in milliseconds before update * @param x the <i>x</i> coordinate
--- a/jdk/src/share/classes/java/awt/Container.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Container.java Fri Oct 11 03:06:10 2013 -0700 @@ -75,7 +75,7 @@ * (and hence to the bottom of the stacking order). * <p> * <b>Note</b>: For details on the focus subsystem, see - * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html"> + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> * How to Use the Focus Subsystem</a>, * a section in <em>The Java Tutorial</em>, and the * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
--- a/jdk/src/share/classes/java/awt/DefaultFocusTraversalPolicy.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/DefaultFocusTraversalPolicy.java Fri Oct 11 03:06:10 2013 -0700 @@ -54,7 +54,7 @@ * impact, the focusability of the Component itself. * <p> * Please see - * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html"> + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> * How to Use the Focus Subsystem</a>, * a section in <em>The Java Tutorial</em>, and the * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
--- a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Fri Oct 11 03:06:10 2013 -0700 @@ -49,7 +49,7 @@ * Container's FocusTraversalPolicy. * <p> * Please see - * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html"> + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> * How to Use the Focus Subsystem</a>, * a section in <em>The Java Tutorial</em>, and the * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
--- a/jdk/src/share/classes/java/awt/DisplayMode.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/DisplayMode.java Fri Oct 11 03:06:10 2013 -0700 @@ -35,7 +35,7 @@ * (see {@link GraphicsDevice#isDisplayChangeSupported}). * <p> * For more information on full-screen exclusive mode API, see the - * <a href="http://java.sun.com/docs/books/tutorial/extra/fullscreen/index.html"> + * <a href="http://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html"> * Full-Screen Exclusive Mode API Tutorial</a>. * * @see GraphicsDevice
--- a/jdk/src/share/classes/java/awt/EventQueue.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/EventQueue.java Fri Oct 11 03:06:10 2013 -0700 @@ -652,7 +652,7 @@ * Dispatches an event. The manner in which the event is * dispatched depends upon the type of the event and the * type of the event's source object: - * <p> </p> + * <p> * <table border=1 summary="Event types, source types, and dispatch methods"> * <tr> * <th>Event Type</th> @@ -680,7 +680,7 @@ * <td>No action (ignored)</td> * </tr> * </table> - * <p> </p> + * <p> * @param event an instance of <code>java.awt.AWTEvent</code>, * or a subclass of it * @throws NullPointerException if <code>event</code> is <code>null</code>
--- a/jdk/src/share/classes/java/awt/FileDialog.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/FileDialog.java Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -457,9 +457,16 @@ * specified file. This file becomes the default file if it is set * before the file dialog window is first shown. * <p> + * When the dialog is shown, the specified file is selected. The kind of + * selection depends on the file existence, the dialog type, and the native + * platform. E.g., the file could be highlighted in the file list, or a + * file name editbox could be populated with the file name. + * <p> + * This method accepts either a full file path, or a file name with an + * extension if used together with the {@code setDirectory} method. + * <p> * Specifying "" as the file is exactly equivalent to specifying - * <code>null</code> - * as the file. + * {@code null} as the file. * * @param file the file being set * @see #getFile
--- a/jdk/src/share/classes/java/awt/FlowLayout.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/FlowLayout.java Fri Oct 11 03:06:10 2013 -0700 @@ -54,7 +54,7 @@ * <p> * <img src="doc-files/FlowLayout-1.gif" * ALT="Graphic of Layout for Three Buttons" - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * Here is the code for this applet: * <p>
--- a/jdk/src/share/classes/java/awt/FocusTraversalPolicy.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/FocusTraversalPolicy.java Fri Oct 11 03:06:10 2013 -0700 @@ -49,7 +49,7 @@ * policy is used to perform the search operation. * <p> * Please see - * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html"> + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> * How to Use the Focus Subsystem</a>, * a section in <em>The Java Tutorial</em>, and the * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a>
--- a/jdk/src/share/classes/java/awt/Font.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Font.java Fri Oct 11 03:06:10 2013 -0700 @@ -127,7 +127,7 @@ * <p> * For a discussion of the relative advantages and disadvantages of using * physical or logical fonts, see the - * <a href="http://java.sun.com/j2se/corejava/intl/reference/faqs/index.html#desktop-rendering">Internationalization FAQ</a> + * <a href="http://www.oracle.com/technetwork/java/javase/tech/faq-jsp-138165.html">Internationalization FAQ</a> * document. * * <h4>Font Faces and Names</h4>
--- a/jdk/src/share/classes/java/awt/FontMetrics.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/FontMetrics.java Fri Oct 11 03:06:10 2013 -0700 @@ -51,8 +51,8 @@ * <li>{@link #charsWidth(char[], int, int)} * </ul> * <p> - * <img src="doc-files/FontMetrics-1.gif" alt="The letter 'p' showing its 'reference point'" border=15 align - * ALIGN=right HSPACE=10 VSPACE=7> + * <img src="doc-files/FontMetrics-1.gif" alt="The letter 'p' showing its 'reference point'" + * style="border:15px; float:right; margin: 7px 10px;"> * Note that the implementations of these methods are * inefficient, so they are usually overridden with more efficient * toolkit-specific implementations.
--- a/jdk/src/share/classes/java/awt/Frame.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Frame.java Fri Oct 11 03:06:10 2013 -0700 @@ -83,7 +83,7 @@ * <img src="doc-files/MultiScreen.gif" * alt="Diagram of virtual device encompassing three physical screens and one primary physical screen. The primary physical screen * shows (0,0) coords while a different physical screen shows (-80,-100) coords." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * In such an environment, when calling <code>setLocation</code>, * you must pass a virtual coordinate to this method. Similarly,
--- a/jdk/src/share/classes/java/awt/GraphicsDevice.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/GraphicsDevice.java Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -69,7 +69,7 @@ * </pre> * <p> * For more information on full-screen exclusive mode API, see the - * <a href="http://java.sun.com/docs/books/tutorial/extra/fullscreen/index.html"> + * <a href="http://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html"> * Full-Screen Exclusive Mode API Tutorial</a>. * * @see GraphicsEnvironment @@ -334,11 +334,12 @@ } /** - * Returns the <code>Window</code> object representing the + * Returns the {@code Window} object representing the * full-screen window if the device is in full-screen mode. * - * @return the full-screen window, or <code>null</code> if the device is - * not in full-screen mode. + * @return the full-screen window, or {@code null} if the device is + * not in full-screen mode. The {@code Window} object can differ + * from the object previously set by {@code setFullScreenWindow}. * @see #setFullScreenWindow(Window) * @since 1.4 */
--- a/jdk/src/share/classes/java/awt/GridBagLayout.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/GridBagLayout.java Fri Oct 11 03:06:10 2013 -0700 @@ -125,9 +125,9 @@ * <center><table BORDER=0 WIDTH=800 * SUMMARY="absolute, relative and baseline values as described above"> * <tr> - * <th><P ALIGN="LEFT">Absolute Values</th> - * <th><P ALIGN="LEFT">Orientation Relative Values</th> - * <th><P ALIGN="LEFT">Baseline Relative Values</th> + * <th><P STYLE="TEXT-ALIGN:LEFT">Absolute Values</th> + * <th><P STYLE="TEXT-ALIGN:LEFT">Orientation Relative Values</th> + * <th><P STYLE="TEXT-ALIGN:LEFT">Baseline Relative Values</th> * </tr> * <tr> * <td> @@ -201,7 +201,7 @@ * <tr ALIGN=CENTER> * <td> * <img src="doc-files/GridBagLayout-baseline.png" - * alt="The following text describes this graphic (Figure 1)." ALIGN=center> + * alt="The following text describes this graphic (Figure 1)." style="float:center"> * </td> * </table></center> * This layout consists of three components: @@ -255,10 +255,10 @@ * <center><table WIDTH=600 summary="layout"> * <tr ALIGN=CENTER> * <td> - * <img src="doc-files/GridBagLayout-1.gif" alt="The preceeding text describes this graphic (Figure 1)." ALIGN=center HSPACE=10 VSPACE=7> + * <img src="doc-files/GridBagLayout-1.gif" alt="The preceeding text describes this graphic (Figure 1)." style="float:center; margin: 7px 10px;"> * </td> * <td> - * <img src="doc-files/GridBagLayout-2.gif" alt="The preceeding text describes this graphic (Figure 2)." ALIGN=center HSPACE=10 VSPACE=7> + * <img src="doc-files/GridBagLayout-2.gif" alt="The preceeding text describes this graphic (Figure 2)." style="float:center; margin: 7px 10px;"> * </td> * <tr ALIGN=CENTER> * <td>Figure 2: Horizontal, Left-to-Right</td>
--- a/jdk/src/share/classes/java/awt/GridLayout.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/GridLayout.java Fri Oct 11 03:06:10 2013 -0700 @@ -55,7 +55,7 @@ * If the container's <code>ComponentOrientation</code> property is horizontal * and right-to-left, the example produces the output shown in Figure 2. * <p> - * <center><table WIDTH=600 summary="layout"> + * <table style="float:center" WIDTH=600 summary="layout"> * <tr ALIGN=CENTER> * <td><img SRC="doc-files/GridLayout-1.gif" * alt="Shows 6 buttons in rows of 2. Row 1 shows buttons 1 then 2. @@ -73,7 +73,7 @@ * * <td>Figure 2: Horizontal, Right-to-Left</td> * </tr> - * </table></center> + * </table> * <p> * When both the number of rows and the number of columns have * been set to non-zero values, either by a constructor or
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Fri Oct 11 03:06:10 2013 -0700 @@ -88,7 +88,7 @@ * ClassLoader. * <p> * Please see - * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html"> + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html"> * How to Use the Focus Subsystem</a>, * a section in <em>The Java Tutorial</em>, and the * <a href="../../java/awt/doc-files/FocusSpec.html">Focus Specification</a> @@ -590,6 +590,7 @@ * * @see Component#requestFocus() * @see java.awt.event.FocusEvent#FOCUS_LOST + * @since 1.8 */ public void clearFocusOwner() { if (getFocusOwner() != null) {
--- a/jdk/src/share/classes/java/awt/Label.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Label.java Fri Oct 11 03:06:10 2013 -0700 @@ -46,7 +46,7 @@ * produces the following labels: * <p> * <img src="doc-files/Label-1.gif" alt="Two labels: 'Hi There!' and 'Another label'" - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * * @author Sami Shaio * @since JDK1.0
--- a/jdk/src/share/classes/java/awt/LinearGradientPaint.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/LinearGradientPaint.java Fri Oct 11 03:06:10 2013 -0700 @@ -94,7 +94,7 @@ * of the three cycle methods: * <p> * <center> - * <img src = "doc-files/LinearGradientPaint.png"> + * <img src = "doc-files/LinearGradientPaint.png" alt="LinearGradientPaint"> * </center> * * @see java.awt.Paint
--- a/jdk/src/share/classes/java/awt/List.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/List.java Fri Oct 11 03:06:10 2013 -0700 @@ -61,7 +61,7 @@ * scrolling list: * <p> * <img src="doc-files/List-1.gif" - * alt="Shows a list containing: Venus, Earth, JavaSoft, and Mars. Javasoft is selected." ALIGN=center HSPACE=10 VSPACE=7> + * alt="Shows a list containing: Venus, Earth, JavaSoft, and Mars. Javasoft is selected." style="float:center; margin: 7px 10px;"> * <p> * If the List allows multiple selections, then clicking on * an item that is already selected deselects it. In the preceding
--- a/jdk/src/share/classes/java/awt/MenuBar.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/MenuBar.java Fri Oct 11 03:06:10 2013 -0700 @@ -45,7 +45,7 @@ * <img src="doc-files/MenuBar-1.gif" * alt="Diagram of MenuBar containing 2 menus: Examples and Options. * Examples menu is expanded showing items: Basic, Simple, Check, and More Examples." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * A menu bar handles keyboard shortcuts for menu items, passing them * along to its child menus.
--- a/jdk/src/share/classes/java/awt/MenuItem.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/MenuItem.java Fri Oct 11 03:06:10 2013 -0700 @@ -42,8 +42,8 @@ * <p> * This picture of a menu bar shows five menu items: * <IMG SRC="doc-files/MenuBar-1.gif" alt="The following text describes this graphic." - * ALIGN=CENTER HSPACE=10 VSPACE=7> - * <br CLEAR=LEFT> + * style="float:center; margin: 7px 10px;"> + * <br style="clear:left;"> * The first two items are simple menu items, labeled * <code>"Basic"</code> and <code>"Simple"</code>. * Following these two items is a separator, which is itself
--- a/jdk/src/share/classes/java/awt/RadialGradientPaint.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/RadialGradientPaint.java Fri Oct 11 03:06:10 2013 -0700 @@ -80,14 +80,14 @@ * from the focus point. The following figure shows that the distance AB * is equal to the distance BC, and the distance AD is equal to the distance DE. * <center> - * <img src = "doc-files/RadialGradientPaint-3.png"> + * <img src = "doc-files/RadialGradientPaint-3.png" alt="RadialGradientPaint-3"> * </center> * If the gradient and graphics rendering transforms are uniformly scaled and * the user sets the focus so that it coincides with the center of the circle, * the gradient color proportions are equal for any line drawn from the center. * The following figure shows the distances AB, BC, AD, and DE. They are all equal. * <center> - * <img src = "doc-files/RadialGradientPaint-4.png"> + * <img src = "doc-files/RadialGradientPaint-4.png" alt="RadialGradientPaint-4"> * </center> * Note that some minor variations in distances may occur due to sampling at * the granularity of a pixel. @@ -117,7 +117,7 @@ * (centered) focus for each of the three cycle methods: * <p> * <center> - * <img src = "doc-files/RadialGradientPaint-1.png"> + * <img src = "doc-files/RadialGradientPaint-1.png" alt="RadialGradientPaint-1"> * </center> * * <p> @@ -141,7 +141,7 @@ * focus for each of the three cycle methods: * <p> * <center> - * <img src = "doc-files/RadialGradientPaint-2.png"> + * <img src = "doc-files/RadialGradientPaint-2.png" alt="RadialGradientPaint-2"> * </center> * * @see java.awt.Paint
--- a/jdk/src/share/classes/java/awt/Scrollbar.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Scrollbar.java Fri Oct 11 03:06:10 2013 -0700 @@ -42,7 +42,7 @@ * the red, green, and blue components of a color: * <p> * <img src="doc-files/Scrollbar-1.gif" alt="Image shows 3 vertical sliders, side-by-side." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * Each scroll bar in this example could be created with * code similar to the following: @@ -60,7 +60,7 @@ * <p> * <img src="doc-files/Scrollbar-2.gif" * alt="Image shows horizontal slider with starting range of 0 and ending range of 300. The slider thumb is labeled 60." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * The value range represented by the bubble in this example * is the <em>visible amount</em>. The horizontal scroll bar @@ -295,7 +295,7 @@ * Constructs a new vertical scroll bar. * The default properties of the scroll bar are listed in * the following table: - * <p> </p> + * <p> * <table border=1 summary="Scrollbar default properties"> * <tr> * <th>Property</th>
--- a/jdk/src/share/classes/java/awt/SystemTray.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/SystemTray.java Fri Oct 11 03:06:10 2013 -0700 @@ -361,7 +361,7 @@ /** * Adds a {@code PropertyChangeListener} to the list of listeners for the * specific property. The following properties are currently supported: - * <p> </p> + * <p> * <table border=1 summary="SystemTray properties"> * <tr> * <th>Property</th> @@ -384,7 +384,7 @@ * The property is accessed by the {@link #getSystemTray} method.</td> * </tr> * </table> - * <p> </p> + * <p> * The {@code listener} listens to property changes only in this context. * <p> * If {@code listener} is {@code null}, no exception is thrown
--- a/jdk/src/share/classes/java/awt/TextArea.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/TextArea.java Fri Oct 11 03:06:10 2013 -0700 @@ -42,7 +42,7 @@ * The following image shows the appearance of a text area: * <p> * <img src="doc-files/TextArea-1.gif" alt="A TextArea showing the word 'Hello!'" - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * This text area could be created by the following line of code: * <p>
--- a/jdk/src/share/classes/java/awt/TextComponent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/TextComponent.java Fri Oct 11 03:06:10 2013 -0700 @@ -822,37 +822,6 @@ // Accessibility support //////////////// - - /** - * - */ - int getIndexAtPoint(Point p) { - return -1; -/* To be fully implemented in a future release - if (peer == null) { - return -1; - } - TextComponentPeer peer = (TextComponentPeer)this.peer; - return peer.getIndexAtPoint(p.x, p.y); -*/ - } - - - /** - * - */ - Rectangle getCharacterBounds(int i) { - return null; -/* To be fully implemented in a future release - if (peer == null) { - return null; - } - TextComponentPeer peer = (TextComponentPeer)this.peer; - return peer.getCharacterBounds(i); -*/ - } - - /** * Gets the AccessibleContext associated with this TextComponent. * For text components, the AccessibleContext takes the form of an @@ -963,7 +932,7 @@ * @return the zero-based index of the character under Point p. */ public int getIndexAtPoint(Point p) { - return TextComponent.this.getIndexAtPoint(p); + return -1; } /** @@ -976,7 +945,7 @@ * @return the screen coordinates of the character's bounding box */ public Rectangle getCharacterBounds(int i) { - return TextComponent.this.getCharacterBounds(i); + return null; } /**
--- a/jdk/src/share/classes/java/awt/TextField.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/TextField.java Fri Oct 11 03:06:10 2013 -0700 @@ -42,7 +42,7 @@ * display the predefined text <code>"Hello"</code>. * <p> * <img src="doc-files/TextField-1.gif" alt="The preceding text describes this image." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * Here is the code that produces these four text fields: * <p>
--- a/jdk/src/share/classes/java/awt/Toolkit.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Toolkit.java Fri Oct 11 03:06:10 2013 -0700 @@ -83,7 +83,7 @@ * <p> * <li>Moving the focus from one component to another. * <br>For more information, see - * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/focus.html#transferTiming">Timing + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html#transferTiming">Timing * Focus Transfers</a>, a section in * <a href="http://java.sun.com/docs/books/tutorial/uiswing/">The Swing * Tutorial</a>.
--- a/jdk/src/share/classes/java/awt/Window.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/Window.java Fri Oct 11 03:06:10 2013 -0700 @@ -85,7 +85,7 @@ * <p> * <img src="doc-files/MultiScreen.gif" * alt="Diagram shows virtual device containing 4 physical screens. Primary physical screen shows coords (0,0), other screen shows (-80,-100)." - * ALIGN=center HSPACE=10 VSPACE=7> + * style="float:center; margin: 7px 10px;"> * <p> * In such an environment, when calling {@code setLocation}, * you must pass a virtual coordinate to this method. Similarly, @@ -226,6 +226,7 @@ boolean syncLWRequests = false; transient boolean beforeFirstShow = true; private transient boolean disposing = false; + transient WindowDisposerRecord disposerRecord = null; static final int OPENED = 0x01; @@ -437,18 +438,28 @@ transient Object anchor = new Object(); static class WindowDisposerRecord implements sun.java2d.DisposerRecord { - final WeakReference<Window> owner; + WeakReference<Window> owner; final WeakReference<Window> weakThis; final WeakReference<AppContext> context; + WindowDisposerRecord(AppContext context, Window victim) { - owner = new WeakReference<Window>(victim.getOwner()); weakThis = victim.weakThis; this.context = new WeakReference<AppContext>(context); } + + public void updateOwner() { + Window victim = weakThis.get(); + owner = (victim == null) + ? null + : new WeakReference<Window>(victim.getOwner()); + } + public void dispose() { - Window parent = owner.get(); - if (parent != null) { - parent.removeOwnedWindow(weakThis); + if (owner != null) { + Window parent = owner.get(); + if (parent != null) { + parent.removeOwnedWindow(weakThis); + } } AppContext ac = context.get(); if (null != ac) { @@ -502,6 +513,8 @@ } modalExclusionType = Dialog.ModalExclusionType.NO_EXCLUDE; + disposerRecord = new WindowDisposerRecord(appContext, this); + sun.java2d.Disposer.addRecord(anchor, disposerRecord); SunToolkit.checkAndSetPolicy(this); } @@ -617,11 +630,16 @@ this.parent = owner; if (owner != null) { owner.addOwnedWindow(weakThis); + if (owner.isAlwaysOnTop()) { + try { + setAlwaysOnTop(true); + } catch (SecurityException ignore) { + } + } } - // Fix for 6758673: this call is moved here from init(gc), because // WindowDisposerRecord requires a proper value of parent field. - Disposer.addRecord(anchor, new WindowDisposerRecord(appContext, this)); + disposerRecord.updateOwner(); } /** @@ -1022,7 +1040,9 @@ closeSplashScreen(); Dialog.checkShouldBeBlocked(this); super.show(); - locationByPlatform = false; + synchronized (getTreeLock()) { + this.locationByPlatform = false; + } for (int i = 0; i < ownedWindowList.size(); i++) { Window child = ownedWindowList.elementAt(i).get(); if ((child != null) && child.showWithParent) { @@ -1095,6 +1115,9 @@ modalBlocker.unblockWindow(this); } super.hide(); + synchronized (getTreeLock()) { + this.locationByPlatform = false; + } } final void clearMostRecentFocusOwnerOnHide() { @@ -2180,8 +2203,8 @@ * windows. To detect if always-on-top windows are supported by the * current platform, use {@link Toolkit#isAlwaysOnTopSupported()} and * {@link Window#isAlwaysOnTopSupported()}. If always-on-top mode - * isn't supported by the toolkit or for this window, calling this - * method has no effect. + * isn't supported for this window or this window's toolkit does not + * support always-on-top windows, calling this method has no effect. * <p> * If a SecurityManager is installed, the calling thread must be * granted the AWTPermission "setWindowAlwaysOnTop" in @@ -2194,11 +2217,13 @@ * windows * @throws SecurityException if the calling thread does not have * permission to set the value of always-on-top property + * * @see #isAlwaysOnTop * @see #toFront * @see #toBack * @see AWTPermission * @see #isAlwaysOnTopSupported + * @see #getToolkit * @see Toolkit#isAlwaysOnTopSupported * @since 1.5 */ @@ -2224,6 +2249,15 @@ } firePropertyChange("alwaysOnTop", oldAlwaysOnTop, alwaysOnTop); } + for (WeakReference<Window> ref : ownedWindowList) { + Window window = ref.get(); + if (window != null) { + try { + window.setAlwaysOnTop(alwaysOnTop); + } catch (SecurityException ignore) { + } + } + } } /** @@ -2231,11 +2265,13 @@ * window. Some platforms may not support always-on-top windows, some * may support only some kinds of top-level windows; for example, * a platform may not support always-on-top modal dialogs. - * @return {@code true}, if the always-on-top mode is - * supported by the toolkit and for this window, - * {@code false}, if always-on-top mode is not supported - * for this window or toolkit doesn't support always-on-top windows. + * + * @return {@code true}, if the always-on-top mode is supported for + * this window and this window's toolkit supports always-on-top windows, + * {@code false} otherwise + * * @see #setAlwaysOnTop(boolean) + * @see #getToolkit * @see Toolkit#isAlwaysOnTopSupported * @since 1.6 */ @@ -2774,6 +2810,7 @@ void connectOwnedWindow(Window child) { child.parent = this; addOwnedWindow(child.weakThis); + child.disposerRecord.updateOwner(); } private void addToWindowList() { @@ -2936,7 +2973,8 @@ weakThis = new WeakReference<>(this); anchor = new Object(); - sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(appContext, this)); + disposerRecord = new WindowDisposerRecord(appContext, this); + sun.java2d.Disposer.addRecord(anchor, disposerRecord); addToWindowList(); initGC(null);
--- a/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/datatransfer/DataFlavor.java Fri Oct 11 03:06:10 2013 -0700 @@ -90,7 +90,7 @@ * the same results. * <p> * For more information on the using data transfer with Swing see - * the <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html"> + * the <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html"> * How to Use Drag and Drop and Data Transfer</a>, * section in <em>Java Tutorial</em>. *
--- a/jdk/src/share/classes/java/awt/datatransfer/Transferable.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/datatransfer/Transferable.java Fri Oct 11 03:06:10 2013 -0700 @@ -32,7 +32,7 @@ * for a transfer operation. * <p> * For information on using data transfer with Swing, see - * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html"> + * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html"> * How to Use Drag and Drop and Data Transfer</a>, * a section in <em>The Java Tutorial</em>, for more information. *
--- a/jdk/src/share/classes/java/awt/event/ActionEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ActionEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -52,7 +52,7 @@ * in the range from {@code ACTION_FIRST} to {@code ACTION_LAST}. * * @see ActionListener - * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html">Tutorial: How to Write an Action Listener</a> * * @author Carl Quinn * @since 1.1
--- a/jdk/src/share/classes/java/awt/event/ActionListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ActionListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -37,7 +37,7 @@ * invoked. * * @see ActionEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/eventmodel.html">Tutorial: Java 1.1 Event Model</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html">How to Write an Action Listener</a> * * @author Carl Quinn * @since 1.1
--- a/jdk/src/share/classes/java/awt/event/ComponentAdapter.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ComponentAdapter.java Fri Oct 11 03:06:10 2013 -0700 @@ -44,7 +44,7 @@ * * @see ComponentEvent * @see ComponentListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/componentlistener.html">Tutorial: Writing a Component Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a> * * @author Carl Quinn * @since 1.1
--- a/jdk/src/share/classes/java/awt/event/ComponentEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ComponentEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -60,7 +60,7 @@ * * @see ComponentAdapter * @see ComponentListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/componentlistener.html">Tutorial: Writing a Component Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a> * * @author Carl Quinn * @since 1.1
--- a/jdk/src/share/classes/java/awt/event/ComponentListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ComponentListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -46,7 +46,7 @@ * * @see ComponentAdapter * @see ComponentEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/componentlistener.html">Tutorial: Writing a Component Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/componentlistener.html">Tutorial: Writing a Component Listener</a> * * @author Carl Quinn * @since 1.1
--- a/jdk/src/share/classes/java/awt/event/ContainerAdapter.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ContainerAdapter.java Fri Oct 11 03:06:10 2013 -0700 @@ -44,7 +44,7 @@ * * @see ContainerEvent * @see ContainerListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/containerlistener.html">Tutorial: Writing a Container Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a> * * @author Amy Fowler * @since 1.1
--- a/jdk/src/share/classes/java/awt/event/ContainerEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ContainerEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -52,7 +52,7 @@ * * @see ContainerAdapter * @see ContainerListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/containerlistener.html">Tutorial: Writing a Container Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a> * * @author Tim Prinzing * @author Amy Fowler
--- a/jdk/src/share/classes/java/awt/event/ContainerListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ContainerListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -46,7 +46,7 @@ * * @see ContainerAdapter * @see ContainerEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/containerlistener.html">Tutorial: Writing a Container Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/containerlistener.html">Tutorial: Writing a Container Listener</a> * * @author Tim Prinzing * @author Amy Fowler
--- a/jdk/src/share/classes/java/awt/event/FocusAdapter.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/FocusAdapter.java Fri Oct 11 03:06:10 2013 -0700 @@ -44,7 +44,7 @@ * * @see FocusEvent * @see FocusListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/focuslistener.html">Tutorial: Writing a Focus Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a> * * @author Carl Quinn * @since 1.1
--- a/jdk/src/share/classes/java/awt/event/FocusEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/FocusEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -57,7 +57,7 @@ * * @see FocusAdapter * @see FocusListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/focuslistener.html">Tutorial: Writing a Focus Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a> * * @author Carl Quinn * @author Amy Fowler
--- a/jdk/src/share/classes/java/awt/event/FocusListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/FocusListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -42,7 +42,7 @@ * * @see FocusAdapter * @see FocusEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/focuslistener.html">Tutorial: Writing a Focus Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/focuslistener.html">Tutorial: Writing a Focus Listener</a> * * @author Carl Quinn * @since 1.1
--- a/jdk/src/share/classes/java/awt/event/InputEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/InputEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -445,7 +445,7 @@ * <PRE> * int onmask = SHIFT_DOWN_MASK | BUTTON1_DOWN_MASK; * int offmask = CTRL_DOWN_MASK; - * if ((event.getModifiersEx() & (onmask | offmask)) == onmask) { + * if ((event.getModifiersEx() & (onmask | offmask)) == onmask) { * ... * } * </PRE>
--- a/jdk/src/share/classes/java/awt/event/ItemEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ItemEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -58,7 +58,7 @@ * * @see java.awt.ItemSelectable * @see ItemListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/itemlistener.html">Tutorial: Writing an Item Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/itemlistener.html">Tutorial: Writing an Item Listener</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/event/ItemListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/ItemListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -40,7 +40,7 @@ * * @see java.awt.ItemSelectable * @see ItemEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/itemlistener.html">Tutorial: Writing an Item Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/itemlistener.html">Tutorial: Writing an Item Listener</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/event/KeyAdapter.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/KeyAdapter.java Fri Oct 11 03:06:10 2013 -0700 @@ -46,7 +46,7 @@ * * @see KeyEvent * @see KeyListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/keylistener.html">Tutorial: Writing a Key Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html">Tutorial: Writing a Key Listener</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/event/KeyEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/KeyEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -145,7 +145,7 @@ * * @see KeyAdapter * @see KeyListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/keylistener.html">Tutorial: Writing a Key Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html">Tutorial: Writing a Key Listener</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/event/MouseAdapter.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/MouseAdapter.java Fri Oct 11 03:06:10 2013 -0700 @@ -63,7 +63,7 @@ * @see MouseListener * @see MouseMotionListener * @see MouseWheelListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/mouselistener.html">Tutorial: Writing a Mouse Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/event/MouseEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/MouseEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -146,12 +146,12 @@ * {@link InputEvent#getMaskForButton(int) getMaskForButton(button)} method may be used * as button masks. * <p> - * <code>MOUSE_DRAGGED</code> events are delivered to the <code>Component</code> + * {@code MOUSE_DRAGGED} events are delivered to the {@code Component} * in which the mouse button was pressed until the mouse button is released * (regardless of whether the mouse position is within the bounds of the - * <code>Component</code>). Due to platform-dependent Drag&Drop implementations, - * <code>MOUSE_DRAGGED</code> events may not be delivered during a native - * Drag&Drop operation. + * {@code Component}). Due to platform-dependent Drag&Drop implementations, + * {@code MOUSE_DRAGGED} events may not be delivered during a native + * Drag&Drop operation. * * In a multi-screen environment mouse drag events are delivered to the * <code>Component</code> even if the mouse position is outside the bounds of the @@ -182,8 +182,8 @@ * @see MouseMotionAdapter * @see MouseMotionListener * @see MouseWheelListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/mouselistener.html">Tutorial: Writing a Mouse Listener</a> - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a> * * @since 1.1 */ @@ -327,7 +327,7 @@ * For all other events the count will be 0. * * @serial - * @see #getClickCount(). + * @see #getClickCount() */ int clickCount; @@ -403,7 +403,7 @@ /** * Initialize JNI field and method IDs for fields that may be - accessed from C. + * accessed from C. */ private static native void initIDs();
--- a/jdk/src/share/classes/java/awt/event/MouseListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/MouseListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -50,7 +50,7 @@ * * @see MouseAdapter * @see MouseEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/mouselistener.html">Tutorial: Writing a Mouse Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html">Tutorial: Writing a Mouse Listener</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/event/MouseMotionAdapter.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/MouseMotionAdapter.java Fri Oct 11 03:06:10 2013 -0700 @@ -49,7 +49,7 @@ * * @see MouseEvent * @see MouseMotionListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/event/MouseMotionListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/MouseMotionListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -47,7 +47,7 @@ * * @see MouseMotionAdapter * @see MouseEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/mousemotionlistener.html">Tutorial: Writing a Mouse Motion Listener</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/event/WindowAdapter.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/WindowAdapter.java Fri Oct 11 03:06:10 2013 -0700 @@ -45,7 +45,7 @@ * * @see WindowEvent * @see WindowListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/windowlistener.html">Tutorial: Writing a Window Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a> * * @author Carl Quinn * @author Amy Fowler
--- a/jdk/src/share/classes/java/awt/event/WindowEvent.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/WindowEvent.java Fri Oct 11 03:06:10 2013 -0700 @@ -52,7 +52,7 @@ * * @see WindowAdapter * @see WindowListener - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/windowlistener.html">Tutorial: Writing a Window Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a> * * @since JDK1.1 */
--- a/jdk/src/share/classes/java/awt/event/WindowFocusListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/WindowFocusListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -47,7 +47,7 @@ * * @see WindowAdapter * @see WindowEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/post1.0/ui/windowlistener.html">Tutorial: Writing a Window Listener</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a> * * @since 1.4 */
--- a/jdk/src/share/classes/java/awt/event/WindowListener.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/event/WindowListener.java Fri Oct 11 03:06:10 2013 -0700 @@ -44,7 +44,7 @@ * * @see WindowAdapter * @see WindowEvent - * @see <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/windowlistener.html">Tutorial: How to Write Window Listeners</a> + * @see <a href="http://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: How to Write Window Listeners</a> * * @since 1.1 */
--- a/jdk/src/share/classes/java/awt/font/TextAttribute.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/font/TextAttribute.java Fri Oct 11 03:06:10 2013 -0700 @@ -97,10 +97,10 @@ * <h4>Summary of attributes</h4> * <p> * <font size="-1"> - * <table align="center" border="0" cellspacing="0" cellpadding="2" width="%95" + * <table style="float:center" border="0" cellspacing="0" cellpadding="2" width="%95" * summary="Key, value type, principal constants, and default value * behavior of all TextAttributes"> - * <tr bgcolor="#ccccff"> + * <tr style="background-color:#ccccff"> * <th valign="TOP" align="CENTER">Key</th> * <th valign="TOP" align="CENTER">Value Type</th> * <th valign="TOP" align="CENTER">Principal Constants</th> @@ -115,7 +115,7 @@ </td> * <td valign="TOP">"Default" (use platform default)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #WEIGHT}</td> * <td valign="TOP">Number</td> * <td valign="TOP">WEIGHT_REGULAR, WEIGHT_BOLD</td> @@ -127,7 +127,7 @@ * <td valign="TOP">WIDTH_CONDENSED, WIDTH_REGULAR,<br>WIDTH_EXTENDED</td> * <td valign="TOP">WIDTH_REGULAR</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #POSTURE}</td> * <td valign="TOP">Number</td> * <td valign="TOP">POSTURE_REGULAR, POSTURE_OBLIQUE</td> @@ -139,7 +139,7 @@ * <td valign="TOP">none</td> * <td valign="TOP">12.0</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #TRANSFORM}</td> * <td valign="TOP">{@link TransformAttribute}</td> * <td valign="TOP">See TransformAttribute {@link TransformAttribute#IDENTITY IDENTITY}</td> @@ -151,7 +151,7 @@ * <td valign="TOP">SUPERSCRIPT_SUPER, SUPERSCRIPT_SUB</td> * <td valign="TOP">0 (use the standard glyphs and metrics)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #FONT}</td> * <td valign="TOP">{@link java.awt.Font}</td> * <td valign="TOP">none</td> @@ -163,7 +163,7 @@ * <td valign="TOP">none</td> * <td valign="TOP">null (draw text using font glyphs)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #FOREGROUND}</td> * <td valign="TOP">{@link java.awt.Paint}</td> * <td valign="TOP">none</td> @@ -175,7 +175,7 @@ * <td valign="TOP">none</td> * <td valign="TOP">null (do not render background)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #UNDERLINE}</td> * <td valign="TOP">Integer</td> * <td valign="TOP">UNDERLINE_ON</td> @@ -187,7 +187,7 @@ * <td valign="TOP">STRIKETHROUGH_ON</td> * <td valign="TOP">false (do not render strikethrough)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #RUN_DIRECTION}</td> * <td valign="TOP">Boolean</td> * <td valign="TOP">RUN_DIRECTION_LTR<br>RUN_DIRECTION_RTL</td> @@ -199,7 +199,7 @@ * <td valign="TOP">none</td> * <td valign="TOP">0 (use base line direction)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #JUSTIFICATION}</td> * <td valign="TOP">Number</td> * <td valign="TOP">JUSTIFICATION_FULL</td> @@ -211,7 +211,7 @@ * <td valign="TOP">(see class)</td> * <td valign="TOP">null (do not apply input highlighting)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #INPUT_METHOD_UNDERLINE}</td> * <td valign="TOP">Integer</td> * <td valign="TOP">UNDERLINE_LOW_ONE_PIXEL,<br>UNDERLINE_LOW_TWO_PIXEL</td> @@ -223,7 +223,7 @@ * <td valign="TOP">SWAP_COLORS_ON</td> * <td valign="TOP">false (do not swap colors)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #NUMERIC_SHAPING}</td> * <td valign="TOP">{@link java.awt.font.NumericShaper}</td> * <td valign="TOP">none</td> @@ -235,7 +235,7 @@ * <td valign="TOP">KERNING_ON</td> * <td valign="TOP">0 (do not request kerning)</td> * </tr> - * <tr bgcolor="#eeeeff"> + * <tr style="background-color:#eeeeff"> * <td valign="TOP">{@link #LIGATURES}</td> * <td valign="TOP">Integer</td> * <td valign="TOP">LIGATURES_ON</td>
--- a/jdk/src/share/classes/java/awt/geom/AffineTransform.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/geom/AffineTransform.java Fri Oct 11 03:06:10 2013 -0700 @@ -47,7 +47,7 @@ * [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ] * </pre> * <p> - * <a name="quadrantapproximation"><h4>Handling 90-Degree Rotations</h4></a> + * <a name="quadrantapproximation"></a><h4>Handling 90-Degree Rotations</h4> * <p> * In some variations of the <code>rotate</code> methods in the * <code>AffineTransform</code> class, a double-precision argument
--- a/jdk/src/share/classes/java/awt/geom/Line2D.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/geom/Line2D.java Fri Oct 11 03:06:10 2013 -0700 @@ -35,7 +35,7 @@ * default coordinate system called <i>user space</i> in which the y-axis * values increase downward and x-axis values increase to the right. For * more information on the user space coordinate system, see the - * <a href="http://java.sun.com/j2se/1.3/docs/guide/2d/spec/j2d-intro.fm2.html#61857"> + * <a href="http://docs.oracle.com/javase/1.3/docs/guide/2d/spec/j2d-intro.fm2.html#61857"> * Coordinate Systems</a> section of the Java 2D Programmer's Guide. * <p> * This class is only the abstract superclass for all objects that @@ -82,7 +82,7 @@ public float y2; /** - * Constructs and initializes a Line with coordinates (0, 0) -> (0, 0). + * Constructs and initializes a Line with coordinates (0, 0) → (0, 0). * @since 1.2 */ public Float() { @@ -249,7 +249,7 @@ public double y2; /** - * Constructs and initializes a Line with coordinates (0, 0) -> (0, 0). + * Constructs and initializes a Line with coordinates (0, 0) → (0, 0). * @since 1.2 */ public Double() { @@ -623,7 +623,7 @@ * specified line segment * @param y2 the Y coordinate of the end point of the * specified line segment - * @return <true> if this line segment and the specified line segment + * @return {@code <true>} if this line segment and the specified line segment * intersect each other; <code>false</code> otherwise. * @since 1.2 */
--- a/jdk/src/share/classes/java/awt/im/InputContext.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/im/InputContext.java Fri Oct 11 03:06:10 2013 -0700 @@ -118,7 +118,6 @@ * Otherwise, an input method or keyboard layout that supports the requested * locale is selected in an implementation dependent way.</li> * - * <p> * </ul> * Before switching away from an input method, any currently uncommitted text * is committed. If no input method or keyboard layout supporting the requested
--- a/jdk/src/share/classes/java/awt/im/InputMethodHighlight.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/im/InputMethodHighlight.java Fri Oct 11 03:06:10 2013 -0700 @@ -51,8 +51,8 @@ * mappings from abstract to concrete styles. Currently defined state values * are raw (unconverted) and converted. * These state values are recommended for use before and after the -* main conversion step of text composition, say, before and after kana->kanji -* or pinyin->hanzi conversion. +* main conversion step of text composition, say, before and after kana->kanji +* or pinyin->hanzi conversion. * The <code>variation</code> field allows input methods to express additional * information about the conversion results. * <p>
--- a/jdk/src/share/classes/java/awt/peer/ComponentPeer.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/peer/ComponentPeer.java Fri Oct 11 03:06:10 2013 -0700 @@ -260,15 +260,6 @@ ColorModel getColorModel(); /** - * Returns the toolkit that is responsible for the component. - * - * @return the toolkit that is responsible for the component - * - * @see Component#getToolkit() - */ - Toolkit getToolkit(); - - /** * Returns a graphics object to paint on the component. * * @return a graphics object to paint on the component
--- a/jdk/src/share/classes/java/awt/peer/TextComponentPeer.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/peer/TextComponentPeer.java Fri Oct 11 03:06:10 2013 -0700 @@ -60,11 +60,11 @@ /** * Sets the content for the text component. * - * @param l the content to set + * @param text the content to set * * @see TextComponent#setText(String) */ - void setText(String l); + void setText(String text); /** * Returns the start index of the current selection.
--- a/jdk/src/share/classes/java/awt/print/PrinterJob.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/awt/print/PrinterJob.java Fri Oct 11 03:06:10 2013 -0700 @@ -98,7 +98,7 @@ * Calling this method is equivalent to calling * {@link javax.print.PrintServiceLookup#lookupPrintServices( * DocFlavor, AttributeSet) - * <code>PrintServiceLookup.lookupPrintServices()</code>} + * PrintServiceLookup.lookupPrintServices()} * and specifying a Pageable DocFlavor. * @return a possibly empty array of 2D print services. * @since 1.4 @@ -136,8 +136,8 @@ * <code>PrinterJob</code> instances which support print services. * Calling this method is equivalent to calling * {@link javax.print.StreamPrintServiceFactory#lookupStreamPrintServiceFactories(DocFlavor, String) - * <code>StreamPrintServiceFactory.lookupStreamPrintServiceFactories() - * </code>} and specifying a Pageable DocFlavor. + * StreamPrintServiceFactory.lookupStreamPrintServiceFactories() + * } and specifying a Pageable DocFlavor. * * @param mimeType the required output format, or null to mean any format. * @return a possibly empty array of 2D stream print service factories. @@ -155,7 +155,7 @@ /** * A <code>PrinterJob</code> object should be created using the - * static {@link #getPrinterJob() <code>getPrinterJob</code>} method. + * static {@link #getPrinterJob() getPrinterJob} method. */ public PrinterJob() { }
--- a/jdk/src/share/classes/java/beans/EventHandler.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/beans/EventHandler.java Fri Oct 11 03:06:10 2013 -0700 @@ -33,6 +33,7 @@ import java.security.PrivilegedAction; import sun.reflect.misc.MethodUtil; +import sun.reflect.misc.ReflectUtil; /** * The <code>EventHandler</code> class provides @@ -677,22 +678,38 @@ * * @see EventHandler */ - @SuppressWarnings("unchecked") public static <T> T create(Class<T> listenerInterface, Object target, String action, String eventPropertyName, String listenerMethodName) { // Create this first to verify target/action are non-null - EventHandler eventHandler = new EventHandler(target, action, + final EventHandler handler = new EventHandler(target, action, eventPropertyName, listenerMethodName); if (listenerInterface == null) { throw new NullPointerException( "listenerInterface must be non-null"); } - return (T)Proxy.newProxyInstance(target.getClass().getClassLoader(), - new Class<?>[] {listenerInterface}, - eventHandler); + final ClassLoader loader = getClassLoader(listenerInterface); + final Class<?>[] interfaces = {listenerInterface}; + return AccessController.doPrivileged(new PrivilegedAction<T>() { + @SuppressWarnings("unchecked") + public T run() { + return (T) Proxy.newProxyInstance(loader, interfaces, handler); + } + }); + } + + private static ClassLoader getClassLoader(Class<?> type) { + ReflectUtil.checkPackageAccess(type); + ClassLoader loader = type.getClassLoader(); + if (loader == null) { + loader = Thread.currentThread().getContextClassLoader(); // avoid use of BCP + if (loader == null) { + loader = ClassLoader.getSystemClassLoader(); + } + } + return loader; } }
--- a/jdk/src/share/classes/java/beans/Introspector.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/beans/Introspector.java Fri Oct 11 03:06:10 2013 -0700 @@ -87,7 +87,7 @@ * <p> * For more information about introspection and design patterns, please * consult the - * <a href="http://java.sun.com/products/javabeans/docs/index.html">JavaBeans™ specification</a>. + * <a href="http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html">JavaBeans™ specification</a>. */ public class Introspector {
--- a/jdk/src/share/classes/java/io/File.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/io/File.java Fri Oct 11 03:06:10 2013 -0700 @@ -1908,10 +1908,18 @@ } else { n = Math.abs(n); } + + // Use only the file name from the supplied prefix + prefix = (new File(prefix)).getName(); + String name = prefix + Long.toString(n) + suffix; File f = new File(dir, name); - if (!name.equals(f.getName()) || f.isInvalid()) - throw new IOException("Unable to create temporary file"); + if (!name.equals(f.getName()) || f.isInvalid()) { + if (System.getSecurityManager() != null) + throw new IOException("Unable to create temporary file"); + else + throw new IOException("Unable to create temporary file, " + f); + } return f; } }
--- a/jdk/src/share/classes/java/lang/Class.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/Class.java Fri Oct 11 03:06:10 2013 -0700 @@ -3414,16 +3414,20 @@ transient ClassValue.ClassValueMap classValueMap; /** - * Returns an AnnotatedType object that represents the use of a type to specify - * the superclass of the entity represented by this Class. (The <em>use</em> of type - * Foo to specify the superclass in '... extends Foo' is distinct from the - * <em>declaration</em> of type Foo.) + * Returns an {@code AnnotatedType} object that represents the use of a + * type to specify the superclass of the entity represented by this {@code + * Class} object. (The <em>use</em> of type Foo to specify the superclass + * in '... extends Foo' is distinct from the <em>declaration</em> of type + * Foo.) * - * If this Class represents a class type whose declaration does not explicitly - * indicate an annotated superclass, the return value is null. + * <p> If this {@code Class} object represents a type whose declaration + * does not explicitly indicate an annotated superclass, then the return + * value is an {@code AnnotatedType} object representing an element with no + * annotations. * - * If this Class represents either the Object class, an interface type, an - * array type, a primitive type, or void, the return value is null. + * <p> If this {@code Class} represents either the {@code Object} class, an + * interface type, an array type, a primitive type, or void, the return + * value is {@code null}. * * @return an object representing the superclass * @since 1.8 @@ -3441,30 +3445,33 @@ } /** - * Returns an array of AnnotatedType objects that represent the use of types to - * specify superinterfaces of the entity represented by this Class. (The <em>use</em> - * of type Foo to specify a superinterface in '... implements Foo' is - * distinct from the <em>declaration</em> of type Foo.) + * Returns an array of {@code AnnotatedType} objects that represent the use + * of types to specify superinterfaces of the entity represented by this + * {@code Class} object. (The <em>use</em> of type Foo to specify a + * superinterface in '... implements Foo' is distinct from the + * <em>declaration</em> of type Foo.) * - * If this Class represents a class, the return value is an array - * containing objects representing the uses of interface types to specify - * interfaces implemented by the class. The order of the objects in the - * array corresponds to the order of the interface types used in the - * 'implements' clause of the declaration of this Class. + * <p> If this {@code Class} object represents a class, the return value is + * an array containing objects representing the uses of interface types to + * specify interfaces implemented by the class. The order of the objects in + * the array corresponds to the order of the interface types used in the + * 'implements' clause of the declaration of this {@code Class} object. * - * If this Class represents an interface, the return value is an array - * containing objects representing the uses of interface types to specify - * interfaces directly extended by the interface. The order of the objects in - * the array corresponds to the order of the interface types used in the - * 'extends' clause of the declaration of this Class. + * <p> If this {@code Class} object represents an interface, the return + * value is an array containing objects representing the uses of interface + * types to specify interfaces directly extended by the interface. The + * order of the objects in the array corresponds to the order of the + * interface types used in the 'extends' clause of the declaration of this + * {@code Class} object. * - * If this Class represents a class or interface whose declaration does not - * explicitly indicate any annotated superinterfaces, the return value is an + * <p> If this {@code Class} object represents a class or interface whose + * declaration does not explicitly indicate any annotated superinterfaces, + * the return value is an array of length 0. + * + * <p> If this {@code Class} object represents either the {@code Object} + * class, an array type, a primitive type, or void, the return value is an * array of length 0. * - * If this Class represents either the Object class, an array type, a - * primitive type, or void, the return value is an array of length 0. - * * @return an array representing the superinterfaces * @since 1.8 */
--- a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Fri Oct 11 03:06:10 2013 -0700 @@ -125,10 +125,7 @@ this.implMethod = implMethod; this.implInfo = caller.revealDirect(implMethod); - // @@@ Temporary work-around pending resolution of 8005119 - this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial) - ? MethodHandleInfo.REF_invokeVirtual - : implInfo.getReferenceKind(); + this.implKind = implInfo.getReferenceKind(); this.implIsInstanceMethod = implKind == MethodHandleInfo.REF_invokeVirtual || implKind == MethodHandleInfo.REF_invokeSpecial ||
--- a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Fri Oct 11 03:06:10 2013 -0700 @@ -360,6 +360,10 @@ return new Name(mh, mhName); } + NamedFunction getterFunction(int i) { + return new NamedFunction(getters[i]); + } + static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class); private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) { @@ -394,6 +398,7 @@ private boolean isPlaceholder() { return clazz == null; } private static final HashMap<String, SpeciesData> CACHE = new HashMap<>(); + static { CACHE.put("", EMPTY); } // make bootstrap predictable private static final boolean INIT_DONE; // set after <clinit> finishes... SpeciesData extendWithType(char type) { @@ -524,18 +529,18 @@ * A concrete BMH species adheres to the following schema: * * <pre> - * class Species_<<types>> extends BoundMethodHandle { - * <<fields>> - * final SpeciesData speciesData() { return SpeciesData.get("<<types>>"); } + * class Species_[[types]] extends BoundMethodHandle { + * [[fields]] + * final SpeciesData speciesData() { return SpeciesData.get("[[types]]"); } * } * </pre> * - * The {@code <<types>>} signature is precisely the string that is passed to this + * The {@code [[types]]} signature is precisely the string that is passed to this * method. * - * The {@code <<fields>>} section consists of one field definition per character in + * The {@code [[fields]]} section consists of one field definition per character in * the type signature, adhering to the naming schema described in the definition of - * {@link #makeFieldName()}. + * {@link #makeFieldName}. * * For example, a concrete BMH species for two reference and one integral bound values * would have the following shape: @@ -817,7 +822,7 @@ * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through * {@link MethodHandle#linkToSpecial}. * - * The last {@link LambdaForm#Name Name} in the argument's form is expected to be the {@code void} + * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void} * result of the {@code <init>} invocation. This entry is replaced. */ private static MethodHandle linkConstructor(MethodHandle cmh) {
--- a/jdk/src/share/classes/java/lang/invoke/CallSite.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java Fri Oct 11 03:06:10 2013 -0700 @@ -60,7 +60,7 @@ * <p> * Here is a sample use of call sites and bootstrap methods which links every * dynamic call site to print its arguments: -<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java --> +<blockquote><pre>{@code static void test() throws Throwable { // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14); @@ -79,7 +79,7 @@ // ignore caller and name, but match the type: return new ConstantCallSite(printArgs.asType(type)); } -</pre></blockquote> +}</pre></blockquote> * @author John Rose, JSR 292 EG */ abstract @@ -199,12 +199,12 @@ * which has been linked to this call site. * <p> * This method is equivalent to the following code: - * <blockquote><pre> + * <blockquote><pre>{@code * MethodHandle getTarget, invoker, result; * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class)); * invoker = MethodHandles.exactInvoker(this.type()); * result = MethodHandles.foldArguments(invoker, getTarget) - * </pre></blockquote> + * }</pre></blockquote> * * @return a method handle which always invokes this call site's current target */ @@ -261,7 +261,7 @@ Object info, // Caller information: Class<?> callerClass) { - Object caller = IMPL_LOOKUP.in(callerClass); + MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass); CallSite site; try { Object binding; @@ -273,14 +273,44 @@ } else { Object[] argv = (Object[]) info; maybeReBoxElements(argv); - if (3 + argv.length > 255) - throw new BootstrapMethodError("too many bootstrap method arguments"); - MethodType bsmType = bootstrapMethod.type(); - if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class) - binding = bootstrapMethod.invoke(caller, name, type, argv); - else - binding = MethodHandles.spreadInvoker(bsmType, 3) - .invoke(bootstrapMethod, caller, name, type, argv); + switch (argv.length) { + case 0: + binding = bootstrapMethod.invoke(caller, name, type); + break; + case 1: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0]); + break; + case 2: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1]); + break; + case 3: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1], argv[2]); + break; + case 4: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1], argv[2], argv[3]); + break; + case 5: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1], argv[2], argv[3], argv[4]); + break; + case 6: + binding = bootstrapMethod.invoke(caller, name, type, + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + break; + default: + final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type) + if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY) + throw new BootstrapMethodError("too many bootstrap method arguments"); + MethodType bsmType = bootstrapMethod.type(); + MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length); + MethodHandle typedBSM = bootstrapMethod.asType(invocationType); + MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT); + binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv); + } } //System.out.println("BSM for "+name+type+" => "+binding); if (binding instanceof CallSite) {
--- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Oct 11 03:06:10 2013 -0700 @@ -257,12 +257,12 @@ assert(names.length == nameCursor); if (doesAlloc) { // names = { argx,y,z,... new C, init method } - names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]); - names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]); + names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]); } else if (needsInit) { - names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]); } else { - names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]); + names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]); } Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class); assert(outArgs[outArgs.length-1] == names[GET_MEMBER]); // look, shifted args! @@ -637,18 +637,18 @@ final int RESULT = nameCursor-1; // either the call or the cast Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); if (needsInit) - names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]); + names[INIT_BAR] = new Name(Lazy.NF_ensureInitialized, names[DMH_THIS]); if (needsCast && !isGetter) - names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]); + names[PRE_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[SET_VALUE]); Object[] outArgs = new Object[1 + linkerType.parameterCount()]; assert(outArgs.length == (isGetter ? 3 : 4)); outArgs[0] = UNSAFE; if (isStatic) { - outArgs[1] = names[F_HOLDER] = new Name(NF_staticBase, names[DMH_THIS]); - outArgs[2] = names[F_OFFSET] = new Name(NF_staticOffset, names[DMH_THIS]); + outArgs[1] = names[F_HOLDER] = new Name(Lazy.NF_staticBase, names[DMH_THIS]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_staticOffset, names[DMH_THIS]); } else { - outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]); - outArgs[2] = names[F_OFFSET] = new Name(NF_fieldOffset, names[DMH_THIS]); + outArgs[1] = names[OBJ_CHECK] = new Name(Lazy.NF_checkBase, names[OBJ_BASE]); + outArgs[2] = names[F_OFFSET] = new Name(Lazy.NF_fieldOffset, names[DMH_THIS]); } if (!isGetter) { outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]); @@ -656,7 +656,7 @@ for (Object a : outArgs) assert(a != null); names[LINKER_CALL] = new Name(linker, outArgs); if (needsCast && isGetter) - names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); + names[POST_CAST] = new Name(Lazy.NF_checkCast, names[DMH_THIS], names[LINKER_CALL]); for (Name n : names) assert(n != null); String fieldOrStatic = (isStatic ? "Static" : "Field"); String lambdaName = (linkerName + fieldOrStatic); // significant only for debugging @@ -665,48 +665,54 @@ return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT); } - private static final NamedFunction - NF_internalMemberName, - NF_internalMemberNameEnsureInit, - NF_ensureInitialized, - NF_fieldOffset, - NF_checkBase, - NF_staticBase, - NF_staticOffset, - NF_checkCast, - NF_allocateInstance, - NF_constructorMethod; - static { - try { - NamedFunction nfs[] = { - NF_internalMemberName = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberName", Object.class)), - NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), - NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("ensureInitialized", Object.class)), - NF_fieldOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("fieldOffset", Object.class)), - NF_checkBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkBase", Object.class)), - NF_staticBase = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticBase", Object.class)), - NF_staticOffset = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("staticOffset", Object.class)), - NF_checkCast = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("checkCast", Object.class, Object.class)), - NF_allocateInstance = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("allocateInstance", Object.class)), - NF_constructorMethod = new NamedFunction(DirectMethodHandle.class - .getDeclaredMethod("constructorMethod", Object.class)) - }; - for (NamedFunction nf : nfs) { - // Each nf must be statically invocable or we get tied up in our bootstraps. - assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; - nf.resolve(); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction + NF_internalMemberName, + NF_internalMemberNameEnsureInit, + NF_ensureInitialized, + NF_fieldOffset, + NF_checkBase, + NF_staticBase, + NF_staticOffset, + NF_checkCast, + NF_allocateInstance, + NF_constructorMethod; + static { + try { + NamedFunction nfs[] = { + NF_internalMemberName = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberName", Object.class)), + NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)), + NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("ensureInitialized", Object.class)), + NF_fieldOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("fieldOffset", Object.class)), + NF_checkBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkBase", Object.class)), + NF_staticBase = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticBase", Object.class)), + NF_staticOffset = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("staticOffset", Object.class)), + NF_checkCast = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("checkCast", Object.class, Object.class)), + NF_allocateInstance = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("allocateInstance", Object.class)), + NF_constructorMethod = new NamedFunction(DirectMethodHandle.class + .getDeclaredMethod("constructorMethod", Object.class)) + }; + for (NamedFunction nf : nfs) { + // Each nf must be statically invocable or we get tied up in our bootstraps. + assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf; + nf.resolve(); + } + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); } - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); } } }
--- a/jdk/src/share/classes/java/lang/invoke/InvokeGeneric.java Thu Oct 10 10:09:19 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2009, 2011, 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 java.lang.invoke; - -import sun.invoke.util.*; -import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; - -/** - * Adapters which manage inexact MethodHandle.invoke calls. - * The JVM calls one of these when the exact type match fails. - * @author jrose - */ -class InvokeGeneric { - // erased type for the call, which originates from an inexact invoke site - private final MethodType erasedCallerType; - // an invoker of type (MT, MH; A...) -> R - private final MethodHandle initialInvoker; - - /** Compute and cache information for this adapter, so that it can - * call out to targets of the erasure-family of the given erased type. - */ - /*non-public*/ InvokeGeneric(MethodType erasedCallerType) throws ReflectiveOperationException { - assert(erasedCallerType.equals(erasedCallerType.erase())); - this.erasedCallerType = erasedCallerType; - this.initialInvoker = makeInitialInvoker(); - assert initialInvoker.type().equals(erasedCallerType - .insertParameterTypes(0, MethodType.class, MethodHandle.class)) - : initialInvoker.type(); - } - - private static MethodHandles.Lookup lookup() { - return IMPL_LOOKUP; - } - - /** Return the adapter information for this type's erasure. */ - /*non-public*/ static MethodHandle generalInvokerOf(MethodType erasedCallerType) throws ReflectiveOperationException { - InvokeGeneric gen = new InvokeGeneric(erasedCallerType); - return gen.initialInvoker; - } - - private MethodHandle makeInitialInvoker() throws ReflectiveOperationException { - // postDispatch = #(MH'; MT, MH; A...){MH'(MT, MH; A)} - MethodHandle postDispatch = makePostDispatchInvoker(); - MethodHandle invoker; - if (returnConversionPossible()) { - invoker = MethodHandles.foldArguments(postDispatch, - dispatcher("dispatchWithConversion")); - } else { - invoker = MethodHandles.foldArguments(postDispatch, dispatcher("dispatch")); - } - return invoker; - } - - private static final Class<?>[] EXTRA_ARGS = { MethodType.class, MethodHandle.class }; - private MethodHandle makePostDispatchInvoker() { - // Take (MH'; MT, MH; A...) and run MH'(MT, MH; A...). - MethodType invokerType = erasedCallerType.insertParameterTypes(0, EXTRA_ARGS); - return invokerType.invokers().exactInvoker(); - } - private MethodHandle dropDispatchArguments(MethodHandle targetInvoker) { - assert(targetInvoker.type().parameterType(0) == MethodHandle.class); - return MethodHandles.dropArguments(targetInvoker, 1, EXTRA_ARGS); - } - - private MethodHandle dispatcher(String dispatchName) throws ReflectiveOperationException { - return lookup().bind(this, dispatchName, - MethodType.methodType(MethodHandle.class, - MethodType.class, MethodHandle.class)); - } - - static final boolean USE_AS_TYPE_PATH = true; - - /** Return a method handle to invoke on the callerType, target, and remaining arguments. - * The method handle must finish the call. - * This is the first look at the caller type and target. - */ - private MethodHandle dispatch(MethodType callerType, MethodHandle target) { - MethodType targetType = target.type(); - if (USE_AS_TYPE_PATH || target.isVarargsCollector()) { - MethodHandle newTarget = target.asType(callerType); - targetType = callerType; - Invokers invokers = targetType.invokers(); - MethodHandle invoker = invokers.erasedInvokerWithDrops; - if (invoker == null) { - invokers.erasedInvokerWithDrops = invoker = - dropDispatchArguments(invokers.erasedInvoker()); - } - return invoker.bindTo(newTarget); - } - throw new RuntimeException("NYI"); - } - - private MethodHandle dispatchWithConversion(MethodType callerType, MethodHandle target) { - MethodHandle finisher = dispatch(callerType, target); - if (returnConversionNeeded(callerType, target)) - finisher = addReturnConversion(finisher, callerType.returnType()); //FIXME: slow - return finisher; - } - - private boolean returnConversionPossible() { - Class<?> needType = erasedCallerType.returnType(); - return !needType.isPrimitive(); - } - private boolean returnConversionNeeded(MethodType callerType, MethodHandle target) { - Class<?> needType = callerType.returnType(); - if (needType == erasedCallerType.returnType()) - return false; // no conversions possible, since must be primitive or Object - Class<?> haveType = target.type().returnType(); - if (VerifyType.isNullConversion(haveType, needType) && !needType.isInterface()) - return false; - return true; - } - private MethodHandle addReturnConversion(MethodHandle finisher, Class<?> type) { - // FIXME: This is slow because it creates a closure node on every call that requires a return cast. - MethodType finisherType = finisher.type(); - MethodHandle caster = ValueConversions.identity(type); - caster = caster.asType(caster.type().changeParameterType(0, finisherType.returnType())); - finisher = MethodHandles.filterReturnValue(finisher, caster); - return finisher.asType(finisherType); - } - - public String toString() { - return "InvokeGeneric"+erasedCallerType; - } -}
--- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Oct 11 03:06:10 2013 -0700 @@ -242,9 +242,6 @@ /** * Extract the MemberName of a newly-defined method. - * - * @param classFile - * @return */ private MemberName loadMethod(byte[] classFile) { Class<?> invokerClass = loadAndInitializeInvokerClass(classFile, cpPatches(classFile)); @@ -253,10 +250,6 @@ /** * Define a given class as anonymous class in the runtime system. - * - * @param classBytes - * @param patches - * @return */ private static Class<?> loadAndInitializeInvokerClass(byte[] classBytes, Object[] patches) { Class<?> invokerClass = UNSAFE.defineAnonymousClass(HOST_CLASS, classBytes, patches); @@ -264,14 +257,6 @@ return invokerClass; } - /** - * TODO - * - * @param invokerClass - * @param name - * @param type - * @return - */ private static MemberName resolveInvokerMember(Class<?> invokerClass, String name, MethodType type) { MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic); //System.out.println("resolveInvokerMember => "+member); @@ -499,10 +484,6 @@ /** * Generate customized bytecode for a given LambdaForm. - * - * @param form - * @param invokerType - * @return */ static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) { InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType); @@ -565,8 +546,6 @@ /** * Emit an invoke for the given name. - * - * @param name */ void emitInvoke(Name name) { if (true) { @@ -645,8 +624,6 @@ /** * Emit an invoke for the given name, using the MemberName directly. - * - * @param name */ void emitStaticInvoke(MemberName member, Name name) { assert(member.equals(name.function.member())); @@ -690,9 +667,6 @@ /** * Check if MemberName is a call to MethodHandleImpl.selectAlternative. - * - * @param member - * @return true if member is a call to MethodHandleImpl.selectAlternative */ private boolean isSelectAlternative(MemberName member) { return member != null && @@ -704,14 +678,12 @@ * Emit bytecode for the selectAlternative idiom. * * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest): - * + * <blockquote><pre>{@code * Lambda(a0:L,a1:I)=>{ * t2:I=foo.test(a1:I); * t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int)); * t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I} - * - * @param selectAlternativeName - * @param invokeBasicName + * }</pre></blockquote> */ private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) { MethodType type = selectAlternativeName.function.methodType(); @@ -750,11 +722,6 @@ mv.visitLabel(L_done); } - /** - * - * @param name - * @param paramIndex - */ private void emitPushArgument(Name name, int paramIndex) { Object arg = name.arguments[paramIndex]; char ptype = name.function.parameterType(paramIndex); @@ -923,9 +890,6 @@ /** * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments. - * - * @param sig - * @return */ static MemberName generateLambdaFormInterpreterEntryPoint(String sig) { assert(LambdaForm.isValidSignature(sig)); @@ -993,10 +957,6 @@ /** * Generate bytecode for a NamedFunction invoker. - * - * @param srcType - * @param dstType - * @return */ static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) { MethodType invokerType = LambdaForm.NamedFunction.INVOKER_METHOD_TYPE;
--- a/jdk/src/share/classes/java/lang/invoke/Invokers.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java Fri Oct 11 03:06:10 2013 -0700 @@ -44,6 +44,7 @@ // exact invoker for the outgoing call private /*lazy*/ MethodHandle exactInvoker; + private /*lazy*/ MethodHandle basicInvoker; // invokeBasic (unchecked exact) // erased (partially untyped but with primitives) invoker for the outgoing call // FIXME: get rid of @@ -74,21 +75,7 @@ /*non-public*/ MethodHandle exactInvoker() { MethodHandle invoker = exactInvoker; if (invoker != null) return invoker; - MethodType mtype = targetType; - MethodType invokerType = mtype.invokerType(); - LambdaForm lform; - final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value - if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - MTYPE_ARG_APPENDED) { - lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_INVOKER); - invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype); - } else { - // At maximum arity, we cannot afford an extra mtype argument, - // so build a fully customized (non-cached) invoker form. - lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER); - invoker = SimpleMethodHandle.make(invokerType, lform); - } - invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invokeExact", mtype)); - assert(checkInvoker(invoker)); + invoker = makeExactOrGeneralInvoker(true); exactInvoker = invoker; return invoker; } @@ -96,43 +83,56 @@ /*non-public*/ MethodHandle generalInvoker() { MethodHandle invoker = generalInvoker; if (invoker != null) return invoker; - MethodType mtype = targetType; - MethodType invokerType = mtype.invokerType(); - LambdaForm lform; - final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value - assert(GENERIC_INVOKER_SLOP >= MTYPE_ARG_APPENDED); - if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - GENERIC_INVOKER_SLOP) { - prepareForGenericCall(mtype); - lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_INVOKER); - invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype); - } else { - // At maximum arity, we cannot afford an extra mtype argument, - // so build a fully customized (non-cached) invoker form. - lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER); - invoker = SimpleMethodHandle.make(invokerType, lform); - } - invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invoke", mtype)); - assert(checkInvoker(invoker)); + invoker = makeExactOrGeneralInvoker(false); generalInvoker = invoker; return invoker; } - /*non-public*/ MethodHandle makeBasicInvoker() { - MethodHandle invoker = DirectMethodHandle.make(invokeBasicMethod(targetType)); - assert(targetType == targetType.basicType()); - // Note: This is not cached here. It is cached by the calling MethodTypeForm. + private MethodHandle makeExactOrGeneralInvoker(boolean isExact) { + MethodType mtype = targetType; + MethodType invokerType = mtype.invokerType(); + int which = (isExact ? MethodTypeForm.LF_EX_INVOKER : MethodTypeForm.LF_GEN_INVOKER); + LambdaForm lform = invokeHandleForm(mtype, false, which); + MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype); + String whichName = (isExact ? "invokeExact" : "invoke"); + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke(whichName, mtype)); assert(checkInvoker(invoker)); + maybeCompileToBytecode(invoker); return invoker; } - static MemberName invokeBasicMethod(MethodType type) { - type = type.basicType(); - String name = "invokeBasic"; + /** If the target type seems to be common enough, eagerly compile the invoker to bytecodes. */ + private void maybeCompileToBytecode(MethodHandle invoker) { + final int EAGER_COMPILE_ARITY_LIMIT = 10; + if (targetType == targetType.erase() && + targetType.parameterCount() < EAGER_COMPILE_ARITY_LIMIT) { + invoker.form.compileToBytecode(); + } + } + + /*non-public*/ MethodHandle basicInvoker() { + MethodHandle invoker = basicInvoker; + if (invoker != null) return invoker; + MethodType basicType = targetType.basicType(); + if (basicType != targetType) { + // double cache; not used significantly + return basicInvoker = basicType.invokers().basicInvoker(); + } + MemberName method = invokeBasicMethod(basicType); + invoker = DirectMethodHandle.make(method); + assert(checkInvoker(invoker)); + basicInvoker = invoker; + return invoker; + } + + // This next one is called from LambdaForm.NamedFunction.<init>. + /*non-public*/ static MemberName invokeBasicMethod(MethodType basicType) { + assert(basicType == basicType.basicType()); try { //Lookup.findVirtual(MethodHandle.class, name, type); - return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, name, type); + return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, "invokeBasic", basicType); } catch (ReflectiveOperationException ex) { - throw newInternalError("JVM cannot find invoker for "+type, ex); + throw newInternalError("JVM cannot find invoker for "+basicType, ex); } } @@ -184,6 +184,7 @@ vaInvoker = MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader); } assert(vaInvoker.type().equals(spreadInvokerType.invokerType())); + maybeCompileToBytecode(vaInvoker); spreadInvokers[leadingArgCount] = vaInvoker; return vaInvoker; } @@ -231,32 +232,38 @@ return "Invokers"+targetType; } - static MemberName exactInvokerMethod(MethodType mtype, Object[] appendixResult) { + static MemberName methodHandleInvokeLinkerMethod(String name, + MethodType mtype, + Object[] appendixResult) { + int which; + switch (name) { + case "invokeExact": which = MethodTypeForm.LF_EX_LINKER; break; + case "invoke": which = MethodTypeForm.LF_GEN_LINKER; break; + default: throw new InternalError("not invoker: "+name); + } LambdaForm lform; - final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value - if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MTYPE_ARG_APPENDED) { - lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_LINKER); + if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) { + lform = invokeHandleForm(mtype, false, which); appendixResult[0] = mtype; } else { - lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_LINKER); + lform = invokeHandleForm(mtype, true, which); } return lform.vmentry; } - static MemberName genericInvokerMethod(MethodType mtype, Object[] appendixResult) { - LambdaForm lform; - final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value - if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - (MTYPE_ARG_APPENDED + GENERIC_INVOKER_SLOP)) { - lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_LINKER); - appendixResult[0] = mtype; - prepareForGenericCall(mtype); - } else { - lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_LINKER); - } - return lform.vmentry; - } + // argument count to account for trailing "appendix value" (typically the mtype) + private static final int MH_LINKER_ARG_APPENDED = 1; - private static LambdaForm invokeForm(MethodType mtype, boolean customized, int which) { + /** Returns an adapter for invokeExact or generic invoke, as a MH or constant pool linker. + * If !customized, caller is responsible for supplying, during adapter execution, + * a copy of the exact mtype. This is because the adapter might be generalized to + * a basic type. + * @param mtype the caller's method type (either basic or full-custom) + * @param customized whether to use a trailing appendix argument (to carry the mtype) + * @param which bit-encoded 0x01 whether it is a CP adapter ("linker") or MHs.invoker value ("invoker"); + * 0x02 whether it is for invokeExact or generic invoke + */ + private static LambdaForm invokeHandleForm(MethodType mtype, boolean customized, int which) { boolean isCached; if (!customized) { mtype = mtype.basicType(); // normalize Z to I, String to Object, etc. @@ -301,41 +308,24 @@ : Arrays.asList(mtype, customized, which, nameCursor, names.length); if (MTYPE_ARG >= INARG_LIMIT) { assert(names[MTYPE_ARG] == null); - names[MTYPE_ARG] = BoundMethodHandle.getSpeciesData("L").getterName(names[THIS_MH], 0); + NamedFunction getter = BoundMethodHandle.getSpeciesData("L").getterFunction(0); + names[MTYPE_ARG] = new Name(getter, names[THIS_MH]); // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM) } // Make the final call. If isGeneric, then prepend the result of type checking. - MethodType outCallType; - Object[] outArgs; + MethodType outCallType = mtype.basicType(); + Object[] outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class); Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]); if (!isGeneric) { names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg); // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*) - outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class); - outCallType = mtype; - } else if (customized) { - names[CHECK_TYPE] = new Name(NF_asType, names[CALL_MH], mtypeArg); - // mh.invokeGeneric(a*):R => - // let mt=TYPEOF(a*:R), tmh=asType(mh, mt); - // tmh.invokeBasic(a*) - outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class); - outCallType = mtype; } else { names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg); - // mh.invokeGeneric(a*):R => - // let mt=TYPEOF(a*:R), gamh=checkGenericType(mh, mt); - // gamh.invokeBasic(mt, mh, a*) - final int PREPEND_GAMH = 0, PREPEND_MT = 1, PREPEND_COUNT = 2; - assert(GENERIC_INVOKER_SLOP == PREPEND_COUNT); - outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT + PREPEND_COUNT, Object[].class); - // prepend arguments: - System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT); - outArgs[PREPEND_GAMH] = names[CHECK_TYPE]; - outArgs[PREPEND_MT] = mtypeArg; - outCallType = mtype.insertParameterTypes(0, MethodType.class, MethodHandle.class); + // mh.invokeGeneric(a*):R => checkGenericType(mh, TYPEOF(a*:R)).invokeBasic(a*) + outArgs[0] = names[CHECK_TYPE]; } - names[LINKER_CALL] = new Name(invokeBasicMethod(outCallType), outArgs); + names[LINKER_CALL] = new Name(outCallType, outArgs); lform = new LambdaForm(debugName, INARG_LIMIT, names); if (isLinker) lform.compileToBytecode(); // JVM needs a real methodOop @@ -343,7 +333,6 @@ lform = mtype.form().setCachedLambdaForm(which, lform); return lform; } - private static final int GENERIC_INVOKER_SLOP = 2; // used elsewhere to avoid arity problems /*non-public*/ static WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) { @@ -362,47 +351,53 @@ throw newWrongMethodTypeException(expected, actual); } - /** Static definition of MethodHandle.invokeGeneric checking code. */ + /** Static definition of MethodHandle.invokeGeneric checking code. + * Directly returns the type-adjusted MH to invoke, as follows: + * {@code (R)MH.invoke(a*) => MH.asType(TYPEOF(a*:R)).invokeBasic(a*)} + */ /*non-public*/ static @ForceInline Object checkGenericType(Object mhObj, Object expectedObj) { MethodHandle mh = (MethodHandle) mhObj; MethodType expected = (MethodType) expectedObj; - //MethodType actual = mh.type(); - MethodHandle gamh = expected.form().genericInvoker; - if (gamh != null) return gamh; - return prepareForGenericCall(expected); - } - - /** - * Returns an adapter GA for invoking a MH with type adjustments. - * The MethodType of the generic invocation site is prepended to MH - * and its arguments as follows: - * {@code (R)MH.invoke(A*) => GA.invokeBasic(TYPEOF<A*,R>, MH, A*)} - */ - /*non-public*/ static MethodHandle prepareForGenericCall(MethodType mtype) { - // force any needed adapters to be preconstructed - MethodTypeForm form = mtype.form(); - MethodHandle gamh = form.genericInvoker; - if (gamh != null) return gamh; - try { - // Trigger adapter creation. - gamh = InvokeGeneric.generalInvokerOf(form.erasedType); - form.genericInvoker = gamh; - return gamh; - } catch (Exception ex) { - throw newInternalError("Exception while resolving inexact invoke", ex); - } + if (mh.type() == expected) return mh; + MethodHandle atc = mh.asTypeCache; + if (atc != null && atc.type() == expected) return atc; + return mh.asType(expected); + /* Maybe add more paths here. Possible optimizations: + * for (R)MH.invoke(a*), + * let MT0 = TYPEOF(a*:R), MT1 = MH.type + * + * if MT0==MT1 or MT1 can be safely called by MT0 + * => MH.invokeBasic(a*) + * if MT1 can be safely called by MT0[R := Object] + * => MH.invokeBasic(a*) & checkcast(R) + * if MT1 can be safely called by MT0[* := Object] + * => checkcast(A)* & MH.invokeBasic(a*) & checkcast(R) + * if a big adapter BA can be pulled out of (MT0,MT1) + * => BA.invokeBasic(MT0,MH,a*) + * if a local adapter LA can cached on static CS0 = new GICS(MT0) + * => CS0.LA.invokeBasic(MH,a*) + * else + * => MH.asType(MT0).invokeBasic(A*) + */ } static MemberName linkToCallSiteMethod(MethodType mtype) { - LambdaForm lform = callSiteForm(mtype); + LambdaForm lform = callSiteForm(mtype, false); return lform.vmentry; } - private static LambdaForm callSiteForm(MethodType mtype) { + static MemberName linkToTargetMethod(MethodType mtype) { + LambdaForm lform = callSiteForm(mtype, true); + return lform.vmentry; + } + + // skipCallSite is true if we are optimizing a ConstantCallSite + private static LambdaForm callSiteForm(MethodType mtype, boolean skipCallSite) { mtype = mtype.basicType(); // normalize Z to I, String to Object, etc. - LambdaForm lform = mtype.form().cachedLambdaForm(MethodTypeForm.LF_CS_LINKER); + final int which = (skipCallSite ? MethodTypeForm.LF_MH_LINKER : MethodTypeForm.LF_CS_LINKER); + LambdaForm lform = mtype.form().cachedLambdaForm(which); if (lform != null) return lform; // exactInvokerForm (Object,Object)Object // link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial @@ -410,24 +405,26 @@ final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount(); final int INARG_LIMIT = OUTARG_LIMIT + 1; int nameCursor = OUTARG_LIMIT; - final int CSITE_ARG = nameCursor++; // the last in-argument - final int CALL_MH = nameCursor++; // result of getTarget + final int APPENDIX_ARG = nameCursor++; // the last in-argument + final int CSITE_ARG = skipCallSite ? -1 : APPENDIX_ARG; + final int CALL_MH = skipCallSite ? APPENDIX_ARG : nameCursor++; // result of getTarget final int LINKER_CALL = nameCursor++; - MethodType invokerFormType = mtype.appendParameterTypes(CallSite.class); + MethodType invokerFormType = mtype.appendParameterTypes(skipCallSite ? MethodHandle.class : CallSite.class); Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType); assert(names.length == nameCursor); - assert(names[CSITE_ARG] != null); - names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]); + assert(names[APPENDIX_ARG] != null); + if (!skipCallSite) + names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]); // (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*) final int PREPEND_MH = 0, PREPEND_COUNT = 1; Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class); // prepend MH argument: System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT); outArgs[PREPEND_MH] = names[CALL_MH]; - names[LINKER_CALL] = new Name(invokeBasicMethod(mtype), outArgs); - lform = new LambdaForm("linkToCallSite", INARG_LIMIT, names); + names[LINKER_CALL] = new Name(mtype, outArgs); + lform = new LambdaForm((skipCallSite ? "linkToTargetMethod" : "linkToCallSite"), INARG_LIMIT, names); lform.compileToBytecode(); // JVM needs a real methodOop - lform = mtype.form().setCachedLambdaForm(MethodTypeForm.LF_CS_LINKER, lform); + lform = mtype.form().setCachedLambdaForm(which, lform); return lform; }
--- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java Fri Oct 11 03:06:10 2013 -0700 @@ -50,7 +50,7 @@ * The result of the lambda is defined as one of the names, often the last one. * <p> * Here is an approximate grammar: - * <pre> + * <blockquote><pre>{@code * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}" * ArgName = "a" N ":" T * TempName = "t" N ":" T "=" Function "(" Argument* ");" @@ -60,7 +60,7 @@ * NameRef = "a" N | "t" N * N = (any whole number) * T = "L" | "I" | "J" | "F" | "D" | "V" - * </pre> + * }</pre></blockquote> * Names are numbered consecutively from left to right starting at zero. * (The letters are merely a taste of syntax sugar.) * Thus, the first temporary (if any) is always numbered N (where N=arity). @@ -69,7 +69,7 @@ * A lambda has a void result if and only if its result index is -1. * If a temporary has the type "V", it cannot be the subject of a NameRef, * even though possesses a number. - * Note that all reference types are erased to "L", which stands for {@code Object). + * Note that all reference types are erased to "L", which stands for {@code Object}. * All subword types (boolean, byte, short, char) are erased to "I" which is {@code int}. * The other types stand for the usual primitive types. * <p> @@ -89,7 +89,7 @@ * encoded by using temporary expressions which call type-transformed identity functions. * <p> * Examples: - * <pre> + * <blockquote><pre>{@code * (a0:J)=>{ a0 } * == identity(long) * (a0:I)=>{ t1:V = System.out#println(a0); void } @@ -113,14 +113,14 @@ * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0); * t3:L = Class#cast(t2,a1); t3 } * == invoker for identity method handle which performs cast - * </pre> + * }</pre></blockquote> * <p> * @author John Rose, JSR 292 EG */ class LambdaForm { final int arity; final int result; - final Name[] names; + @Stable final Name[] names; final String debugName; MemberName vmentry; // low-level behavior, or null if not yet prepared private boolean isCompiled; @@ -457,7 +457,7 @@ isCompiled = true; return vmentry; } catch (Error | Exception ex) { - throw newInternalError(this.toString(), ex); + throw newInternalError("compileToBytecode", ex); } } @@ -683,8 +683,9 @@ */ static void traceInterpreter(String event, Object obj, Object... args) { - if (!TRACE_INTERPRETER) return; - System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : "")); + if (TRACE_INTERPRETER) { + System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : "")); + } } static void traceInterpreter(String event, Object obj) { traceInterpreter(event, obj, (Object[])null); @@ -971,8 +972,8 @@ static class NamedFunction { final MemberName member; - MethodHandle resolvedHandle; - MethodHandle invoker; + @Stable MethodHandle resolvedHandle; + @Stable MethodHandle invoker; NamedFunction(MethodHandle resolvedHandle) { this(resolvedHandle.internalMemberName(), resolvedHandle); @@ -982,6 +983,16 @@ //resolvedHandle = eraseSubwordTypes(resolvedHandle); this.resolvedHandle = resolvedHandle; } + NamedFunction(MethodType basicInvokerType) { + assert(basicInvokerType == basicInvokerType.basicType()) : basicInvokerType; + if (basicInvokerType.parameterSlotCount() < MethodType.MAX_MH_INVOKER_ARITY) { + this.resolvedHandle = basicInvokerType.invokers().basicInvoker(); + this.member = resolvedHandle.internalMemberName(); + } else { + // necessary to pass BigArityTest + this.member = Invokers.invokeBasicMethod(basicInvokerType); + } + } // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc. // Any LambdaForm containing such a member is not interpretable. @@ -1229,7 +1240,7 @@ } public String toString() { - if (member == null) return resolvedHandle.toString(); + if (member == null) return String.valueOf(resolvedHandle); return member.getDeclaringClass().getSimpleName()+"."+member.getName(); } } @@ -1267,7 +1278,7 @@ final char type; private short index; final NamedFunction function; - final Object[] arguments; + @Stable final Object[] arguments; private Name(int index, char type, NamedFunction function, Object[] arguments) { this.index = (short)index; @@ -1279,6 +1290,10 @@ Name(MethodHandle function, Object... arguments) { this(new NamedFunction(function), arguments); } + Name(MethodType functionType, Object... arguments) { + this(new NamedFunction(functionType), arguments); + assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == 'L'); + } Name(MemberName function, Object... arguments) { this(new NamedFunction(function), arguments); } @@ -1426,8 +1441,6 @@ * Does this Name precede the given binding node in some canonical order? * This predicate is used to order data bindings (via insertion sort) * with some stability. - * @param binding - * @return */ boolean isSiblingBindingBefore(Name binding) { assert(!binding.isParam()); @@ -1622,4 +1635,12 @@ */ static { NamedFunction.initializeInvokers(); } + + // The following hack is necessary in order to suppress TRACE_INTERPRETER + // during execution of the static initializes of this class. + // Turning on TRACE_INTERPRETER too early will cause + // stack overflows and other misbehavior during attempts to trace events + // that occur during LambdaForm.<clinit>. + // Therefore, do not move this line higher in this file, and do not remove. + private static final boolean TRACE_INTERPRETER = MethodHandleStatics.TRACE_INTERPRETER; }
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java Fri Oct 11 03:06:10 2013 -0700 @@ -70,13 +70,13 @@ * @author jrose */ /*non-public*/ final class MemberName implements Member, Cloneable { - private Class<?> clazz; // class in which the method is defined - private String name; // may be null if not yet materialized - private Object type; // may be null if not yet materialized - private int flags; // modifier bits; see reflect.Modifier + private Class<?> clazz; // class in which the method is defined + private String name; // may be null if not yet materialized + private Object type; // may be null if not yet materialized + private int flags; // modifier bits; see reflect.Modifier //@Injected JVM_Method* vmtarget; //@Injected int vmindex; - private Object resolution; // if null, this guy is resolved + private Object resolution; // if null, this guy is resolved /** Return the declaring class of this member. * In the case of a bare name and type, the declaring class will be null. @@ -98,7 +98,9 @@ public String getName() { if (name == null) { expandFromVM(); - if (name == null) return null; + if (name == null) { + return null; + } } return name; } @@ -119,28 +121,39 @@ public MethodType getMethodType() { if (type == null) { expandFromVM(); - if (type == null) return null; + if (type == null) { + return null; + } + } + if (!isInvocable()) { + throw newIllegalArgumentException("not invocable, no method type"); } - if (!isInvocable()) - throw newIllegalArgumentException("not invocable, no method type"); - if (type instanceof MethodType) { - return (MethodType) type; + + { + // Get a snapshot of type which doesn't get changed by racing threads. + final Object type = this.type; + if (type instanceof MethodType) { + return (MethodType) type; + } } - if (type instanceof String) { - String sig = (String) type; - MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader()); - this.type = res; - return res; + + // type is not a MethodType yet. Convert it thread-safely. + synchronized (this) { + if (type instanceof String) { + String sig = (String) type; + MethodType res = MethodType.fromMethodDescriptorString(sig, getClassLoader()); + type = res; + } else if (type instanceof Object[]) { + Object[] typeInfo = (Object[]) type; + Class<?>[] ptypes = (Class<?>[]) typeInfo[1]; + Class<?> rtype = (Class<?>) typeInfo[0]; + MethodType res = MethodType.methodType(rtype, ptypes); + type = res; + } + // Make sure type is a MethodType for racing threads. + assert type instanceof MethodType : "bad method type " + type; } - if (type instanceof Object[]) { - Object[] typeInfo = (Object[]) type; - Class<?>[] ptypes = (Class<?>[]) typeInfo[1]; - Class<?> rtype = (Class<?>) typeInfo[0]; - MethodType res = MethodType.methodType(rtype, ptypes); - this.type = res; - return res; - } - throw new InternalError("bad method type "+type); + return (MethodType) type; } /** Return the actual type under which this method or constructor must be invoked. @@ -173,21 +186,34 @@ public Class<?> getFieldType() { if (type == null) { expandFromVM(); - if (type == null) return null; + if (type == null) { + return null; + } } - if (isInvocable()) + if (isInvocable()) { throw newIllegalArgumentException("not a field or nested class, no simple type"); - if (type instanceof Class<?>) { - return (Class<?>) type; } - if (type instanceof String) { - String sig = (String) type; - MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader()); - Class<?> res = mtype.returnType(); - this.type = res; - return res; + + { + // Get a snapshot of type which doesn't get changed by racing threads. + final Object type = this.type; + if (type instanceof Class<?>) { + return (Class<?>) type; + } } - throw new InternalError("bad field type "+type); + + // type is not a Class yet. Convert it thread-safely. + synchronized (this) { + if (type instanceof String) { + String sig = (String) type; + MethodType mtype = MethodType.fromMethodDescriptorString("()"+sig, getClassLoader()); + Class<?> res = mtype.returnType(); + type = res; + } + // Make sure type is a Class for racing threads. + assert type instanceof Class<?> : "bad field type " + type; + } + return (Class<?>) type; } /** Utility method to produce either the method type or field type of this member. */ @@ -201,10 +227,10 @@ public String getSignature() { if (type == null) { expandFromVM(); - if (type == null) return null; + if (type == null) { + return null; + } } - if (type instanceof String) - return (String) type; if (isInvocable()) return BytecodeDescriptor.unparse(getMethodType()); else @@ -463,10 +489,17 @@ //assert(referenceKindIsConsistent()); // do this after resolution } + /** + * Calls down to the VM to fill in the fields. This method is + * synchronized to avoid racing calls. + */ private void expandFromVM() { - if (!isResolved()) return; - if (type instanceof Object[]) - type = null; // don't saddle JVM w/ typeInfo + if (type != null) { + return; + } + if (!isResolved()) { + return; + } MethodHandleNatives.expand(this); } @@ -523,6 +556,9 @@ } throw new IllegalArgumentException(this.toString()); } + /** If this MN is not REF_newInvokeSpecial, return a clone with that ref. kind. + * In that case it must already be REF_invokeSpecial. + */ public MemberName asConstructor() { switch (getReferenceKind()) { case REF_invokeSpecial: return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial); @@ -530,6 +566,32 @@ } throw new IllegalArgumentException(this.toString()); } + /** If this MN is a REF_invokeSpecial, return a clone with the "normal" kind + * REF_invokeVirtual; also switch either to REF_invokeInterface if clazz.isInterface. + * The end result is to get a fully virtualized version of the MN. + * (Note that resolving in the JVM will sometimes devirtualize, changing + * REF_invokeVirtual of a final to REF_invokeSpecial, and REF_invokeInterface + * in some corner cases to either of the previous two; this transform + * undoes that change under the assumption that it occurred.) + */ + public MemberName asNormalOriginal() { + byte normalVirtual = clazz.isInterface() ? REF_invokeInterface : REF_invokeVirtual; + byte refKind = getReferenceKind(); + byte newRefKind = refKind; + MemberName result = this; + switch (refKind) { + case REF_invokeInterface: + case REF_invokeVirtual: + case REF_invokeSpecial: + newRefKind = normalVirtual; + break; + } + if (newRefKind == refKind) + return this; + result = clone().changeReferenceKind(newRefKind, refKind); + assert(this.referenceKindIsConsistentWith(result.getReferenceKind())); + return result; + } /** Create a name for the given reflected constructor. The resulting name will be in a resolved state. */ @SuppressWarnings("LeakingThisInConstructor") public MemberName(Constructor<?> ctor) { @@ -627,7 +689,7 @@ @Override public int hashCode() { - return Objects.hash(clazz, flags, name, getType()); + return Objects.hash(clazz, getReferenceKind(), name, getType()); } @Override public boolean equals(Object that) { @@ -643,13 +705,14 @@ if (this == that) return true; if (that == null) return false; return this.clazz == that.clazz - && this.flags == that.flags + && this.getReferenceKind() == that.getReferenceKind() && Objects.equals(this.name, that.name) && Objects.equals(this.getType(), that.getType()); } // Construction from symbolic parts, for queries: - /** Create a field or type name from the given components: Declaring class, name, type, reference kind. + /** Create a field or type name from the given components: + * Declaring class, name, type, reference kind. * The declaring class may be supplied as null if this is to be a bare name and type. * The resulting name will in an unresolved state. */ @@ -673,21 +736,34 @@ * The resulting name will in an unresolved state. */ public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) { - @SuppressWarnings("LocalVariableHidesMemberVariable") - int flags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD); - init(defClass, name, type, flagsMods(flags, 0, refKind)); + int initFlags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD); + init(defClass, name, type, flagsMods(initFlags, 0, refKind)); initResolved(false); } -// /** Create a method or constructor name from the given components: Declaring class, name, type, modifiers. -// * It will be a constructor if and only if the name is {@code "<init>"}. -// * The declaring class may be supplied as null if this is to be a bare name and type. -// * The modifier flags default to zero. -// * The resulting name will in an unresolved state. -// */ -// public MemberName(Class<?> defClass, String name, MethodType type, Void unused) { -// this(defClass, name, type, REF_NONE); -// } - + /** Create a method, constructor, or field name from the given components: + * Reference kind, declaring class, name, type. + */ + public MemberName(byte refKind, Class<?> defClass, String name, Object type) { + int kindFlags; + if (MethodHandleNatives.refKindIsField(refKind)) { + kindFlags = IS_FIELD; + if (!(type instanceof Class)) + throw newIllegalArgumentException("not a field type"); + } else if (MethodHandleNatives.refKindIsMethod(refKind)) { + kindFlags = IS_METHOD; + if (!(type instanceof MethodType)) + throw newIllegalArgumentException("not a method type"); + } else if (refKind == REF_newInvokeSpecial) { + kindFlags = IS_CONSTRUCTOR; + if (!(type instanceof MethodType) || + !CONSTRUCTOR_NAME.equals(name)) + throw newIllegalArgumentException("not a constructor type or name"); + } else { + throw newIllegalArgumentException("bad reference kind "+refKind); + } + init(defClass, name, type, flagsMods(kindFlags, 0, refKind)); + initResolved(false); + } /** Query whether this member name is resolved to a non-static, non-final method. */ public boolean hasReceiverTypeDispatch() {
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Fri Oct 11 03:06:10 2013 -0700 @@ -292,7 +292,7 @@ * generates a single invokevirtual instruction with * the symbolic type descriptor indicated in the following comment. * In these examples, the helper method {@code assertEquals} is assumed to - * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals } + * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals} * on its arguments, and asserts that the result is true. * * <h1>Exceptions</h1> @@ -392,7 +392,7 @@ * Java types. * <ul> * <li>Method types range over all possible arities, - * from no arguments to up to 255 of arguments (a limit imposed by the JVM). + * from no arguments to up to the <a href="MethodHandle.html#maxarity">maximum number</a> of allowed arguments. * Generics are not variadic, and so cannot represent this.</li> * <li>Method types can specify arguments of primitive types, * which Java generic types cannot range over.</li> @@ -402,6 +402,22 @@ * genericity with a Java type parameter.</li> * </ul> * + * <h1><a name="maxarity"></a>Arity limits</h1> + * The JVM imposes on all methods and constructors of any kind an absolute + * limit of 255 stacked arguments. This limit can appear more restrictive + * in certain cases: + * <ul> + * <li>A {@code long} or {@code double} argument counts (for purposes of arity limits) as two argument slots. + * <li>A non-static method consumes an extra argument for the object on which the method is called. + * <li>A constructor consumes an extra argument for the object which is being constructed. + * <li>Since a method handle’s {@code invoke} method (or other signature-polymorphic method) is non-virtual, + * it consumes an extra argument for the method handle itself, in addition to any non-virtual receiver object. + * </ul> + * These limits imply that certain method handles cannot be created, solely because of the JVM limit on stacked arguments. + * For example, if a static JVM method accepts exactly 255 arguments, a method handle cannot be created for it. + * Attempts to create method handles with impossible method types lead to an {@link IllegalArgumentException}. + * In particular, a method handle’s type must not have an arity of the exact maximum 255. + * * @see MethodType * @see MethodHandles * @author John Rose, JSR 292 EG @@ -420,6 +436,8 @@ private final MethodType type; /*private*/ final LambdaForm form; // form is not private so that invokers can easily fetch it + /*private*/ MethodHandle asTypeCache; + // asTypeCache is not private so that invokers can easily fetch it /** * Reports the type of this method handle. @@ -557,10 +575,10 @@ /*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable; /** - * Performs a variable arity invocation, passing the arguments in the given array + * Performs a variable arity invocation, passing the arguments in the given list * to the method handle, as if via an inexact {@link #invoke invoke} from a call site * which mentions only the type {@code Object}, and whose arity is the length - * of the argument array. + * of the argument list. * <p> * Specifically, execution proceeds as if by the following steps, * although the methods are not guaranteed to be called if the JVM @@ -590,10 +608,10 @@ * or forced to null if the return type is void. * <p> * This call is equivalent to the following code: - * <p><blockquote><pre> + * <p><blockquote><pre>{@code * MethodHandle invoker = MethodHandles.spreadInvoker(this.type(), 0); * Object result = invoker.invokeExact(this, arguments); - * </pre></blockquote> + * }</pre></blockquote> * <p> * Unlike the signature polymorphic methods {@code invokeExact} and {@code invoke}, * {@code invokeWithArguments} can be accessed normally via the Core Reflection API and JNI. @@ -626,7 +644,7 @@ * <p> * This method is also equivalent to the following code: * <p><blockquote><pre> - * {@link #invokeWithArguments(Object...) invokeWithArguments}(arguments.toArray()) + * {@link #invokeWithArguments(Object...) invokeWithArguments}{@code(arguments.toArray())} * </pre></blockquote> * * @param arguments the arguments to pass to the target @@ -739,10 +757,24 @@ * @see MethodHandles#explicitCastArguments */ public MethodHandle asType(MethodType newType) { - if (!type.isConvertibleTo(newType)) { + // Fast path alternative to a heavyweight {@code asType} call. + // Return 'this' if the conversion will be a no-op. + if (newType == type) { + return this; + } + // Return 'this.asTypeCache' if the conversion is already memoized. + MethodHandle atc = asTypeCache; + if (atc != null && newType == atc.type) { + return atc; + } + return asTypeUncached(newType); + } + + /** Override this to change asType behavior. */ + /*non-public*/ MethodHandle asTypeUncached(MethodType newType) { + if (!type.isConvertibleTo(newType)) throw new WrongMethodTypeException("cannot convert "+this+" to "+newType); - } - return convertArguments(newType); + return asTypeCache = convertArguments(newType); } /** @@ -772,6 +804,10 @@ * to the target method handle. * (The array may also be null when zero elements are required.) * <p> + * If, when the adapter is called, the supplied array argument does + * not have the correct number of elements, the adapter will throw + * an {@link IllegalArgumentException} instead of invoking the target. + * <p> * Here are some simple examples of array-spreading method handles: * <blockquote><pre>{@code MethodHandle equals = publicLookup() @@ -782,6 +818,12 @@ MethodHandle eq2 = equals.asSpreader(Object[].class, 2); assert( (boolean) eq2.invokeExact(new Object[]{ "me", "me" })); assert(!(boolean) eq2.invokeExact(new Object[]{ "me", "thee" })); +// try to spread from anything but a 2-array: +for (int n = 0; n <= 10; n++) { + Object[] badArityArgs = (n == 2 ? null : new Object[n]); + try { assert((boolean) eq2.invokeExact(badArityArgs) && false); } + catch (IllegalArgumentException ex) { } // OK +} // spread both arguments from a String array: MethodHandle eq2s = equals.asSpreader(String[].class, 2); assert( (boolean) eq2s.invokeExact(new String[]{ "me", "me" })); @@ -815,10 +857,12 @@ * @return a new method handle which spreads its final array argument, * before calling the original method handle * @throws NullPointerException if {@code arrayType} is a null reference - * @throws IllegalArgumentException if {@code arrayType} is not an array type - * @throws IllegalArgumentException if target does not have at least + * @throws IllegalArgumentException if {@code arrayType} is not an array type, + * or if target does not have at least * {@code arrayLength} parameter types, - * or if {@code arrayLength} is negative + * or if {@code arrayLength} is negative, + * or if the resulting method handle's type would have + * <a href="MethodHandle.html#maxarity">too many parameters</a> * @throws WrongMethodTypeException if the implied {@code asType} call fails * @see #asCollector */ @@ -931,7 +975,9 @@ * @throws NullPointerException if {@code arrayType} is a null reference * @throws IllegalArgumentException if {@code arrayType} is not an array type * or {@code arrayType} is not assignable to this method handle's trailing parameter type, - * or {@code arrayLength} is not a legal array size + * or {@code arrayLength} is not a legal array size, + * or the resulting method handle's type would have + * <a href="MethodHandle.html#maxarity">too many parameters</a> * @throws WrongMethodTypeException if the implied {@code asType} call fails * @see #asSpreader * @see #asVarargsCollector @@ -1226,9 +1272,9 @@ * starting with the string {@code "MethodHandle"} and * ending with the string representation of the method handle's type. * In other words, this method returns a string equal to the value of: - * <blockquote><pre> + * <blockquote><pre>{@code * "MethodHandle" + type().toString() - * </pre></blockquote> + * }</pre></blockquote> * <p> * (<em>Note:</em> Future releases of this API may add further information * to the string representation. @@ -1285,6 +1331,11 @@ } /*non-public*/ + Class<?> internalCallerClass() { + return null; // caller-bound MH for @CallerSensitive method returns caller + } + + /*non-public*/ MethodHandle withInternalMemberName(MemberName member) { if (member != null) { return MethodHandleImpl.makeWrappedMember(this, member); @@ -1434,7 +1485,6 @@ * Threads may continue running the old form indefinitely, * but it is likely that the new one will be preferred for new executions. * Use with discretion. - * @param newForm */ /*non-public*/ void updateForm(LambdaForm newForm) {
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Oct 11 03:06:10 2013 -0700 @@ -314,13 +314,13 @@ static class AsVarargsCollector extends MethodHandle { private final MethodHandle target; private final Class<?> arrayType; - private MethodHandle cache; + private /*@Stable*/ MethodHandle asCollectorCache; AsVarargsCollector(MethodHandle target, MethodType type, Class<?> arrayType) { super(type, reinvokerForm(target)); this.target = target; this.arrayType = arrayType; - this.cache = target.asCollector(arrayType, 0); + this.asCollectorCache = target.asCollector(arrayType, 0); } @Override MethodHandle reinvokerTarget() { return target; } @@ -336,18 +336,19 @@ } @Override - public MethodHandle asType(MethodType newType) { + public MethodHandle asTypeUncached(MethodType newType) { MethodType type = this.type(); int collectArg = type.parameterCount() - 1; int newArity = newType.parameterCount(); if (newArity == collectArg+1 && type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) { // if arity and trailing parameter are compatible, do normal thing - return asFixedArity().asType(newType); + return asTypeCache = asFixedArity().asType(newType); } // check cache - if (cache.type().parameterCount() == newArity) - return cache.asType(newType); + MethodHandle acc = asCollectorCache; + if (acc != null && acc.type().parameterCount() == newArity) + return asTypeCache = acc.asType(newType); // build and cache a collector int arrayLength = newArity - collectArg; MethodHandle collector; @@ -357,8 +358,8 @@ } catch (IllegalArgumentException ex) { throw new WrongMethodTypeException("cannot build collector", ex); } - cache = collector; - return collector.asType(newType); + asCollectorCache = collector; + return asTypeCache = collector.asType(newType); } @Override @@ -380,6 +381,10 @@ MemberName internalMemberName() { return asFixedArity().internalMemberName(); } + @Override + Class<?> internalCallerClass() { + return asFixedArity().internalCallerClass(); + } /*non-public*/ @Override @@ -435,7 +440,7 @@ // Spread the array. MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType); Name array = names[argIndex]; - names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount); + names[nameCursor++] = new Name(Lazy.NF_checkSpreadArgument, array, spreadArgCount); for (int j = 0; j < spreadArgCount; i++, j++) { indexes[i] = nameCursor; names[nameCursor++] = new Name(aload, array, j); @@ -459,14 +464,8 @@ } static void checkSpreadArgument(Object av, int n) { - // FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE - // but the actual exception raised by an arity mismatch should be WMTE - final boolean RAISE_RANDOM_EXCEPTIONS = true; // FIXME: delete in JSR 292 M1 if (av == null) { if (n == 0) return; - int len; - if (RAISE_RANDOM_EXCEPTIONS) - len = ((Object[])av).length; // throw NPE; but delete this after tests are fixed } else if (av instanceof Object[]) { int len = ((Object[])av).length; if (len == n) return; @@ -475,19 +474,23 @@ if (len == n) return; } // fall through to error: - if (RAISE_RANDOM_EXCEPTIONS) - throw newIllegalArgumentException("Array is not of length "+n); - throw new WrongMethodTypeException("Array is not of length "+n); + throw newIllegalArgumentException("array is not of length "+n); } - private static final NamedFunction NF_checkSpreadArgument; - static { - try { - NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class - .getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); - NF_checkSpreadArgument.resolve(); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); + /** + * Pre-initialized NamedFunctions for bootstrapping purposes. + * Factored in an inner class to delay initialization until first usage. + */ + private static class Lazy { + static final NamedFunction NF_checkSpreadArgument; + static { + try { + NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class + .getDeclaredMethod("checkSpreadArgument", Object.class, int.class)); + NF_checkSpreadArgument.resolve(); + } catch (ReflectiveOperationException ex) { + throw newInternalError(ex); + } } } @@ -832,7 +835,7 @@ MethodHandle vamh = prepareForInvoker(mh); // Cache the result of makeInjectedInvoker once per argument class. MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass); - return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName()); + return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName(), hostClass); } private static MethodHandle makeInjectedInvoker(Class<?> hostClass) { @@ -887,10 +890,12 @@ } // Undo the adapter effect of prepareForInvoker: - private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, MemberName member) { + private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, + MemberName member, + Class<?> hostClass) { MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount()); mh = mh.asType(type); - mh = mh.withInternalMemberName(member); + mh = new WrappedMember(mh, type, member, hostClass); return mh; } @@ -959,11 +964,13 @@ static class WrappedMember extends MethodHandle { private final MethodHandle target; private final MemberName member; + private final Class<?> callerClass; - private WrappedMember(MethodHandle target, MethodType type, MemberName member) { + private WrappedMember(MethodHandle target, MethodType type, MemberName member, Class<?> callerClass) { super(type, reinvokerForm(target)); this.target = target; this.member = member; + this.callerClass = callerClass; } @Override @@ -971,23 +978,33 @@ return target; } @Override + public MethodHandle asTypeUncached(MethodType newType) { + // This MH is an alias for target, except for the MemberName + // Drop the MemberName if there is any conversion. + return asTypeCache = target.asType(newType); + } + @Override MemberName internalMemberName() { return member; } @Override + Class<?> internalCallerClass() { + return callerClass; + } + @Override boolean isInvokeSpecial() { return target.isInvokeSpecial(); } @Override MethodHandle viewAsType(MethodType newType) { - return new WrappedMember(target, newType, member); + return new WrappedMember(target, newType, member, callerClass); } } static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) { if (member.equals(target.internalMemberName())) return target; - return new WrappedMember(target, target.type(), member); + return new WrappedMember(target, target.type(), member, null); } }
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java Fri Oct 11 03:06:10 2013 -0700 @@ -32,9 +32,10 @@ import static java.lang.invoke.MethodHandleStatics.*; /** - * A symbolic reference obtained by cracking a method handle into its consitutent symbolic parts. + * A symbolic reference obtained by cracking a direct method handle + * into its consitutent symbolic parts. * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}. - * <p> + * <h1><a name="directmh"></a>Direct Method Handles</h1> * A <em>direct method handle</em> represents a method, constructor, or field without * any intervening argument bindings or other transformations. * The method, constructor, or field referred to by a direct method handle is called @@ -56,11 +57,25 @@ * or {@link Lookup#unreflectSetter Lookup.unreflectSetter} * to convert a {@link Field} into a method handle. * </ul> - * In all of these cases, it is possible to crack the resulting direct method handle + * + * <h1>Restrictions on Cracking</h1> + * Given a suitable {@code Lookup} object, it is possible to crack any direct method handle * to recover a symbolic reference for the underlying method, constructor, or field. * Cracking must be done via a {@code Lookup} object equivalent to that which created * the target method handle, or which has enough access permissions to recreate * an equivalent method handle. + * <p> + * If the underlying method is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>, + * the direct method handle will have been "bound" to a particular caller class, the + * {@linkplain java.lang.invoke.MethodHandles.Lookup#lookupClass() lookup class} + * of the lookup object used to create it. + * Cracking this method handle with a different lookup class will fail + * even if the underlying method is public (like {@code Class.forName}). + * <p> + * The requirement of lookup object matching provides a "fast fail" behavior + * for programs which may otherwise trust erroneous revelation of a method + * handle with symbolic information (or caller binding) from an unexpected scope. + * Use {@link java.lang.invoke.MethodHandles#reflectAs} to override this limitation. * * <h1><a name="refkinds"></a>Reference kinds</h1> * The <a href="MethodHandles.Lookup.html#lookups">Lookup Factory Methods</a> @@ -190,7 +205,7 @@ * @return the Java language modifiers for underlying member, * or -1 if the member cannot be accessed * @see Modifier - * @see reflectAs + * @see #reflectAs */ public int getModifiers();
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Fri Oct 11 03:06:10 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 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 @@ -233,20 +233,19 @@ } static String refKindName(byte refKind) { assert(refKindIsValid(refKind)); - return REFERENCE_KIND_NAME[refKind]; + switch (refKind) { + case REF_getField: return "getField"; + case REF_getStatic: return "getStatic"; + case REF_putField: return "putField"; + case REF_putStatic: return "putStatic"; + case REF_invokeVirtual: return "invokeVirtual"; + case REF_invokeStatic: return "invokeStatic"; + case REF_invokeSpecial: return "invokeSpecial"; + case REF_newInvokeSpecial: return "newInvokeSpecial"; + case REF_invokeInterface: return "invokeInterface"; + default: return "REF_???"; + } } - private static String[] REFERENCE_KIND_NAME = { - null, - "getField", - "getStatic", - "putField", - "putStatic", - "invokeVirtual", - "invokeStatic", - "invokeSpecial", - "newInvokeSpecial", - "invokeInterface" - }; private static native int getNamedCon(int which, Object[] name); static boolean verifyConstants() { @@ -294,12 +293,18 @@ Class<?> caller = (Class<?>)callerObj; String name = nameObj.toString().intern(); MethodType type = (MethodType)typeObj; - appendixResult[0] = CallSite.makeSite(bootstrapMethod, + CallSite callSite = CallSite.makeSite(bootstrapMethod, name, type, staticArguments, caller); - return Invokers.linkToCallSiteMethod(type); + if (callSite instanceof ConstantCallSite) { + appendixResult[0] = callSite.dynamicInvoker(); + return Invokers.linkToTargetMethod(type); + } else { + appendixResult[0] = callSite; + return Invokers.linkToCallSiteMethod(type); + } } /** @@ -388,12 +393,7 @@ Object[] appendixResult) { try { if (defc == MethodHandle.class && refKind == REF_invokeVirtual) { - switch (name) { - case "invoke": - return Invokers.genericInvokerMethod(fixMethodType(callerClass, type), appendixResult); - case "invokeExact": - return Invokers.exactInvokerMethod(fixMethodType(callerClass, type), appendixResult); - } + return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult); } } catch (Throwable ex) { if (ex instanceof LinkageError) @@ -440,14 +440,34 @@ Lookup lookup = IMPL_LOOKUP.in(callerClass); assert(refKindIsValid(refKind)); return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type); + } catch (IllegalAccessException ex) { + Error err = new IllegalAccessError(ex.getMessage()); + throw initCauseFrom(err, ex); + } catch (NoSuchMethodException ex) { + Error err = new NoSuchMethodError(ex.getMessage()); + throw initCauseFrom(err, ex); + } catch (NoSuchFieldException ex) { + Error err = new NoSuchFieldError(ex.getMessage()); + throw initCauseFrom(err, ex); } catch (ReflectiveOperationException ex) { Error err = new IncompatibleClassChangeError(); - err.initCause(ex); - throw err; + throw initCauseFrom(err, ex); } } /** + * Use best possible cause for err.initCause(), substituting the + * cause for err itself if the cause has the same (or better) type. + */ + static private Error initCauseFrom(Error err, Exception ex) { + Throwable th = ex.getCause(); + if (err.getClass().isInstance(th)) + return (Error) th; + err.initCause(th == null ? ex : th); + return err; + } + + /** * Is this method a caller-sensitive method? * I.e., does it call Reflection.getCallerClass or a similer method * to ask about the identity of its caller?
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java Fri Oct 11 03:06:10 2013 -0700 @@ -107,6 +107,11 @@ * such as abstract classes with single abstract methods. * Future versions of this API may also equip wrapper instances * with one or more additional public "marker" interfaces. + * <p> + * If a security manager is installed, this method is caller sensitive. + * During any invocation of the target method handle via the returned wrapper, + * the original creator of the wrapper (the caller) will be visible + * to context checks requested by the security manager. * * @param <T> the desired type of the wrapper, a single-method interface * @param intfc a class object representing {@code T}
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Thu Oct 10 10:09:19 2013 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Fri Oct 11 03:06:10 2013 -0700 @@ -39,6 +39,7 @@ import sun.security.util.SecurityConstants; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; +import java.util.concurrent.ConcurrentHashMap; import sun.security.util.SecurityConstants; /** @@ -48,7 +49,6 @@ * <li>Lookup methods which help create method handles for methods and fields. * <li>Combinator methods, which combine or transform pre-existing method handles into new ones. * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns. - * <li>Wrapper methods which can convert between method handles and interface types. * </ul> * <p> * @author John Rose, JSR 292 EG @@ -65,12 +65,25 @@ //// Method handle creation from ordinary methods. /** - * Returns a {@link Lookup lookup object} on the caller, - * which has the capability to access any method handle that the caller has access to, - * including direct method handles to private fields and methods. + * Returns a {@link Lookup lookup object} with + * full capabilities to emulate all supported bytecode behaviors of the caller. + * These capabilities include <a href="MethodHandles.Lookup.html#privacc">private access</a> to the caller. + * Factory methods on the lookup object can create + * <a href="MethodHandleInfo.html#directmh">direct method handles</a> + * for any member that the caller has access to via bytecodes, + * including protected and private fields and methods. * This lookup object is a <em>capability</em> which may be delegated to trusted agents. * Do not store it in place where untrusted code can access it. - * @return a lookup object for the caller of this method + * <p> + * This method is caller sensitive, which means that it may return different + * values to different callers. + * <p> + * For any given caller class {@code C}, the lookup object returned by this call + * has equivalent capabilities to any lookup object + * supplied by the JVM to the bootstrap method of an + * <a href="package-summary.html#indyinsn">invokedynamic instruction</a> + * executing in the same caller class {@code C}. + * @return a lookup object for the caller of this method, with private access */ @CallerSensitive public static Lookup lookup() { @@ -84,11 +97,17 @@ * <p> * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class} * of this lookup object will be {@link java.lang.Object}. - * <p> + * + * <p style="font-size:smaller;"> + * <em>Discussion:</em> * The lookup class can be changed to any other class {@code C} using an expression of the form - * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}. + * {@link Lookup#in publicLookup().in(C.class)}. * Since all classes have equal access to public names, * such a change would confer no new access rights. + * A public lookup object is always subject to + * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>. + * Also, it cannot access + * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>. * @return a lookup object which is trusted minimally */ public static Lookup publicLookup() { @@ -96,7 +115,8 @@ } /** - * Performs an unchecked "crack" of a direct method handle. + * Performs an unchecked "crack" of a + * <a href="MethodHandleInfo.html#directmh">direct method handle</a>. * The result is as if the user had obtained a lookup object capable enough * to crack the target method handle, called * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect} @@ -149,10 +169,17 @@ * <h1><a name="lookups"></a>Lookup Factory Methods</h1> * The factory methods on a {@code Lookup} object correspond to all major * use cases for methods, constructors, and fields. + * Each method handle created by a factory method is the functional + * equivalent of a particular <em>bytecode behavior</em>. + * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.) * Here is a summary of the correspondence between these factory methods and * the behavior the resulting method handles: * <table border=1 cellpadding=5 summary="lookup method behaviors"> - * <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr> + * <tr> + * <th><a name="equiv"></a>lookup expression</th> + * <th>member</th> + * <th>bytecode behavior</th> + * </tr> * <tr> * <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td> * <td>{@code FT f;}</td><td>{@code (T) this.f;}</td> @@ -228,10 +255,12 @@ * In cases where the given member is of variable arity (i.e., a method or constructor) * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}. * In all other cases, the returned method handle will be of fixed arity. - * <p> + * <p style="font-size:smaller;"> + * <em>Discussion:</em> * The equivalence between looked-up method handles and underlying - * class members can break down in a few ways: - * <ul> + * class members and bytecode behaviors + * can break down in a few ways: + * <ul style="font-size:smaller;"> * <li>If {@code C} is not symbolically accessible from the lookup class's loader, * the lookup can still succeed, even when there is no equivalent * Java expression or bytecoded constant. @@ -241,9 +270,13 @@ * For example, lookups for {@code MethodHandle.invokeExact} and * {@code MethodHandle.invoke} will always succeed, regardless of requested type. * <li>If there is a security manager installed, it can forbid the lookup - * on various grounds (<a href="#secmgr">see below</a>). - * By contrast, the {@code ldc} instruction is not subject to - * security manager checks. + * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>). + * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle} + * constant is not subject to security manager checks. + * <li>If the looked-up method has a + * <a href="MethodHandle.html#maxarity">very large arity</a>, + * the method handle creation may fail, due to the method handle + * type having too many parameters. * </ul> * * <h1><a name="access"></a>Access checking</h1> @@ -271,7 +304,8 @@ * A lookup can fail, because * the containing class is not accessible to the lookup class, or * because the desired class member is missing, or because the - * desired class member is not accessible to the lookup class. + * desired class member is not accessible to the lookup class, or + * because the lookup object is not trusted enough to access the member. * In any of these cases, a {@code ReflectiveOperationException} will be * thrown from the attempted lookup. The exact class will be one of * the following: @@ -282,11 +316,23 @@ * </ul> * <p> * In general, the conditions under which a method handle may be - * looked up for a method {@code M} are exactly equivalent to the conditions - * under which the lookup class could have compiled and resolved a call to {@code M}. + * looked up for a method {@code M} are no more restrictive than the conditions + * under which the lookup class could have compiled, verified, and resolved a call to {@code M}. + * Where the JVM would raise exceptions like {@code NoSuchMethodError}, + * a method handle lookup will generally raise a corresponding + * checked exception, such as {@code NoSuchMethodException}. * And the effect of invoking the method handle resulting from the lookup - * is exactly equivalent to executing the compiled and resolved call to {@code M}. + * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a> + * to executing the compiled, verified, and resolved call to {@code M}. * The same point is true of fields and constructors. + * <p style="font-size:smaller;"> + * <em>Discussion:</em> + * Access checks only apply to named and reflected methods, + * constructors, and fields. + * Other method handle creation methods, such as + * {@link MethodHandle#asType MethodHandle.asType}, + * do not require any access checks, and are used + * independently of any {@code Lookup} object. * <p> * If the desired member is {@code protected}, the usual JVM rules apply, * including the requirement that the lookup class must be either be in the @@ -300,6 +346,18 @@ * (which will necessarily be a superclass of the lookup class) * to the lookup class itself. * <p> + * The JVM imposes a similar requirement on {@code invokespecial} instruction, + * that the receiver argument must match both the resolved method <em>and</em> + * the current class. Again, this requirement is enforced by narrowing the + * type of the leading parameter to the resulting method handle. + * (See the Java Virtual Machine Specification, section 4.10.1.9.) + * <p> + * The JVM represents constructors and static initializer blocks as internal methods + * with special names ({@code "<init>"} and {@code "<clinit>"}). + * The internal syntax of invocation instructions allows them to refer to such internal + * methods as if they were normal methods, but the JVM bytecode verifier rejects them. + * A lookup of such an internal method will produce a {@code NoSuchMethodException}. + * <p> * In some cases, access between nested classes is obtained by the Java compiler by creating * an wrapper method to access a private method of another class * in the same top-level declaration. @@ -313,6 +371,43 @@ * which can transform a lookup on {@code C.E} into one on any of those other * classes, without special elevation of privilege. * <p> + * The accesses permitted to a given lookup object may be limited, + * according to its set of {@link #lookupModes lookupModes}, + * to a subset of members normally accessible to the lookup class. + * For example, the {@link MethodHandles#publicLookup publicLookup} + * method produces a lookup object which is only allowed to access + * public members in public classes. + * The caller sensitive method {@link MethodHandles#lookup lookup} + * produces a lookup object with full capabilities relative to + * its caller class, to emulate all supported bytecode behaviors. + * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object + * with fewer access modes than the original lookup object. + * + * <p style="font-size:smaller;"> + * <a name="privacc"></a> + * <em>Discussion of private access:</em> + * We say that a lookup has <em>private access</em> + * if its {@linkplain #lookupModes lookup modes} + * include the possibility of accessing {@code private} members. + * As documented in the relevant methods elsewhere, + * only lookups with private access possess the following capabilities: + * <ul style="font-size:smaller;"> + * <li>access private fields, methods, and constructors of the lookup class + * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods, + * such as {@code Class.forName} + * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions + * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a> + * for classes accessible to the lookup class + * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes + * within the same package member + * </ul> + * <p style="font-size:smaller;"> + * Each of these permissions is a consequence of the fact that a lookup object + * with private access can be securely traced back to an originating class, + * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions + * can be reliably determined and emulated by method handles. + * + * <h1><a name="secmgr"></a>Security manager interactions</h1> * Although bytecode instructions can only refer to classes in * a related class loader, this API can search for methods in any * class, as long as a reference to its {@code Class} object is @@ -325,16 +420,6 @@ * and the Core Reflection API * (as found on {@link java.lang.Class Class}). * <p> - * Access checks only apply to named and reflected methods, - * constructors, and fields. - * Other method handle creation methods, such as - * {@link MethodHandle#asType MethodHandle.asType}, - * do not require any access checks, and are done - * with static methods of {@link MethodHandles}, - * independently of any {@code Lookup} object. - * - * <h1>Security manager interactions</h1> - * <a name="secmgr"></a> * If a security manager is present, member lookups are subject to * additional checks. * From one to three calls are made to the security manager. @@ -347,26 +432,79 @@ * member is actually defined. * The value {@code lookc} is defined as <em>not present</em> * if the current lookup object does not have - * {@linkplain java.lang.invoke.MethodHandles.Lookup#PRIVATE private access}. + * <a href="MethodHandles.Lookup.html#privacc">private access</a>. * The calls are made according to the following rules: * <ul> - * <li>If {@code lookc} is not present, or if its class loader is not + * <li><b>Step 1:</b> + * If {@code lookc} is not present, or if its class loader is not * the same as or an ancestor of the class loader of {@code refc}, * then {@link SecurityManager#checkPackageAccess * smgr.checkPackageAccess(refcPkg)} is called, * where {@code refcPkg} is the package of {@code refc}. - * <li>If the retrieved member is not public and + * <li><b>Step 2:</b> + * If the retrieved member is not public and * {@code lookc} is not present, then * {@link SecurityManager#checkPermission smgr.checkPermission} * with {@code RuntimePermission("accessDeclaredMembers")} is called. - * <li>If the retrieved member is not public, + * <li><b>Step 3:</b> + * If the retrieved member is not public, + * and if {@code lookc} is not present, * and if {@code defc} and {@code refc} are different, * then {@link SecurityManager#checkPackageAccess * smgr.checkPackageAccess(defcPkg)} is called, * where {@code defcPkg} is the package of {@code defc}. * </ul> + * Security checks are performed after other access checks have passed. + * Therefore, the above rules presuppose a member that is public, + * or else that is being accessed from a lookup class that has + * rights to access the member. + * + * <h1><a name="callsens"></a>Caller sensitive methods</h1> + * A small number of Java methods have a special property called caller sensitivity. + * A <em>caller-sensitive</em> method can behave differently depending on the + * identity of its immediate caller. + * <p> + * If a method handle for a caller-sensitive method is requested, + * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply, + * but they take account of the lookup class in a special way. + * The resulting method handle behaves as if it were called + * from an instruction contained in the lookup class, + * so that the caller-sensitive method detects the lookup class. + * (By contrast, the invoker of the method handle is disregarded.) + * Thus, in the case of caller-sensitive methods, + * different lookup classes may give rise to + * differently behaving method handles. + * <p> + * In cases where the lookup object is + * {@link MethodHandles#publicLookup() publicLookup()}, + * or some other lookup object without + * <a href="MethodHandles.Lookup.html#privacc">private access</a>, + * the lookup class is disregarded. + * In such cases, no caller-sensitive method handle can be created, + * access is forbidden, and the lookup fails with an + * {@code IllegalAccessException}. + * <p style="font-size:smaller;"> + * <em>Discussion:</em> + * For example, the caller-sensitive method + * {@link java.lang.Class#forName(String) Class.forName(x)} + * can return varying classes or throw varying exceptions, + * depending on the class loader of the class that calls it. + * A public lookup of {@code Class.forName} will fail, because + * there is no reasonable way to determine its bytecode behavior. + * <p style="font-size:smaller;"> + * If an application caches method handles for broad sharing, + * it should use {@code publicLookup()} to create them. + * If there is a lookup of {@code Class.forName}, it will fail, + * and the application must take appropriate action in that case. + * It may be that a later lookup, perhaps during the invocation of a + * bootstrap method, can incorporate the specific identity + * of the caller, making the method accessible. + * <p style="font-size:smaller;"> + * The function {@code MethodHandles.lookup} is caller sensitive + * so that there can be a secure foundation for lookups. + * Nearly all other methods in the JSR 292 API rely on lookup + * objects to check access requests. */ - // FIXME in MR1: clarify that the bytecode behavior of a caller-ID method (like Class.forName) is relative to the lookupClass used to create the method handle, not the dynamic caller of the method handle public static final class Lookup { /** The class on behalf of whom the lookup is being performed. */ @@ -592,13 +730,23 @@ * (Since static methods do not take receivers, there is no * additional receiver argument inserted into the method handle type, * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.) - * The method and all its argument types must be accessible to the lookup class. - * If the method's class has not yet been initialized, that is done - * immediately, before the method handle is returned. + * The method and all its argument types must be accessible to the lookup object. * <p> * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + * <p> + * If the returned method handle is invoked, the method's class will + * be initialized, if it has not already been initialized. + * <p><b>Example:</b> + * <p><blockquote><pre>{@code +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +... +MethodHandle MH_asList = publicLookup().findStatic(Arrays.class, + "asList", methodType(List.class, Object[].class)); +assertEquals("[x, y]", MH_asList.invoke("x", "y").toString()); + * }</pre></blockquote> * @param refc the class from which the method is accessed * @param name the name of the method * @param type the type of the method @@ -615,7 +763,6 @@ public MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type); - checkSecurityManager(refc, method); return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method)); } @@ -623,7 +770,7 @@ * Produces a method handle for a virtual method. * The type of the method handle will be that of the method, * with the receiver type (usually {@code refc}) prepended. - * The method and all its argument types must be accessible to the lookup class. + * The method and all its argument types must be accessible to the lookup object. * <p> * When called, the handle will treat the first argument as a receiver * and dispatch on the receiver's type to determine which method @@ -640,7 +787,7 @@ * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. * <p> - * Because of the general equivalence between {@code invokevirtual} + * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual} * instructions and method handles produced by {@code findVirtual}, * if the class is {@code MethodHandle} and the name string is * {@code invokeExact} or {@code invoke}, the resulting @@ -649,6 +796,34 @@ * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker} * with the same {@code type} argument. * + * <b>Example:</b> + * <p><blockquote><pre>{@code +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +... +MethodHandle MH_concat = publicLookup().findVirtual(String.class, + "concat", methodType(String.class, String.class)); +MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class, + "hashCode", methodType(int.class)); +MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class, + "hashCode", methodType(int.class)); +assertEquals("xy", (String) MH_concat.invokeExact("x", "y")); +assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy")); +assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy")); +// interface method: +MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class, + "subSequence", methodType(CharSequence.class, int.class, int.class)); +assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString()); +// constructor "internal method" must be accessed differently: +MethodType MT_newString = methodType(void.class); //()V for new String() +try { assertEquals("impossible", lookup() + .findVirtual(String.class, "<init>", MT_newString)); + } catch (NoSuchMethodException ex) { } // OK +MethodHandle MH_newString = publicLookup() + .findConstructor(String.class, MT_newString); +assertEquals("", (String) MH_newString.invokeExact()); + * }</pre></blockquote> + * * @param refc the class or interface from which the method is accessed * @param name the name of the method * @param type the type of the method, with the receiver argument omitted @@ -669,7 +844,6 @@ } byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual); MemberName method = resolveOrFail(refKind, refc, name, type); - checkSecurityManager(refc, method); return getDirectMethod(refKind, refc, method, findBoundCallerClass(method)); } private MethodHandle findVirtualForMH(String name, MethodType type) { @@ -687,16 +861,35 @@ * the constructor of the specified type. * The parameter types of the method handle will be those of the constructor, * while the return type will be a reference to the constructor's class. - * The constructor and all its argument types must be accessible to the lookup class. - * If the constructor's class has not yet been initialized, that is done - * immediately, before the method handle is returned. + * The constructor and all its argument types must be accessible to the lookup object. * <p> - * Note: The requested type must have a return type of {@code void}. - * This is consistent with the JVM's treatment of constructor type descriptors. + * The requested type must have a return type of {@code void}. + * (This is consistent with the JVM's treatment of constructor type descriptors.) * <p> * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the constructor's variable arity modifier bit ({@code 0x0080}) is set. + * <p> + * If the returned method handle is invoked, the constructor's class will + * be initialized, if it has not already been initialized. + * <p><b>Example:</b> + * <p><blockquote><pre>{@code +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +... +MethodHandle MH_newArrayList = publicLookup().findConstructor( + ArrayList.class, methodType(void.class, Collection.class)); +Collection orig = Arrays.asList("x", "y"); +Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig); +assert(orig != copy); +assertEquals(orig, copy); +// a variable-arity constructor: +MethodHandle MH_newProcessBuilder = publicLookup().findConstructor( + ProcessBuilder.class, methodType(void.class, String[].class)); +ProcessBuilder pb = (ProcessBuilder) + MH_newProcessBuilder.invoke("x", "y", "z"); +assertEquals("[x, y, z]", pb.command().toString()); + * }</pre></blockquote> * @param refc the class or interface from which the method is accessed * @param type the type of the method, with the receiver argument omitted, and a void return type * @return the desired method handle @@ -711,31 +904,68 @@ public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException { String name = "<init>"; MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type); - checkSecurityManager(refc, ctor); return getDirectConstructor(refc, ctor); } /** - * Produces an early-bound method handle for a virtual method, - * as if called from an {@code invokespecial} - * instruction from {@code caller}. + * Produces an early-bound method handle for a virtual method. + * It will bypass checks for overriding methods on the receiver, + * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial} + * instruction from within the explicitly specified {@code specialCaller}. * The type of the method handle will be that of the method, - * with a suitably restricted receiver type (such as {@code caller}) prepended. + * with a suitably restricted receiver type prepended. + * (The receiver type will be {@code specialCaller} or a subtype.) * The method and all its argument types must be accessible - * to the caller. + * to the lookup object. * <p> - * When called, the handle will treat the first argument as a receiver, - * but will not dispatch on the receiver's type. - * (This direct invocation action is identical with that performed by an - * {@code invokespecial} instruction.) - * <p> - * If the explicitly specified caller class is not identical with the - * lookup class, or if this lookup object does not have private access + * Before method resolution, + * if the explicitly specified caller class is not identical with the + * lookup class, or if this lookup object does not have + * <a href="MethodHandles.Lookup.html#privacc">private access</a> * privileges, the access fails. * <p> * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + * <p style="font-size:smaller;"> + * <em>(Note: JVM internal methods named {@code "<init>"} are not visible to this API, + * even though the {@code invokespecial} instruction can refer to them + * in special circumstances. Use {@link #findConstructor findConstructor} + * to access instance initialization methods in a safe manner.)</em> + * <p><b>Example:</b> + * <p><blockquote><pre>{@code +import static java.lang.invoke.MethodHandles.*; +import static java.lang.invoke.MethodType.*; +... +static class Listie extends ArrayList { + public String toString() { return "[wee Listie]"; } + static Lookup lookup() { return MethodHandles.lookup(); } +} +... +// no access to constructor via invokeSpecial: +MethodHandle MH_newListie = Listie.lookup() + .findConstructor(Listie.class, methodType(void.class)); +Listie l = (Listie) MH_newListie.invokeExact(); +try { assertEquals("impossible", Listie.lookup().findSpecial( + Listie.class, "<init>", methodType(void.class), Listie.class)); + } catch (NoSuchMethodException ex) { } // OK +// access to super and self methods via invokeSpecial: +MethodHandle MH_super = Listie.lookup().findSpecial( + ArrayList.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_this = Listie.lookup().findSpecial( + Listie.class, "toString" , methodType(String.class), Listie.class); +MethodHandle MH_duper = Listie.lookup().findSpecial( + Object.class, "toString" , methodType(String.class), Listie.class); +assertEquals("[]", (String) MH_super.invokeExact(l)); +assertEquals(""+l, (String) MH_this.invokeExact(l)); +assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method +try { assertEquals("inaccessible", Listie.lookup().findSpecial( + String.class, "toString", methodType(String.class), Listie.class)); + } catch (IllegalAccessException ex) { } // OK +Listie subl = new Listie() { public String toString() { return "[subclass]"; } }; +assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method + * }</pre></blockquote> + * * @param refc the class or interface from which the method is accessed * @param name the name of the method (which must not be "<init>") * @param type the type of the method, with the receiver argument omitted @@ -754,7 +984,6 @@ checkSpecialCaller(specialCaller); Lookup specialLookup = this.in(specialCaller); MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type); - checkSecurityManager(refc, method); return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method)); } @@ -777,7 +1006,6 @@ */ public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { MemberName field = resolveOrFail(REF_getField, refc, name, type); - checkSecurityManager(refc, field); return getDirectField(REF_getField, refc, field); } @@ -800,7 +1028,6 @@ */ public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { MemberName field = resolveOrFail(REF_putField, refc, name, type); - checkSecurityManager(refc, field); return getDirectField(REF_putField, refc, field); } @@ -810,6 +1037,9 @@ * value type. * The method handle will take no arguments. * Access checking is performed immediately on behalf of the lookup class. + * <p> + * If the returned method handle is invoked, the field's class will + * be initialized, if it has not already been initialized. * @param refc the class or interface from which the method is accessed * @param name the field's name * @param type the field's type @@ -822,7 +1052,6 @@ */ public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { MemberName field = resolveOrFail(REF_getStatic, refc, name, type); - checkSecurityManager(refc, field); return getDirectField(REF_getStatic, refc, field); } @@ -832,6 +1061,9 @@ * The method handle will take a single * argument, of the field's value type, the value to be stored. * Access checking is performed immediately on behalf of the lookup class. + * <p> + * If the returned method handle is invoked, the field's class will + * be initialized, if it has not already been initialized. * @param refc the class or interface from which the method is accessed * @param name the field's name * @param type the field's type @@ -844,7 +1076,6 @@ */ public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { MemberName field = resolveOrFail(REF_putStatic, refc, name, type); - checkSecurityManager(refc, field); return getDirectField(REF_putStatic, refc, field); } @@ -852,7 +1083,7 @@ * Produces an early-bound method handle for a non-static method. * The receiver must have a supertype {@code defc} in which a method * of the given name and type is accessible to the lookup class. - * The method and all its argument types must be accessible to the lookup class. + * The method and all its argument types must be accessible to the lookup object. * The type of the method handle will be that of the method, * without any insertion of an additional receiver parameter. * The given receiver will be bound into the method handle, @@ -867,17 +1098,17 @@ * the given receiver value will be bound to it.) * <p> * This is equivalent to the following code: - * <blockquote><pre> + * <blockquote><pre>{@code import static java.lang.invoke.MethodHandles.*; import static java.lang.invoke.MethodType.*; ... -MethodHandle mh0 = lookup().{@link #findVirtual findVirtual}(defc, name, type); -MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver); +MethodHandle mh0 = lookup().findVirtual(defc, name, type); +MethodHandle mh1 = mh0.bindTo(receiver); MethodType mt1 = mh1.type(); if (mh0.isVarargsCollector()) mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1)); return mh1; - * </pre></blockquote> + * }</pre></blockquote> * where {@code defc} is either {@code receiver.getClass()} or a super * type of that class, in which the requested method is accessible * to the lookup class. @@ -893,17 +1124,19 @@ * @exception SecurityException if a security manager is present and it * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * @throws NullPointerException if any argument is null + * @see MethodHandle#bindTo + * @see #findVirtual */ public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { Class<? extends Object> refc = receiver.getClass(); // may get NPE MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type); - checkSecurityManager(refc, method); MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method)); return mh.bindReceiver(receiver).setVarargs(method); } /** - * Makes a direct method handle to <i>m</i>, if the lookup class has permission. + * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a> + * to <i>m</i>, if the lookup class has permission. * If <i>m</i> is non-static, the receiver argument is treated as an initial argument. * If <i>m</i> is virtual, overriding is respected on every call. * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped. @@ -916,6 +1149,10 @@ * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. + * <p> + * If <i>m</i> is static, and + * if the returned method handle is invoked, the method's class will + * be initialized, if it has not already been initialized. * @param m the reflected method * @return a method handle which can invoke the reflected method * @throws IllegalAccessException if access checking fails @@ -934,7 +1171,7 @@ refKind = REF_invokeVirtual; assert(method.isMethod()); Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this; - return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method)); + return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method)); } private MethodHandle unreflectForMH(Method m) { // these names require special lookups because they throw UnsupportedOperationException @@ -946,13 +1183,21 @@ /** * Produces a method handle for a reflected method. * It will bypass checks for overriding methods on the receiver, - * as if by a {@code invokespecial} instruction from within the {@code specialCaller}. + * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial} + * instruction from within the explicitly specified {@code specialCaller}. * The type of the method handle will be that of the method, - * with the special caller type prepended (and <em>not</em> the receiver of the method). + * with a suitably restricted receiver type prepended. + * (The receiver type will be {@code specialCaller} or a subtype.) * If the method's {@code accessible} flag is not set, * access checking is performed immediately on behalf of the lookup class, * as if {@code invokespecial} instruction were being linked. * <p> + * Before method resolution, + * if the explicitly specified caller class is not identical with the + * lookup class, or if this lookup object does not have + * <a href="MethodHandles.Lookup.html#privacc">private access</a> + * privileges, the access fails. + * <p> * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. @@ -970,7 +1215,7 @@ MemberName method = new MemberName(m, true); assert(method.isMethod()); // ignore m.isAccessible: this is a new kind of access - return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method)); + return specialLookup.getDirectMethodNoSecurityManager(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method)); } /** @@ -987,6 +1232,9 @@ * The returned method handle will have * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the constructor's variable arity modifier bit ({@code 0x0080}) is set. + * <p> + * If the returned method handle is invoked, the constructor's class will + * be initialized, if it has not already been initialized. * @param c the reflected constructor * @return a method handle which can invoke the reflected constructor * @throws IllegalAccessException if access checking fails @@ -994,12 +1242,11 @@ * is set and {@code asVarargsCollector} fails * @throws NullPointerException if the argument is null */ - @SuppressWarnings("rawtypes") // Will be Constructor<?> after JSR 292 MR - public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException { + public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException { MemberName ctor = new MemberName(c); assert(ctor.isConstructor()); Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this; - return lookup.getDirectConstructor(ctor.getDeclaringClass(), ctor); + return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor); } /** @@ -1011,6 +1258,10 @@ * the field. * If the field's {@code accessible} flag is not set, * access checking is performed immediately on behalf of the lookup class. + * <p> + * If the field is static, and + * if the returned method handle is invoked, the field's class will + * be initialized, if it has not already been initialized. * @param f the reflected field * @return a method handle which can load values from the reflected field * @throws IllegalAccessException if access checking fails @@ -1025,7 +1276,7 @@ ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind()) : MethodHandleNatives.refKindIsGetter(field.getReferenceKind())); Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this; - return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field); + return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field); } /** @@ -1037,6 +1288,10 @@ * the field, and the value to be stored. * If the field's {@code accessible} flag is not set, * access checking is performed immediately on behalf of the lookup class. + * <p> + * If the field is static, and + * if the returned method handle is invoked, the field's class will + * be initialized, if it has not already been initialized. * @param f the reflected field * @return a method handle which can store values into the reflected field * @throws IllegalAccessException if access checking fails @@ -1047,17 +1302,21 @@ } /** - * Cracks a direct method handle created by this lookup object or a similar one. + * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a> + * created by this lookup object or a similar one. * Security and access checks are performed to ensure that this lookup object * is capable of reproducing the target method handle. * This means that the cracking may fail if target is a direct method handle * but was created by an unrelated lookup object. + * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> + * and was created by a lookup object for a different class. * @param target a direct method handle to crack into symbolic reference components * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object * @exception SecurityException if a security manager is present and it * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a> * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails * @exception NullPointerException if the target is {@code null} + * @see MethodHandleInfo * @since 1.8 */ public MethodHandleInfo revealDirect(MethodHandle target) { @@ -1077,11 +1336,16 @@ refKind = REF_invokeInterface; // Check SM permissions and member access before cracking. try { + checkAccess(refKind, defc, member); checkSecurityManager(defc, member); - checkAccess(refKind, defc, member); } catch (IllegalAccessException ex) { throw new IllegalArgumentException(ex); } + if (allowedModes != TRUSTED && member.isCallerSensitive()) { + Class<?> callerClass = target.internalCallerClass(); + if (!hasPrivateAccess() || callerClass != lookupClass()) + throw new IllegalArgumentException("method handle is caller sensitive: "+callerClass); + } // Produce the handle to the results. return new InfoFromMemberName(this, member, refKind); } @@ -1090,24 +1354,43 @@ MemberName resolveOrFail(byte refKind, Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException { checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); type.getClass(); // NPE + name.getClass(); // NPE + type.getClass(); // NPE return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchFieldException.class); } MemberName resolveOrFail(byte refKind, Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { checkSymbolicClass(refc); // do this before attempting to resolve - name.getClass(); type.getClass(); // NPE + name.getClass(); // NPE + type.getClass(); // NPE + checkMethodName(refKind, name); // NPE check on name return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), NoSuchMethodException.class); } + MemberName resolveOrFail(byte refKind, MemberName member) throws ReflectiveOperationException { + checkSymbolicClass(member.getDeclaringClass()); // do this before attempting to resolve + member.getName().getClass(); // NPE + member.getType().getClass(); // NPE + return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(), + ReflectiveOperationException.class); + } + void checkSymbolicClass(Class<?> refc) throws IllegalAccessException { + refc.getClass(); // NPE Class<?> caller = lookupClassOrNull(); if (caller != null && !VerifyAccess.isClassAccessible(refc, caller, allowedModes)) throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this); } + /** Check name for an illegal leading "<" character. */ + void checkMethodName(byte refKind, String name) throws NoSuchMethodException { + if (name.startsWith("<") && refKind != REF_newInvokeSpecial) + throw new NoSuchMethodException("illegal method name: "+name); + } + + /** * Find my trustable caller class if m is a caller sensitive method. * If this lookup object has private access, then the caller class is the lookupClass. @@ -1116,8 +1399,8 @@ Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException { Class<?> callerClass = null; if (MethodHandleNatives.isCallerSensitive(m)) { - // Only full-power lookup is allowed to resolve caller-sensitive methods - if (isFullPowerLookup()) { + // Only lookups with private access are allowed to resolve caller-sensitive methods + if (hasPrivateAccess()) { callerClass = lookupClass; } else { throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object"); @@ -1126,7 +1409,7 @@ return callerClass; } - private boolean isFullPowerLookup() { + private boolean hasPrivateAccess() { return (allowedModes & PRIVATE) != 0; } @@ -1141,22 +1424,21 @@ if (allowedModes == TRUSTED) return; // Step 1: - if (!isFullPowerLookup() || + boolean fullPowerLookup = hasPrivateAccess(); + if (!fullPowerLookup || !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) { ReflectUtil.checkPackageAccess(refc); } // Step 2: if (m.isPublic()) return; - Class<?> defc = m.getDeclaringClass(); - { - if (!isFullPowerLookup()) { - smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); - } + if (!fullPowerLookup) { + smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); } // Step 3: - if (defc != refc) { + Class<?> defc = m.getDeclaringClass(); + if (!fullPowerLookup && defc != refc) { ReflectUtil.checkPackageAccess(defc); } } @@ -1185,6 +1467,7 @@ throw m.makeAccessException(message, this); } + /** Check public/protected/private bits on the symbolic reference class and its member. */ void checkAccess(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException { assert(m.referenceKindIsConsistentWith(refKind) && MethodHandleNatives.refKindIsValid(refKind) && @@ -1192,6 +1475,26 @@ int allowedModes = this.allowedModes; if (allowedModes == TRUSTED) return; int mods = m.getModifiers(); + if (Modifier.isProtected(mods) && + refKind == REF_invokeVirtual && + m.getDeclaringClass() == Object.class && + m.getName().equals("clone") && + refc.isArray()) { + // The JVM does this hack also. + // (See ClassVerifier::verify_invoke_instructions + // and LinkResolver::check_method_accessability.) + // Because the JVM does not allow separate methods on array types, + // there is no separate method for int[].clone. + // All arrays simply inherit Object.clone. + // But for access checking logic, we make Object.clone + // (normally protected) appear to be public. + // Later on, when the DirectMethodHandle is created, + // its leading argument will be restricted to the + // requested array type. + // N.B. The return type is not adjusted, because + // that is *not* the bytecode behavior. + mods ^= Modifier.PROTECTED | Modifier.PUBLIC; + } if (Modifier.isFinal(mods) && MethodHandleNatives.refKindIsSetter(refKind)) throw m.makeAccessException("unexpected set of a final field", this); @@ -1239,7 +1542,7 @@ private void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException { int allowedModes = this.allowedModes; if (allowedModes == TRUSTED) return; - if ((allowedModes & PRIVATE) == 0 + if (!hasPrivateAccess() || (specialCaller != lookupClass() && !(ALLOW_NESTMATE_ACCESS && VerifyAccess.isSamePackageMember(specialCaller, lookupClass())))) @@ -1271,18 +1574,32 @@ return mh.viewAsType(narrowType); } + /** Check access and get the requested method. */ private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException { - return getDirectMethodCommon(refKind, refc, method, - (refKind == REF_invokeSpecial || - (MethodHandleNatives.refKindHasReceiver(refKind) && - restrictProtectedReceiver(method))), callerClass); + final boolean doRestrict = true; + final boolean checkSecurity = true; + return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass); + } + /** Check access and get the requested method, eliding receiver narrowing rules. */ + private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException { + final boolean doRestrict = false; + final boolean checkSecurity = true; + return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass); } - private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException { - return getDirectMethodCommon(refKind, refc, method, false, callerClass); + /** Check access and get the requested method, eliding security manager checks. */ + private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException { + final boolean doRestrict = true; + final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants + return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass); } + /** Common code for all methods; do not call directly except from immediately above. */ private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method, + boolean checkSecurity, boolean doRestrict, Class<?> callerClass) throws IllegalAccessException { checkMethod(refKind, refc, method); + // Optionally check with the security manager; this isn't needed for unreflect* calls. + if (checkSecurity) + checkSecurityManager(refc, method); assert(!method.isMethodHandleInvoke()); Class<?> refcAsSuper; @@ -1312,7 +1629,11 @@ MethodHandle mh = DirectMethodHandle.make(refKind, refc, method); mh = maybeBindCaller(method, mh, callerClass); mh = mh.setVarargs(method); - if (doRestrict) + // Optionally narrow the receiver argument to refc using restrictReceiver. + if (doRestrict && + (refKind == REF_invokeSpecial || + (MethodHandleNatives.refKindHasReceiver(refKind) && + restrictProtectedReceiver(method)))) mh = restrictReceiver(method, mh, lookupClass()); return mh; } @@ -1322,14 +1643,29 @@ if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method)) return mh; Class<?> hostClass = lookupClass; - if ((allowedModes & PRIVATE) == 0) // caller must use full-power lookup + if (!hasPrivateAccess()) // caller must have private access hostClass = callerClass; // callerClass came from a security manager style stack walk MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass); // Note: caller will apply varargs after this step happens. return cbmh; } + /** Check access and get the requested field. */ private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException { + final boolean checkSecurity = true; + return getDirectFieldCommon(refKind, refc, field, checkSecurity); + } + /** Check access and get the requested field, eliding security manager checks. */ + private MethodHandle getDirectFieldNoSecurityManager(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException { + final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants + return getDirectFieldCommon(refKind, refc, field, checkSecurity); + } + /** Common code for all fields; do not call directly except from immediately above. */ + private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field, + boolean checkSecurity) throws IllegalAccessException { checkField(refKind, refc, field); + // Optionally check with the security manager; this isn't needed for unreflect* calls. + if (checkSecurity) + checkSecurityManager(refc, field); MethodHandle mh = DirectMethodHandle.make(refc, field); boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) && restrictProtectedReceiver(field)); @@ -1337,9 +1673,24 @@ mh = restrictReceiver(field, mh, lookupClass()); return mh; } + /** Check access and get the requested constructor. */ private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException { + final boolean checkSecurity = true; + return getDirectConstructorCommon(refc, ctor, checkSecurity); + } + /** Check access and get the requested constructor, eliding security manager checks. */ + private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException { + final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants + return getDirectConstructorCommon(refc, ctor, checkSecurity); + } + /** Common code for all constructors; do not call directly except from immediately above. */ + private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor, + boolean checkSecurity) throws IllegalAccessException { assert(ctor.isConstructor()); checkAccess(REF_newInvokeSpecial, refc, ctor); + // Optionally check with the security manager; this isn't needed for unreflect* calls. + if (checkSecurity) + checkSecurityManager(refc, ctor); assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here return DirectMethodHandle.make(ctor).setVarargs(ctor); } @@ -1348,29 +1699,75 @@ */ /*non-public*/ MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type) throws ReflectiveOperationException { - MemberName resolved = null; - if (type instanceof MemberName) { - resolved = (MemberName) type; - if (!resolved.isResolved()) throw new InternalError("unresolved MemberName"); - assert(name == null || name.equals(resolved.getName())); + if (!(type instanceof Class || type instanceof MethodType)) + throw new InternalError("unresolved MemberName"); + MemberName member = new MemberName(refKind, defc, name, type); + MethodHandle mh = LOOKASIDE_TABLE.get(member); + if (mh != null) { + checkSymbolicClass(defc); + return mh; + } + MemberName resolved = resolveOrFail(refKind, member); + mh = getDirectMethodForConstant(refKind, defc, resolved); + if (mh instanceof DirectMethodHandle + && canBeCached(refKind, defc, resolved)) { + MemberName key = mh.internalMemberName(); + if (key != null) { + key = key.asNormalOriginal(); + } + if (member.equals(key)) { // better safe than sorry + LOOKASIDE_TABLE.put(key, (DirectMethodHandle) mh); + } + } + return mh; + } + private + boolean canBeCached(byte refKind, Class<?> defc, MemberName member) { + if (refKind == REF_invokeSpecial) { + return false; } + if (!Modifier.isPublic(defc.getModifiers()) || + !Modifier.isPublic(member.getDeclaringClass().getModifiers()) || + !member.isPublic() || + member.isCallerSensitive()) { + return false; + } + ClassLoader loader = defc.getClassLoader(); + if (!sun.misc.VM.isSystemDomainLoader(loader)) { + ClassLoader sysl = ClassLoader.getSystemClassLoader(); + boolean found = false; + while (sysl != null) { + if (loader == sysl) { found = true; break; } + sysl = sysl.getParent(); + } + if (!found) { + return false; + } + } + try { + MemberName resolved2 = publicLookup().resolveOrFail(refKind, + new MemberName(refKind, defc, member.getName(), member.getType())); + checkSecurityManager(defc, resolved2); + } catch (ReflectiveOperationException | SecurityException ex) { + return false; + } + return true; + } + private + MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member) + throws ReflectiveOperationException { if (MethodHandleNatives.refKindIsField(refKind)) { - MemberName field = (resolved != null) ? resolved - : resolveOrFail(refKind, defc, name, (Class<?>) type); - return getDirectField(refKind, defc, field); + return getDirectFieldNoSecurityManager(refKind, defc, member); } else if (MethodHandleNatives.refKindIsMethod(refKind)) { - MemberName method = (resolved != null) ? resolved - : resolveOrFail(refKind, defc, name, (MethodType) type); - return getDirectMethod(refKind, defc, method, lookupClass); + return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass); } else if (refKind == REF_newInvokeSpecial) { - assert(name == null || name.equals("<init>")); - MemberName ctor = (resolved != null) ? resolved - : resolveOrFail(REF_newInvokeSpecial, defc, name, (MethodType) type); - return getDirectConstructor(defc, ctor); + return getDirectConstructorNoSecurityManager(defc, member); } // oops - throw new ReflectiveOperationException("bad MethodHandle constant #"+refKind+" "+name+" : "+type); + throw newIllegalArgumentException("bad MethodHandle constant #"+member); } + + static ConcurrentHashMap<MemberName, DirectMethodHandle> LOOKASIDE_TABLE = new ConcurrentHashMap<>(); } /** @@ -1430,22 +1827,26 @@ * <p> * Before invoking its target, the invoker will spread the final array, apply * reference casts as necessary, and unbox and widen primitive arguments. + * If, when the invoker is called, the supplied array argument does + * not have the correct number of elements, the invoker will throw + * an {@link IllegalArgumentException} instead of invoking the target. * <p> * This method is equivalent to the following code (though it may be more efficient): - * <p><blockquote><pre> + * <blockquote><pre>{@code MethodHandle invoker = MethodHandles.invoker(type); int spreadArgCount = type.parameterCount() - leadingArgCount; invoker = invoker.asSpreader(Object[].class, spreadArgCount); return invoker; - * </pre></blockquote> - * <p> + * }</pre></blockquote> * This method throws no reflective or security exceptions. * @param type the desired target type * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target * @return a method handle suitable for invoking any method handle of the given type * @throws NullPointerException if {@code type} is null * @throws IllegalArgumentException if {@code leadingArgCount} is not in - * the range from 0 to {@code type.parameterCount()} inclusive + * the range from 0 to {@code type.parameterCount()} inclusive, + * or if the resulting method handle's type would have + * <a href="MethodHandle.html#maxarity">too many parameters</a> */ static public MethodHandle spreadInvoker(MethodType type, int leadingArgCount) { @@ -1462,9 +1863,7 @@ * an additional leading argument of type {@code MethodHandle}. * <p> * This method is equivalent to the following code (though it may be more efficient): - * <p><blockquote><pre> -publicLookup().findVirtual(MethodHandle.class, "invokeExact", type) - * </pre></blockquote> + * {@code publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)} * * <p style="font-size:smaller;"> * <em>Discussion:</em> @@ -1479,7 +1878,7 @@ * If spreading, collecting, or other argument transformations are required, * they can be applied once to the invoker {@code X} and reused on many {@code M} * method handle values, as long as they are compatible with the type of {@code X}. - * <p> + * <p style="font-size:smaller;"> * <em>(Note: The invoker method is not available via the Core Reflection API. * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke} * on the declared {@code invokeExact} or {@code invoke} method will raise an @@ -1488,6 +1887,8 @@ * This method throws no reflective or security exceptions. * @param type the desired target type * @return a method handle suitable for invoking any method handle of the given type + * @throws IllegalArgumentException if the resulting method handle's type would have + * <a href="MethodHandle.html#maxarity">too many parameters</a> */ static public MethodHandle exactInvoker(MethodType type) { @@ -1508,19 +1909,25 @@ * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle}, * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}. * <p> - * A {@linkplain MethodType#genericMethodType general method type}, + * This method is equivalent to the following code (though it may be more efficient): + * {@code publicLookup().findVirtual(MethodHandle.class, "invoke", type)} + * <p style="font-size:smaller;"> + * <em>Discussion:</em> + * A {@linkplain MethodType#genericMethodType general method type} is one which * mentions only {@code Object} arguments and return values. * An invoker for such a type is capable of calling any method handle * of the same arity as the general type. - * <p> - * This method is equivalent to the following code (though it may be more efficient): - * <p><blockquote><pre> -publicLookup().findVirtual(MethodHandle.class, "invoke", type) - * </pre></blockquote> + * <p style="font-size:smaller;"> + * <em>(Note: The invoker method is not available via the Core Reflection API. + * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke} + * on the declared {@code invokeExact} or {@code invoke} method will raise an + * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em> * <p> * This method throws no reflective or security exceptions. * @param type the desired target type * @return a method handle suitable for invoking any method handle convertible to the given type