--- a/jdk/make/data/swingbeaninfo/SwingBeanInfo.template Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 1998, 2015, 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 @(BeanPackageName);
-
-import java.beans.BeanDescriptor;
-import java.beans.PropertyDescriptor;
-import java.awt.Image;
-
-import sun.swing.BeanInfoUtils;
-
-/**
- * Descriptive information about the @(BeanClassName) class for Java
- * Beans application builders. This BeanInfo class provides descriptions
- * of each property, of the bean itself, it indicates which
- * @(BeanClassName) properties are bound, and it provides other
- * information and icons useful to builders.
- *
- * @author Auto-Generated Source Code
- */
-
-public class @(BeanClassName)BeanInfo extends javax.swing.SwingBeanInfoBase {
- private static final Class<?> class@(BeanClassName) = @(BeanClassObject);
-
- /**
- * @return a @(BeanClassName) BeanDescriptor
- */
- public BeanDescriptor getBeanDescriptor() {
- return BeanInfoUtils.createBeanDescriptor(class@(BeanClassName),
- new Object[] {
- BeanInfoUtils.PREFERRED, Boolean.TRUE,
- @(ClassDescriptors)
- BeanInfoUtils.SHORTDESCRIPTION, "@(BeanDescription)"
- });
- }
-
-
- /**
- * Create a @(BeanClassName) PropertyDescriptor. This is just an internal
- * convenience method that allows one to leave the @(BeanClassName).class
- * argument out of the createPropertyDescriptor() class in the
- * getPropertyDescriptors() method below.
- *
- * @param name the name of the property
- * @param args an array java.beans.PropertyDescriptor property names and values
- * @return a @(BeanClassName) PropertyDescriptor.
- * @see BeanInfoUtils#createPropertyDescriptor
- */
- private PropertyDescriptor createPropertyDescriptor(String name, Object[] args) {
- return BeanInfoUtils.createPropertyDescriptor(class@(BeanClassName), name, args);
- }
-
-
- /**
- * This method returns a list of bean PropertyDescriptors, one for each public
- * property in @(BeanClassName). The first property is the "default" property.
- *
- * @return a complete list of bean PropertyDescriptors for @(BeanClassName)
- * @see SwingBeanInfo
- * @see java.beans.BeanInfo#getDefaultPropertyIndex
- */
- public PropertyDescriptor[] getPropertyDescriptors() {
- @(EnumVariables)
- return new PropertyDescriptor[] {
- @(BeanPropertyDescriptors)
- };
- }
-
-
- /**
- * @return an icon of the specified kind for @(BeanClassName)
- */
- public Image getIcon(final int kind) {
- Image i;
- switch (kind){
- case ICON_COLOR_32x32:
- i = loadStandardImage("beaninfo/images/@(BeanClassName)Color32.gif");
- return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor32.gif") : i);
- case ICON_COLOR_16x16:
- i = loadStandardImage("beaninfo/images/@(BeanClassName)Color16.gif");
- return ((i == null) ? loadStandardImage("beaninfo/images/JComponentColor16.gif") : i);
- case ICON_MONO_32x32:
- i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono32.gif");
- return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono32.gif") : i);
- case ICON_MONO_16x16:
- i = loadStandardImage("beaninfo/images/@(BeanClassName)Mono16.gif");
- return ((i == null) ? loadStandardImage("beaninfo/images/JComponentMono16.gif") : i);
- default:
- return super.getIcon(kind);
- }
- }
-
- /**
- * This is a utility method to help in loading standard icon images.
- *
- * @param resourceName A pathname relative to the directory holding the
- * class file of the current class
- * @return an image object. May be null if the load failed.
- * @see java.beans.SimpleBeanInfo#loadImage(String)
- */
- private Image loadStandardImage(final String resourceName) {
- return java.security.AccessController.doPrivileged(
- (java.security.PrivilegedAction<Image>) () -> loadImage(resourceName));
- }
-}
-
-
Binary file jdk/make/data/swingbeaninfo/images/AbstractButtonColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/BorderColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/BoxColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/BoxColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/BoxMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/BoxMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JAppletColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JAppletColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JAppletMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JAppletMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JButtonColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JButtonColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JButtonMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JButtonMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JCheckBoxColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JCheckBoxColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JCheckBoxMenuItemMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JCheckBoxMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JCheckBoxMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JColorChooserColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JColorChooserColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JColorChooserMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JColorChooserMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JComboBoxColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JComboBoxColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JComboBoxMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JComboBoxMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JComponentColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JDesktopPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JDesktopPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JDesktopPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JDesktopPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JDialogColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JDialogColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JDialogMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JDialogMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JEditorPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JEditorPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JEditorPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JEditorPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFileChooserColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFileChooserColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFileChooserMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFileChooserMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFormattedTextFieldColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFormattedTextFieldColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFormattedTextFieldMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFormattedTextFieldMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFrameColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFrameColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFrameMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JFrameMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JInternalFrameColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JInternalFrameColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JInternalFrameMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JInternalFrameMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JLabelColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JLabelColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JLabelMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JLabelMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JLayeredPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JLayeredPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JLayeredPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JLayeredPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JListColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JListColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JListMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JListMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuBarColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuBarColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuBarMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuBarMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuItemColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuItemColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuItemMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuItemMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JMenuMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JOptionPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JOptionPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JOptionPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JOptionPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPanelColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPanelColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPanelMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPanelMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPasswordFieldColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPasswordFieldColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPasswordFieldMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPasswordFieldMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPopupMenuColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPopupMenuColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPopupMenuMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JPopupMenuMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JProgressBarColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JProgressBarColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JProgressBarMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JProgressBarMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRadioButtonColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRadioButtonColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRadioButtonMenuItemMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRadioButtonMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRadioButtonMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRootPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRootPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRootPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JRootPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JScrollBarColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JScrollBarColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JScrollBarMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JScrollBarMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JScrollPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JScrollPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JScrollPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JScrollPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSeparatorColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSeparatorColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSeparatorMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSeparatorMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSliderColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSliderColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSliderMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSliderMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSpinnerColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSpinnerColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSpinnerMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSpinnerMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSplitPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSplitPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSplitPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JSplitPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTabbedPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTabbedPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTabbedPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTabbedPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTableColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTableColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTableMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTableMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextAreaColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextAreaColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextAreaMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextAreaMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextFieldColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextFieldColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextFieldMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextFieldMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextPaneColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextPaneColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextPaneMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTextPaneMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JToggleButtonColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JToggleButtonColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JToggleButtonMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JToggleButtonMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JToolBarColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JToolBarColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JToolBarMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JToolBarMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTreeColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTreeColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTreeMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JTreeMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JViewportColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JViewportColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JViewportMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JViewportMono32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JWindowColor16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JWindowColor32.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JWindowMono16.gif has changed
Binary file jdk/make/data/swingbeaninfo/images/JWindowMono32.gif has changed
--- a/jdk/make/data/swingbeaninfo/javax/swing/SwingBeanInfoBase.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 1997, 2014, 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 javax.swing;
-
-import java.beans.*;
-import java.lang.reflect.*;
-import java.awt.Image;
-
-/**
- * The superclass for all Swing BeanInfo classes. It provides
- * default implementations of <code>getIcon</code> and
- * <code>getDefaultPropertyIndex</code> as well as utility
- * methods, like createPropertyDescriptor, for writing BeanInfo
- * implementations. This classes is intended to be used along
- * with <code>GenSwingBeanInfo</code> a BeanInfo class code generator.
- *
- * @see GenSwingBeanInfo
- * @author Hans Muller
- */
-public class SwingBeanInfoBase extends SimpleBeanInfo
-{
- /**
- * The default index is always 0. In other words the first property
- * listed in the getPropertyDescriptors() method is the one
- * to show a (JFC builder) user in a situation where just a single
- * property will be shown.
- */
- public int getDefaultPropertyIndex() {
- return 0;
- }
-
- /**
- * Returns a generic Swing icon, all icon "kinds" are supported.
- * Subclasses should defer to this method when they don't have
- * a particular beans icon kind.
- */
- public Image getIcon(int kind) {
- // PENDING(hmuller) need generic swing icon images.
- return null;
- }
-
- /**
- * Returns the BeanInfo for the superclass of our bean, so that
- * its PropertyDescriptors will be included.
- */
- public BeanInfo[] getAdditionalBeanInfo() {
- Class<?> superClass = getBeanDescriptor().getBeanClass().getSuperclass();
- BeanInfo superBeanInfo = null;
- try {
- superBeanInfo = Introspector.getBeanInfo(superClass);
- } catch (IntrospectionException ie) {}
- if (superBeanInfo != null) {
- BeanInfo[] ret = new BeanInfo[1];
- ret[0] = superBeanInfo;
- return ret;
- }
- return null;
- }
-}
--- a/jdk/make/data/swingbeaninfo/manifest.mf Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-Name: javax/swing/JApplet.class
-Java-Bean: True
-
-Name: javax/swing/JButton.class
-Java-Bean: True
-
-Name: javax/swing/JCheckBox.class
-Java-Bean: True
-
-Name: javax/swing/JCheckBoxMenuItem.class
-Java-Bean: True
-
-Name: javax/swing/JComboBox.class
-Java-Bean: True
-
-Name: javax/swing/JDialog.class
-Java-Bean: True
-
-Name: javax/swing/JEditorPane.class
-Java-Bean: True
-
-Name: javax/swing/JFormattedTextField.class
-Java-Bean: True
-
-Name: javax/swing/JInternalFrame.class
-Java-Bean: True
-
-Name: javax/swing/JFrame.class
-Java-Bean: True
-
-Name: javax/swing/JLabel.class
-Java-Bean: True
-
-Name: javax/swing/JList.class
-Java-Bean: True
-
-Name: javax/swing/JMenu.class
-Java-Bean: True
-
-Name: javax/swing/JMenuBar.class
-Java-Bean: True
-
-Name: javax/swing/JMenuItem.class
-Java-Bean: True
-
-Name: javax/swing/JOptionPane.class
-Java-Bean: True
-
-Name: javax/swing/JPanel.class
-Java-Bean: True
-
-Name: javax/swing/JPasswordField.class
-Java-Bean: True
-
-Name: javax/swing/JPopupMenu.class
-Java-Bean: True
-
-Name: javax/swing/JProgressBar.class
-Java-Bean: True
-
-Name: javax/swing/JRadioButton.class
-Java-Bean: True
-
-Name: javax/swing/JRadioButtonMenuItem.class
-Java-Bean: True
-
-Name: javax/swing/JScrollBar.class
-Java-Bean: True
-
-Name: javax/swing/JScrollPane.class
-Java-Bean: True
-
-Name: javax/swing/JSeparator.class
-Java-Bean: True
-
-Name: javax/swing/JSlider.class
-Java-Bean: True
-
-Name: javax/swing/JSpinner.class
-Java-Bean: True
-
-Name: javax/swing/JSplitPane.class
-Java-Bean: True
-
-Name: javax/swing/JTabbedPane.class
-Java-Bean: True
-
-Name: javax/swing/JTextArea.class
-Java-Bean: True
-
-Name: javax/swing/JTextField.class
-Java-Bean: True
-
-Name: javax/swing/JTextPane.class
-Java-Bean: True
-
-Name: javax/swing/JToolBar.class
-Java-Bean: True
-
-Name: javax/swing/JTree.class
-Java-Bean: True
-
-Name: javax/swing/JTable.class
-Java-Bean: True
-
-Name: javax/swing/JToggleButton.class
-Java-Bean: True
-
-Name: javax/swing/JWindow.class
-Java-Bean: True
-
--- a/jdk/make/data/swingbeaninfo/sun/swing/BeanInfoUtils.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,293 +0,0 @@
-/*
- * Copyright (c) 1998, 2014, 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 sun.swing;
-
-import java.beans.*;
-import java.lang.reflect.Method;
-
-public class BeanInfoUtils
-{
- /* The values of these createPropertyDescriptor() and
- * createBeanDescriptor() keywords are the names of the
- * properties they're used to set.
- */
- public static final String BOUND = "bound";
- public static final String CONSTRAINED = "constrained";
- public static final String PROPERTYEDITORCLASS = "propertyEditorClass";
- public static final String READMETHOD = "readMethod";
- public static final String WRITEMETHOD = "writeMethod";
- public static final String DISPLAYNAME = "displayName";
- public static final String EXPERT = "expert";
- public static final String HIDDEN = "hidden";
- public static final String PREFERRED = "preferred";
- public static final String SHORTDESCRIPTION = "shortDescription";
- public static final String CUSTOMIZERCLASS = "customizerClass";
-
- static private void initFeatureDescriptor(FeatureDescriptor fd, String key, Object value)
- {
- if (DISPLAYNAME.equals(key)) {
- fd.setDisplayName((String)value);
- }
-
- if (EXPERT.equals(key)) {
- fd.setExpert(((Boolean)value).booleanValue());
- }
-
- if (HIDDEN.equals(key)) {
- fd.setHidden(((Boolean)value).booleanValue());
- }
-
- if (PREFERRED.equals(key)) {
- fd.setPreferred(((Boolean)value).booleanValue());
- }
-
- else if (SHORTDESCRIPTION.equals(key)) {
- fd.setShortDescription((String)value);
- }
-
- /* Otherwise assume that we have an arbitrary FeatureDescriptor
- * "attribute".
- */
- else {
- fd.setValue(key, value);
- }
- }
-
- /**
- * Create a beans PropertyDescriptor given an of keyword/value
- * arguments. The following sample call shows all of the supported
- * keywords:
- *<pre>
- * createPropertyDescriptor("contentPane", new Object[] {
- * BOUND, Boolean.TRUE,
- * CONSTRAINED, Boolean.TRUE,
- * PROPERTYEDITORCLASS, package.MyEditor.class,
- * READMETHOD, "getContentPane",
- * WRITEMETHOD, "setContentPane",
- * DISPLAYNAME, "contentPane",
- * EXPERT, Boolean.FALSE,
- * HIDDEN, Boolean.FALSE,
- * PREFERRED, Boolean.TRUE,
- * SHORTDESCRIPTION, "A top level window with a window manager border",
- * "random attribute","random object value"
- * }
- * );
- * </pre>
- * The keywords correspond to <code>java.beans.PropertyDescriptor</code> and
- * <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
- * for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
- * Using createPropertyDescriptor instead of the PropertyDescriptor
- * constructor and set methods is preferrable in that it regularizes
- * the code in a <code>java.beans.BeanInfo.getPropertyDescriptors()</code>
- * method implementation. One can use <code>createPropertyDescriptor</code>
- * to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
- * "random object value".
- * <p>
- * All properties should provide a reasonable value for the
- * <code>SHORTDESCRIPTION</code> keyword and should set <code>BOUND</code>
- * to <code>Boolean.TRUE</code> if neccessary. The remaining keywords
- * are optional. There's no need to provide values for keywords like
- * READMETHOD if the correct value can be computed, i.e. if the properties
- * get/is method follows the standard beans pattern.
- * <p>
- * The PREFERRED keyword is not supported by the JDK1.1 java.beans package.
- * It's still worth setting it to true for properties that are most
- * likely to be interested to the average developer, e.g. AbstractButton.title
- * is a preferred property, AbstractButton.focusPainted is not.
- *
- * @see java.beans#BeanInfo
- * @see java.beans#PropertyDescriptor
- * @see java.beans#FeatureDescriptor
- */
- public static PropertyDescriptor createPropertyDescriptor(Class<?> cls, String name, Object[] args)
- {
- PropertyDescriptor pd = null;
- try {
- pd = new PropertyDescriptor(name, cls);
- } catch (IntrospectionException e) {
- // Try creating a read-only property, in case setter isn't defined.
- try {
- pd = createReadOnlyPropertyDescriptor(name, cls);
- } catch (IntrospectionException ie) {
- throwError(ie, "Can't create PropertyDescriptor for " + name + " ");
- }
- }
-
- for(int i = 0; i < args.length; i += 2) {
- String key = (String)args[i];
- Object value = args[i + 1];
-
- if (BOUND.equals(key)) {
- pd.setBound(((Boolean)value).booleanValue());
- }
-
- else if (CONSTRAINED.equals(key)) {
- pd.setConstrained(((Boolean)value).booleanValue());
- }
-
- else if (PROPERTYEDITORCLASS.equals(key)) {
- pd.setPropertyEditorClass((Class)value);
- }
-
- else if (READMETHOD.equals(key)) {
- String methodName = (String)value;
- Method method;
- try {
- method = cls.getMethod(methodName, new Class<?>[0]);
- pd.setReadMethod(method);
- }
- catch(Exception e) {
- throwError(e, cls + " no such method as \"" + methodName + "\"");
- }
- }
-
- else if (WRITEMETHOD.equals(key)) {
- String methodName = (String)value;
- Method method;
- try {
- Class<?> type = pd.getPropertyType();
- method = cls.getMethod(methodName, new Class<?>[]{type});
- pd.setWriteMethod(method);
- }
- catch(Exception e) {
- throwError(e, cls + " no such method as \"" + methodName + "\"");
- }
- }
-
- else {
- initFeatureDescriptor(pd, key, value);
- }
- }
-
- return pd;
- }
-
-
- /**
- * Create a BeanDescriptor object given an of keyword/value
- * arguments. The following sample call shows all of the supported
- * keywords:
- *<pre>
- * createBeanDescriptor(JWindow..class, new Object[] {
- * CUSTOMIZERCLASS, package.MyCustomizer.class,
- * DISPLAYNAME, "JFrame",
- * EXPERT, Boolean.FALSE,
- * HIDDEN, Boolean.FALSE,
- * PREFERRED, Boolean.TRUE,
- * SHORTDESCRIPTION, "A top level window with a window manager border",
- * "random attribute","random object value"
- * }
- * );
- * </pre>
- * The keywords correspond to <code>java.beans.BeanDescriptor</code> and
- * <code>java.beans.FeatureDescriptor</code> properties, e.g. providing a value
- * for displayName is comparable to <code>FeatureDescriptor.setDisplayName()</code>.
- * Using createBeanDescriptor instead of the BeanDescriptor
- * constructor and set methods is preferrable in that it regularizes
- * the code in a <code>java.beans.BeanInfo.getBeanDescriptor()</code>
- * method implementation. One can use <code>createBeanDescriptor</code>
- * to set <code>FeatureDescriptor</code> attributes, as in "random attribute"
- * "random object value".
- *
- * @see java.beans#BeanInfo
- * @see java.beans#PropertyDescriptor
- */
- public static BeanDescriptor createBeanDescriptor(Class<?> cls, Object[] args)
- {
- Class<?> customizerClass = null;
-
- /* For reasons I don't understand, customizerClass is a
- * readOnly property. So we have to find it and pass it
- * to the constructor here.
- */
- for(int i = 0; i < args.length; i += 2) {
- if (CUSTOMIZERCLASS.equals((String)args[i])) {
- customizerClass = (Class)args[i + 1];
- break;
- }
- }
-
- BeanDescriptor bd = new BeanDescriptor(cls, customizerClass);
-
- for(int i = 0; i < args.length; i += 2) {
- String key = (String)args[i];
- Object value = args[i + 1];
- initFeatureDescriptor(bd, key, value);
- }
-
- return bd;
- }
-
- static private PropertyDescriptor createReadOnlyPropertyDescriptor(
- String name, Class<?> cls) throws IntrospectionException {
-
- Method readMethod = null;
- String base = capitalize(name);
- Class<?>[] parameters = new Class<?>[0];
-
- // Is it a boolean?
- try {
- readMethod = cls.getMethod("is" + base, parameters);
- } catch (Exception ex) {}
- if (readMethod == null) {
- try {
- // Try normal accessor pattern.
- readMethod = cls.getMethod("get" + base, parameters);
- } catch (Exception ex2) {}
- }
- if (readMethod != null) {
- return new PropertyDescriptor(name, readMethod, null);
- }
-
- try {
- // Try indexed accessor pattern.
- parameters = new Class<?>[1];
- parameters[0] = int.class;
- readMethod = cls.getMethod("get" + base, parameters);
- } catch (NoSuchMethodException nsme) {
- throw new IntrospectionException(
- "cannot find accessor method for " + name + " property.");
- }
- return new IndexedPropertyDescriptor(name, null, null, readMethod, null);
- }
-
- // Modified methods from java.beans.Introspector
- private static String capitalize(String s) {
- if (s.length() == 0) {
- return s;
- }
- char chars[] = s.toCharArray();
- chars[0] = Character.toUpperCase(chars[0]);
- return new String(chars);
- }
-
- /**
- * Fatal errors are handled by calling this method.
- */
- public static void throwError(Exception e, String s) {
- throw new Error(e.toString() + " " + s);
- }
-}
--- a/jdk/make/gensrc/Gensrc-java.base.gmk Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/make/gensrc/Gensrc-java.base.gmk Thu Apr 07 11:03:59 2016 -0700
@@ -33,6 +33,7 @@
include GensrcCharsetCoder.gmk
include GensrcBuffer.gmk
include GensrcExceptions.gmk
+include GensrcVarHandles.gmk
include GensrcModuleLoaderMap.gmk
################################################################################
--- a/jdk/make/gensrc/Gensrc-java.desktop.gmk Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/make/gensrc/Gensrc-java.desktop.gmk Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, 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
@@ -62,7 +62,9 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/windows/classes/sun/awt/windows
-else
+endif
+
+ifeq ($(filter $(OPENJDK_TARGET_OS), windows macosx), )
PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/resources
endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gensrc/GensrcVarHandles.gmk Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,162 @@
+#
+# Copyright (c) 2015, 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.
+#
+
+GENSRC_VARHANDLES :=
+
+VARHANDLES_GENSRC_DIR := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/java/lang/invoke
+VARHANDLES_SRC_DIR := $(JDK_TOPDIR)/src/java.base/share/classes/java/lang/invoke
+
+################################################################################
+# Setup a rule for generating a VarHandle java class
+# Param 1 - Variable declaration prefix
+# Param 2 - Type with first letter capitalized
+define GenerateVarHandle
+
+ $1_Type := $2
+
+ $1_FILENAME := $(VARHANDLES_GENSRC_DIR)/VarHandle$$($1_Type)s.java
+
+ ifneq ($$(findstring $$($1_Type), Object Int Long), )
+ $1_ARGS += -KCAS
+ endif
+
+ ifneq ($$(findstring $$($1_Type), Int Long), )
+ $1_ARGS += -KAtomicAdd
+ endif
+
+ $$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandle.java.template $(BUILD_TOOLS_JDK)
+ ifeq ($$($1_Type), Object)
+ $$(eval $1_type := $$($1_Type))
+ else
+ $$(eval $1_type := $$$$(shell $(TR) '[:upper:]' '[:lower:]' <<< $$$$($1_Type)))
+ endif
+ $$(call MakeDir, $$(@D))
+ $(TOOL_SPP) -nel -K$$($1_type) -Dtype=$$($1_type) -DType=$$($1_Type) \
+ $$($1_ARGS) < $$< > $$@
+
+ GENSRC_VARHANDLES += $$($1_FILENAME)
+endef
+
+################################################################################
+
+################################################################################
+# Setup a rule for generating a VarHandleByteArray java class
+# Param 1 - Variable declaration prefix
+# Param 2 - Type with first letter capitalized
+define GenerateVarHandleByteArray
+
+ $1_Type := $2
+
+ $1_FILENAME := $(VARHANDLES_GENSRC_DIR)/VarHandleByteArrayAs$$($1_Type)s.java
+
+ ifeq ($$($1_Type), Short)
+ $1_type := short
+ $1_BoxType := $$($1_Type)
+
+ $1_rawType := $$($1_type)
+ $1_RawType := $$($1_Type)
+ $1_RawBoxType := $$($1_BoxType)
+ endif
+
+ ifeq ($$($1_Type), Char)
+ $1_type := char
+ $1_BoxType := Character
+
+ $1_rawType := $$($1_type)
+ $1_RawType := $$($1_Type)
+ $1_RawBoxType := $$($1_BoxType)
+ endif
+
+ ifeq ($$($1_Type), Int)
+ $1_type := int
+ $1_BoxType := Integer
+
+ $1_rawType := $$($1_type)
+ $1_RawType := $$($1_Type)
+ $1_RawBoxType := $$($1_BoxType)
+
+ $1_ARGS += -KCAS
+ $1_ARGS += -KAtomicAdd
+ endif
+
+ ifeq ($$($1_Type), Long)
+ $1_type := long
+ $1_BoxType := $$($1_Type)
+
+ $1_rawType := $$($1_type)
+ $1_RawType := $$($1_Type)
+ $1_RawBoxType := $$($1_BoxType)
+
+ $1_ARGS += -KCAS
+ $1_ARGS += -KAtomicAdd
+ endif
+
+ ifeq ($$($1_Type), Float)
+ $1_type := float
+ $1_BoxType := $$($1_Type)
+
+ $1_rawType := int
+ $1_RawType := Int
+ $1_RawBoxType := Integer
+
+ $1_ARGS += -KCAS
+ $1_ARGS += -KfloatingPoint
+ endif
+
+ ifeq ($$($1_Type), Double)
+ $1_type := double
+ $1_BoxType := $$($1_Type)
+
+ $1_rawType := long
+ $1_RawType := Long
+ $1_RawBoxType := Long
+
+ $1_ARGS += -KCAS
+ $1_ARGS += -KfloatingPoint
+ endif
+
+ $$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandleByteArrayView.java.template $(BUILD_TOOLS_JDK)
+ $$(call MakeDir, $$(@D))
+ $(TOOL_SPP) -nel -K$$($1_type) \
+ -Dtype=$$($1_type) -DType=$$($1_Type) -DBoxType=$$($1_BoxType) \
+ -DrawType=$$($1_rawType) -DRawType=$$($1_RawType) -DRawBoxType=$$($1_RawBoxType) \
+ $$($1_ARGS) < $$< > $$@
+
+ GENSRC_VARHANDLES += $$($1_FILENAME)
+endef
+
+################################################################################
+
+# List the types to generate source for, with capitalized first letter
+VARHANDLES_TYPES := Boolean Byte Short Char Int Long Float Double Object
+$(foreach t, $(VARHANDLES_TYPES), \
+ $(eval $(call GenerateVarHandle,VAR_HANDLE_$t,$t)))
+
+# List the types to generate source for, with capitalized first letter
+VARHANDLES_BYTE_ARRAY_TYPES := Short Char Int Long Float Double
+$(foreach t, $(VARHANDLES_BYTE_ARRAY_TYPES), \
+ $(eval $(call GenerateVarHandleByteArray,VAR_HANDLE_BYTE_ARRAY_$t,$t)))
+
+GENSRC_JAVA_BASE += $(GENSRC_VARHANDLES)
--- a/jdk/make/lib/Awt2dLibraries.gmk Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/make/lib/Awt2dLibraries.gmk Thu Apr 07 11:03:59 2016 -0700
@@ -204,6 +204,7 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
LIBAWT_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
$(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \
+ $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt/systemscale \
# Why does libawt need java.base headers?
LIBAWT_CFLAGS += -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
-I$(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \
@@ -311,6 +312,10 @@
$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt \
#
+ ifneq ($(filter $(OPENJDK_TARGET_OS),linux solaris aix), )
+ LIBAWT_XAWT_DIRS += $(JDK_TOPDIR)/src/java.desktop/unix/native/common/awt/systemscale
+ endif
+
LIBAWT_XAWT_EXCLUDES := medialib
LIBAWT_XAWT_CFLAGS := $(addprefix -I, $(shell $(FIND) $(LIBAWT_XAWT_DIRS) -type d)) \
@@ -883,6 +888,13 @@
LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/java.desktop/macosx/native/libsplashscreen
endif
+ ifneq ($(filter $(OPENJDK_TARGET_OS),linux solaris aix), )
+ LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/java.desktop/unix/native/common/awt/systemscale
+ endif
+
+ ifeq ($(OPENJDK_TARGET_OS), windows)
+ LIBSPLASHSCREEN_DIRS += $(JDK_TOPDIR)/src/java.desktop/windows/native/common/awt/systemscale
+ endif
LIBSPLASHSCREEN_CFLAGS += -DSPLASHSCREEN -DPNG_NO_MMX_CODE -DPNG_ARM_NEON_OPT=0 \
$(addprefix -I, $(LIBSPLASHSCREEN_DIRS)) \
$(LIBJAVA_HEADER_FLAGS) \
@@ -923,7 +935,7 @@
-framework JavaNativeFoundation
else ifeq ($(OPENJDK_TARGET_OS), windows)
LIBSPLASHSCREEN_LDFLAGS := -delayload:user32.dll
- LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib
+ LIBSPLASHSCREEN_LIBS += kernel32.lib user32.lib gdi32.lib delayimp.lib $(WIN_JAVA_LIB) jvm.lib
else
LIBSPLASHSCREEN_LIBS += $(X_LIBS) -lX11 -lXext $(LIBM) -lpthread
endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/lib/Lib-java.rmi.gmk Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2016, 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.
+#
+
+include LibCommon.gmk
+
+################################################################################
+
+$(eval $(call SetupNativeCompilation,BUILD_LIBRMI, \
+ LIBRARY := rmi, \
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ SRC := $(JDK_TOPDIR)/src/java.rmi/share/native/librmi, \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) -I$(SUPPORT_OUTPUTDIR)/headers/java.rmi, \
+ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/librmi/mapfile-vers, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS_unix := -ljvm, \
+ LIBS_windows := jvm.lib, \
+ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
+ RC_FLAGS := $(RC_FLAGS) \
+ -D "JDK_FNAME=rmi.dll" \
+ -D "JDK_INTERNAL_NAME=rmi" \
+ -D "JDK_FTYPE=0x2L", \
+ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/librmi, \
+))
+
+$(BUILD_LIBRMI): $(call FindLib, java.base, java)
+
+TARGETS += $(BUILD_LIBRMI)
+
+################################################################################
--- a/jdk/make/mapfiles/libawt_xawt/mapfile-vers Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/make/mapfiles/libawt_xawt/mapfile-vers Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2016, 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
@@ -150,6 +150,12 @@
Java_sun_awt_X11_XlibWrapper_XdbeEndIdiom;
Java_sun_awt_X11_XDesktopPeer_init;
Java_sun_awt_X11_XDesktopPeer_gnome_1url_1show;
+ Java_sun_awt_X11_XTaskbarPeer_init;
+ Java_sun_awt_X11_XTaskbarPeer_runloop;
+ Java_sun_awt_X11_XTaskbarPeer_setBadge;
+ Java_sun_awt_X11_XTaskbarPeer_setUrgent;
+ Java_sun_awt_X11_XTaskbarPeer_updateProgress;
+ Java_sun_awt_X11_XTaskbarPeer_setNativeMenu;
Java_sun_awt_X11_XRobotPeer_getRGBPixelsImpl;
Java_sun_awt_X11_XRobotPeer_keyPressImpl;
Java_sun_awt_X11_XRobotPeer_keyReleaseImpl;
--- a/jdk/make/mapfiles/libjava/mapfile-vers Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Thu Apr 07 11:03:59 2016 -0700
@@ -259,7 +259,6 @@
Java_java_io_Console_istty;
Java_java_io_Console_encoding;
Java_java_io_Console_echo;
- Java_sun_misc_GC_maxObjectInspectionAge;
Java_sun_reflect_NativeConstructorAccessorImpl_newInstance0;
Java_sun_reflect_NativeMethodAccessorImpl_invoke0;
Java_sun_reflect_Reflection_getCallerClass__;
@@ -283,8 +282,8 @@
Java_jdk_internal_loader_BootLoader_getSystemPackageNames;
Java_jdk_internal_loader_BootLoader_setBootLoaderUnnamedModule0;
- Java_sun_misc_VMSupport_initAgentProperties;
- Java_sun_misc_VMSupport_getVMTemporaryDirectory;
+ Java_jdk_internal_vm_VMSupport_initAgentProperties;
+ Java_jdk_internal_vm_VMSupport_getVMTemporaryDirectory;
# ZipFile.c needs this one
throwFileNotFoundException;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mapfiles/librmi/mapfile-vers Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2016, 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.
+#
+
+SUNWprivate_1.1 {
+ global:
+ Java_sun_rmi_transport_GC_maxObjectInspectionAge;
+ local:
+ *;
+};
--- a/jdk/make/mapfiles/libsplashscreen/mapfile-vers Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/make/mapfiles/libsplashscreen/mapfile-vers Thu Apr 07 11:03:59 2016 -0700
@@ -42,6 +42,8 @@
SplashInit;
SplashClose;
SplashSetFileJarName;
+ SplashSetScaleFactor;
+ SplashGetScaledImageName;
local:
*;
};
--- a/jdk/make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/make/src/classes/build/tools/cldrconverter/LDMLParseHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -786,10 +786,10 @@
return keyName;
}
- private String getTarget(String qName, String path, String calType, String context, String width) {
- // qName
+ private String getTarget(String path, String calType, String context, String width) {
+ // Target qName
int lastSlash = path.lastIndexOf('/');
- qName = path.substring(lastSlash+1);
+ String qName = path.substring(lastSlash+1);
int bracket = qName.indexOf('[');
if (bracket != -1) {
qName = qName.substring(0, bracket);
@@ -885,7 +885,7 @@
String[] tmp = keyName.split(",", 3);
String calType = currentCalendarType.lname();
String src = calType+"."+tmp[0];
- String target = getTarget(containerqName,
+ String target = getTarget(
entry.getKey(),
calType,
tmp[1].length()>0 ? tmp[1] : currentContext,
--- a/jdk/make/src/classes/build/tools/swingbeaninfo/DocBeanInfo.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 1998, 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 build.tools.swingbeaninfo;
-
-import java.util.HashMap;
-
-/**
- * Class that holds information for populating a FeatureDescriptor. For the class,
- * This information represents the BeanDescriptor, for a property, it represents
- * a PropertyDescriptor.
- */
-public class DocBeanInfo {
-
- // Values of the BeanFlags
- public static final int BOUND = 1;
- public static final int EXPERT = 2;
- public static final int CONSTRAINED = 4;
- public static final int HIDDEN = 8;
- public static final int PREFERRED = 16 ;
-
- public String name;
- public int beanflags;
- public String desc;
- public String displayname;
- public String propertyeditorclass;
- public String customizerclass;
-
- public HashMap attribs;
- public HashMap enums;
-
- public DocBeanInfo(){}
-
- public DocBeanInfo(String p, int flags, String d,
- String displayname, String pec, String cc,
- HashMap attribs, HashMap enums) {
- this.name = p;
- this.beanflags = flags;
- this.desc = d;
- this.displayname = displayname;
- this.propertyeditorclass = pec;
- this.customizerclass = cc;
-
- this.attribs = attribs;
- this.enums = enums;
- }
-
- public String toString() {
- StringBuffer buffer = new StringBuffer("*****");
- buffer.append("\nProperty: " + name);
- buffer.append("\tDescription: " + desc);
- buffer.append("\nDisplayname: " + displayname);
- buffer.append("\nPropertyEditorClass: " + propertyeditorclass);
- buffer.append("\nCustomizerClass: " + customizerclass);
-
- if ((beanflags & BOUND) != 0)
- buffer.append("\nBound: true");
-
- if ((beanflags & EXPERT) != 0)
- buffer.append("\nExpert: true");
-
- if ((beanflags & CONSTRAINED) != 0)
- buffer.append("\nConstrained: true");
-
- if ((beanflags & HIDDEN) !=0)
- buffer.append("\nHidden: true");
-
- if ((beanflags & PREFERRED) !=0)
-
- if (attribs != null)
- buffer.append(attribs.toString());
-
- if (enums != null)
- buffer.append(enums.toString());
-
- return buffer.toString();
- }
-
-}
--- a/jdk/make/src/classes/build/tools/swingbeaninfo/GenDocletBeanInfo.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,447 +0,0 @@
-/*
- * Copyright (c) 1998, 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 build.tools.swingbeaninfo;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.RootDoc;
-import com.sun.javadoc.Tag;
-
-import java.beans.Introspector;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.HashMap;
-import java.util.StringTokenizer;
-
-/**
- * Properties supported and tag syntax:
- *
- * @beaninfo
- * bound: flag
- * constrained: flag
- * expert: flag
- * hidden: flag
- * preferred: flag
- * description: string
- * displayname: string
- * propertyeditorclass: string (with dots: foo.bar.MyPropertyEditor
- * customizerclass: string (w/dots: foo.bar.MyCustomizer)
- * attribute: key1 value1
- * attribute: key2 value2
- *
- * TODO: getValue and genDocletInfo needs some cleaning.
- *
- * @author Hans Muller
- * @author Rich Schiavi
- * @author Mark Davidson
- */
-public class GenDocletBeanInfo {
-
- static String[] ATTRIBUTE_NAMES = { "bound",
- "constrained",
- "expert",
- "hidden",
- "preferred",
- "displayname",
- "propertyeditorclass",
- "customizerclass",
- "displayname",
- "description",
- "enum",
- "attribute" };
- private static boolean DEBUG = false;
-
- private static String fileDir = "";
- private static String templateDir = "";
-
- public static final String TRUE = "true";
- public static final String FALSE = "false";
-
- /**
- * Method called from the javadoc environment to determint the options length.
- * Doclet options:
- * -t template location
- * -d outputdir
- * -x true Enable debug output.
- */
- public static int optionLength(String option) {
- // remind: this needs to be cleaned up
- if (option.equals("-t"))
- return 2;
- if (option.equals("-d"))
- return 2;
- if (option.equals("-x"))
- return 2;
- return 0;
- }
-
- /** @beaninfo
- * bound:true
- * constrained:false
- * expert:true
- * hidden:true
- * preferred:false
- * description: the description of this method can
- * do all sorts of funky things. if it \n
- * is indented like this, we have to remove
- * all char spaces greater than 2 and also any hard-coded \n
- * newline characters and all newlines
- * displayname: theString
- * propertyeditorclass: foo.bar.MyPropertyEditorClass
- * customizerclass: foo.bar.MyCustomizerClass
- * attribute:key1 value1
- * attribute: key2 value2
- *
- */
- public static boolean start(RootDoc doc) {
- readOptions(doc.options());
-
- if (templateDir.length() == 0) {
- System.err.println("-t option not specified");
- return false;
- }
- if (fileDir.length() == 0) {
- System.err.println("-d option not specified");
- return false;
- }
-
- GenSwingBeanInfo generator = new GenSwingBeanInfo(fileDir, templateDir, DEBUG);
- Hashtable dochash = new Hashtable();
- DocBeanInfo dbi;
-
- /* "javadoc Foo.java Bar.java" will return:
- * "Foo Foo.I1 Foo.I2 Bar Bar.I1 Bar.I2"
- * i.e., with all the innerclasses of classes specified in the command
- * line. We don't want to generate BeanInfo for any of these inner
- * classes, so we ignore these by remembering what the last outer
- * class was. A hack, I admit, but makes the build faster.
- */
- String previousClass = null;
-
- ClassDoc[] classes = doc.classes();
-
- for (int cnt = 0; cnt < classes.length; cnt++) {
- String className = classes[cnt].qualifiedName();
- if (previousClass != null &&
- className.startsWith(previousClass) &&
- className.charAt(previousClass.length()) == '.') {
- continue;
- }
- previousClass = className;
-
- // XXX - debug
- System.out.println("\n>>> Generating beaninfo for " + className + "...");
-
- // Examine the javadoc tags and look for the the @beaninfo tag
- // This first block looks at the javadoc for the class
- Tag[] tags = classes[cnt].tags();
- for (int i = 0; i < tags.length; i++) {
- if (tags[i].kind().equalsIgnoreCase("@beaninfo")) {
- if (DEBUG)
- System.out.println("GenDocletBeanInfo: found @beaninfo tagged Class: " + tags[i].text());
- dbi = genDocletInfo(tags[i].text(), classes[cnt].name());
- dochash.put(dbi.name, dbi);
- break;
- }
- }
-
- // This block looks at the javadoc for the class methods.
- int startPos = -1;
- MethodDoc[] methods = classes[cnt].methods();
- for (int j = 0; j < methods.length; j++) {
- // actually don't "introspect" - look for all
- // methods with a @beaninfo tag
- tags = methods[j].tags();
- for (int x = 0; x < tags.length; x++){
- if (tags[x].kind().equalsIgnoreCase("@beaninfo")){
- if ((methods[j].name().startsWith("get")) ||
- (methods[j].name().startsWith("set")))
- startPos = 3;
- else if (methods[j].name().startsWith("is"))
- startPos = 2;
- else
- startPos = 0;
- String propDesc =
- Introspector.decapitalize((methods[j].name()).substring(startPos));
- if (DEBUG)
- System.out.println("GenDocletBeanInfo: found @beaninfo tagged Method: " + tags[x].text());
- dbi = genDocletInfo(tags[x].text(), propDesc);
- dochash.put(dbi.name, dbi);
- break;
- }
- }
- }
- if (DEBUG) {
- // dump our classes doc beaninfo
- System.out.println(">>>>DocletBeanInfo for class: " + classes[cnt].name());
- Enumeration e = dochash.elements();
- while (e.hasMoreElements()) {
- DocBeanInfo db = (DocBeanInfo)e.nextElement();
- System.out.println(db.toString());
- }
- }
-
- // Use the generator to create the beaninfo code for the class.
- generator.genBeanInfo(classes[cnt].containingPackage().name(),
- classes[cnt].name(), dochash);
- // reset the values!
- dochash.clear();
- } // end for loop
- return true;
- }
-
- /**
- * Reads the command line options.
- * Side Effect, sets class variables templateDir, fileDir and DEBUG
- */
- private static void readOptions(String[][] options) {
- // Parse the command line args
- for (int i = 0; i < options.length; i++){
- if (options[i][0].equals("-t")) {
- templateDir = options[i][1];
- } else if (options[i][0].equals("-d")) {
- fileDir = options[i][1];
- } else if (options[i][0].equals("-x")){
- if (options[i][1].equals("true"))
- DEBUG=true;
- else
- DEBUG=false;
- }
- }
- }
-
- /**
- * Create a "BeanInfo" data structure from the tag. This is a data structure
- * which contains all beaninfo data for a method or a class.
- *
- * @param text All the text after the @beaninfo tag.
- * @param name Name of the property i.e., mnemonic for setMnemonic
- */
- private static DocBeanInfo genDocletInfo(String text, String name) {
- int beanflags = 0;
- String desc = "null";
- String displayname = "null";
- String propertyeditorclass = "null";
- String customizerclass = "null";
- String value = "null";
- HashMap attribs = null;
- HashMap enums = null;
-
- int index;
-
- for (int j = 0; j < ATTRIBUTE_NAMES.length; j++){
- index = 0;
- if ((index = text.indexOf(ATTRIBUTE_NAMES[j])) != -1){
- value = getValue((text).substring(index),ATTRIBUTE_NAMES[j]);
-
- if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("attribute")) {
- attribs = getAttributeMap(value, " ");
- }
- if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("enum")) {
- enums = getAttributeMap(value, " \n");
- }
- else if (ATTRIBUTE_NAMES[j].equals("displayname")){
- displayname = value;
- }
- else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("propertyeditorclass")) {
- propertyeditorclass = value;
- }
- else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("customizerclass")){
- customizerclass = value;
- }
- else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("bound"))
- && (value.equalsIgnoreCase(TRUE)))
- beanflags = beanflags | DocBeanInfo.BOUND;
- else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("expert"))
- && (value.equalsIgnoreCase(TRUE)))
- beanflags = beanflags | DocBeanInfo.EXPERT;
- else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("constrained"))
- && (value.equalsIgnoreCase(TRUE)))
- beanflags = beanflags | DocBeanInfo.CONSTRAINED;
- else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("hidden"))
- && (value.equalsIgnoreCase(TRUE)))
- beanflags = beanflags | DocBeanInfo.HIDDEN;
- else if ((ATTRIBUTE_NAMES[j].equalsIgnoreCase("preferred"))
- && (value.equalsIgnoreCase(TRUE)))
- beanflags = beanflags | DocBeanInfo.PREFERRED;
- else if (ATTRIBUTE_NAMES[j].equalsIgnoreCase("description")){
- desc = value;
- }
- }
- }
- /** here we create our doclet-beaninfo data structure, which we read in
- * later if it has anything worthwhile
- */
-
- // Construct a new Descriptor class
- return new DocBeanInfo(name, beanflags, desc,displayname,
- propertyeditorclass, customizerclass,
- attribs, enums);
- }
-
- /**
- * Parses the substring and returns the cleaned up value for the attribute.
- * @param substring Full String of the attrib tag.
- * i.e., "attribute: visualUpdate true" will return "visualUpdate true";
- */
- private static String getValue(String substring, String prop) {
- StringTokenizer t;
- String value = "null";
-
- try {
- /** if the ATTRIBUTE_NAMES is NOT the description, then we
- * parse until newline
- * if it is the description we read until the next token
- * and then look for a match in the last MAXMATCH index
- * and truncate the description
- * if it is the attribute we wead until no more
- */
- if (prop.equalsIgnoreCase("attribute")){
- StringBuffer tmp = new StringBuffer();
- try {
- t = new StringTokenizer(substring, " :\n");
- t.nextToken().trim();//the prop
- // we want to return : key1 value1 key2 value2
- while (t.hasMoreTokens()){
- tmp.append(t.nextToken().trim()).append(" ");
- tmp.append(t.nextToken().trim()).append(" ");
- String test = t.nextToken().trim();
- if (!(test.equalsIgnoreCase("attribute")))
- break;
- }
- } catch (Exception e){
- }
- value = tmp.toString();
- }
- else if (prop.equalsIgnoreCase("enum")){
- t = new StringTokenizer(substring, ":");
- t.nextToken().trim(); // the prop we already know
- StringBuffer tmp = new StringBuffer(t.nextToken().trim());
- for (int i = 0; i < ATTRIBUTE_NAMES.length; i++){
- if (tmp.toString().endsWith(ATTRIBUTE_NAMES[i])){
- int len = ATTRIBUTE_NAMES[i].length();
- // trim off that
- tmp.setLength(tmp.length() - len);
- break;
- }
- }
- value = tmp.toString();
- }
- else if (prop.equalsIgnoreCase("description")){
- t = new StringTokenizer(substring, ":");
- t.nextToken().trim(); // the prop we already know
- StringBuffer tmp = new StringBuffer(t.nextToken().trim());
- for (int i = 0; i < ATTRIBUTE_NAMES.length; i++){
- if (tmp.toString().endsWith(ATTRIBUTE_NAMES[i])){
- int len = ATTRIBUTE_NAMES[i].length();
- // trim off that
- tmp.setLength(tmp.length() - len);
- break;
- }
- }
- value = hansalizeIt(tmp.toString());
- }
- else {
- // Single value properties like bound: true
- t = new StringTokenizer(substring, ":\n");
- t.nextToken().trim(); // the prop we already know
- value = t.nextToken().trim();
- }
-
- // now we need to look for a match of any of the
- // property
-
- return value;
- }
- catch (Exception e){
- return "invalidValue";
- }
- }
-
- /**
- * Creates a HashMap containing the key value pair for the parsed values
- * of the "attributes" and "enum" tags.
- * ie. For attribute value: visualUpdate true
- * The HashMap will have key: visualUpdate, value: true
- */
- private static HashMap getAttributeMap(String str, String delim) {
- StringTokenizer t = new StringTokenizer(str, delim);
- HashMap map = null;
- String key;
- String value;
-
- int num = t.countTokens()/2;
- if (num > 0) {
- map = new HashMap();
- for (int i = 0; i < num; i++) {
- key = t.nextToken().trim();
- value = t.nextToken().trim();
- map.put(key, value);
- }
- }
- return map;
- }
-
- // looks for extra spaces, \n hard-coded and invisible,etc
- private static String hansalizeIt(String from){
- char [] chars = from.toCharArray();
- int len = chars.length;
- int toss = 0;
-
- // remove double spaces
- for (int i = 0; i < len; i++){
- if ((chars[i] == ' ')) {
- if (i+1 < len) {
- if ((chars[i+1] == ' ' ) || (chars[i+1] == '\n'))
- {
- --len;
- System.arraycopy(chars,i+1,chars,i,len-i);
- --i;
- }
- }
- }
-
- if (chars[i] == '\n'){
- chars[i] = ' ';
- i -= 2;
- }
-
- if (chars[i] == '\\') {
- if (i+1 < len) {
- if (chars[i+1] == 'n'){
- chars[i+1] = ' ';
- --len;
- System.arraycopy(chars,i+1, chars,i, len-i);
- --i;
- }
- }
- }
- }
- return new String(chars,0,len);
- }
-
-}
--- a/jdk/make/src/classes/build/tools/swingbeaninfo/GenSwingBeanInfo.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,532 +0,0 @@
-/*
- * Copyright (c) 1998, 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 build.tools.swingbeaninfo;
-
-import java.beans.BeanInfo;
-import java.beans.BeanDescriptor;
-import java.beans.Introspector;
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-
-import java.io.*;
-
-import java.util.Hashtable;
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * A utlity for generating a BeanInfo source file from a template and a
- * Hashtable with hints that were generated from a doclet.
- * it's neccessary to write things like the per property descriptions
- * by hand. To run the application:
- * <pre>
- * java GenSwingBeanInfo <class name>
- * </pre>
- * Code for a bean info class is written to out. If the class is
- * swing package, you don't need to fully specify its name.
- *
- * @author Hans Muller
- * @author Rich Schiavi
- * @author Mark Davidson
- */
-public class GenSwingBeanInfo {
- private final static String BEANINFO_SUFFIX = "BeanInfo.java";
-
- // Tokens in @(...)
- private final static String TOK_BEANPACKAGE = "BeanPackageName";
- private final static String TOK_BEANCLASS = "BeanClassName";
- private final static String TOK_BEANOBJECT = "BeanClassObject";
- private final static String TOK_CLASSDESC = "ClassDescriptors";
- private final static String TOK_BEANDESC = "BeanDescription";
- private final static String TOK_PROPDESC = "BeanPropertyDescriptors";
- private final static String TOK_ENUMVARS = "EnumVariables";
-
- private String enumcode; // Generated code for enumerated properties.
-
- private boolean DEBUG = false;
-
- private String fileDir;
- private String templateFilename;
-
- /**
- * Public constructor
- * @param fileDir Location to put the generated source files.
- * @param templateFilename Location of the BeanInfo template
- * @param debug Flag to turn on debugging
- */
- public GenSwingBeanInfo(String fileDir, String templateFilename, boolean debug) {
- this.fileDir = fileDir;
- this.templateFilename = templateFilename;
- this.DEBUG = debug;
- }
-
- /**
- * Opens a BeanInfo PrintStream for the class.
- */
- private PrintStream initOutputFile(String classname) {
- try {
- OutputStream out = new FileOutputStream(fileDir + File.separator + classname + BEANINFO_SUFFIX);
- BufferedOutputStream bout = new BufferedOutputStream(out);
- return new PrintStream(out);
- } catch (IOException e){
- // System.err.println("GenSwingBeanInfo: " + e.toString());
- }
- return null;
- }
-
- private static void messageAndExit(String msg) {
- System.err.println("\n" + msg);
- System.exit(1);
- }
-
-
- /**
- * Load the contents of the BeanInfo template into a string and
- * return the string.
- */
- private String loadTemplate() {
- String template = "<no template>";
-
- try {
- File file = new File(templateFilename);
- DataInputStream stream = new DataInputStream(new FileInputStream(file));
- BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
- StringBuffer buffer = new StringBuffer();
-
- int c;
- while((c = reader.read()) != -1) {
- buffer.append((char)c);
- }
-
- template = buffer.toString();
- reader.close();
- } catch (IOException e) {
- System.out.println(e.getMessage());
- messageAndExit("GenSwingBeanInfo: Couldn't load template: " + templateFilename + e);
- }
- return template;
- }
-
-
- /**
- * Generates a string for the BeanDescriptor
- */
- private String genBeanDescriptor(DocBeanInfo dbi) {
- String code = "";
- int beanflags = dbi.beanflags;
-
- // we support export, hidden, preferred
- if ((beanflags & DocBeanInfo.EXPERT) != 0)
- code += " sun.swing.BeanInfoUtils.EXPERT, Boolean.TRUE,\n";
- if ((beanflags & DocBeanInfo.HIDDEN) !=0)
- code += " sun.swing.BeanInfoUtils.HIDDEN, Boolean.TRUE,\n";
- /* 1.2 only - make sure build flag build using 1.2 */
- if ((beanflags & DocBeanInfo.PREFERRED) !=0)
- code += " sun.swing.BeanInfoUtils.PREFERRED, Boolean.TRUE,\n";
- if (!(dbi.customizerclass.equals("null")))
- code += " sun.swing.BeanInfoUtils.CUSTOMIZERCLASS, " + dbi.customizerclass + ".class,\n";
-
- if (dbi.attribs != null) {
- code += genAttributes(dbi.attribs);
- }
-
- return code;
- }
-
- /**
- * Generates the code for the attributes table.
- */
- private String genAttributes(HashMap attribs) {
- StringBuffer code = new StringBuffer();
- String key;
- String value;
-
- Iterator iterator = attribs.keySet().iterator();
- while(iterator.hasNext()) {
- key = (String)iterator.next();
- value = (String)attribs.get(key);
-
- if (value.equals("true") || value.equals("false")) {
- // Substitute the "true" and "false" for codegen Boolean values.
- if(value.equals("true"))
- value = "Boolean.TRUE";
- else
- value = "Boolean.FALSE";
-
- code.append(" \"").append(key).append("\", ").append(value).append(",\n");
- } else {
- code.append(" \"").append(key).append("\", \"").append(value).append("\",\n");
- }
- }
- return code.toString();
- }
-
- /**
- * Generates the code for the enumeration.
- * XXX - side effect: Modifies the enumcode field variable.
- */
- private String genEnumeration(String propName, HashMap enums) {
- String objectName = propName + "Enumeration";
- String key;
- String value;
-
- StringBuffer code = new StringBuffer("\n\t\tObject[] ");
- code.append(objectName).append(" = new Object[] { \n");
-
- Iterator iterator = enums.keySet().iterator();
- while(iterator.hasNext()) {
- key = (String)iterator.next();
- value = (String)enums.get(key);
-
- code.append("\t\t\t\"").append(key).append("\" , new Integer(");
- code.append(value).append("), \"").append(value).append("\",\n");
- }
- // Close the statically initialized Object[]
- code.replace(code.length() - 2, code.length(), "\n\t\t};\n");
-
- // Add this string to the enumeration code.
- enumcode += code.toString();
-
- // Return the PropertyDescriptor init string;
- return " \"enumerationValues\", " + objectName + ",\n";
- }
-
- /**
- * Generate the createPropertyDescriptor() calls, one per property.
- * A fully specified createPropertyDescriptor() call looks like this:
- * <pre>
- * createPropertyDescriptor("contentPane", new Object[] {
- * BOUND, Boolean.TRUE,
- * CONSTRAINED, Boolean.TRUE,
- * PROPERTYEDITORCLASS, package.MyEditor.cl
- * WRITEMETHOD, "setContentPane",
- * DISPLAYNAME, "contentPane",
- * EXPERT, Boolean.FALSE,
- * HIDDEN, Boolean.FALSE,
- * PREFERRED, Boolean.TRUE,
- * SHORTDESCRIPTION, "A top level window with a window manager border",
- * "random attribute","random value"
- * }
- * );
- * </pre>
- *
- * @param info The actual BeanInfo class generated from from the Intospector.
- * @param dochash Set of DocBeanInfo pairs for each property. This information
- * is used to suplement the instrospected properties.
- * @return A snippet of source code which would construct all the PropertyDescriptors.
- */
- private String genPropertyDescriptors(BeanInfo info, Hashtable dochash) {
- String code = "";
- enumcode = " "; // code for enumerated properties.
- PropertyDescriptor[] pds = info.getPropertyDescriptors();
- boolean hash_match = false;
- DocBeanInfo dbi = null;
-
- for(int i = 0; i < pds.length; i++) {
- if (pds[i].getReadMethod() != null) {
- code += "\ncreatePropertyDescriptor(\"" + pds[i].getName() + "\", new Object[] {\n";
-
- if (DEBUG)
- System.out.println("Introspected propertyDescriptor: " + pds[i].getName());
-
- if (dochash.size() > 0 && dochash.containsKey(pds[i].getName())) {
- dbi = (DocBeanInfo)dochash.remove(pds[i].getName());
- // override/set properties on this *introspected*
- // BeanInfo pds using our DocBeanInfo class values
- setDocInfoProps(dbi, pds[i]);
- hash_match = true;
- if (DEBUG)
- System.out.println("DocBeanInfo class exists for propertyDescriptor: " + pds[i].getName() + "\n");
- } else {
- hash_match = false;
- }
-
- // Do I need to do anything with this property descriptor
- if (hash_match) {
- if ((dbi.beanflags & DocBeanInfo.BOUND) != 0) {
- code += " sun.swing.BeanInfoUtils.BOUND, Boolean.TRUE,\n";
- } else {
- code += " sun.swing.BeanInfoUtils.BOUND, Boolean.FALSE,\n";
- }
- }
-
- if (pds[i].isConstrained()) {
- code += " sun.swing.BeanInfoUtils.CONSTRAINED, Boolean.TRUE,\n";
- }
-
- if (pds[i].getPropertyEditorClass() != null) {
- String className = pds[i].getPropertyEditorClass().getName();
- code += " sun.swing.BeanInfoUtils.PROPERTYEDITORCLASS, " + className + ".class,\n";
- } else if ((hash_match) && (!(dbi.propertyeditorclass.equals("null")))) {
- code += " sun.swing.BeanInfoUtils.PROPERTYEDITORCLASS, " + dbi.propertyeditorclass + ".class,\n";
- }
-
- if ((hash_match) && (!(dbi.customizerclass.equals("null")))) {
- code += " sun.swing.BeanInfoUtils.CUSTOMIZERCLASS, " + dbi.customizerclass + ".class,\n";
- }
-
- if ((hash_match) && (dbi.enums != null)) {
- code += genEnumeration(pds[i].getName(), dbi.enums);
- }
-
- if (!pds[i].getDisplayName().equals(pds[i].getName())) {
- code += " sun.swing.BeanInfoUtils.DISPLAYNAME, \"" + pds[i].getDisplayName() + "\",\n";
- }
-
- if (pds[i].isExpert()) {
- code += " sun.swing.BeanInfoUtils.EXPERT, Boolean.TRUE,\n";
- }
-
- if (pds[i].isHidden()) {
- code += " sun.swing.BeanInfoUtils.HIDDEN, Boolean.TRUE,\n";
- }
-
- if (pds[i].isPreferred()) {
- code += " sun.swing.BeanInfoUtils.PREFERRED, Boolean.TRUE,\n";
- }
-
- // user attributes
- if (hash_match) {
- if (dbi.attribs != null) {
- code += genAttributes(dbi.attribs);
- }
- }
- code += " sun.swing.BeanInfoUtils.SHORTDESCRIPTION, \"" + pds[i].getShortDescription() + "\",\n";
-
- // Print the closing brackets. If this is the last array initializer,
- // don't print the trailing comma.
- if (i == (pds.length - 1)) {
- code += " }\n)\n";
- } else {
- code += " }\n),\n";
- }
-
- } // end if ( readMethod != null )
- } // end for
- return code;
- }
-
- /**
- * Sets properties from the BeanInfo supplement on the
- * introspected PropertyDescriptor
- */
- private void setDocInfoProps(DocBeanInfo dbi, PropertyDescriptor pds) {
- int beanflags = dbi.beanflags;
-
- if ((beanflags & DocBeanInfo.BOUND) != 0)
- pds.setBound(true);
- if ((beanflags & DocBeanInfo.EXPERT) != 0)
- pds.setExpert(true);
- if ((beanflags & DocBeanInfo.CONSTRAINED) != 0)
- pds.setConstrained(true);
- if ((beanflags & DocBeanInfo.HIDDEN) !=0)
- pds.setHidden(true);
- if ((beanflags & DocBeanInfo.PREFERRED) !=0)
- pds.setPreferred(true);
-
- if (!(dbi.desc.equals("null"))){
- pds.setShortDescription(dbi.desc);
- }
- if (!(dbi.displayname.equals("null"))){
- pds.setDisplayName(dbi.displayname);
- }
- }
-
- /**
- * Generates the BeanInfo source file using instrospection and a
- * Hashtable full of hints. This the only public method in this class.
- *
- * @param classname Root name of the class. i.e., JButton
- * @param dochash A hashtable containing the DocBeanInfo.
- */
- public void genBeanInfo(String packageName, String classname, Hashtable dochash) {
- // The following initial values are just examples. All of these
- // fields are initialized below.
- String beanClassName = "JInternalFrame";
- String beanClassObject = "javax.swing.JInternalFrame.class";
- String beanDescription = "<A description of this component>.";
- String beanPropertyDescriptors = "<createSwingPropertyDescriptor code>";
- String classPropertyDescriptors = "<createSwingClassPropertyDescriptor code>";
-
- Class cls = getClass(packageName, classname);
- if (cls == null){
- messageAndExit("Can't find class: " + classname);
- }
-
- // Get the output stream.
- PrintStream out = initOutputFile(classname);
-
- // Run the Introspector and initialize the variables
-
- BeanInfo beanInfo = null;
- BeanDescriptor beanDescriptor = null;
-
- try {
- if (cls == javax.swing.JComponent.class) {
- // Go all the way up the heirarchy for JComponent
- beanInfo = Introspector.getBeanInfo(cls);
- } else {
- beanInfo = Introspector.getBeanInfo(cls, cls.getSuperclass());
- }
- beanDescriptor = beanInfo.getBeanDescriptor();
- beanDescription = beanDescriptor.getShortDescription();
- } catch (IntrospectionException e) {
- messageAndExit("Introspection failed for " + cls.getName() + " " + e);
- }
-
- beanClassName = beanDescriptor.getName();
- beanClassObject = cls.getName() + ".class";
-
- if (DEBUG){
- System.out.println(">>>>GenSwingBeanInfo class: " + beanClassName);
- }
- // Generate the Class BeanDescriptor information first
- if (dochash.size() > 0) {
- if (dochash.containsKey(beanClassName)) {
- DocBeanInfo dbi = (DocBeanInfo)dochash.remove(beanClassName);
- classPropertyDescriptors = genBeanDescriptor(dbi);
- if (DEBUG)
- System.out.println("ClassPropertyDescriptors: " + classPropertyDescriptors);
- if (!(dbi.desc.equals("null")))
- beanDescription = dbi.desc;
- } else
- beanDescription = beanDescriptor.getShortDescription();
- } else
- beanDescription = beanDescriptor.getShortDescription();
-
- // Generate the Property descriptors
- beanPropertyDescriptors = genPropertyDescriptors(beanInfo,dochash);
-
- // Dump the template to out, substituting values for
- // @(token) tokens as they're encountered.
-
- int currentIndex = 0;
- // not loading this to get around build issue for now
- String template = loadTemplate();
-
- // This loop substitutes the "@(...)" tags in the template with the ones for the
- // current class.
- while (currentIndex < template.length()) {
- // Find the Token
- int tokenStart = template.indexOf("@(", currentIndex);
- if (tokenStart != -1) {
- out.print(template.substring(currentIndex, tokenStart));
-
- int tokenEnd = template.indexOf(")", tokenStart);
- if (tokenEnd == -1) {
- messageAndExit("Bad @(<token>) beginning at " + tokenStart);
- }
- String token = template.substring(tokenStart+2, tokenEnd);
-
- if (token.equals(TOK_BEANCLASS)) {
- out.print(beanClassName);
- } else if (token.equals(TOK_CLASSDESC)) {
- if (!(classPropertyDescriptors.equals("<createSwingClassPropertyDescriptor code>"))) {
- printDescriptors(out, classPropertyDescriptors, template, tokenStart);
- }
- } else if (token.equals(TOK_BEANPACKAGE)){
- out.print(packageName);
- } else if (token.equals(TOK_BEANOBJECT)) {
- out.print(beanClassObject);
- } else if (token.equals(TOK_BEANDESC)) {
- out.print(beanDescription);
- } else if (token.equals(TOK_ENUMVARS)){
- out.print(enumcode);
- } else if (token.equals(TOK_PROPDESC)) {
- printDescriptors(out, beanPropertyDescriptors, template, tokenStart);
- } else if (token.equals("#")) {
- // Ignore the @(#) Version Control tag if it exists.
- } else {
- messageAndExit("Unrecognized token @(" + token + ")");
- }
- currentIndex = tokenEnd + 1;
- } else {
- // tokenStart == -1 - We are finsihed.
- out.print(template.substring(currentIndex, template.length()));
- break;
- }
- }
- out.close();
- }
-
- /**
- * Returns the class from the package name and the class root name.
- *
- * @param packageName The name of the package of the containing class.
- * @param rootname The root name of the class. i.e, JButton
- * @return The class instance or null.
- */
- private Class getClass(String packageName, String rootname) {
- Class cls = null;
- String classname = rootname;
-
- if (packageName != null || !packageName.equals("")) {
- classname = packageName + "." + rootname;
- }
-
- try {
- cls = Class.forName(classname);
- } catch (ClassNotFoundException e) {
- // Fail silently.
- }
- return cls;
- }
-
- /**
- * Prints the formated descriptors to the PrintStream
- * @param out Open PrintStream
- * @param s String descriptor
- * @param template Template
- * @param tokenStart Index into the template
- */
- private void printDescriptors(PrintStream out, String s,
- String template, int tokenStart) {
- String indent = "";
-
- // Find the newline that preceeds @(BeanPropertyDescriptors) to
- // calculate the indent.
- for (int i = tokenStart; i >= 0; i--) {
- if (template.charAt(i) == '\n') {
- char[] chars = new char[tokenStart - i];
- for (int j = 0; j < chars.length; j++) {
- chars[j] = ' ';
- }
- indent = new String(chars);
- break;
- }
- }
-
- int i = 0;
- while(i < s.length()) {
- int nlIndex = s.indexOf('\n', i);
- out.print(s.substring(i, nlIndex+1));
- out.print(indent);
- i = nlIndex + 1;
- }
- }
-
-
-}
--- a/jdk/src/java.base/share/classes/java/lang/StringCoding.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/StringCoding.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -146,7 +146,7 @@
}
@HotSpotIntrinsicCandidate
- private static boolean hasNegatives(byte[] ba, int off, int len) {
+ public static boolean hasNegatives(byte[] ba, int off, int len) {
for (int i = off; i < off + len; i++) {
if (ba[i] < 0) {
return true;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InfoFromMemberName.java Thu Apr 07 11:03:59 2016 -0700
@@ -41,7 +41,7 @@
private final int referenceKind;
InfoFromMemberName(Lookup lookup, MemberName member, byte referenceKind) {
- assert(member.isResolved() || member.isMethodHandleInvoke());
+ assert(member.isResolved() || member.isMethodHandleInvoke() || member.isVarHandleMethodInvoke());
assert(member.referenceKindIsConsistentWith(referenceKind));
this.member = member;
this.referenceKind = referenceKind;
@@ -79,7 +79,8 @@
@Override
public <T extends Member> T reflectAs(Class<T> expected, Lookup lookup) {
- if (member.isMethodHandleInvoke() && !member.isVarargs()) {
+ if ((member.isMethodHandleInvoke() || member.isVarHandleMethodInvoke())
+ && !member.isVarargs()) {
// This member is an instance of a signature-polymorphic method, which cannot be reflected
// A method handle invoker can come in either of two forms:
// A generic placeholder (present in the source code, and varargs)
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Thu Apr 07 11:03:59 2016 -0700
@@ -93,6 +93,16 @@
return setCachedInvoker(INV_BASIC, invoker);
}
+ /*non-public*/ MethodHandle varHandleMethodInvoker(VarHandle.AccessMode ak) {
+ // TODO cache invoker
+ return makeVarHandleMethodInvoker(ak);
+ }
+
+ /*non-public*/ MethodHandle varHandleMethodExactInvoker(VarHandle.AccessMode ak) {
+ // TODO cache invoker
+ return makeVarHandleMethodExactInvoker(ak);
+ }
+
private MethodHandle cachedInvoker(int idx) {
return invokers[idx];
}
@@ -117,6 +127,36 @@
return invoker;
}
+ private MethodHandle makeVarHandleMethodInvoker(VarHandle.AccessMode ak) {
+ MethodType mtype = targetType;
+ MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
+
+ LambdaForm lform = varHandleMethodGenericInvokerHandleForm(ak.name(), mtype);
+ VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
+ MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
+
+ invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.name(), mtype), false);
+ assert(checkVarHandleInvoker(invoker));
+
+ maybeCompileToBytecode(invoker);
+ return invoker;
+ }
+
+ private MethodHandle makeVarHandleMethodExactInvoker(VarHandle.AccessMode ak) {
+ MethodType mtype = targetType;
+ MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class);
+
+ LambdaForm lform = varHandleMethodExactInvokerHandleForm(ak.name(), mtype);
+ VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
+ MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad);
+
+ invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.name(), mtype), false);
+ assert(checkVarHandleInvoker(invoker));
+
+ maybeCompileToBytecode(invoker);
+ return invoker;
+ }
+
/** 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;
@@ -146,6 +186,16 @@
return true;
}
+ private boolean checkVarHandleInvoker(MethodHandle invoker) {
+ MethodType invokerType = targetType.insertParameterTypes(0, VarHandle.class);
+ assert(invokerType.equals(invoker.type()))
+ : java.util.Arrays.asList(targetType, invokerType, invoker);
+ assert(invoker.internalMemberName() == null ||
+ invoker.internalMemberName().getMethodType().equals(targetType));
+ assert(!invoker.isVarargsCollector());
+ return true;
+ }
+
/**
* Find or create an invoker which passes unchanged a given number of arguments
* and spreads the rest from a trailing array argument.
@@ -193,9 +243,9 @@
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);
+ 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;
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
@@ -296,6 +346,199 @@
return lform;
}
+
+ static MemberName varHandleInvokeLinkerMethod(String name,
+ MethodType mtype) {
+ LambdaForm lform;
+ if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
+ lform = varHandleMethodGenericLinkerHandleForm(name, mtype);
+ } else {
+ // TODO
+ throw newInternalError("Unsupported parameter slot count " + mtype.parameterSlotCount());
+ }
+ return lform.vmentry;
+ }
+
+ private static LambdaForm varHandleMethodGenericLinkerHandleForm(String name, MethodType mtype) {
+ // TODO Cache form?
+
+ final int THIS_VH = 0;
+ final int ARG_BASE = THIS_VH + 1;
+ final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
+ int nameCursor = ARG_LIMIT;
+ final int VAD_ARG = nameCursor++;
+ final int CHECK_TYPE = nameCursor++;
+ final int CHECK_CUSTOM = (CUSTOMIZE_THRESHOLD >= 0) ? nameCursor++ : -1;
+ final int LINKER_CALL = nameCursor++;
+
+ Name[] names = new Name[LINKER_CALL + 1];
+ names[THIS_VH] = argument(THIS_VH, BasicType.basicType(Object.class));
+ for (int i = 0; i < mtype.parameterCount(); i++) {
+ names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
+ }
+ names[VAD_ARG] = new Name(ARG_LIMIT, BasicType.basicType(Object.class));
+
+ names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[THIS_VH], names[VAD_ARG]);
+
+ Object[] outArgs = new Object[ARG_LIMIT + 1];
+ outArgs[0] = names[CHECK_TYPE];
+ for (int i = 0; i < ARG_LIMIT; i++) {
+ outArgs[i + 1] = names[i];
+ }
+
+ if (CHECK_CUSTOM != -1) {
+ names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
+ }
+
+ MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
+ .basicType();
+ names[LINKER_CALL] = new Name(outCallType, outArgs);
+ LambdaForm lform = new LambdaForm(name + ":VarHandle_invoke_MT_" + shortenSignature(basicTypeSignature(mtype)),
+ ARG_LIMIT + 1, names);
+
+ lform.prepare();
+ return lform;
+ }
+
+ private static LambdaForm varHandleMethodExactInvokerHandleForm(String name, MethodType mtype) {
+ // TODO Cache form?
+
+ final int THIS_MH = 0;
+ final int CALL_VH = THIS_MH + 1;
+ final int ARG_BASE = CALL_VH + 1;
+ final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
+ int nameCursor = ARG_LIMIT;
+ final int VAD_ARG = nameCursor++;
+ final int CHECK_TYPE = nameCursor++;
+ final int GET_MEMBER = nameCursor++;
+ final int LINKER_CALL = nameCursor++;
+
+ MethodType invokerFormType = mtype.insertParameterTypes(0, VarHandle.class)
+ .basicType()
+ .appendParameterTypes(MemberName.class);
+
+ MemberName linker = new MemberName(MethodHandle.class, "linkToStatic", invokerFormType, REF_invokeStatic);
+ try {
+ linker = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
+ } catch (ReflectiveOperationException ex) {
+ throw newInternalError(ex);
+ }
+
+ Name[] names = new Name[LINKER_CALL + 1];
+ names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class));
+ names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class));
+ for (int i = 0; i < mtype.parameterCount(); i++) {
+ names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
+ }
+
+ BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L();
+ names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
+
+ NamedFunction getter = speciesData.getterFunction(0);
+ names[VAD_ARG] = new Name(getter, names[THIS_MH]);
+
+ Object[] outArgs = Arrays.copyOfRange(names, CALL_VH, ARG_LIMIT + 1, Object[].class);
+
+ names[CHECK_TYPE] = new Name(NF_checkVarHandleExactType, names[CALL_VH], names[VAD_ARG]);
+
+ names[GET_MEMBER] = new Name(NF_getVarHandleMemberName, names[CALL_VH], names[VAD_ARG]);
+ outArgs[outArgs.length - 1] = names[GET_MEMBER];
+
+ names[LINKER_CALL] = new Name(linker, outArgs);
+ LambdaForm lform = new LambdaForm(name + ":VarHandle_exactInvoker" + shortenSignature(basicTypeSignature(mtype)),
+ ARG_LIMIT, names);
+
+ lform.prepare();
+ return lform;
+ }
+
+ private static LambdaForm varHandleMethodGenericInvokerHandleForm(String name, MethodType mtype) {
+ // TODO Cache form?
+
+ final int THIS_MH = 0;
+ final int CALL_VH = THIS_MH + 1;
+ final int ARG_BASE = CALL_VH + 1;
+ final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
+ int nameCursor = ARG_LIMIT;
+ final int VAD_ARG = nameCursor++;
+ final int CHECK_TYPE = nameCursor++;
+ final int LINKER_CALL = nameCursor++;
+
+ Name[] names = new Name[LINKER_CALL + 1];
+ names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class));
+ names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class));
+ for (int i = 0; i < mtype.parameterCount(); i++) {
+ names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i)));
+ }
+
+ BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L();
+ names[THIS_MH] = names[THIS_MH].withConstraint(speciesData);
+
+ NamedFunction getter = speciesData.getterFunction(0);
+ names[VAD_ARG] = new Name(getter, names[THIS_MH]);
+
+ names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[CALL_VH], names[VAD_ARG]);
+
+ Object[] outArgs = new Object[ARG_LIMIT];
+ outArgs[0] = names[CHECK_TYPE];
+ for (int i = 1; i < ARG_LIMIT; i++) {
+ outArgs[i] = names[i];
+ }
+
+ MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class)
+ .basicType();
+ names[LINKER_CALL] = new Name(outCallType, outArgs);
+ LambdaForm lform = new LambdaForm(name + ":VarHandle_invoker" + shortenSignature(basicTypeSignature(mtype)),
+ ARG_LIMIT, names);
+
+ lform.prepare();
+ return lform;
+ }
+
+ /*non-public*/ static
+ @ForceInline
+ MethodHandle checkVarHandleGenericType(VarHandle vh, VarHandle.AccessDescriptor vad) {
+ MethodType expected = vad.symbolicMethodType;
+ MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh);
+
+ MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform);
+ if (mn == null)
+ throw vh.unsupported();
+ // TODO the following MH is not constant, cache in stable field array
+ // on VarForm?
+ MethodHandle mh = DirectMethodHandle.make(mn);
+ if (actual == expected) {
+ return mh;
+ }
+ else {
+ // Adapt to the actual (which should never fail since mh's method
+ // type is in the basic form), then to the expected (which my fail
+ // if the symbolic type descriptor does not match)
+ // TODO optimize for the case of actual.erased() == expected.erased()
+ return mh.asType(actual.insertParameterTypes(0, VarHandle.class)).
+ asType(expected.insertParameterTypes(0, VarHandle.class));
+ }
+ }
+
+ /*non-public*/ static
+ @ForceInline
+ void checkVarHandleExactType(VarHandle vh, VarHandle.AccessDescriptor vad) {
+ MethodType expected = vad.symbolicMethodType;
+ MethodType actual = VarHandle.AccessType.getMethodType(vad.type, vh);
+ if (actual != expected)
+ throw newWrongMethodTypeException(expected, actual);
+ }
+
+ /*non-public*/ static
+ @ForceInline
+ MemberName getVarHandleMemberName(VarHandle vh, VarHandle.AccessDescriptor vad) {
+ MemberName mn = VarHandle.AccessMode.getMemberName(vad.mode, vh.vform);
+ if (mn == null) {
+ throw vh.unsupported();
+ }
+ return mn;
+ }
+
/*non-public*/ static
WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) {
// FIXME: merge with JVM logic for throwing WMTE
@@ -415,7 +658,10 @@
NF_checkExactType,
NF_checkGenericType,
NF_getCallSiteTarget,
- NF_checkCustomized;
+ NF_checkCustomized,
+ NF_checkVarHandleGenericType,
+ NF_checkVarHandleExactType,
+ NF_getVarHandleMemberName;
static {
try {
NamedFunction nfs[] = {
@@ -426,7 +672,13 @@
NF_getCallSiteTarget = new NamedFunction(Invokers.class
.getDeclaredMethod("getCallSiteTarget", CallSite.class)),
NF_checkCustomized = new NamedFunction(Invokers.class
- .getDeclaredMethod("checkCustomized", MethodHandle.class))
+ .getDeclaredMethod("checkCustomized", MethodHandle.class)),
+ NF_checkVarHandleGenericType = new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class)),
+ NF_checkVarHandleExactType = new NamedFunction(Invokers.class
+ .getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class)),
+ NF_getVarHandleMemberName = new NamedFunction(Invokers.class
+ .getDeclaredMethod("getVarHandleMemberName", VarHandle.class, VarHandle.AccessDescriptor.class))
};
// Each nf must be statically invocable or we get tied up in our bootstraps.
assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs));
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Thu Apr 07 11:03:59 2016 -0700
@@ -363,6 +363,23 @@
return false;
}
}
+ public boolean isVarHandleMethodInvoke() {
+ final int bits = MH_INVOKE_MODS &~ Modifier.PUBLIC;
+ final int negs = Modifier.STATIC;
+ if (testFlags(bits | negs, bits) &&
+ clazz == VarHandle.class) {
+ return isVarHandleMethodInvokeName(name);
+ }
+ return false;
+ }
+ public static boolean isVarHandleMethodInvokeName(String name) {
+ try {
+ VarHandle.AccessMode.valueOf(name);
+ return true;
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ }
private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC;
/** Utility method to query the modifier flags of this member. */
@@ -538,6 +555,17 @@
if (isMethodHandleInvoke())
return;
}
+ if (m.getDeclaringClass() == VarHandle.class &&
+ isVarHandleMethodInvokeName(m.getName())) {
+ // The JVM did not reify this signature-polymorphic instance.
+ // Need a special case here.
+ // See comments on MethodHandleNatives.linkMethod.
+ MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes());
+ int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual);
+ init(VarHandle.class, m.getName(), type, flags);
+ if (isVarHandleMethodInvoke())
+ return;
+ }
throw new LinkageError(m.toString());
}
assert(isResolved() && this.clazz != null);
@@ -666,6 +694,16 @@
return mem;
}
+ static MemberName makeVarHandleMethodInvoke(String name, MethodType type) {
+ return makeVarHandleMethodInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC);
+ }
+ static MemberName makeVarHandleMethodInvoke(String name, MethodType type, int mods) {
+ MemberName mem = new MemberName(VarHandle.class, name, type, REF_invokeVirtual);
+ mem.flags |= mods; // it's not resolved, but add these modifiers anyway
+ assert(mem.isVarHandleMethodInvoke()) : mem;
+ return mem;
+ }
+
// bare-bones constructor; the JVM will fill it in
MemberName() { }
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Thu Apr 07 11:03:59 2016 -0700
@@ -26,9 +26,11 @@
package java.lang.invoke;
-import java.util.*;
import jdk.internal.HotSpotIntrinsicCandidate;
+import java.util.Arrays;
+import java.util.Objects;
+
import static java.lang.invoke.MethodHandleStatics.*;
/**
@@ -92,14 +94,16 @@
* and {@code invoke} compile to an {@code invokevirtual} instruction.
* More unusually, the compiler must record the actual argument types,
* and may not perform method invocation conversions on the arguments.
- * Instead, it must push them on the stack according to their own unconverted types.
- * The method handle object itself is pushed on the stack before the arguments.
- * The compiler then calls the method handle with a symbolic type descriptor which
- * describes the argument and return types.
+ * Instead, it must generate instructions that push them on the stack according
+ * to their own unconverted types. The method handle object itself is pushed on
+ * the stack before the arguments.
+ * The compiler then generates an {@code invokevirtual} instruction that invokes
+ * the method handle with a symbolic type descriptor which describes the argument
+ * and return types.
* <p>
* To issue a complete symbolic type descriptor, the compiler must also determine
* the return type. This is based on a cast on the method invocation expression,
- * if there is one, or else {@code Object} if the invocation is an expression
+ * if there is one, or else {@code Object} if the invocation is an expression,
* or else {@code void} if the invocation is a statement.
* The cast may be to a primitive type (but not {@code void}).
* <p>
@@ -109,12 +113,12 @@
* {@code Void} except the null reference.
*
* <h1>Method handle invocation</h1>
- * The first time a {@code invokevirtual} instruction is executed
- * it is linked, by symbolically resolving the names in the instruction
+ * The first time an {@code invokevirtual} instruction is executed
+ * it is linked by symbolically resolving the names in the instruction
* and verifying that the method call is statically legal.
- * This is true of calls to {@code invokeExact} and {@code invoke}.
+ * This also holds for calls to {@code invokeExact} and {@code invoke}.
* In this case, the symbolic type descriptor emitted by the compiler is checked for
- * correct syntax and names it contains are resolved.
+ * correct syntax, and names it contains are resolved.
* Thus, an {@code invokevirtual} instruction which invokes
* a method handle will always link, as long
* as the symbolic type descriptor is syntactically well-formed
@@ -163,7 +167,7 @@
* in a program which uses method handles.
* <p>
* Because method types contain "live" {@code Class} objects,
- * method type matching takes into account both types names and class loaders.
+ * method type matching takes into account both type names and class loaders.
* Thus, even if a method handle {@code M} is created in one
* class loader {@code L1} and used in another {@code L2},
* method handle calls are type-safe, because the caller's symbolic type
@@ -174,7 +178,7 @@
* and its type is assigned, while the resolution in {@code L2} happens
* when the {@code invokevirtual} instruction is linked.
* <p>
- * Apart from the checking of type descriptors,
+ * Apart from type descriptor checks,
* a method handle's capability to call its underlying method is unrestricted.
* If a method handle is formed on a non-public method by a class
* that has access to that method, the resulting handle can be used
@@ -196,7 +200,7 @@
* Java code can create a method handle that directly accesses
* any method, constructor, or field that is accessible to that code.
* This is done via a reflective, capability-based API called
- * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}
+ * {@link java.lang.invoke.MethodHandles.Lookup MethodHandles.Lookup}.
* For example, a static method handle can be obtained
* from {@link java.lang.invoke.MethodHandles.Lookup#findStatic Lookup.findStatic}.
* There are also conversion methods from Core Reflection API objects,
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Apr 07 11:03:59 2016 -0700
@@ -1060,6 +1060,19 @@
FAKE_METHOD_HANDLE_INVOKE[idx] = mh;
return mh;
}
+ static MethodHandle fakeVarHandleInvoke(MemberName method) {
+ // TODO caching, is it necessary?
+ MethodType type = MethodType.methodType(method.getReturnType(), UnsupportedOperationException.class,
+ VarHandle.class, Object[].class);
+ MethodHandle mh = throwException(type);
+ mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke VarHandle"));
+ if (!method.getInvocationType().equals(mh.type()))
+ throw new InternalError(method.toString());
+ mh = mh.withInternalMemberName(method, false);
+ mh = mh.asVarargsCollector(Object[].class);
+ assert(method.isVarargs());
+ return mh;
+ }
/**
* Create an alias for the method handle which, when called,
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Apr 07 11:03:59 2016 -0700
@@ -25,12 +25,15 @@
package java.lang.invoke;
+import jdk.internal.ref.CleanerFactory;
+import sun.invoke.util.Wrapper;
+
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Field;
+
import static java.lang.invoke.MethodHandleNatives.Constants.*;
-import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandleStatics.TRACE_METHOD_LINKAGE;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-import jdk.internal.ref.CleanerFactory;
/**
* The JVM interface for the method handles package is all here.
@@ -367,8 +370,14 @@
Class<?> defc, String name, Object type,
Object[] appendixResult) {
try {
- if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
- return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
+ if (refKind == REF_invokeVirtual) {
+ if (defc == MethodHandle.class) {
+ return Invokers.methodHandleInvokeLinkerMethod(
+ name, fixMethodType(callerClass, type), appendixResult);
+ } else if (defc == VarHandle.class) {
+ return varHandleOperationLinkerMethod(
+ name, fixMethodType(callerClass, type), appendixResult);
+ }
}
} catch (Throwable ex) {
if (ex instanceof LinkageError)
@@ -400,6 +409,80 @@
}
}
+ /**
+ * Obtain the method to link to the VarHandle operation.
+ * This method is located here and not in Invokers to avoid
+ * intializing that and other classes early on in VM bootup.
+ */
+ private static MemberName varHandleOperationLinkerMethod(String name,
+ MethodType mtype,
+ Object[] appendixResult) {
+ // Get the signature method type
+ MethodType sigType = mtype.basicType();
+
+ // Get the access kind from the method name
+ VarHandle.AccessMode ak;
+ try {
+ ak = VarHandle.AccessMode.valueOf(name);
+ } catch (IllegalArgumentException e) {
+ throw MethodHandleStatics.newInternalError(e);
+ }
+
+ // If not polymorphic in the return type, such as the compareAndSet
+ // methods that return boolean
+ if (ak.isPolyMorphicInReturnType) {
+ if (ak.returnType != mtype.returnType()) {
+ // The caller contains a different return type than that
+ // defined by the method
+ throw newNoSuchMethodErrorOnVarHandle(name, mtype);
+ }
+ // Adjust the return type of the signature method type
+ sigType = sigType.changeReturnType(ak.returnType);
+ }
+
+ // Get the guard method type for linking
+ MethodType guardType = sigType
+ // VarHandle at start
+ .insertParameterTypes(0, VarHandle.class)
+ // Access descriptor at end
+ .appendParameterTypes(VarHandle.AccessDescriptor.class);
+
+ // Create the appendix descriptor constant
+ VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal());
+ appendixResult[0] = ad;
+
+ if (MethodHandleStatics.VAR_HANDLE_GUARDS) {
+ MemberName linker = new MemberName(
+ VarHandleGuards.class, "guard_" + getVarHandleMethodSignature(sigType),
+ guardType, REF_invokeStatic);
+ try {
+ return MemberName.getFactory().resolveOrFail(
+ REF_invokeStatic, linker, VarHandleGuards.class, ReflectiveOperationException.class);
+ } catch (ReflectiveOperationException ex) {
+ // Fall back to lambda form linkage if guard method is not available
+ // TODO Optionally log fallback ?
+ }
+ }
+ return Invokers.varHandleInvokeLinkerMethod(name, mtype);
+ }
+ static String getVarHandleMethodSignature(MethodType mt) {
+ StringBuilder sb = new StringBuilder(mt.parameterCount() + 1);
+
+ for (int i = 0; i < mt.parameterCount(); i++) {
+ Class<?> pt = mt.parameterType(i);
+ sb.append(getCharType(pt));
+ }
+
+ sb.append('_').append(getCharType(mt.returnType()));
+
+ return sb.toString();
+ }
+ static char getCharType(Class<?> pt) {
+ return Wrapper.forBasicType(pt).basicTypeChar();
+ }
+ static NoSuchMethodError newNoSuchMethodErrorOnVarHandle(String name, MethodType mtype) {
+ return new NoSuchMethodError("VarHandle." + name + mtype);
+ }
/**
* The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Thu Apr 07 11:03:59 2016 -0700
@@ -50,9 +50,10 @@
static final int PROFILE_LEVEL;
static final boolean PROFILE_GWT;
static final int CUSTOMIZE_THRESHOLD;
+ static final boolean VAR_HANDLE_GUARDS;
static {
- final Object[] values = new Object[9];
+ final Object[] values = new Object[10];
AccessController.doPrivileged(new PrivilegedAction<>() {
public Void run() {
values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
@@ -64,6 +65,7 @@
values[6] = Integer.getInteger("java.lang.invoke.MethodHandle.PROFILE_LEVEL", 0);
values[7] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.MethodHandle.PROFILE_GWT", "true"));
values[8] = Integer.getInteger("java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD", 127);
+ values[9] = Boolean.parseBoolean(System.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true"));
return null;
}
});
@@ -76,6 +78,7 @@
PROFILE_LEVEL = (Integer) values[6];
PROFILE_GWT = (Boolean) values[7];
CUSTOMIZE_THRESHOLD = (Integer) values[8];
+ VAR_HANDLE_GUARDS = (Boolean) values[9];
if (CUSTOMIZE_THRESHOLD < -1 || CUSTOMIZE_THRESHOLD > 127) {
throw newInternalError("CUSTOMIZE_THRESHOLD should be in [-1...127] range");
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Apr 07 11:03:59 2016 -0700
@@ -53,6 +53,10 @@
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
+import static java.lang.invoke.MethodHandleImpl.Intrinsic;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
+
/**
* This class consists exclusively of static methods that operate on or return
* method handles. They fall into several categories:
@@ -873,7 +877,14 @@
* {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
* {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
* with the same {@code type} argument.
- *
+ * <p>
+ * If the class is {@code VarHandle} and the name string corresponds to
+ * the name of a signature-polymorphic access mode method, the resulting
+ * method handle is equivalent to one produced by
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker} with
+ * the access mode corresponding to the name string and with the same
+ * {@code type} arguments.
+ * <p>
* <b>Example:</b>
* <blockquote><pre>{@code
import static java.lang.invoke.MethodHandles.*;
@@ -920,6 +931,9 @@
if (refc == MethodHandle.class) {
MethodHandle mh = findVirtualForMH(name, type);
if (mh != null) return mh;
+ } else if (refc == VarHandle.class) {
+ MethodHandle mh = findVirtualForVH(name, type);
+ if (mh != null) return mh;
}
byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
MemberName method = resolveOrFail(refKind, refc, name, type);
@@ -936,6 +950,13 @@
assert(!MemberName.isMethodHandleInvokeName(name));
return null;
}
+ private MethodHandle findVirtualForVH(String name, MethodType type) {
+ try {
+ return varHandleInvoker(VarHandle.AccessMode.valueOf(name), type);
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
/**
* Produces a method handle which creates an object and initializes it, using
@@ -1135,6 +1156,7 @@
* @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 #findVarHandle(Class, String, Class)
*/
public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(REF_getField, refc, name, type);
@@ -1157,6 +1179,7 @@
* @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 #findVarHandle(Class, String, Class)
*/
public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
MemberName field = resolveOrFail(REF_putField, refc, name, type);
@@ -1164,6 +1187,53 @@
}
/**
+ * Produces a VarHandle giving access to non-static fields of type
+ * {@code T} declared by a receiver class of type {@code R}, supporting
+ * shape {@code (R : T)}.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, and numeric atomic update access modes are unsupported.
+ * <li>if the field type is anything other than {@code int},
+ * {@code long} or a reference type, then atomic update access modes
+ * are unsupported. (Future major platform releases of the JDK may
+ * support additional types for certain currently unsupported access
+ * modes.)
+ * <li>if the field type is anything other than {@code int} or
+ * {@code long}, then numeric atomic update access modes are
+ * unsupported. (Future major platform releases of the JDK may
+ * support additional numeric types for certain currently
+ * unsupported access modes.)
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to it's specified
+ * access modes.
+ * @param recv the receiver class, of type {@code R}, that declares the
+ * non-static field
+ * @param name the field's name
+ * @param type the field's type, of type {@code T}
+ * @return a VarHandle giving access to non-static fields.
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
+ * @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
+ * @since 9
+ */
+ public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ MemberName getField = resolveOrFail(REF_getField, recv, name, type);
+ MemberName putField = resolveOrFail(REF_putField, recv, name, type);
+ return getFieldVarHandle(REF_getField, REF_putField, recv, getField, putField);
+ }
+
+ /**
* Produces a method handle giving read access to a static field.
* The type of the method handle will have a return type of the field's
* value type.
@@ -1212,6 +1282,55 @@
}
/**
+ * Produces a VarHandle giving access to a static field of type
+ * {@code T} declared by a given declaring class, supporting shape
+ * {@code ((empty) : T)}.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class.
+ * <p>
+ * If the returned VarHandle is operated on, the declaring class will be
+ * initialized, if it has not already been initialized.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, and numeric atomic update access modes are unsupported.
+ * <li>if the field type is anything other than {@code int},
+ * {@code long} or a reference type, then atomic update access modes
+ * are unsupported. (Future major platform releases of the JDK may
+ * support additional types for certain currently unsupported access
+ * modes.)
+ * <li>if the field type is anything other than {@code int} or
+ * {@code long}, then numeric atomic update access modes are
+ * unsupported. (Future major platform releases of the JDK may
+ * support additional numeric types for certain currently
+ * unsupported access modes.)
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to it's specified
+ * access modes.
+ * @param decl the class that declares the static field
+ * @param name the field's name
+ * @param type the field's type, of type {@code T}
+ * @return a VarHandle giving access to a static field
+ * @throws NoSuchFieldException if the field does not exist
+ * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
+ * @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
+ * @since 9
+ */
+ public VarHandle findStaticVarHandle(Class<?> decl, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ MemberName getField = resolveOrFail(REF_getStatic, decl, name, type);
+ MemberName putField = resolveOrFail(REF_putStatic, decl, name, type);
+ return getFieldVarHandle(REF_getStatic, REF_putStatic, decl, getField, putField);
+ }
+
+ /**
* 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.
@@ -1297,6 +1416,10 @@
MethodHandle mh = unreflectForMH(m);
if (mh != null) return mh;
}
+ if (m.getDeclaringClass() == VarHandle.class) {
+ MethodHandle mh = unreflectForVH(m);
+ if (mh != null) return mh;
+ }
MemberName method = new MemberName(m);
byte refKind = method.getReferenceKind();
if (refKind == REF_invokeSpecial)
@@ -1311,6 +1434,12 @@
return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m));
return null;
}
+ private MethodHandle unreflectForVH(Method m) {
+ // these names require special lookups because they throw UnsupportedOperationException
+ if (MemberName.isVarHandleMethodInvokeName(m.getName()))
+ return MethodHandleImpl.fakeVarHandleInvoke(new MemberName(m));
+ return null;
+ }
/**
* Produces a method handle for a reflected method.
@@ -1435,6 +1564,57 @@
}
/**
+ * Produces a VarHandle that accesses fields of type {@code T} declared
+ * by a class of type {@code R}, as described by the given reflected
+ * field.
+ * If the field is non-static the VarHandle supports a shape of
+ * {@code (R : T)}, otherwise supports a shape of {@code ((empty) : T)}.
+ * <p>
+ * Access checking is performed immediately on behalf of the lookup
+ * class, regardless of the value of the field's {@code accessible}
+ * flag.
+ * <p>
+ * If the field is static, and if the returned VarHandle is operated
+ * on, the field's declaring class will be initialized, if it has not
+ * already been initialized.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the field is declared {@code final}, then the write, atomic
+ * update, and numeric atomic update access modes are unsupported.
+ * <li>if the field type is anything other than {@code int},
+ * {@code long} or a reference type, then atomic update access modes
+ * are unsupported. (Future major platform releases of the JDK may
+ * support additional types for certain currently unsupported access
+ * modes.)
+ * <li>if the field type is anything other than {@code int} or
+ * {@code long}, then numeric atomic update access modes are
+ * unsupported. (Future major platform releases of the JDK may
+ * support additional numeric types for certain currently
+ * unsupported access modes.)
+ * </ul>
+ * <p>
+ * If the field is declared {@code volatile} then the returned VarHandle
+ * will override access to the field (effectively ignore the
+ * {@code volatile} declaration) in accordance to it's specified
+ * access modes.
+ * @param f the reflected field, with a field of type {@code T}, and
+ * a declaring class of type {@code R}
+ * @return a VarHandle giving access to non-static fields or a static
+ * field
+ * @throws IllegalAccessException if access checking fails
+ * @throws NullPointerException if the argument is null
+ * @since 9
+ */
+ public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
+ MemberName getField = new MemberName(f, false);
+ MemberName putField = new MemberName(f, true);
+ return getFieldVarHandleNoSecurityManager(getField.getReferenceKind(), putField.getReferenceKind(),
+ f.getDeclaringClass(), getField, putField);
+ }
+
+ /**
* 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
@@ -1454,7 +1634,9 @@
*/
public MethodHandleInfo revealDirect(MethodHandle target) {
MemberName member = target.internalMemberName();
- if (member == null || (!member.isResolved() && !member.isMethodHandleInvoke()))
+ if (member == null || (!member.isResolved() &&
+ !member.isMethodHandleInvoke() &&
+ !member.isVarHandleMethodInvoke()))
throw newIllegalArgumentException("not a direct method handle");
Class<?> defc = member.getDeclaringClass();
byte refKind = member.getReferenceKind();
@@ -1829,6 +2011,52 @@
return restrictReceiver(field, dmh, lookupClass());
return dmh;
}
+ private VarHandle getFieldVarHandle(byte getRefKind, byte putRefKind,
+ Class<?> refc, MemberName getField, MemberName putField)
+ throws IllegalAccessException {
+ final boolean checkSecurity = true;
+ return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity);
+ }
+ private VarHandle getFieldVarHandleNoSecurityManager(byte getRefKind, byte putRefKind,
+ Class<?> refc, MemberName getField, MemberName putField)
+ throws IllegalAccessException {
+ final boolean checkSecurity = false;
+ return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity);
+ }
+ private VarHandle getFieldVarHandleCommon(byte getRefKind, byte putRefKind,
+ Class<?> refc, MemberName getField, MemberName putField,
+ boolean checkSecurity) throws IllegalAccessException {
+ assert getField.isStatic() == putField.isStatic();
+ assert getField.isGetter() && putField.isSetter();
+ assert MethodHandleNatives.refKindIsStatic(getRefKind) == MethodHandleNatives.refKindIsStatic(putRefKind);
+ assert MethodHandleNatives.refKindIsGetter(getRefKind) && MethodHandleNatives.refKindIsSetter(putRefKind);
+
+ checkField(getRefKind, refc, getField);
+ if (checkSecurity)
+ checkSecurityManager(refc, getField);
+
+ if (!putField.isFinal()) {
+ // A VarHandle does not support updates to final fields, any
+ // such VarHandle to a final field will be read-only and
+ // therefore the following write-based accessibility checks are
+ // only required for non-final fields
+ checkField(putRefKind, refc, putField);
+ if (checkSecurity)
+ checkSecurityManager(refc, putField);
+ }
+
+ boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
+ restrictProtectedReceiver(getField));
+ if (doRestrict) {
+ assert !getField.isStatic();
+ // receiver type of VarHandle is too wide; narrow to caller
+ if (!getField.getDeclaringClass().isAssignableFrom(lookupClass())) {
+ throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
+ }
+ refc = lookupClass();
+ }
+ return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(), this.allowedModes == TRUSTED);
+ }
/** Check access and get the requested constructor. */
private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
final boolean checkSecurity = true;
@@ -2018,6 +2246,205 @@
return MethodHandleImpl.makeArrayElementAccessor(arrayClass, true);
}
+ /**
+ *
+ * Produces a VarHandle giving access to elements of an array type
+ * {@code T[]}, supporting shape {@code (T[], int : T)}.
+ * <p>
+ * Certain access modes of the returned VarHandle are unsupported under
+ * the following conditions:
+ * <ul>
+ * <li>if the component type is anything other than {@code int},
+ * {@code long} or a reference type, then atomic update access modes
+ * are unsupported. (Future major platform releases of the JDK may
+ * support additional types for certain currently unsupported access
+ * modes.)
+ * <li>if the component type is anything other than {@code int} or
+ * {@code long}, then numeric atomic update access modes are
+ * unsupported. (Future major platform releases of the JDK may
+ * support additional numeric types for certain currently
+ * unsupported access modes.)
+ * </ul>
+ * @param arrayClass the class of an array, of type {@code T[]}
+ * @return a VarHandle giving access to elements of an array
+ * @throws NullPointerException if the arrayClass is null
+ * @throws IllegalArgumentException if arrayClass is not an array type
+ * @since 9
+ */
+ public static
+ VarHandle arrayElementVarHandle(Class<?> arrayClass) throws IllegalArgumentException {
+ return VarHandles.makeArrayElementHandle(arrayClass);
+ }
+
+ /**
+ * Produces a VarHandle giving access to elements of a {@code byte[]} array
+ * viewed as if it were a different primitive array type, such as
+ * {@code int[]} or {@code long[]}. The shape of the resulting VarHandle is
+ * {@code (byte[], int : T)}, where the {@code int} coordinate type
+ * corresponds to an argument that is an index in a {@code byte[]} array,
+ * and {@code T} is the component type of the given view array class. The
+ * returned VarHandle accesses bytes at an index in a {@code byte[]} array,
+ * composing bytes to or from a value of {@code T} according to the given
+ * endianness.
+ * <p>
+ * The supported component types (variables types) are {@code short},
+ * {@code char}, {@code int}, {@code long}, {@code float} and
+ * {@code double}.
+ * <p>
+ * Access of bytes at a given index will result in an
+ * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
+ * or greater than the {@code byte[]} array length minus the size (in bytes)
+ * of {@code T}.
+ * <p>
+ * Access of bytes at an index may be aligned or misaligned for {@code T},
+ * with respect to the underlying memory address, {@code A} say, associated
+ * with the array and index.
+ * If access is misaligned then access for anything other than the
+ * {@code get} and {@code set} access modes will result in an
+ * {@code IllegalStateException}. In such cases atomic access is only
+ * guaranteed with respect to the largest power of two that divides the GCD
+ * of {@code A} and the size (in bytes) of {@code T}.
+ * If access is aligned then following access modes are supported and are
+ * guaranteed to support atomic access:
+ * <ul>
+ * <li>read write access modes for all {@code T};
+ * <li>atomic update access modes for {@code int}, {@code long},
+ * {@code float} or {@code double}.
+ * (Future major platform releases of the JDK may support additional
+ * types for certain currently unsupported access modes.)
+ * <li>numeric atomic update access modes for {@code int} and {@code long}.
+ * (Future major platform releases of the JDK may support additional
+ * numeric types for certain currently unsupported access modes.)
+ * </ul>
+ * <p>
+ * Misaligned access, and therefore atomicity guarantees, may be determined
+ * for {@code byte[]} arrays without operating on a specific array. Given
+ * an {@code index}, {@code T} and it's corresponding boxed type,
+ * {@code T_BOX}, misalignment may be determined as follows:
+ * <pre>{@code
+ * int sizeOfT = T_BOX.BYTES; // size in bytes of T
+ * int misalignedAtZeroIndex = ByteBuffer.wrap(new byte[0]).
+ * alignmentOffset(0, sizeOfT);
+ * int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT;
+ * boolean isMisaligned = misalignedAtIndex != 0;
+ * }</pre>
+ *
+ * @implNote
+ * The variable types {@code float} and {@code double} are supported as if
+ * by transformation to and access with the variable types {@code int} and
+ * {@code long} respectively. For example, the transformation of a
+ * {@code double} value to a long value is performed as if using
+ * {@link Double#doubleToRawLongBits(double)}, and the reverse
+ * transformation is performed as if using
+ * {@link Double#longBitsToDouble(long)}.
+ *
+ * @param viewArrayClass the view array class, with a component type of
+ * type {@code T}
+ * @param bigEndian true if the endianness of the view array elements, as
+ * stored in the underlying {@code byte} array, is big endian, otherwise
+ * little endian
+ * @return a VarHandle giving access to elements of a {@code byte[]} array
+ * viewed as if elements corresponding to the components type of the view
+ * array class
+ * @throws NullPointerException if viewArrayClass is null
+ * @throws IllegalArgumentException if viewArrayClass is not an array type
+ * @throws UnsupportedOperationException if the component type of
+ * viewArrayClass is not supported as a variable type
+ * @since 9
+ */
+ public static
+ VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
+ boolean bigEndian) throws IllegalArgumentException {
+ return VarHandles.byteArrayViewHandle(viewArrayClass, bigEndian);
+ }
+
+ /**
+ * Produces a VarHandle giving access to elements of a {@code ByteBuffer}
+ * viewed as if it were an array of elements of a different primitive
+ * component type to that of {@code byte}, such as {@code int[]} or
+ * {@code long[]}. The shape of the resulting VarHandle is
+ * {@code (ByteBuffer, int : T)}, where the {@code int} coordinate type
+ * corresponds to an argument that is an index in a {@code ByteBuffer}, and
+ * {@code T} is the component type of the given view array class. The
+ * returned VarHandle accesses bytes at an index in a {@code ByteBuffer},
+ * composing bytes to or from a value of {@code T} according to the given
+ * endianness.
+ * <p>
+ * The supported component types (variables types) are {@code short},
+ * {@code char}, {@code int}, {@code long}, {@code float} and
+ * {@code double}.
+ * <p>
+ * Access will result in a {@code ReadOnlyBufferException} for anything
+ * other than the read access modes if the {@code ByteBuffer} is read-only.
+ * <p>
+ * Access of bytes at a given index will result in an
+ * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
+ * or greater than the {@code ByteBuffer} limit minus the size (in bytes) of
+ * {@code T}.
+ * <p>
+ * Access of bytes at an index may be aligned or misaligned for {@code T},
+ * with respect to the underlying memory address, {@code A} say, associated
+ * with the {@code ByteBuffer} and index.
+ * If access is misaligned then access for anything other than the
+ * {@code get} and {@code set} access modes will result in an
+ * {@code IllegalStateException}. In such cases atomic access is only
+ * guaranteed with respect to the largest power of two that divides the GCD
+ * of {@code A} and the size (in bytes) of {@code T}.
+ * If access is aligned then following access modes are supported and are
+ * guaranteed to support atomic access:
+ * <ul>
+ * <li>read write access modes for all {@code T};
+ * <li>atomic update access modes for {@code int}, {@code long},
+ * {@code float} or {@code double}.
+ * (Future major platform releases of the JDK may support additional
+ * types for certain currently unsupported access modes.)
+ * <li>numeric atomic update access modes for {@code int} and {@code long}.
+ * (Future major platform releases of the JDK may support additional
+ * numeric types for certain currently unsupported access modes.)
+ * </ul>
+ * <p>
+ * Misaligned access, and therefore atomicity guarantees, may be determined
+ * for a {@code ByteBuffer}, {@code bb} (direct or otherwise), an
+ * {@code index}, {@code T} and it's corresponding boxed type,
+ * {@code T_BOX}, as follows:
+ * <pre>{@code
+ * int sizeOfT = T_BOX.BYTES; // size in bytes of T
+ * ByteBuffer bb = ...
+ * int misalignedAtIndex = bb.alignmentOffset(index, sizeOfT);
+ * boolean isMisaligned = misalignedAtIndex != 0;
+ * }</pre>
+ *
+ * @implNote
+ * The variable types {@code float} and {@code double} are supported as if
+ * by transformation to and access with the variable types {@code int} and
+ * {@code long} respectively. For example, the transformation of a
+ * {@code double} value to a long value is performed as if using
+ * {@link Double#doubleToRawLongBits(double)}, and the reverse
+ * transformation is performed as if using
+ * {@link Double#longBitsToDouble(long)}.
+ *
+ * @param viewArrayClass the view array class, with a component type of
+ * type {@code T}
+ * @param bigEndian true if the endianness of the view array elements, as
+ * stored in the underlying {@code ByteBuffer}, is big endian, otherwise
+ * little endian (Note this overrides the endianness of a
+ * {@code ByteBuffer})
+ * @return a VarHandle giving access to elements of a {@code ByteBuffer}
+ * viewed as if elements corresponding to the components type of the view
+ * array class
+ * @throws NullPointerException if viewArrayClass is null
+ * @throws IllegalArgumentException if viewArrayClass is not an array type
+ * @throws UnsupportedOperationException if the component type of
+ * viewArrayClass is not supported as a variable type
+ * @since 9
+ */
+ public static
+ VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
+ boolean bigEndian) throws IllegalArgumentException {
+ return VarHandles.makeByteBufferViewHandle(viewArrayClass, bigEndian);
+ }
+
+
/// method handle invocation (reflective style)
/**
@@ -2153,6 +2580,54 @@
return type.invokers().genericInvoker();
}
+ /**
+ * Produces a special <em>invoker method handle</em> which can be used to
+ * invoke a signature-polymorphic access mode method on any VarHandle whose
+ * associated access mode type is compatible with the given type.
+ * The resulting invoker will have a type which is exactly equal to the
+ * desired given type, except that it will accept an additional leading
+ * argument of type {@code VarHandle}.
+ *
+ * @param accessMode the VarHandle access mode
+ * @param type the desired target type
+ * @return a method handle suitable for invoking an access mode method of
+ * any VarHandle whose access mode type is of the given type.
+ * @since 9
+ */
+ static public
+ MethodHandle varHandleExactInvoker(VarHandle.AccessMode accessMode, MethodType type) {
+ return type.invokers().varHandleMethodExactInvoker(accessMode);
+ }
+
+ /**
+ * Produces a special <em>invoker method handle</em> which can be used to
+ * invoke a signature-polymorphic access mode method on any VarHandle whose
+ * associated access mode type is compatible with the given type.
+ * The resulting invoker will have a type which is exactly equal to the
+ * desired given type, except that it will accept an additional leading
+ * argument of type {@code VarHandle}.
+ * <p>
+ * Before invoking its target, if the access mode type differs from the
+ * desired given type, the invoker will apply reference casts as necessary
+ * and box, unbox, or widen primitive values, as if by
+ * {@link MethodHandle#asType asType}. Similarly, the return value will be
+ * converted as necessary.
+ * <p>
+ * This method is equivalent to the following code (though it may be more
+ * efficient): {@code publicLookup().findVirtual(VarHandle.class, accessMode.name(), type)}
+ *
+ * @param accessMode the VarHandle access mode
+ * @param type the desired target type
+ * @return a method handle suitable for invoking an access mode method of
+ * any VarHandle whose access mode type is convertible to the given
+ * type.
+ * @since 9
+ */
+ static public
+ MethodHandle varHandleInvoker(VarHandle.AccessMode accessMode, MethodType type) {
+ return type.invokers().varHandleMethodInvoker(accessMode);
+ }
+
static /*non-public*/
MethodHandle basicInvoker(MethodType type) {
return type.invokers().basicInvoker();
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java Thu Apr 07 11:03:59 2016 -0700
@@ -95,7 +95,7 @@
// The rtype and ptypes fields define the structural identity of the method type:
private final Class<?> rtype;
- private final Class<?>[] ptypes;
+ private final @Stable Class<?>[] ptypes;
// The remaining fields are caches of various sorts:
private @Stable MethodTypeForm form; // erased form, plus cached data about primitives
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarForm.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014, 2015, 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 java.lang.invoke.VarHandle.AccessMode;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
+
+/**
+ * A var handle form containing a set of member name, one for each operation.
+ * Each member characterizes a static method.
+ */
+class VarForm {
+
+ // Holds VarForm for VarHandle implementation classes
+ private static final ClassValue<VarForm> VFORMS
+ = new ClassValue<VarForm>() {
+ @Override
+ protected VarForm computeValue(Class<?> impl) {
+ return new VarForm(link(staticMethodLinker(impl)));
+ }
+ };
+
+ final MemberName mbGet;
+ final MemberName mbSet;
+ final MemberName mbGetVolatile;
+ final MemberName mbSetVolatile;
+ final MemberName mbGetAcquire;
+ final MemberName mbSetRelease;
+ final MemberName mbCompareAndSet;
+ final MemberName mbCompareAndExchangeVolatile;
+ final MemberName mbCompareAndExchangeAcquire;
+ final MemberName mbCompareAndExchangeRelease;
+ final MemberName mbWeakCompareAndSet;
+ final MemberName mbWeakCompareAndSetAcquire;
+ final MemberName mbWeakCompareAndSetRelease;
+ final MemberName mbGetAndSet;
+ final MemberName mbGetAndAdd;
+ final MemberName mbAddAndGet;
+ final MemberName mbGetOpaque;
+ final MemberName mbSetOpaque;
+
+ VarForm(Map<AccessMode, MemberName> linkMap) {
+ mbGet = linkMap.get(AccessMode.get);
+ mbSet = linkMap.get(AccessMode.set);
+ mbGetVolatile = linkMap.get(AccessMode.getVolatile);
+ mbSetVolatile = linkMap.get(AccessMode.setVolatile);
+ mbGetOpaque = linkMap.get(AccessMode.getOpaque);
+ mbSetOpaque = linkMap.get(AccessMode.setOpaque);
+ mbGetAcquire = linkMap.get(AccessMode.getAcquire);
+ mbSetRelease = linkMap.get(AccessMode.setRelease);
+ mbCompareAndSet = linkMap.get(AccessMode.compareAndSet);
+ mbCompareAndExchangeVolatile = linkMap.get(AccessMode.compareAndExchangeVolatile);
+ mbCompareAndExchangeAcquire = linkMap.get(AccessMode.compareAndExchangeAcquire);
+ mbCompareAndExchangeRelease = linkMap.get(AccessMode.compareAndExchangeRelease);
+ mbWeakCompareAndSet = linkMap.get(AccessMode.weakCompareAndSet);
+ mbWeakCompareAndSetAcquire = linkMap.get(AccessMode.weakCompareAndSetAcquire);
+ mbWeakCompareAndSetRelease = linkMap.get(AccessMode.weakCompareAndSetRelease);
+ mbGetAndSet = linkMap.get(AccessMode.getAndSet);
+ mbGetAndAdd = linkMap.get(AccessMode.getAndAdd);
+ mbAddAndGet = linkMap.get(AccessMode.addAndGet);
+ }
+
+ /**
+ * Creates a var form given an VarHandle implementation class.
+ * Each signature polymorphic method is linked to a static method of the
+ * same name on the implementation class or a super class.
+ */
+ static VarForm createFromStatic(Class<? extends VarHandle> impl) {
+ return VFORMS.get(impl);
+ }
+
+ /**
+ * Link all signature polymorphic methods.
+ */
+ private static Map<AccessMode, MemberName> link(Function<AccessMode, MemberName> linker) {
+ Map<AccessMode, MemberName> links = new HashMap<>();
+ for (AccessMode ak : AccessMode.values()) {
+ links.put(ak, linker.apply(ak));
+ }
+ return links;
+ }
+
+
+ /**
+ * Returns a function that associates an AccessMode with a MemberName that
+ * is a static concrete method implementation for the access operation of
+ * the implementing class.
+ */
+ private static Function<AccessMode, MemberName> staticMethodLinker(Class<?> implClass) {
+ // Find all declared static methods on the implementation class and
+ // all super classes up to but not including VarHandle
+ List<Method> staticMethods = new ArrayList<>(AccessMode.values().length);
+ for (Class<?> c = implClass; c != VarHandle.class; c = c.getSuperclass()) {
+ for (Method m : c.getDeclaredMethods()) {
+ if (Modifier.isStatic(m.getModifiers())) {
+ staticMethods.add(m);
+ }
+ }
+ }
+
+ // This needs to be an anonymous inner class and not a lambda expression
+ // The latter will cause the intialization of classes in java.lang.invoke
+ // resulting in circular dependencies if VarHandles are utilized early
+ // in the start up process. For example, if ConcurrentHashMap
+ // is modified to use VarHandles.
+ return new Function<>() {
+ @Override
+ public MemberName apply(AccessMode ak) {
+ Method m = null;
+ for (Method to_m : staticMethods) {
+ if (to_m.getName().equals(ak.name()) &&
+ Modifier.isStatic(to_m.getModifiers())) {
+ assert m == null : String.format(
+ "Two or more static methods named %s are present on " +
+ "class %s or a super class", ak.name(), implClass.getName());
+ m = to_m;
+ }
+ }
+
+ if (m == null)
+ return null;
+
+ MemberName linkedMethod = new MemberName(m);
+ try {
+ return MemberName.getFactory().resolveOrFail(
+ REF_invokeStatic, linkedMethod, m.getDeclaringClass(), NoSuchMethodException.class);
+ }
+ catch (ReflectiveOperationException e) {
+ throw new InternalError(e);
+ }
+ }
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,1416 @@
+/*
+ * Copyright (c) 2014, 2015, 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 jdk.internal.HotSpotIntrinsicCandidate;
+import jdk.internal.vm.annotation.ForceInline;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BiFunction;
+
+import static java.lang.invoke.MethodHandleStatics.UNSAFE;
+import static java.lang.invoke.MethodHandleStatics.newInternalError;
+
+/**
+ * A VarHandle is a dynamically typed reference to a variable, or to a
+ * parametrically-defined family of variables, including static fields,
+ * non-static fields, array elements, or components of an off-heap data
+ * structure. Access to such variables is supported under various
+ * <em>access modes</em>, including plain read/write access, volatile
+ * read/write access, and compare-and-swap.
+ *
+ * <p>VarHandles are immutable and have no visible state. VarHandles cannot be
+ * subclassed by the user.
+ *
+ * <p>A VarHandle has:
+ * <ul>
+ * <li>a {@link #varType variable type}, referred to as {@code T}, which is the
+ * type of variable(s) referenced by this VarHandle;
+ * <li>a list of {@link #coordinateTypes coordinate types}, referred to as
+ * {@code CT}, where the types (primitive and reference) are represented by
+ * {@link Class} objects). A list of arguments corresponding to instances of
+ * the coordinate types uniquely locates a variable referenced by this
+ * VarHandle; and
+ * <li>a <em>shape</em>, that combines the variable type and coordinate types,
+ * and is declared with the notation {@code (CT : T)}. An empty list of
+ * coordinate types is declared as {@code (empty)}.
+ * </ul>
+ *
+ * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
+ * lookup} VarHandle instances document the supported variable type, coordinate
+ * types, and shape.
+ *
+ * For example, a VarHandle referencing a non-static field will declare a shape
+ * of {@code (R : T)}, where {@code R} is the receiver type and
+ * {@code T} is the field type, and where the VarHandle and an instance of the
+ * receiver type can be utilized to access the field variable.
+ * A VarHandle referencing array elements will declare a shape of
+ * {@code (T[], int : T)}, where {@code T[]} is the array type and {@code T}
+ * its component type, and where the VarHandle, an instance of the array type,
+ * and an {@code int} index can be utilized to access an array element variable.
+ *
+ * <p>Each access mode is associated with a
+ * <a href="MethodHandle.html#sigpoly">signature polymorphic</a> method of the
+ * same name, where the VarHandle shape and access mode uniquely determine the
+ * canonical {@link #accessModeType(AccessMode) access mode type},
+ * which in turn determines the matching constraints on a valid symbolic
+ * type descriptor at the call site of an access mode's method
+ * <a href="VarHandle.html#invoke">invocation</a>.
+ *
+ * As such, VarHandles are dynamically and strongly typed. Their arity,
+ * argument types, and return type of an access mode method invocation are not
+ * statically checked. If they, and associated values, do not match the arity
+ * and types of the access mode's type, an exception will be thrown.
+ *
+ * The parameter types of an access mode method type will consist of those that
+ * are the VarHandles's coordinate types (in order), followed by access mode
+ * parameter types specific to the access mode.
+ *
+ * <p>An access mode's method documents the form of its method signature, which
+ * is derived from the access mode parameter types. The form is declared with
+ * the notation {@code (CT, P1 p1, P2 p2, ..., PN pn)R}, where {@code CT} is the
+ * coordinate types (as documented by a VarHandle factory method), {@code P1},
+ * {@code P2} and {@code PN} are the first, second and the n'th access mode
+ * parameters named {@code p1}, {@code p2} and {@code pn} respectively, and
+ * {@code R} is the return type.
+ *
+ * For example, for the generic shape of {@code (CT : T)} the
+ * {@link #compareAndSet} access mode method documents that its method
+ * signature is of the form {@code (CT, T expectedValue, T newValue)boolean},
+ * where the parameter types named {@code extendedValue} and {@code newValue}
+ * are the access mode parameter types. If the VarHandle accesses array
+ * elements with a shape of say {@code (T[], int : T)} then the access mode
+ * method type is {@code (T[], int, T, T)boolean}.
+ *
+ * <p>Access modes are grouped into the following categories:
+ * <ul>
+ * <li>read access modes that get the value of a variable under specified
+ * memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #get get},
+ * {@link #getVolatile getVolatile},
+ * {@link #getAcquire getAcquire},
+ * {@link #getOpaque getOpaque}.
+ * <li>write access modes that set the value of a variable under specified
+ * memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #set set},
+ * {@link #setVolatile setVolatile},
+ * {@link #setRelease setRelease},
+ * {@link #setOpaque setOpaque}.
+ * <li>atomic update access modes that, for example, atomically compare and set
+ * the value of a variable under specified memory ordering effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #compareAndSet compareAndSet},
+ * {@link #weakCompareAndSet weakCompareAndSet},
+ * {@link #weakCompareAndSetAcquire weakCompareAndSetAcquire},
+ * {@link #weakCompareAndSetRelease weakCompareAndSetRelease},
+ * {@link #compareAndExchangeAcquire compareAndExchangeAcquire},
+ * {@link #compareAndExchangeVolatile compareAndExchangeVolatile},
+ * {@link #compareAndExchangeRelease compareAndExchangeRelease},
+ * {@link #getAndSet getAndSet}.
+ * <li>numeric atomic update access modes that, for example, atomically get and
+ * set with addition the value of a variable under specified memory ordering
+ * effects.
+ * The set of corresponding access mode methods belonging to this group
+ * consists of the methods
+ * {@link #getAndAdd getAndAdd},
+ * {@link #addAndGet addAndGet}.
+ * </ul>
+ *
+ * <p>Factory methods that produce or {@link java.lang.invoke.MethodHandles.Lookup
+ * lookup} VarHandle instances document the set of access modes that are
+ * supported, which may also include documenting restrictions based on the
+ * variable type and whether a variable is read-only. If an access mode is not
+ * supported then the corresponding signature-polymorphic method will on
+ * invocation throw an {@code UnsupportedOperationException}.
+ * The {@link #get get} access mode is supported for all
+ * VarHandle instances and the corresponding method never throws
+ * {@code UnsupportedOperationException}.
+ * If a VarHandle references a read-only variable (for example a {@code final}
+ * field) then write, atomic update and numeric atomic update access modes are
+ * not supported and corresponding methods throw
+ * {@code UnsupportedOperationException}.
+ * Read/write access modes (if supported), with the exception of
+ * {@code get} and {@code set}, provide atomic access for
+ * reference types and all primitive types.
+ * Unless stated otherwise in the documentation of a factory method, the access
+ * modes {@code get} and {@code set} (if supported) provide atomic access for
+ * reference types and all primitives types, with the exception of {@code long}
+ * and {@code double} on 32-bit platforms
+ *
+ * <p>Access modes will override any memory ordering effects specified at
+ * the declaration site of a variable. For example, a VarHandle accessing a
+ * a field using the {@code get} access mode will access the field as
+ * specified <em>by its access mode</em> even if that field is declared
+ * {@code volatile}. When mixed access is performed extreme care should be
+ * taken since the Java Memory Model may permit surprising results.
+ *
+ * <p>In addition to supporting access to variables under various access modes,
+ * a set of static methods, referred to as memory fence methods, is also
+ * provided for fine-grained control of memory ordering.
+ *
+ * The Java Language Specification permits other threads to observe operations
+ * as if they were executed in orders different than are apparent in program
+ * source code, subject to constraints arising, for example, from the use of
+ * locks, {@code volatile} fields or VarHandles. The static methods,
+ * {@link #fullFence fullFence}, {@link #acquireFence acquireFence},
+ * {@link #releaseFence releaseFence}, {@link #loadLoadFence loadLoadFence} and
+ * {@link #storeStoreFence storeStoreFence}, can also be used to impose
+ * constraints. Their specifications, as is the case for certain access modes,
+ * are phrased in terms of the lack of "reorderings" -- observable ordering
+ * effects that might otherwise occur if the fence was not present. More
+ * precise phrasing of the specification of access mode methods and memory fence
+ * methods may accompany future updates of the Java Language Specification.
+ *
+ * <h1>Compilation of an access mode's method</h1>
+ * A Java method call expression naming an access mode method can invoke a
+ * VarHandle from Java source code. From the viewpoint of source code, these
+ * methods can take any arguments and their polymorphic result (if expressed)
+ * can be cast to any return type. Formally this is accomplished by giving the
+ * access mode methods variable arity {@code Object} arguments and
+ * {@code Object} return types (if the return type is polymorphic), but they
+ * have an additional quality called <em>signature polymorphism</em> which
+ * connects this freedom of invocation directly to the JVM execution stack.
+ * <p>
+ * As is usual with virtual methods, source-level calls to access mode methods
+ * compile to an {@code invokevirtual} instruction. More unusually, the
+ * compiler must record the actual argument types, and may not perform method
+ * invocation conversions on the arguments. Instead, it must generate
+ * instructions to push them on the stack according to their own unconverted
+ * types. The VarHandle object itself will be pushed on the stack before the
+ * arguments. The compiler then generates an {@code invokevirtual} instruction
+ * that invokes the access mode method with a symbolic type descriptor which
+ * describes the argument and return types.
+ * <p>
+ * To issue a complete symbolic type descriptor, the compiler must also
+ * determine the return type (if polymorphic). This is based on a cast on the
+ * method invocation expression, if there is one, or else {@code Object} if the
+ * invocation is an expression, or else {@code void} if the invocation is a
+ * statement. The cast may be to a primitive type (but not {@code void}).
+ * <p>
+ * As a corner case, an uncasted {@code null} argument is given a symbolic type
+ * descriptor of {@code java.lang.Void}. The ambiguity with the type
+ * {@code Void} is harmless, since there are no references of type {@code Void}
+ * except the null reference.
+ *
+ *
+ * <h1><a name="invoke">Invocation of an access mode's method</a></h1>
+ * The first time an {@code invokevirtual} instruction is executed it is linked
+ * by symbolically resolving the names in the instruction and verifying that
+ * the method call is statically legal. This also holds for calls to access mode
+ * methods. In this case, the symbolic type descriptor emitted by the compiler
+ * is checked for correct syntax, and names it contains are resolved. Thus, an
+ * {@code invokevirtual} instruction which invokes an access mode method will
+ * always link, as long as the symbolic type descriptor is syntactically
+ * well-formed and the types exist.
+ * <p>
+ * When the {@code invokevirtual} is executed after linking, the receiving
+ * VarHandle's access mode type is first checked by the JVM to ensure that it
+ * matches the symbolic type descriptor. If the type
+ * match fails, it means that the access mode method which the caller is
+ * invoking is not present on the individual VarHandle being invoked.
+ *
+ * <p>
+ * Invocation of an access mode's signature-polymorphic method behaves as if an
+ * invocation of {@link MethodHandle#invoke}, where the receiving method handle
+ * is bound to a VarHandle instance and the access mode. More specifically, the
+ * following:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * R r = (R) vh.{access-mode}(p1, p2, ..., pN);
+ * }</pre>
+ * behaves as if (modulo the access mode methods do not declare throwing of
+ * {@code Throwable}):
+ * <pre> {@code
+ * VarHandle vh = ..
+ * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ * VarHandle.AccessMode.{access-mode},
+ * vh.accessModeType(VarHandle.AccessMode.{access-mode}));
+ *
+ * mh = mh.bindTo(vh);
+ * R r = (R) mh.invoke(p1, p2, ..., pN)
+ * }</pre>
+ * or, more concisely, behaves as if:
+ * <pre> {@code
+ * VarHandle vh = ..
+ * MethodHandle mh = vh.toMethodHandle(VarHandle.AccessMode.{access-mode});
+ *
+ * R r = (R) mh.invoke(p1, p2, ..., pN)
+ * }</pre>
+ * In terms of equivalent {@code invokevirtual} bytecode behaviour an access
+ * mode method invocation is equivalent to:
+ * <pre> {@code
+ * MethodHandle mh = MethodHandles.lookup().findVirtual(
+ * VarHandle.class,
+ * VarHandle.AccessMode.{access-mode}.name(),
+ * MethodType.methodType(R, p1, p2, ..., pN));
+ *
+ * R r = (R) mh.invokeExact(vh, p1, p2, ..., pN)
+ * }</pre>
+ * where the desired method type is the symbolic type descriptor and a
+ * {@link MethodHandle#invokeExact} is performed, since before invocation of the
+ * target, the handle will apply reference casts as necessary and box, unbox, or
+ * widen primitive values, as if by {@link MethodHandle#asType asType} (see also
+ * {@link MethodHandles#varHandleInvoker}).
+ *
+ * <h1>Invocation checking</h1>
+ * In typical programs, VarHandle access mode type matching will usually
+ * succeed. But if a match fails, the JVM will throw a
+ * {@link WrongMethodTypeException}.
+ * <p>
+ * Thus, an access mode type mismatch which might show up as a linkage error
+ * in a statically typed program can show up as a dynamic
+ * {@code WrongMethodTypeException} in a program which uses VarHandles.
+ * <p>
+ * Because access mode types contain "live" {@code Class} objects, method type
+ * matching takes into account both type names and class loaders.
+ * Thus, even if a VarHandle {@code VH} is created in one class loader
+ * {@code L1} and used in another {@code L2}, VarHandle access mode method
+ * calls are type-safe, because the caller's symbolic type descriptor, as
+ * resolved in {@code L2}, is matched against the original callee method's
+ * symbolic type descriptor, as resolved in {@code L1}. The resolution in
+ * {@code L1} happens when {@code VH} is created and its access mode types are
+ * assigned, while the resolution in {@code L2} happens when the
+ * {@code invokevirtual} instruction is linked.
+ * <p>
+ * Apart from type descriptor checks, a VarHandles's capability to
+ * access it's variables is unrestricted.
+ * If a VarHandle is formed on a non-public variable by a class that has access
+ * to that variable, the resulting VarHandle can be used in any place by any
+ * caller who receives a reference to it.
+ * <p>
+ * Unlike with the Core Reflection API, where access is checked every time a
+ * reflective method is invoked, VarHandle access checking is performed
+ * <a href="MethodHandles.Lookup.html#access">when the VarHandle is
+ * created</a>.
+ * Thus, VarHandles to non-public variables, or to variables in non-public
+ * classes, should generally be kept secret. They should not be passed to
+ * untrusted code unless their use from the untrusted code would be harmless.
+ *
+ *
+ * <h1>VarHandle creation</h1>
+ * Java code can create a VarHandle that directly accesses any field that is
+ * accessible to that code. This is done via a reflective, capability-based
+ * API called {@link java.lang.invoke.MethodHandles.Lookup
+ * MethodHandles.Lookup}.
+ * For example, a VarHandle for a non-static field can be obtained
+ * from {@link java.lang.invoke.MethodHandles.Lookup#findVarHandle
+ * Lookup.findVarHandle}.
+ * There is also a conversion method from Core Reflection API objects,
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
+ * Lookup.unreflectVarHandle}.
+ * <p>
+ * Access to protected field members is restricted to receivers only of the
+ * accessing class, or one of its subclasses, and the accessing class must in
+ * turn be a subclass (or package sibling) of the protected member's defining
+ * class. If a VarHandle refers to a protected non-static field of a declaring
+ * class outside the current package, the receiver argument will be narrowed to
+ * the type of the accessing class.
+ *
+ * <h1>Interoperation between VarHandles and the Core Reflection API</h1>
+ * Using factory methods in the {@link java.lang.invoke.MethodHandles.Lookup
+ * Lookup} API, any field represented by a Core Reflection API object
+ * can be converted to a behaviorally equivalent VarHandle.
+ * For example, a reflective {@link java.lang.reflect.Field Field} can
+ * be converted to a VarHandle using
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflectVarHandle
+ * Lookup.unreflectVarHandle}.
+ * The resulting VarHandles generally provide more direct and efficient
+ * access to the underlying fields.
+ * <p>
+ * As a special case, when the Core Reflection API is used to view the
+ * signature polymorphic access mode methods in this class, they appear as
+ * ordinary non-polymorphic methods. Their reflective appearance, as viewed by
+ * {@link java.lang.Class#getDeclaredMethod Class.getDeclaredMethod},
+ * is unaffected by their special status in this API.
+ * For example, {@link java.lang.reflect.Method#getModifiers
+ * Method.getModifiers}
+ * will report exactly those modifier bits required for any similarly
+ * declared method, including in this case {@code native} and {@code varargs}
+ * bits.
+ * <p>
+ * As with any reflected method, these methods (when reflected) may be invoked
+ * directly via {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke},
+ * via JNI, or indirectly via
+ * {@link java.lang.invoke.MethodHandles.Lookup#unreflect Lookup.unreflect}.
+ * However, such reflective calls do not result in access mode method
+ * invocations. Such a call, if passed the required argument (a single one, of
+ * type {@code Object[]}), will ignore the argument and will throw an
+ * {@code UnsupportedOperationException}.
+ * <p>
+ * Since {@code invokevirtual} instructions can natively invoke VarHandle
+ * access mode methods under any symbolic type descriptor, this reflective view
+ * conflicts with the normal presentation of these methods via bytecodes.
+ * Thus, these native methods, when reflectively viewed by
+ * {@code Class.getDeclaredMethod}, may be regarded as placeholders only.
+ * <p>
+ * In order to obtain an invoker method for a particular access mode type,
+ * use {@link java.lang.invoke.MethodHandles#varHandleExactInvoker} or
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker}. The
+ * {@link java.lang.invoke.MethodHandles.Lookup#findVirtual Lookup.findVirtual}
+ * API is also able to return a method handle to call an access mode method for
+ * any specified access mode type and is equivalent in behaviour to
+ * {@link java.lang.invoke.MethodHandles#varHandleInvoker}.
+ *
+ * <h1>Interoperation between VarHandles and Java generics</h1>
+ * A VarHandle can be obtained for a variable, such as a a field, which is
+ * declared with Java generic types. As with the Core Reflection API, the
+ * VarHandle's variable type will be constructed from the erasure of the
+ * source-level type. When a VarHandle access mode method is invoked, the
+ * types
+ * of its arguments or the return value cast type may be generic types or type
+ * instances. If this occurs, the compiler will replace those types by their
+ * erasures when it constructs the symbolic type descriptor for the
+ * {@code invokevirtual} instruction.
+ *
+ * @see MethodHandle
+ * @see MethodHandles
+ * @see MethodType
+ * @since 9
+ */
+public abstract class VarHandle {
+ // Use explicit final fields rather than an @Stable array as
+ // this can reduce the memory per handle
+ // e.g. by 24 bytes on 64 bit architectures
+ final MethodType typeGet;
+ final MethodType typeSet;
+ final MethodType typeCompareSwap;
+ final MethodType typeCompareExchange;
+ final MethodType typeGetAndUpdate;
+
+ final VarForm vform;
+
+ VarHandle(VarForm vform, Class<?> receiver, Class<?> value, Class<?>... intermediate) {
+ this.vform = vform;
+
+ // (Receiver, <Intermediates>)
+ List<Class<?>> l = new ArrayList<>();
+ if (receiver != null)
+ l.add(receiver);
+ l.addAll(Arrays.asList(intermediate));
+
+ // (Receiver, <Intermediates>)Value
+ this.typeGet = MethodType.methodType(value, l);
+
+ // (Receiver, <Intermediates>, Value)void
+ l.add(value);
+ this.typeSet = MethodType.methodType(void.class, l);
+
+ // (Receiver, <Intermediates>, Value)Value
+ this.typeGetAndUpdate = MethodType.methodType(value, l);
+
+ // (Receiver, <Intermediates>, Value, Value)boolean
+ l.add(value);
+ this.typeCompareSwap = MethodType.methodType(boolean.class, l);
+
+ // (Receiver, <Intermediates>, Value, Value)Value
+ this.typeCompareExchange = MethodType.methodType(value, l);
+ }
+
+ RuntimeException unsupported() {
+ return new UnsupportedOperationException();
+ }
+
+ // Plain accessors
+
+ /**
+ * Returns the value of a variable, with memory semantics of reading as
+ * if the variable was declared non-{@code volatile}. Commonly referred to
+ * as plain read access.
+ *
+ * <p>The method signature is of the form {@code (CT)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code get}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.get)} on this VarHandle.
+ *
+ * <p>This access mode is supported by all VarHandle instances and never
+ * throws {@code UnsupportedOperationException}.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object get(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, with memory
+ * semantics of setting as if the variable was declared non-{@code volatile}
+ * and non-{@code final}. Commonly referred to as plain write access.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)void}
+ *
+ * <p>The symbolic type descriptor at the call site of {@code set}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.set)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ void set(Object... args);
+
+
+ // Volatile accessors
+
+ /**
+ * Returns the value of a variable, with memory semantics of reading as if
+ * the variable was declared {@code volatile}.
+ *
+ * <p>The method signature is of the form {@code (CT)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getVolatile}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getVolatile)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getVolatile(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, with memory
+ * semantics of setting as if the variable was declared {@code volatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setVolatile}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.setVolatile)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code memory_order_seq_cst}.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ void setVolatile(Object... args);
+
+
+ /**
+ * Returns the value of a variable, accessed in program order, but with no
+ * assurance of memory ordering effects with respect to other threads.
+ *
+ * <p>The method signature is of the form {@code (CT)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getOpaque}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getOpaque)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getOpaque(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, in program order,
+ * but with no assurance of memory ordering effects with respect to other
+ * threads.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setOpaque}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.setOpaque)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ void setOpaque(Object... args);
+
+
+ // Lazy accessors
+
+ /**
+ * Returns the value of a variable, and ensures that subsequent loads and
+ * stores are not reordered before this access.
+ *
+ * <p>The method signature is of the form {@code (CT)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getAcquire)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the value of the
+ * variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code memory_order_acquire} ordering.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getAcquire(Object... args);
+
+ /**
+ * Sets the value of a variable to the {@code newValue}, and ensures that
+ * prior loads and stores are not reordered after this access.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)void}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code setRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.setRelease)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code memory_order_release} ordering.
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ void setRelease(Object... args);
+
+
+ // Compare and set accessors
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndSet} must match the access mode type that is the result of
+ * calling {@code accessModeType(VarHandle.AccessMode.compareAndSet)} on
+ * this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ boolean compareAndSet(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchangeVolatile}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeVolatile)}
+ * on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object compareAndExchangeVolatile(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchangeAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeAcquire)} on
+ * this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object compareAndExchangeAcquire(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setRelease} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * compareAndExchangeRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.compareAndExchangeRelease)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the witness value, which
+ * will be the same as the {@code expectedValue} if successful
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object compareAndExchangeRelease(Object... args);
+
+ // Weak (spurious failures allowed)
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the current value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSet} must match the access mode type that is the result of
+ * calling {@code accessModeType(VarHandle.AccessMode.weakCompareAndSet)} on
+ * this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #set(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSet(Object... args);
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #set} if the variable's current value,
+ * referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #getAcquire}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the current value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSetAcquire}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetAcquire)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #set(Object...)
+ * @see #getAcquire(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSetAcquire(Object... args);
+
+ /**
+ * Possibly atomically sets the value of a variable to the {@code newValue}
+ * with the semantics of {@link #setRelease} if the variable's current
+ * value, referred to as the <em>witness value</em>, {@code ==} the
+ * {@code expectedValue}, as accessed with the memory semantics of
+ * {@link #get}.
+ *
+ * <p>This operation may fail spuriously (typically, due to memory
+ * contention) even if the current value does match the expected value.
+ *
+ * <p>The method signature is of the form {@code (CT, T expectedValue, T newValue)boolean}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code
+ * weakCompareAndSetRelease}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.weakCompareAndSetRelease)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T expectedValue, T newValue)}
+ * , statically represented using varargs.
+ * @return {@code true} if successful, otherwise {@code false} if the
+ * witness value was not the same as the {@code expectedValue} or if this
+ * operation spuriously failed.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setRelease(Object...)
+ * @see #get(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ boolean weakCompareAndSetRelease(Object... args);
+
+ /**
+ * Atomically sets the value of a variable to the {@code newValue} with the
+ * memory semantics of {@link #setVolatile} and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T newValue)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndSet}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getAndSet)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T newValue)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getAndSet(Object... args);
+
+
+ // Primitive adders
+ // Throw UnsupportedOperationException for refs
+
+ /**
+ * Atomically adds the {@code value} to the current value of a variable with
+ * the memory semantics of {@link #setVolatile}, and returns the variable's
+ * previous value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T value)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code getAndAdd}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.getAndAdd)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T value)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the previous value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object getAndAdd(Object... args);
+
+ /**
+ * Atomically adds the {@code value} to the current value of a variable with
+ * the memory semantics of {@link #setVolatile}, and returns the variable's
+ * current (updated) value, as accessed with the memory semantics of
+ * {@link #getVolatile}.
+ *
+ * <p>The method signature is of the form {@code (CT, T value)T}.
+ *
+ * <p>The symbolic type descriptor at the call site of {@code addAndGet}
+ * must match the access mode type that is the result of calling
+ * {@code accessModeType(VarHandle.AccessMode.addAndGet)} on this VarHandle.
+ *
+ * @param args the signature-polymorphic parameter list of the form
+ * {@code (CT, T value)}
+ * , statically represented using varargs.
+ * @return the signature-polymorphic result that is the current value of
+ * the variable
+ * , statically represented using {@code Object}.
+ * @throws UnsupportedOperationException if the access mode is unsupported
+ * for this VarHandle.
+ * @throws WrongMethodTypeException if the access mode type is not
+ * compatible with the caller's symbolic type descriptor.
+ * @see #setVolatile(Object...)
+ * @see #getVolatile(Object...)
+ */
+ public final native
+ @MethodHandle.PolymorphicSignature
+ @HotSpotIntrinsicCandidate
+ Object addAndGet(Object... args);
+
+ enum AccessType {
+ get, // 0
+ set, // 1
+ compareAndSwap, // 2
+ compareAndExchange, // 3
+ getAndUpdate; // 4
+
+ MethodType getMethodType(VarHandle vh) {
+ return getMethodType(this.ordinal(), vh);
+ }
+
+ @ForceInline
+ static MethodType getMethodType(int ordinal, VarHandle vh) {
+ if (ordinal == 0) {
+ return vh.typeGet;
+ }
+ else if (ordinal == 1) {
+ return vh.typeSet;
+ }
+ else if (ordinal == 2) {
+ return vh.typeCompareSwap;
+ }
+ else if (ordinal == 3) {
+ return vh.typeCompareExchange;
+ }
+ else if (ordinal == 4) {
+ return vh.typeGetAndUpdate;
+ }
+ else {
+ throw new IllegalStateException("Illegal access type: " + ordinal);
+ }
+ }
+ }
+
+ /**
+ * The set of access modes that specify how a variable, referenced by a
+ * VarHandle, is accessed.
+ */
+ public enum AccessMode {
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#get VarHandle.get}
+ */
+ get(AccessType.get, Object.class), // 0
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#set VarHandle.set}
+ */
+ set(AccessType.set, void.class), // 1
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getVolatile VarHandle.getVolatile}
+ */
+ getVolatile(AccessType.get, Object.class), // 2
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setVolatile VarHandle.setVolatile}
+ */
+ setVolatile(AccessType.set, void.class), // 3
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAcquire VarHandle.getAcquire}
+ */
+ getAcquire(AccessType.get, Object.class), // 4
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setRelease VarHandle.setRelease}
+ */
+ setRelease(AccessType.set, void.class), // 5
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getOpaque VarHandle.getOpaque}
+ */
+ getOpaque(AccessType.get, Object.class), // 6
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#setOpaque VarHandle.setOpaque}
+ */
+ setOpaque(AccessType.set, void.class), // 7
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndSet VarHandle.compareAndSet}
+ */
+ compareAndSet(AccessType.compareAndSwap, boolean.class), // 8
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchangeVolatile VarHandle.compareAndExchangeVolatile}
+ */
+ compareAndExchangeVolatile(AccessType.compareAndExchange, Object.class), // 9
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchangeAcquire VarHandle.compareAndExchangeAcquire}
+ */
+ compareAndExchangeAcquire(AccessType.compareAndExchange, Object.class), // 10
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#compareAndExchangeRelease VarHandle.compareAndExchangeRelease}
+ */
+ compareAndExchangeRelease(AccessType.compareAndExchange, Object.class), // 11
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSet VarHandle.weakCompareAndSet}
+ */
+ weakCompareAndSet(AccessType.compareAndSwap, boolean.class), // 12
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSetAcquire VarHandle.weakCompareAndSetAcquire}
+ */
+ weakCompareAndSetAcquire(AccessType.compareAndSwap, boolean.class), // 13
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#weakCompareAndSetRelease VarHandle.weakCompareAndSetRelease}
+ */
+ weakCompareAndSetRelease(AccessType.compareAndSwap, boolean.class), // 14
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndSet VarHandle.getAndSet}
+ */
+ getAndSet(AccessType.getAndUpdate, Object.class), // 15
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#getAndAdd VarHandle.getAndAdd}
+ */
+ getAndAdd(AccessType.getAndUpdate, Object.class), // 16
+ /**
+ * The access mode whose access is specified by the corresponding
+ * method
+ * {@link VarHandle#addAndGet VarHandle.addAndGet}
+ */
+ addAndGet(AccessType.getAndUpdate, Object.class), // 17
+ ;
+
+ final AccessType at;
+ final boolean isPolyMorphicInReturnType;
+ final Class<?> returnType;
+
+ AccessMode(AccessType at, Class<?> returnType) {
+ this.at = at;
+
+ // Assert that return type is correct
+ // Otherwise, when disabled avoid using reflection
+ assert returnType == getReturnType(name());
+
+ this.returnType = returnType;
+ isPolyMorphicInReturnType = returnType != Object.class;
+ }
+
+ private static Class<?> getReturnType(String name) {
+ try {
+ Method m = VarHandle.class.getMethod(name, Object[].class);
+ return m.getReturnType();
+ }
+ catch (Exception e) {
+ throw newInternalError(e);
+ }
+ }
+
+ @ForceInline
+ static MemberName getMemberName(int ordinal, VarForm vform) {
+ if (ordinal == 0) {
+ return vform.mbGet;
+ }
+ else if (ordinal == 1) {
+ return vform.mbSet;
+ }
+ else if (ordinal == 2) {
+ return vform.mbGetVolatile;
+ }
+ else if (ordinal == 3) {
+ return vform.mbSetVolatile;
+ }
+ else if (ordinal == 4) {
+ return vform.mbGetAcquire;
+ }
+ else if (ordinal == 5) {
+ return vform.mbSetRelease;
+ }
+ else if (ordinal == 6) {
+ return vform.mbGetOpaque;
+ }
+ else if (ordinal == 7) {
+ return vform.mbSetOpaque;
+ }
+ else if (ordinal == 8) {
+ return vform.mbCompareAndSet;
+ }
+ else if (ordinal == 9) {
+ return vform.mbCompareAndExchangeVolatile;
+ }
+ else if (ordinal == 10) {
+ return vform.mbCompareAndExchangeAcquire;
+ }
+ else if (ordinal == 11) {
+ return vform.mbCompareAndExchangeRelease;
+ }
+ else if (ordinal == 12) {
+ return vform.mbWeakCompareAndSet;
+ }
+ else if (ordinal == 13) {
+ return vform.mbWeakCompareAndSetAcquire;
+ }
+ else if (ordinal == 14) {
+ return vform.mbWeakCompareAndSetRelease;
+ }
+ else if (ordinal == 15) {
+ return vform.mbGetAndSet;
+ }
+ else if (ordinal == 16) {
+ return vform.mbGetAndAdd;
+ }
+ else if (ordinal == 17) {
+ return vform.mbAddAndGet;
+ }
+ else {
+ throw new IllegalStateException("Illegal access mode: " + ordinal);
+ }
+ }
+ }
+
+ static final class AccessDescriptor {
+ final MethodType symbolicMethodType;
+ final int type;
+ final int mode;
+
+ public AccessDescriptor(MethodType symbolicMethodType, int type, int mode) {
+ this.symbolicMethodType = symbolicMethodType;
+ this.type = type;
+ this.mode = mode;
+ }
+ }
+
+ /**
+ * Returns the variable type of variables referenced by this VarHandle.
+ *
+ * @return the variable type of variables referenced by this VarHandle
+ */
+ public final Class<?> varType() {
+ return typeSet.parameterType(typeSet.parameterCount() - 1);
+ }
+
+ /**
+ * Returns the coordinate types for this VarHandle.
+ *
+ * @return the coordinate types for this VarHandle. The returned
+ * list is unmodifiable
+ */
+ public final List<Class<?>> coordinateTypes() {
+ return typeGet.parameterList();
+ }
+
+ /**
+ * Obtains the canonical access mode type for this VarHandle and a given
+ * access mode.
+ *
+ * <p>The access mode type's parameter types will consist of a prefix that
+ * is the coordinate types of this VarHandle followed by further
+ * types as defined by the access mode's method.
+ * The access mode type's return type is defined by the return type of the
+ * access mode's method.
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return the access mode type for the given access mode
+ */
+ public final MethodType accessModeType(AccessMode accessMode) {
+ return accessMode.at.getMethodType(this);
+ }
+
+
+ /**
+ * Returns {@code true} if the given access mode is supported, otherwise
+ * {@code false}.
+ *
+ * <p>The return of a {@code false} value for a given access mode indicates
+ * that an {@code UnsupportedOperationException} is thrown on invocation
+ * of the corresponding access mode's signature-polymorphic method.
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return {@code true} if the given access mode is supported, otherwise
+ * {@code false}.
+ */
+ public final boolean isAccessModeSupported(AccessMode accessMode) {
+ return AccessMode.getMemberName(accessMode.ordinal(), vform) != null;
+ }
+
+ /**
+ * Obtains a method handle bound to this VarHandle and the given access
+ * mode.
+ *
+ * @apiNote This method, for a VarHandle {@code vh} and access mode
+ * {@code {access-mode}}, returns a method handle that is equivalent to
+ * method handle {@code bhm} in the following code (though it may be more
+ * efficient):
+ * <pre>{@code
+ * MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ * vh.accessModeType(VarHandle.AccessMode.{access-mode}));
+ *
+ * MethodHandle bmh = mh.bindTo(vh);
+ * }</pre>
+ *
+ * @param accessMode the access mode, corresponding to the
+ * signature-polymorphic method of the same name
+ * @return a method handle bound to this VarHandle and the given access mode
+ */
+ public final MethodHandle toMethodHandle(AccessMode accessMode) {
+ MemberName mn = AccessMode.getMemberName(accessMode.ordinal(), vform);
+ if (mn != null) {
+ return DirectMethodHandle.make(mn).
+ bindTo(this).
+ asType(accessMode.at.getMethodType(this));
+ }
+ else {
+ // Ensure an UnsupportedOperationException is thrown
+ return MethodHandles.varHandleInvoker(accessMode, accessModeType(accessMode)).
+ bindTo(this);
+ }
+ }
+
+ /*non-public*/
+ final void updateVarForm(VarForm newVForm) {
+ if (vform == newVForm) return;
+ UNSAFE.putObject(this, VFORM_OFFSET, newVForm);
+ UNSAFE.fullFence();
+ }
+
+ static final BiFunction<Integer, Integer, ArrayIndexOutOfBoundsException> AIOOBE_SUPPLIER = new BiFunction<>() {
+ @Override
+ public ArrayIndexOutOfBoundsException apply(Integer a, Integer b) {
+ return new ArrayIndexOutOfBoundsException(a, b);
+ }
+ };
+
+ private static final long VFORM_OFFSET;
+
+ static {
+ try {
+ VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class.getDeclaredField("vform"));
+ }
+ catch (ReflectiveOperationException e) {
+ throw newInternalError(e);
+ }
+ }
+
+
+ // Fence methods
+
+ /**
+ * Ensures that loads and stores before the fence will not be reordered
+ * with
+ * loads and stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_seq_cst)}
+ */
+ @ForceInline
+ public static void fullFence() {
+ UNSAFE.fullFence();
+ }
+
+ /**
+ * Ensures that loads before the fence will not be reordered with loads and
+ * stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_acquire)}
+ */
+ @ForceInline
+ public static void acquireFence() {
+ UNSAFE.loadFence();
+ }
+
+ /**
+ * Ensures that loads and stores before the fence will not be
+ * reordered with stores after the fence.
+ *
+ * @apiNote Ignoring the many semantic differences from C and C++, this
+ * method has memory ordering effects compatible with
+ * {@code atomic_thread_fence(memory_order_release)}
+ */
+ @ForceInline
+ public static void releaseFence() {
+ UNSAFE.storeFence();
+ }
+
+ /**
+ * Ensures that loads before the fence will not be reordered with
+ * loads after the fence.
+ */
+ @ForceInline
+ public static void loadLoadFence() {
+ UNSAFE.loadLoadFence();
+ }
+
+ /**
+ * Ensures that stores before the fence will not be reordered with
+ * stores after the fence.
+ */
+ @ForceInline
+ public static void storeStoreFence() {
+ UNSAFE.storeStoreFence();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, 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 java.nio.Buffer;
+import java.nio.ByteBuffer;
+
+import static java.lang.invoke.MethodHandleStatics.UNSAFE;
+
+/**
+ * The base class for generated byte array and byte buffer view
+ * implementations
+ */
+abstract class VarHandleByteArrayBase {
+ // Buffer.address
+ static final long BUFFER_ADDRESS;
+ // Buffer.limit
+ static final long BUFFER_LIMIT;
+ // ByteBuffer.hb
+ static final long BYTE_BUFFER_HB;
+ // ByteBuffer.isReadOnly
+ static final long BYTE_BUFFER_IS_READ_ONLY;
+
+ static {
+ try {
+ BUFFER_ADDRESS = UNSAFE.objectFieldOffset(
+ Buffer.class.getDeclaredField("address"));
+
+ BUFFER_LIMIT = UNSAFE.objectFieldOffset(
+ Buffer.class.getDeclaredField("limit"));
+
+ BYTE_BUFFER_HB = UNSAFE.objectFieldOffset(
+ ByteBuffer.class.getDeclaredField("hb"));
+
+ BYTE_BUFFER_IS_READ_ONLY = UNSAFE.objectFieldOffset(
+ ByteBuffer.class.getDeclaredField("isReadOnly"));
+ }
+ catch (ReflectiveOperationException e) {
+ throw new Error(e);
+ }
+ }
+
+ static final boolean BE = UNSAFE.isBigEndian();
+
+ static IllegalStateException newIllegalStateExceptionForMisalignedAccess(int index) {
+ return new IllegalStateException("Misaligned access at index: " + index);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandleGuards.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,1391 @@
+/*
+ * Copyright (c) 2014, 2016, 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 jdk.internal.vm.annotation.ForceInline;
+
+// This class is auto-generated by java.lang.invoke.VarHandles$GuardMethodGenerator. Do not edit.
+final class VarHandleGuards {
+
+ @ForceInline
+ final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {
+ MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);
+ if (mn == null) {
+ throw handle.unsupported();
+ }
+ return mn;
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_L_L(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LL_V(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LL_L(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LLL_Z(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LLL_L(VarHandle handle, Object arg0, Object arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_L_I(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LI_V(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LI_I(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LII_Z(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LII_I(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_L_J(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LJ_V(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LJ_J(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_L_F(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LF_V(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LF_F(VarHandle handle, Object arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LFF_Z(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LFF_F(VarHandle handle, Object arg0, float arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_L_D(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LD_V(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LD_D(VarHandle handle, Object arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LDD_Z(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LDD_D(VarHandle handle, Object arg0, double arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard__L(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_L_V(VarHandle handle, Object arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LL_Z(VarHandle handle, Object arg0, Object arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard__I(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_I_V(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_I_I(VarHandle handle, int arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_II_Z(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_II_I(VarHandle handle, int arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard__J(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_J_V(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_J_J(VarHandle handle, long arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_JJ_Z(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_JJ_J(VarHandle handle, long arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard__F(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_F_V(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_F_F(VarHandle handle, float arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_FF_Z(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_FF_F(VarHandle handle, float arg0, float arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard__D(VarHandle handle, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_D_V(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_D_D(VarHandle handle, double arg0, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_DD_Z(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_DD_D(VarHandle handle, double arg0, double arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LI_L(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LIL_V(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LIL_L(VarHandle handle, Object arg0, int arg1, Object arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LILL_Z(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static Object guard_LILL_L(VarHandle handle, Object arg0, int arg1, Object arg2, Object arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ Object r = MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ return symbolic.returnType().cast(r);
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LII_V(VarHandle handle, Object arg0, int arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LIII_Z(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LIII_I(VarHandle handle, Object arg0, int arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LI_J(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LIJ_V(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LIJ_J(VarHandle handle, Object arg0, int arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LIJJ_Z(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LIJJ_J(VarHandle handle, Object arg0, int arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LI_F(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LIF_V(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LIF_F(VarHandle handle, Object arg0, int arg1, float arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LIFF_Z(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static float guard_LIFF_F(VarHandle handle, Object arg0, int arg1, float arg2, float arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (float) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (float) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LI_D(VarHandle handle, Object arg0, int arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LID_V(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LID_D(VarHandle handle, Object arg0, int arg1, double arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LIDD_Z(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static double guard_LIDD_D(VarHandle handle, Object arg0, int arg1, double arg2, double arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (double) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (double) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LJ_I(VarHandle handle, Object arg0, long arg1, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LJI_V(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LJI_I(VarHandle handle, Object arg0, long arg1, int arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LJII_Z(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static int guard_LJII_I(VarHandle handle, Object arg0, long arg1, int arg2, int arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (int) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (int) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static void guard_LJJ_V(VarHandle handle, Object arg0, long arg1, long arg2, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ MethodHandle.linkToStatic(handle, arg0, arg1, arg2, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ vh_invoker.invokeBasic(handle, arg0, arg1, arg2);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static boolean guard_LJJJ_Z(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (boolean) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (boolean) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+ @ForceInline
+ @LambdaForm.Compiled
+ final static long guard_LJJJ_J(VarHandle handle, Object arg0, long arg1, long arg2, long arg3, VarHandle.AccessDescriptor ad) throws Throwable {
+ MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);
+ MethodType symbolic = ad.symbolicMethodType;
+ if (target == symbolic) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else if (target.erase() == symbolic.erase()) {
+ return (long) MethodHandle.linkToStatic(handle, arg0, arg1, arg2, arg3, getMemberName(handle, ad));
+ }
+ else {
+ MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);
+ return (long) vh_invoker.invokeBasic(handle, arg0, arg1, arg2, arg3);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandles.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2014, 2016, 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 static java.lang.invoke.MethodHandleStatics.UNSAFE;
+
+final class VarHandles {
+
+ static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) {
+ if (!f.isStatic()) {
+ long foffset = MethodHandleNatives.objectFieldOffset(f);
+ if (!type.isPrimitive()) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleObjects.FieldInstanceReadOnly(refc, foffset, type)
+ : new VarHandleObjects.FieldInstanceReadWrite(refc, foffset, type);
+ }
+ else if (type == boolean.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == byte.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == short.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleShorts.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleShorts.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == char.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleChars.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleChars.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == int.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleInts.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleInts.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == long.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleLongs.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleLongs.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == float.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleFloats.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleFloats.FieldInstanceReadWrite(refc, foffset);
+ }
+ else if (type == double.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleDoubles.FieldInstanceReadOnly(refc, foffset)
+ : new VarHandleDoubles.FieldInstanceReadWrite(refc, foffset);
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ else {
+ // TODO This is not lazy on first invocation
+ // and might cause some circular initialization issues
+
+ // Replace with something similar to direct method handles
+ // where a barrier is used then elided after use
+
+ if (UNSAFE.shouldBeInitialized(refc))
+ UNSAFE.ensureClassInitialized(refc);
+
+ Object base = MethodHandleNatives.staticFieldBase(f);
+ long foffset = MethodHandleNatives.staticFieldOffset(f);
+ if (!type.isPrimitive()) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleObjects.FieldStaticReadOnly(base, foffset, type)
+ : new VarHandleObjects.FieldStaticReadWrite(base, foffset, type);
+ }
+ else if (type == boolean.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset)
+ : new VarHandleBooleans.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == byte.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleBytes.FieldStaticReadOnly(base, foffset)
+ : new VarHandleBytes.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == short.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleShorts.FieldStaticReadOnly(base, foffset)
+ : new VarHandleShorts.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == char.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleChars.FieldStaticReadOnly(base, foffset)
+ : new VarHandleChars.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == int.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleInts.FieldStaticReadOnly(base, foffset)
+ : new VarHandleInts.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == long.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleLongs.FieldStaticReadOnly(base, foffset)
+ : new VarHandleLongs.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == float.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleFloats.FieldStaticReadOnly(base, foffset)
+ : new VarHandleFloats.FieldStaticReadWrite(base, foffset);
+ }
+ else if (type == double.class) {
+ return f.isFinal() && !isWriteAllowedOnFinalFields
+ ? new VarHandleDoubles.FieldStaticReadOnly(base, foffset)
+ : new VarHandleDoubles.FieldStaticReadWrite(base, foffset);
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ static VarHandle makeArrayElementHandle(Class<?> arrayClass) {
+ if (!arrayClass.isArray())
+ throw new IllegalArgumentException("not an array: " + arrayClass);
+
+ Class<?> componentType = arrayClass.getComponentType();
+
+ int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
+ int ascale = UNSAFE.arrayIndexScale(arrayClass);
+ int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
+
+ if (!componentType.isPrimitive()) {
+ return new VarHandleObjects.Array(aoffset, ashift, arrayClass);
+ }
+ else if (componentType == boolean.class) {
+ return new VarHandleBooleans.Array(aoffset, ashift);
+ }
+ else if (componentType == byte.class) {
+ return new VarHandleBytes.Array(aoffset, ashift);
+ }
+ else if (componentType == short.class) {
+ return new VarHandleShorts.Array(aoffset, ashift);
+ }
+ else if (componentType == char.class) {
+ return new VarHandleChars.Array(aoffset, ashift);
+ }
+ else if (componentType == int.class) {
+ return new VarHandleInts.Array(aoffset, ashift);
+ }
+ else if (componentType == long.class) {
+ return new VarHandleLongs.Array(aoffset, ashift);
+ }
+ else if (componentType == float.class) {
+ return new VarHandleFloats.Array(aoffset, ashift);
+ }
+ else if (componentType == double.class) {
+ return new VarHandleDoubles.Array(aoffset, ashift);
+ }
+ else {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ static VarHandle byteArrayViewHandle(Class<?> viewArrayClass,
+ boolean be) {
+ if (!viewArrayClass.isArray())
+ throw new IllegalArgumentException("not an array: " + viewArrayClass);
+
+ Class<?> viewComponentType = viewArrayClass.getComponentType();
+
+ if (viewComponentType == long.class) {
+ return new VarHandleByteArrayAsLongs.ArrayHandle(be);
+ }
+ else if (viewComponentType == int.class) {
+ return new VarHandleByteArrayAsInts.ArrayHandle(be);
+ }
+ else if (viewComponentType == short.class) {
+ return new VarHandleByteArrayAsShorts.ArrayHandle(be);
+ }
+ else if (viewComponentType == char.class) {
+ return new VarHandleByteArrayAsChars.ArrayHandle(be);
+ }
+ else if (viewComponentType == double.class) {
+ return new VarHandleByteArrayAsDoubles.ArrayHandle(be);
+ }
+ else if (viewComponentType == float.class) {
+ return new VarHandleByteArrayAsFloats.ArrayHandle(be);
+ }
+
+ throw new UnsupportedOperationException();
+ }
+
+ static VarHandle makeByteBufferViewHandle(Class<?> viewArrayClass,
+ boolean be) {
+ if (!viewArrayClass.isArray())
+ throw new IllegalArgumentException("not an array: " + viewArrayClass);
+
+ Class<?> viewComponentType = viewArrayClass.getComponentType();
+
+ if (viewComponentType == long.class) {
+ return new VarHandleByteArrayAsLongs.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == int.class) {
+ return new VarHandleByteArrayAsInts.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == short.class) {
+ return new VarHandleByteArrayAsShorts.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == char.class) {
+ return new VarHandleByteArrayAsChars.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == double.class) {
+ return new VarHandleByteArrayAsDoubles.ByteBufferHandle(be);
+ }
+ else if (viewComponentType == float.class) {
+ return new VarHandleByteArrayAsFloats.ByteBufferHandle(be);
+ }
+
+ throw new UnsupportedOperationException();
+ }
+
+// /**
+// * A helper program to generate the VarHandleGuards class with a set of
+// * static guard methods each of which corresponds to a particular shape and
+// * performs a type check of the symbolic type descriptor with the VarHandle
+// * type descriptor before linking/invoking to the underlying operation as
+// * characterized by the operation member name on the VarForm of the
+// * VarHandle.
+// * <p>
+// * The generated class essentially encapsulates pre-compiled LambdaForms,
+// * one for each method, for the most set of common method signatures.
+// * This reduces static initialization costs, footprint costs, and circular
+// * dependencies that may arise if a class is generated per LambdaForm.
+// * <p>
+// * A maximum of L*T*S methods will be generated where L is the number of
+// * access modes kinds (or unique operation signatures) and T is the number
+// * of variable types and S is the number of shapes (such as instance field,
+// * static field, or array access).
+// * If there are 4 unique operation signatures, 5 basic types (Object, int,
+// * long, float, double), and 3 shapes then a maximum of 60 methods will be
+// * generated. However, the number is likely to be less since there
+// * be duplicate signatures.
+// * <p>
+// * Each method is annotated with @LambdaForm.Compiled to inform the runtime
+// * that such methods should be treated as if a method of a class that is the
+// * result of compiling a LambdaForm. Annotation of such methods is
+// * important for correct evaluation of certain assertions and method return
+// * type profiling in HotSpot.
+// */
+// public static class GuardMethodGenerator {
+//
+// static final String GUARD_METHOD_SIG_TEMPLATE = "<RETURN> <NAME>_<SIGNATURE>(<PARAMS>)";
+//
+// static final String GUARD_METHOD_TEMPLATE =
+// "@ForceInline\n" +
+// "@LambdaForm.Compiled\n" +
+// "final static <METHOD> throws Throwable {\n" +
+// " MethodType target = VarHandle.AccessType.getMethodType(ad.type, handle);\n" +
+// " MethodType symbolic = ad.symbolicMethodType;\n" +
+// " if (target == symbolic) {\n" +
+// " <RETURN>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);\n" +
+// " }\n" +
+// " else if (target.erase() == symbolic.erase()) {\n" +
+// " <RESULT_ERASED>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);<RETURN_ERASED>\n" +
+// " }\n" +
+// " else {\n" +
+// " MethodHandle vh_invoker = MethodHandles.varHandleInvoker(VarHandle.AccessMode.values()[ad.mode], symbolic);\n" +
+// " <RETURN>vh_invoker.invokeBasic(<LINK_TO_INVOKER_ARGS>);\n" +
+// " }\n" +
+// "}";
+//
+// static final String GET_MEMBER_NAME_METHOD =
+// "@ForceInline\n" +
+// "final static MemberName getMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) {\n" +
+// " MemberName mn = VarHandle.AccessMode.getMemberName(ad.mode, handle.vform);\n" +
+// " if (mn == null) {\n" +
+// " throw handle.unsupported();\n" +
+// " }\n" +
+// " return mn;\n" +
+// "}";
+//
+// // A template for deriving the operations
+// // could be supported by annotating VarHandle directly with the
+// // operation kind and shape
+// interface VarHandleTemplate {
+// Object get();
+//
+// void set(Object value);
+//
+// boolean compareAndSwap(Object actualValue, Object expectedValue);
+//
+// Object compareAndExchange(Object actualValue, Object expectedValue);
+//
+// Object getAndUpdate(Object value);
+// }
+//
+// static class HandleType {
+// final Class<?> receiver;
+// final Class<?>[] intermediates;
+// final Class<?> value;
+//
+// HandleType(Class<?> receiver, Class<?> value, Class<?>... intermediates) {
+// this.receiver = receiver;
+// this.intermediates = intermediates;
+// this.value = value;
+// }
+// }
+//
+// /**
+// * @param args parameters
+// */
+// public static void main(String[] args) {
+// System.out.println("package java.lang.invoke;");
+// System.out.println();
+// System.out.println("import jdk.internal.vm.annotation.ForceInline;");
+// System.out.println();
+// System.out.println("// This class is auto-generated by " +
+// GuardMethodGenerator.class.getName() +
+// ". Do not edit.");
+// System.out.println("final class VarHandleGuards {");
+//
+// System.out.println();
+// System.out.println(GET_MEMBER_NAME_METHOD);
+// System.out.println();
+//
+// // Declare the stream of shapes
+// Stream<HandleType> hts = Stream.of(
+// // Object->Object
+// new HandleType(Object.class, Object.class),
+// // Object->int
+// new HandleType(Object.class, int.class),
+// // Object->long
+// new HandleType(Object.class, long.class),
+// // Object->float
+// new HandleType(Object.class, float.class),
+// // Object->double
+// new HandleType(Object.class, double.class),
+//
+// // <static>->Object
+// new HandleType(null, Object.class),
+// // <static>->int
+// new HandleType(null, int.class),
+// // <static>->long
+// new HandleType(null, long.class),
+// // <static>->float
+// new HandleType(null, float.class),
+// // <static>->double
+// new HandleType(null, double.class),
+//
+// // Array[int]->Object
+// new HandleType(Object.class, Object.class, int.class),
+// // Array[int]->int
+// new HandleType(Object.class, int.class, int.class),
+// // Array[int]->long
+// new HandleType(Object.class, long.class, int.class),
+// // Array[int]->float
+// new HandleType(Object.class, float.class, int.class),
+// // Array[int]->double
+// new HandleType(Object.class, double.class, int.class),
+//
+// // Array[long]->int
+// new HandleType(Object.class, int.class, long.class),
+// // Array[long]->long
+// new HandleType(Object.class, long.class, long.class)
+// );
+//
+// hts.flatMap(ht -> Stream.of(VarHandleTemplate.class.getMethods()).
+// map(m -> generateMethodType(m, ht.receiver, ht.value, ht.intermediates))).
+// distinct().
+// map(mt -> generateMethod(mt)).
+// forEach(s -> {
+// System.out.println(s);
+// System.out.println();
+// });
+//
+// System.out.println("}");
+// }
+//
+// static MethodType generateMethodType(Method m, Class<?> receiver, Class<?> value, Class<?>... intermediates) {
+// Class<?> returnType = m.getReturnType() == Object.class
+// ? value : m.getReturnType();
+//
+// List<Class<?>> params = new ArrayList<>();
+// if (receiver != null)
+// params.add(receiver);
+// for (int i = 0; i < intermediates.length; i++) {
+// params.add(intermediates[i]);
+// }
+// for (Parameter p : m.getParameters()) {
+// params.add(value);
+// }
+// return MethodType.methodType(returnType, params);
+// }
+//
+// static String generateMethod(MethodType mt) {
+// Class<?> returnType = mt.returnType();
+//
+// LinkedHashMap<String, Class<?>> params = new LinkedHashMap<>();
+// params.put("handle", VarHandle.class);
+// for (int i = 0; i < mt.parameterCount(); i++) {
+// params.put("arg" + i, mt.parameterType(i));
+// }
+// params.put("ad", VarHandle.AccessDescriptor.class);
+//
+// // Generate method signature line
+// String RETURN = className(returnType);
+// String NAME = "guard";
+// String SIGNATURE = getSignature(mt);
+// String PARAMS = params.entrySet().stream().
+// map(e -> className(e.getValue()) + " " + e.getKey()).
+// collect(joining(", "));
+// String METHOD = GUARD_METHOD_SIG_TEMPLATE.
+// replace("<RETURN>", RETURN).
+// replace("<NAME>", NAME).
+// replace("<SIGNATURE>", SIGNATURE).
+// replace("<PARAMS>", PARAMS);
+//
+// // Generate method
+// params.remove("ad");
+//
+// List<String> LINK_TO_STATIC_ARGS = params.keySet().stream().
+// collect(toList());
+// LINK_TO_STATIC_ARGS.add("getMemberName(handle, ad)");
+//
+// List<String> LINK_TO_INVOKER_ARGS = params.keySet().stream().
+// collect(toList());
+//
+// RETURN = returnType == void.class
+// ? ""
+// : returnType == Object.class
+// ? "return "
+// : "return (" + returnType.getName() + ") ";
+//
+// String RESULT_ERASED = returnType == void.class
+// ? ""
+// : returnType != Object.class
+// ? "return (" + returnType.getName() + ") "
+// : "Object r = ";
+//
+// String RETURN_ERASED = returnType != Object.class
+// ? ""
+// : " return symbolic.returnType().cast(r);";
+//
+// return GUARD_METHOD_TEMPLATE.
+// replace("<METHOD>", METHOD).
+// replace("<NAME>", NAME).
+// replaceAll("<RETURN>", RETURN).
+// replace("<RESULT_ERASED>", RESULT_ERASED).
+// replace("<RETURN_ERASED>", RETURN_ERASED).
+// replaceAll("<LINK_TO_STATIC_ARGS>", LINK_TO_STATIC_ARGS.stream().
+// collect(joining(", "))).
+// replace("<LINK_TO_INVOKER_ARGS>", LINK_TO_INVOKER_ARGS.stream().
+// collect(joining(", ")))
+// ;
+// }
+//
+// static String className(Class<?> c) {
+// String n = c.getName();
+// if (n.startsWith("java.lang.")) {
+// n = n.replace("java.lang.", "");
+// if (n.startsWith("invoke.")) {
+// n = n.replace("invoke.", "");
+// }
+// }
+// return n.replace('$', '.');
+// }
+//
+// static String getSignature(MethodType m) {
+// StringBuilder sb = new StringBuilder(m.parameterCount() + 1);
+//
+// for (int i = 0; i < m.parameterCount(); i++) {
+// Class<?> pt = m.parameterType(i);
+// sb.append(getCharType(pt));
+// }
+//
+// sb.append('_').append(getCharType(m.returnType()));
+//
+// return sb.toString();
+// }
+//
+// static char getCharType(Class<?> pt) {
+// if (pt == void.class) {
+// return 'V';
+// }
+// else if (!pt.isPrimitive()) {
+// return 'L';
+// }
+// else if (pt == boolean.class) {
+// return 'Z';
+// }
+// else if (pt == int.class) {
+// return 'I';
+// }
+// else if (pt == long.class) {
+// return 'J';
+// }
+// else if (pt == float.class) {
+// return 'F';
+// }
+// else if (pt == double.class) {
+// return 'D';
+// }
+// else {
+// throw new IllegalStateException(pt.getName());
+// }
+// }
+// }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,602 @@
+/*
+ * Copyright (c) 2015, 2016, 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 java.util.Objects;
+import jdk.internal.vm.annotation.ForceInline;
+
+import static java.lang.invoke.MethodHandleStatics.UNSAFE;
+
+#warn
+
+final class VarHandle$Type$s {
+
+ static class FieldInstanceReadOnly extends VarHandle {
+ final long fieldOffset;
+ final Class<?> receiverType;
+#if[Object]
+ final Class<?> fieldType;
+#end[Object]
+
+ FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
+ this(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadOnly.class);
+ }
+
+ protected FieldInstanceReadOnly(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType},
+ Class<? extends FieldInstanceReadOnly> handle) {
+ super(VarForm.createFromStatic(handle), receiverType, {#if[Object]?fieldType:$type$.class});
+ this.fieldOffset = fieldOffset;
+ this.receiverType = receiverType;
+#if[Object]
+ this.fieldType = fieldType;
+#end[Object]
+ }
+
+ @ForceInline
+ static $type$ get(FieldInstanceReadOnly handle, Object holder) {
+ return UNSAFE.get$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getVolatile(FieldInstanceReadOnly handle, Object holder) {
+ return UNSAFE.get$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getOpaque(FieldInstanceReadOnly handle, Object holder) {
+ return UNSAFE.get$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getAcquire(FieldInstanceReadOnly handle, Object holder) {
+ return UNSAFE.get$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset);
+ }
+ }
+
+ static class FieldInstanceReadWrite extends FieldInstanceReadOnly {
+
+ FieldInstanceReadWrite(Class<?> receiverType, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
+ super(receiverType, fieldOffset{#if[Object]?, fieldType}, FieldInstanceReadWrite.class);
+ }
+
+ @ForceInline
+ static void set(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ UNSAFE.put$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setVolatile(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ UNSAFE.put$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setOpaque(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ UNSAFE.put$Type$Opaque(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setRelease(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ UNSAFE.put$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$Acquire(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$Release(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getAndSet(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ return UNSAFE.getAndSet$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ value);
+ }
+
+ @ForceInline
+ static $type$ addAndGet(FieldInstanceReadWrite handle, Object holder, $type$ value) {
+ return UNSAFE.getAndAdd$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)),
+ handle.fieldOffset,
+ value) + value;
+ }
+#end[AtomicAdd]
+ }
+
+
+ static class FieldStaticReadOnly extends VarHandle {
+ final Object base;
+ final long fieldOffset;
+#if[Object]
+ final Class<?> fieldType;
+#end[Object]
+
+ FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
+ this(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.class);
+ }
+
+ protected FieldStaticReadOnly(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
+ Class<? extends FieldStaticReadOnly> handle) {
+ super(VarForm.createFromStatic(handle), null, {#if[Object]?fieldType:$type$.class});
+ this.base = base;
+ this.fieldOffset = fieldOffset;
+#if[Object]
+ this.fieldType = fieldType;
+#end[Object]
+ }
+
+ @ForceInline
+ static $type$ get(FieldStaticReadOnly handle) {
+ return UNSAFE.get$Type$(handle.base,
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getVolatile(FieldStaticReadOnly handle) {
+ return UNSAFE.get$Type$Volatile(handle.base,
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getOpaque(FieldStaticReadOnly handle) {
+ return UNSAFE.get$Type$Opaque(handle.base,
+ handle.fieldOffset);
+ }
+
+ @ForceInline
+ static $type$ getAcquire(FieldStaticReadOnly handle) {
+ return UNSAFE.get$Type$Acquire(handle.base,
+ handle.fieldOffset);
+ }
+ }
+
+ static class FieldStaticReadWrite extends FieldStaticReadOnly {
+
+ FieldStaticReadWrite(Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
+ super(base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.class);
+ }
+
+ @ForceInline
+ static void set(FieldStaticReadWrite handle, $type$ value) {
+ UNSAFE.put$Type$(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setVolatile(FieldStaticReadWrite handle, $type$ value) {
+ UNSAFE.put$Type$Volatile(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setOpaque(FieldStaticReadWrite handle, $type$ value) {
+ UNSAFE.put$Type$Opaque(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static void setRelease(FieldStaticReadWrite handle, $type$ value) {
+ UNSAFE.put$Type$Release(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndSwap$Type$(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Volatile(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Acquire(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.compareAndExchange$Type$Release(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$Acquire(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(FieldStaticReadWrite handle, $type$ expected, $type$ value) {
+ return UNSAFE.weakCompareAndSwap$Type$Release(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(expected):expected},
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getAndSet(FieldStaticReadWrite handle, $type$ value) {
+ return UNSAFE.getAndSet$Type$(handle.base,
+ handle.fieldOffset,
+ {#if[Object]?handle.fieldType.cast(value):value});
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(FieldStaticReadWrite handle, $type$ value) {
+ return UNSAFE.getAndAdd$Type$(handle.base,
+ handle.fieldOffset,
+ value);
+ }
+
+ @ForceInline
+ static $type$ addAndGet(FieldStaticReadWrite handle, $type$ value) {
+ return UNSAFE.getAndAdd$Type$(handle.base,
+ handle.fieldOffset,
+ value) + value;
+ }
+#end[AtomicAdd]
+ }
+
+
+ static final class Array extends VarHandle {
+ final int abase;
+ final int ashift;
+#if[Object]
+ final Class<{#if[Object]??:$type$[]}> arrayType;
+ final Class<?> componentType;
+#end[Object]
+
+ Array(int abase, int ashift{#if[Object]?, Class<?> arrayType}) {
+ super(VarForm.createFromStatic(Array.class),
+ {#if[Object]?arrayType:$type$[].class}, {#if[Object]?arrayType.getComponentType():$type$.class}, int.class);
+ this.abase = abase;
+ this.ashift = ashift;
+#if[Object]
+ this.arrayType = {#if[Object]?arrayType:$type$[].class};
+ this.componentType = arrayType.getComponentType();
+#end[Object]
+ }
+
+ @ForceInline
+ static $type$ get(Array handle, Object oarray, int index) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return array[index];
+ }
+
+ @ForceInline
+ static void set(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ array[index] = {#if[Object]?handle.componentType.cast(value):value};
+ }
+
+ @ForceInline
+ static $type$ getVolatile(Array handle, Object oarray, int index) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.get$Type$Volatile(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ }
+
+ @ForceInline
+ static void setVolatile(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ UNSAFE.put$Type$Volatile(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getOpaque(Array handle, Object oarray, int index) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.get$Type$Opaque(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ }
+
+ @ForceInline
+ static void setOpaque(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ UNSAFE.put$Type$Opaque(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getAcquire(Array handle, Object oarray, int index) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.get$Type$Acquire(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ }
+
+ @ForceInline
+ static void setRelease(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ UNSAFE.put$Type$Release(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.compareAndSwap$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.compareAndExchange$Type$Volatile(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.compareAndExchange$Type$Acquire(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.compareAndExchange$Type$Release(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.weakCompareAndSwap$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.weakCompareAndSwap$Type$Acquire(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(Array handle, Object oarray, int index, $type$ expected, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.weakCompareAndSwap$Type$Release(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(expected):expected},
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+
+ @ForceInline
+ static $type$ getAndSet(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.getAndSet$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ {#if[Object]?handle.componentType.cast(value):value});
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.getAndAdd$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ value);
+ }
+
+ @ForceInline
+ static $type$ addAndGet(Array handle, Object oarray, int index, $type$ value) {
+#if[Object]
+ Object[] array = (Object[]) handle.arrayType.cast(oarray);
+#else[Object]
+ $type$[] array = ($type$[]) oarray;
+#end[Object]
+ return UNSAFE.getAndAdd$Type$(array,
+ (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ value) + value;
+ }
+#end[AtomicAdd]
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2015, 2016, 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 jdk.internal.misc.Unsafe;
+import jdk.internal.vm.annotation.ForceInline;
+
+import java.nio.ByteBuffer;
+import java.nio.ReadOnlyBufferException;
+import java.util.Objects;
+
+import static java.lang.invoke.MethodHandleStatics.UNSAFE;
+
+#warn
+
+final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase {
+
+ static final int ALIGN = $BoxType$.BYTES - 1;
+
+#if[floatingPoint]
+ @ForceInline
+ static $rawType$ convEndian(boolean big, $type$ v) {
+ $rawType$ rv = $Type$.$type$ToRaw$RawType$Bits(v);
+ return big == BE ? rv : $RawBoxType$.reverseBytes(rv);
+ }
+
+ @ForceInline
+ static $type$ convEndian(boolean big, $rawType$ rv) {
+ rv = big == BE ? rv : $RawBoxType$.reverseBytes(rv);
+ return $Type$.$rawType$BitsTo$Type$(rv);
+ }
+#else[floatingPoint]
+ @ForceInline
+ static $type$ convEndian(boolean big, $type$ n) {
+ return big == BE ? n : $BoxType$.reverseBytes(n);
+ }
+#end[floatingPoint]
+
+
+ private static class ByteArrayViewVarHandle extends VarHandle {
+ final boolean be;
+
+ ByteArrayViewVarHandle(Class<? extends ByteArrayViewVarHandle> implSubType,
+ Class<?> arrayType, Class<?> component, boolean be) {
+ super(VarForm.createFromStatic(implSubType),
+ arrayType, component, int.class);
+ this.be = be;
+ }
+ }
+
+ static final class ArrayHandle extends ByteArrayViewVarHandle {
+
+ ArrayHandle(boolean be) {
+ super(ArrayHandle.class, byte[].class, $type$.class, be);
+ }
+
+ @ForceInline
+ static int index(byte[] ba, int index) {
+ return Objects.checkIndex(index, ba.length - ALIGN, null);
+ }
+
+ @ForceInline
+ static long address(byte[] ba, int index) {
+ long address = ((long) index) + Unsafe.ARRAY_BYTE_BASE_OFFSET;
+ if ((address & ALIGN) != 0)
+ throw newIllegalStateExceptionForMisalignedAccess(index);
+ return address;
+ }
+
+ @ForceInline
+ static $type$ get(ArrayHandle handle, Object oba, int index) {
+ byte[] ba = (byte[]) oba;
+#if[floatingPoint]
+ $rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
+ ba,
+ ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
+ handle.be);
+ return $Type$.$rawType$BitsTo$Type$(rawValue);
+#else[floatingPoint]
+ return UNSAFE.get$Type$Unaligned(
+ ba,
+ ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
+ handle.be);
+#end[floatingPoint]
+ }
+
+ @ForceInline
+ static void set(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+#if[floatingPoint]
+ UNSAFE.put$RawType$Unaligned(
+ ba,
+ ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
+ $Type$.$type$ToRaw$RawType$Bits(value),
+ handle.be);
+#else[floatingPoint]
+ UNSAFE.put$RawType$Unaligned(
+ ba,
+ ((long) index(ba, index)) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
+ value,
+ handle.be);
+#end[floatingPoint]
+ }
+
+ @ForceInline
+ static $type$ getVolatile(ArrayHandle handle, Object oba, int index) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Volatile(
+ ba,
+ address(ba, index(ba, index))));
+ }
+
+ @ForceInline
+ static void setVolatile(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ UNSAFE.put$RawType$Volatile(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getAcquire(ArrayHandle handle, Object oba, int index) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Acquire(
+ ba,
+ address(ba, index(ba, index))));
+ }
+
+ @ForceInline
+ static void setRelease(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ UNSAFE.put$RawType$Release(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getOpaque(ArrayHandle handle, Object oba, int index) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Opaque(
+ ba,
+ address(ba, index(ba, index))));
+ }
+
+ @ForceInline
+ static void setOpaque(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ UNSAFE.put$RawType$Opaque(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value));
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return UNSAFE.compareAndSwap$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Volatile(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Acquire(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Release(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return UNSAFE.weakCompareAndSwap$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return UNSAFE.weakCompareAndSwap$RawType$Acquire(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return UNSAFE.weakCompareAndSwap$RawType$Release(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getAndSet(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.getAndSet$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value)));
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be,
+ UNSAFE.getAndAdd$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ addAndGet(ArrayHandle handle, Object oba, int index, $type$ value) {
+ byte[] ba = (byte[]) oba;
+ return convEndian(handle.be, UNSAFE.getAndAdd$RawType$(
+ ba,
+ address(ba, index(ba, index)),
+ convEndian(handle.be, value))) + value;
+ }
+#end[AtomicAdd]
+ }
+
+
+ static final class ByteBufferHandle extends ByteArrayViewVarHandle {
+
+ ByteBufferHandle(boolean be) {
+ super(ByteBufferHandle.class, ByteBuffer.class, $type$.class, be);
+ }
+
+ @ForceInline
+ static int index(ByteBuffer bb, int index) {
+ return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
+ }
+
+ @ForceInline
+ static int indexRO(ByteBuffer bb, int index) {
+ if (UNSAFE.getBoolean(bb, BYTE_BUFFER_IS_READ_ONLY))
+ throw new ReadOnlyBufferException();
+ return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
+ }
+
+ @ForceInline
+ static long address(ByteBuffer bb, int index) {
+ long address = ((long) index) + UNSAFE.getLong(bb, BUFFER_ADDRESS);
+ if ((address & ALIGN) != 0)
+ throw newIllegalStateExceptionForMisalignedAccess(index);
+ return address;
+ }
+
+ @ForceInline
+ static $type$ get(ByteBufferHandle handle, Object obb, int index) {
+ ByteBuffer bb = (ByteBuffer) obb;
+#if[floatingPoint]
+ $rawType$ rawValue = UNSAFE.get$RawType$Unaligned(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ ((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
+ handle.be);
+ return $Type$.$rawType$BitsTo$Type$(rawValue);
+#else[floatingPoint]
+ return UNSAFE.get$Type$Unaligned(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ ((long) index(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
+ handle.be);
+#end[floatingPoint]
+ }
+
+ @ForceInline
+ static void set(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+#if[floatingPoint]
+ UNSAFE.put$RawType$Unaligned(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ ((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
+ $Type$.$type$ToRaw$RawType$Bits(value),
+ handle.be);
+#else[floatingPoint]
+ UNSAFE.put$Type$Unaligned(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ ((long) indexRO(bb, index)) + UNSAFE.getLong(bb, BUFFER_ADDRESS),
+ value,
+ handle.be);
+#end[floatingPoint]
+ }
+
+ @ForceInline
+ static $type$ getVolatile(ByteBufferHandle handle, Object obb, int index) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Volatile(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, index(bb, index))));
+ }
+
+ @ForceInline
+ static void setVolatile(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ UNSAFE.put$RawType$Volatile(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getAcquire(ByteBufferHandle handle, Object obb, int index) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Acquire(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, index(bb, index))));
+ }
+
+ @ForceInline
+ static void setRelease(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ UNSAFE.put$RawType$Release(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getOpaque(ByteBufferHandle handle, Object obb, int index) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.get$RawType$Opaque(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, index(bb, index))));
+ }
+
+ @ForceInline
+ static void setOpaque(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ UNSAFE.put$RawType$Opaque(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value));
+ }
+#if[CAS]
+
+ @ForceInline
+ static boolean compareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return UNSAFE.compareAndSwap$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Volatile(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Acquire(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ compareAndExchangeRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.compareAndExchange$RawType$Release(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSet(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return UNSAFE.weakCompareAndSwap$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetAcquire(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return UNSAFE.weakCompareAndSwap$RawType$Acquire(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static boolean weakCompareAndSetRelease(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return UNSAFE.weakCompareAndSwap$RawType$Release(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, expected), convEndian(handle.be, value));
+ }
+
+ @ForceInline
+ static $type$ getAndSet(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.getAndSet$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value)));
+ }
+#end[CAS]
+#if[AtomicAdd]
+
+ @ForceInline
+ static $type$ getAndAdd(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.getAndAdd$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value)));
+ }
+
+ @ForceInline
+ static $type$ addAndGet(ByteBufferHandle handle, Object obb, int index, $type$ value) {
+ ByteBuffer bb = (ByteBuffer) obb;
+ return convEndian(handle.be,
+ UNSAFE.getAndAdd$RawType$(
+ UNSAFE.getObject(bb, BYTE_BUFFER_HB),
+ address(bb, indexRO(bb, index)),
+ convEndian(handle.be, value))) + value;
+ }
+#end[AtomicAdd]
+ }
+}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -32,7 +32,8 @@
* certain types in this package have special relations to dynamic
* language support in the virtual machine:
* <ul>
- * <li>The class {@link java.lang.invoke.MethodHandle MethodHandle} contains
+ * <li>The classes {@link java.lang.invoke.MethodHandle MethodHandle}
+ * {@link java.lang.invoke.VarHandle VarHandle} contain
* <a href="MethodHandle.html#sigpoly">signature polymorphic methods</a>
* which can be linked regardless of their type descriptor.
* Normally, method linkage requires exact matching of type descriptors.
--- a/jdk/src/java.base/share/classes/java/nio/Buffer.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/Buffer.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -25,8 +25,9 @@
package java.nio;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
import java.util.Spliterator;
-import jdk.internal.HotSpotIntrinsicCandidate;
/**
* A container for data of a specific primitive type.
@@ -188,7 +189,15 @@
private int limit;
private int capacity;
- // Used only by direct buffers
+ // Used by heap byte buffers or direct buffers with Unsafe access
+ // For heap byte buffers this field will be the address relative to the
+ // array base address and offset into that array. The address might
+ // not align on a word boundary for slices, nor align at a long word
+ // (8 byte) boundary for byte[] allocations on 32-bit systems.
+ // For direct buffers it is the start address of the memory region. The
+ // address might not align on a word boundary for slices, nor when created
+ // using JNI, see NewDirectByteBuffer(void*, long).
+ // Should ideally be declared final
// NOTE: hoisted here for speed in JNI GetDirectBufferAddress
long address;
--- a/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -140,6 +140,7 @@
att = null;
#else[rw]
super(cap);
+ this.isReadOnly = true;
#end[rw]
}
@@ -180,6 +181,7 @@
att = null;
#else[rw]
super(cap, addr, fd, unmapper);
+ this.isReadOnly = true;
#end[rw]
}
@@ -200,6 +202,7 @@
att = db;
#else[rw]
super(db, mark, pos, lim, cap, off);
+ this.isReadOnly = true;
#end[rw]
}
@@ -213,6 +216,15 @@
return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off);
}
+#if[byte]
+ public $Type$Buffer slice(int pos, int lim) {
+ assert (pos >= 0);
+ assert (pos <= lim);
+ int rem = lim - pos;
+ return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, pos);
+ }
+#end[byte]
+
public $Type$Buffer duplicate() {
return new Direct$Type$Buffer$RW$$BO$(this,
this.markValue(),
--- a/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -74,6 +74,9 @@
super(cap, lim);
this.isReadOnly = true;
#end[rw]
+#if[byte]
+ this.address = arrayBaseOffset;
+#end[byte]
}
Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
@@ -87,6 +90,9 @@
super(buf, off, len);
this.isReadOnly = true;
#end[rw]
+#if[byte]
+ this.address = arrayBaseOffset;
+#end[byte]
}
protected Heap$Type$Buffer$RW$($type$[] buf,
@@ -103,6 +109,9 @@
super(buf, mark, pos, lim, cap, off);
this.isReadOnly = true;
#end[rw]
+#if[byte]
+ this.address = arrayBaseOffset + off;
+#end[byte]
}
public $Type$Buffer slice() {
@@ -114,6 +123,20 @@
this.position() + offset);
}
+#if[byte]
+ $Type$Buffer slice(int pos, int lim) {
+ assert (pos >= 0);
+ assert (pos <= lim);
+ int rem = lim - pos;
+ return new Heap$Type$Buffer$RW$(hb,
+ -1,
+ 0,
+ rem,
+ rem,
+ pos + offset);
+ }
+#end[byte]
+
public $Type$Buffer duplicate() {
return new Heap$Type$Buffer$RW$(hb,
this.markValue(),
@@ -144,7 +167,7 @@
#if[byte]
private long byteOffset(long i) {
- return arrayBaseOffset + i + offset;
+ return address + i;
}
#end[byte]
--- a/jdk/src/java.base/share/classes/java/nio/StringCharBuffer.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/StringCharBuffer.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -39,6 +39,7 @@
if ((start < 0) || (start > n) || (end < start) || (end > n))
throw new IndexOutOfBoundsException();
str = s;
+ this.isReadOnly = true;
}
public CharBuffer slice() {
@@ -58,6 +59,7 @@
int offset) {
super(mark, pos, limit, cap, null, offset);
str = s;
+ this.isReadOnly = true;
}
public CharBuffer duplicate() {
--- a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -269,7 +269,7 @@
//
final $type$[] hb; // Non-null only for heap buffers
final int offset;
- boolean isReadOnly; // Valid only for heap buffers
+ boolean isReadOnly;
// Creates a new buffer with the given mark, position, limit, capacity,
// backing array, and array offset
@@ -530,6 +530,10 @@
* it will be read-only if, and only if, this buffer is read-only. </p>
*
* @return The new $type$ buffer
+#if[byte]
+ *
+ * @see #alignedSlice(int)
+#end[byte]
*/
public abstract $Type$Buffer slice();
@@ -1611,6 +1615,143 @@
return this;
}
+ /**
+ * Returns the memory address, pointing to the byte at the given index,
+ * modulus the given unit size.
+ *
+ * <p> A return value greater than zero indicates the address of the byte at
+ * the index is misaligned for the unit size, and the value's quantity
+ * indicates how much the index should be rounded up or down to locate a
+ * byte at an aligned address. Otherwise, a value of {@code 0} indicates
+ * that the address of the byte at the index is aligned for the unit size.
+ *
+ * @apiNote
+ * This method may be utilized to determine if unit size bytes from an
+ * index can be accessed atomically, if supported by the native platform.
+ *
+ * @implNote
+ * This implementation throws {@code UnsupportedOperationException} for
+ * non-direct buffers when the given unit size is greater then {@code 8}.
+ *
+ * @param index
+ * The index to query for alignment offset, must be non-negative, no
+ * upper bounds check is performed
+ *
+ * @param unitSize
+ * The unit size in bytes, must be a power of {@code 2}
+ *
+ * @return The indexed byte's memory address modulus the unit size
+ *
+ * @throws IllegalArgumentException
+ * If the index is negative or the unit size is not a power of
+ * {@code 2}
+ *
+ * @throws UnsupportedOperationException
+ * If the native platform does not guarantee stable alignment offset
+ * values for the given unit size when managing the memory regions
+ * of buffers of the same kind as this buffer (direct or
+ * non-direct). For example, if garbage collection would result
+ * in the moving of a memory region covered by a non-direct buffer
+ * from one location to another and both locations have different
+ * alignment characteristics.
+ *
+ * @see #alignedSlice(int)
+ * @since 9
+ */
+ public final int alignmentOffset(int index, int unitSize) {
+ if (index < 0)
+ throw new IllegalArgumentException("Index less than zero: " + index);
+ if (unitSize < 1 || (unitSize & (unitSize - 1)) != 0)
+ throw new IllegalArgumentException("Unit size not a power of two: " + unitSize);
+ if (unitSize > 8 && !isDirect())
+ throw new UnsupportedOperationException("Unit size unsupported for non-direct buffers: " + unitSize);
+
+ return (int) ((address + index) % unitSize);
+ }
+
+ /**
+ * Creates a new byte buffer whose content is a shared and aligned
+ * subsequence of this buffer's content.
+ *
+ * <p> The content of the new buffer will start at this buffer's current
+ * position rounded up to the index of the nearest aligned byte for the
+ * given unit size, and end at this buffer's limit rounded down to the index
+ * of the nearest aligned byte for the given unit size.
+ * If rounding results in out-of-bound values then the new buffer's capacity
+ * and limit will be zero. If rounding is within bounds the following
+ * expressions will be true for a new buffer {@code nb} and unit size
+ * {@code unitSize}:
+ * <pre>{@code
+ * nb.alignmentOffset(0, unitSize) == 0
+ * nb.alignmentOffset(nb.limit(), unitSize) == 0
+ * }</pre>
+ *
+ * <p> Changes to this buffer's content will be visible in the new
+ * buffer, and vice versa; the two buffers' position, limit, and mark
+ * values will be independent.
+ *
+ * <p> The new buffer's position will be zero, its capacity and its limit
+ * will be the number of bytes remaining in this buffer or fewer subject to
+ * alignment, its mark will be undefined, and its byte order will be
+ * {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
+ *
+ * The new buffer will be direct if, and only if, this buffer is direct, and
+ * it will be read-only if, and only if, this buffer is read-only. </p>
+ *
+ * @apiNote
+ * This method may be utilized to create a new buffer where unit size bytes
+ * from index, that is a multiple of the unit size, may be accessed
+ * atomically, if supported by the native platform.
+ *
+ * @implNote
+ * This implementation throws {@code UnsupportedOperationException} for
+ * non-direct buffers when the given unit size is greater then {@code 8}.
+ *
+ * @param unitSize
+ * The unit size in bytes, must be a power of {@code 2}
+ *
+ * @return The new byte buffer
+ *
+ * @throws IllegalArgumentException
+ * If the unit size not a power of {@code 2}
+ *
+ * @throws UnsupportedOperationException
+ * If the native platform does not guarantee stable aligned slices
+ * for the given unit size when managing the memory regions
+ * of buffers of the same kind as this buffer (direct or
+ * non-direct). For example, if garbage collection would result
+ * in the moving of a memory region covered by a non-direct buffer
+ * from one location to another and both locations have different
+ * alignment characteristics.
+ *
+ * @see #alignmentOffset(int, int)
+ * @see #slice()
+ * @since 9
+ */
+ public final ByteBuffer alignedSlice(int unitSize) {
+ int pos = position();
+ int lim = limit();
+
+ int pos_mod = alignmentOffset(pos, unitSize);
+ int lim_mod = alignmentOffset(lim, unitSize);
+
+ // Round up the position to align with unit size
+ int aligned_pos = (pos_mod > 0)
+ ? pos + (unitSize - pos_mod)
+ : pos;
+
+ // Round down the limit to align with unit size
+ int aligned_lim = lim - lim_mod;
+
+ if (aligned_pos > lim || aligned_lim < pos) {
+ aligned_pos = aligned_lim = pos;
+ }
+
+ return slice(aligned_pos, aligned_lim);
+ }
+
+ abstract ByteBuffer slice(int pos, int lim);
+
// Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
//
abstract byte _get(int i); // package-private
--- a/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/text/DateFormatSymbols.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -47,7 +47,6 @@
import java.util.Locale;
import java.util.Objects;
import java.util.ResourceBundle;
-import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import sun.util.locale.provider.LocaleProviderAdapter;
@@ -147,6 +146,12 @@
}
/**
+ * Constructs an uninitialized DateFormatSymbols.
+ */
+ private DateFormatSymbols(boolean flag) {
+ }
+
+ /**
* Era strings. For example: "AD" and "BC". An array of 2 strings,
* indexed by <code>Calendar.BC</code> and <code>Calendar.AD</code>.
* @serial
@@ -679,54 +684,80 @@
*/
transient volatile int cachedHashCode;
- private void initializeData(Locale desiredLocale) {
- locale = desiredLocale;
-
- // Copy values of a cached instance if any.
+ /**
+ * Initializes this DateFormatSymbols with the locale data. This method uses
+ * a cached DateFormatSymbols instance for the given locale if available. If
+ * there's no cached one, this method creates an uninitialized instance and
+ * populates its fields from the resource bundle for the locale, and caches
+ * the instance. Note: zoneStrings isn't initialized in this method.
+ */
+ private void initializeData(Locale locale) {
SoftReference<DateFormatSymbols> ref = cachedInstances.get(locale);
DateFormatSymbols dfs;
- if (ref != null && (dfs = ref.get()) != null) {
- copyMembers(dfs, this);
- return;
+ if (ref == null || (dfs = ref.get()) == null) {
+ if (ref != null) {
+ // Remove the empty SoftReference
+ cachedInstances.remove(locale, ref);
+ }
+ dfs = new DateFormatSymbols(false);
+
+ // Initialize the fields from the ResourceBundle for locale.
+ LocaleProviderAdapter adapter
+ = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale);
+ // Avoid any potential recursions
+ if (!(adapter instanceof ResourceBundleBasedAdapter)) {
+ adapter = LocaleProviderAdapter.getResourceBundleBased();
+ }
+ ResourceBundle resource
+ = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale);
+
+ dfs.locale = locale;
+ // JRE and CLDR use different keys
+ // JRE: Eras, short.Eras and narrow.Eras
+ // CLDR: long.Eras, Eras and narrow.Eras
+ if (resource.containsKey("Eras")) {
+ dfs.eras = resource.getStringArray("Eras");
+ } else if (resource.containsKey("long.Eras")) {
+ dfs.eras = resource.getStringArray("long.Eras");
+ } else if (resource.containsKey("short.Eras")) {
+ dfs.eras = resource.getStringArray("short.Eras");
+ }
+ dfs.months = resource.getStringArray("MonthNames");
+ dfs.shortMonths = resource.getStringArray("MonthAbbreviations");
+ dfs.ampms = resource.getStringArray("AmPmMarkers");
+ dfs.localPatternChars = resource.getString("DateTimePatternChars");
+
+ // Day of week names are stored in a 1-based array.
+ dfs.weekdays = toOneBasedArray(resource.getStringArray("DayNames"));
+ dfs.shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations"));
+
+ // Put dfs in the cache
+ ref = new SoftReference<>(dfs);
+ SoftReference<DateFormatSymbols> x = cachedInstances.putIfAbsent(locale, ref);
+ if (x != null) {
+ DateFormatSymbols y = x.get();
+ if (y == null) {
+ // Replace the empty SoftReference with ref.
+ cachedInstances.replace(locale, x, ref);
+ } else {
+ ref = x;
+ dfs = y;
+ }
+ }
+ // If the bundle's locale isn't the target locale, put another cache
+ // entry for the bundle's locale.
+ Locale bundleLocale = resource.getLocale();
+ if (!bundleLocale.equals(locale)) {
+ SoftReference<DateFormatSymbols> z
+ = cachedInstances.putIfAbsent(bundleLocale, ref);
+ if (z != null && z.get() == null) {
+ cachedInstances.replace(bundleLocale, z, ref);
+ }
+ }
}
- // Initialize the fields from the ResourceBundle for locale.
- LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(DateFormatSymbolsProvider.class, locale);
- // Avoid any potential recursions
- if (!(adapter instanceof ResourceBundleBasedAdapter)) {
- adapter = LocaleProviderAdapter.getResourceBundleBased();
- }
- ResourceBundle resource = ((ResourceBundleBasedAdapter)adapter).getLocaleData().getDateFormatData(locale);
-
- // JRE and CLDR use different keys
- // JRE: Eras, short.Eras and narrow.Eras
- // CLDR: long.Eras, Eras and narrow.Eras
- if (resource.containsKey("Eras")) {
- eras = resource.getStringArray("Eras");
- } else if (resource.containsKey("long.Eras")) {
- eras = resource.getStringArray("long.Eras");
- } else if (resource.containsKey("short.Eras")) {
- eras = resource.getStringArray("short.Eras");
- }
- months = resource.getStringArray("MonthNames");
- shortMonths = resource.getStringArray("MonthAbbreviations");
- ampms = resource.getStringArray("AmPmMarkers");
- localPatternChars = resource.getString("DateTimePatternChars");
-
- // Day of week names are stored in a 1-based array.
- weekdays = toOneBasedArray(resource.getStringArray("DayNames"));
- shortWeekdays = toOneBasedArray(resource.getStringArray("DayAbbreviations"));
-
- // Put a clone in the cache
- ref = new SoftReference<>((DateFormatSymbols)this.clone());
- SoftReference<DateFormatSymbols> x = cachedInstances.putIfAbsent(locale, ref);
- if (x != null) {
- DateFormatSymbols y = x.get();
- if (y == null) {
- // Replace the empty SoftReference with ref.
- cachedInstances.put(locale, ref);
- }
- }
+ // Copy the field values from dfs to this instance.
+ copyMembers(dfs, this);
}
private static String[] toOneBasedArray(String[] src) {
@@ -808,12 +839,14 @@
/**
* Clones all the data members from the source DateFormatSymbols to
- * the target DateFormatSymbols. This is only for subclasses.
+ * the target DateFormatSymbols.
+ *
* @param src the source DateFormatSymbols.
* @param dst the target DateFormatSymbols.
*/
private void copyMembers(DateFormatSymbols src, DateFormatSymbols dst)
{
+ dst.locale = src.locale;
dst.eras = Arrays.copyOf(src.eras, src.eras.length);
dst.months = Arrays.copyOf(src.months, src.months.length);
dst.shortMonths = Arrays.copyOf(src.shortMonths, src.shortMonths.length);
--- a/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -61,12 +61,17 @@
*/
package java.time.chrono;
+import static java.time.temporal.ChronoField.HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
+import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
+
import java.time.Clock;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
+import java.time.ZoneOffset;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.ResolverStyle;
import java.time.format.TextStyle;
@@ -712,6 +717,59 @@
return new ChronoPeriodImpl(this, years, months, days);
}
+ //---------------------------------------------------------------------
+
+ /**
+ * Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z.
+ * <p>
+ * The number of seconds is calculated using the proleptic-year,
+ * month, day-of-month, hour, minute, second, and zoneOffset.
+ *
+ * @param prolepticYear the chronology proleptic-year
+ * @param month the chronology month-of-year
+ * @param dayOfMonth the chronology day-of-month
+ * @param hour the hour-of-day, from 0 to 23
+ * @param minute the minute-of-hour, from 0 to 59
+ * @param second the second-of-minute, from 0 to 59
+ * @param zoneOffset the zone offset, not null
+ * @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative
+ * @throws DateTimeException if any of the values are out of range
+ * @since 9
+ */
+ public default long epochSecond(int prolepticYear, int month, int dayOfMonth,
+ int hour, int minute, int second, ZoneOffset zoneOffset) {
+ Objects.requireNonNull(zoneOffset, "zoneOffset");
+ HOUR_OF_DAY.checkValidValue(hour);
+ MINUTE_OF_HOUR.checkValidValue(minute);
+ SECOND_OF_MINUTE.checkValidValue(second);
+ long daysInSec = Math.multiplyExact(date(prolepticYear, month, dayOfMonth).toEpochDay(), 86400);
+ long timeinSec = (hour * 60 + minute) * 60 + second;
+ return Math.addExact(daysInSec, timeinSec - zoneOffset.getTotalSeconds());
+ }
+
+ /**
+ * Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z.
+ * <p>
+ * The number of seconds is calculated using the era, year-of-era,
+ * month, day-of-month, hour, minute, second, and zoneOffset.
+ *
+ * @param era the era of the correct type for the chronology, not null
+ * @param yearOfEra the chronology year-of-era
+ * @param month the chronology month-of-year
+ * @param dayOfMonth the chronology day-of-month
+ * @param hour the hour-of-day, from 0 to 23
+ * @param minute the minute-of-hour, from 0 to 59
+ * @param second the second-of-minute, from 0 to 59
+ * @param zoneOffset the zone offset, not null
+ * @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative
+ * @throws DateTimeException if any of the values are out of range
+ * @since 9
+ */
+ public default long epochSecond(Era era, int yearOfEra, int month, int dayOfMonth,
+ int hour, int minute, int second, ZoneOffset zoneOffset) {
+ Objects.requireNonNull(era, "era");
+ return epochSecond(prolepticYear(era, yearOfEra), month, dayOfMonth, hour, minute, second, zoneOffset);
+ }
//-----------------------------------------------------------------------
/**
* Compares this chronology to another chronology.
--- a/jdk/src/java.base/share/classes/java/time/chrono/IsoChronology.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/chrono/IsoChronology.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -61,14 +61,17 @@
*/
package java.time.chrono;
-import java.io.InvalidObjectException;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.ERA;
+import static java.time.temporal.ChronoField.HOUR_OF_DAY;
+import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
+import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
import static java.time.temporal.ChronoField.YEAR;
import static java.time.temporal.ChronoField.YEAR_OF_ERA;
+import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.time.Clock;
@@ -79,8 +82,9 @@
import java.time.Month;
import java.time.Period;
import java.time.Year;
+import java.time.ZonedDateTime;
import java.time.ZoneId;
-import java.time.ZonedDateTime;
+import java.time.ZoneOffset;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
@@ -132,6 +136,8 @@
*/
private static final long serialVersionUID = -1440403870442975015L;
+ private static final long DAYS_0000_TO_1970 = (146097 * 5L) - (30L * 365L + 7L); // taken from LocalDate
+
/**
* Restricted constructor.
*/
@@ -263,6 +269,94 @@
return LocalDate.from(temporal);
}
+ //-----------------------------------------------------------------------
+ /**
+ * Gets the number of seconds from the epoch of 1970-01-01T00:00:00Z.
+ * <p>
+ * The number of seconds is calculated using the year,
+ * month, day-of-month, hour, minute, second, and zoneOffset.
+ *
+ * @param prolepticYear the year, from MIN_YEAR to MAX_YEAR
+ * @param month the month-of-year, from 1 to 12
+ * @param dayOfMonth the day-of-month, from 1 to 31
+ * @param hour the hour-of-day, from 0 to 23
+ * @param minute the minute-of-hour, from 0 to 59
+ * @param second the second-of-minute, from 0 to 59
+ * @param zoneOffset the zone offset, not null
+ * @return the number of seconds relative to 1970-01-01T00:00:00Z, may be negative
+ * @throws DateTimeException if the value of any argument is out of range,
+ * or if the day-of-month is invalid for the month-of-year
+ * @since 9
+ */
+ @Override
+ public long epochSecond(int prolepticYear, int month, int dayOfMonth,
+ int hour, int minute, int second, ZoneOffset zoneOffset) {
+ YEAR.checkValidValue(prolepticYear);
+ MONTH_OF_YEAR.checkValidValue(month);
+ DAY_OF_MONTH.checkValidValue(dayOfMonth);
+ HOUR_OF_DAY.checkValidValue(hour);
+ MINUTE_OF_HOUR.checkValidValue(minute);
+ SECOND_OF_MINUTE.checkValidValue(second);
+ Objects.requireNonNull(zoneOffset, "zoneOffset");
+ if (dayOfMonth > 28) {
+ int dom = numberOfDaysOfMonth(prolepticYear, month);
+ if (dayOfMonth > dom) {
+ if (dayOfMonth == 29) {
+ throw new DateTimeException("Invalid date 'February 29' as '" + prolepticYear + "' is not a leap year");
+ } else {
+ throw new DateTimeException("Invalid date '" + Month.of(month).name() + " " + dayOfMonth + "'");
+ }
+ }
+ }
+
+ long totalDays = 0;
+ int timeinSec = 0;
+ totalDays += 365L * prolepticYear;
+ if (prolepticYear >= 0) {
+ totalDays += (prolepticYear + 3L) / 4 - (prolepticYear + 99L) / 100 + (prolepticYear + 399L) / 400;
+ } else {
+ totalDays -= prolepticYear / -4 - prolepticYear / -100 + prolepticYear / -400;
+ }
+ totalDays += (367 * month - 362) / 12;
+ totalDays += dayOfMonth - 1;
+ if (month > 2) {
+ totalDays--;
+ if (IsoChronology.INSTANCE.isLeapYear(prolepticYear) == false) {
+ totalDays--;
+ }
+ }
+ totalDays -= DAYS_0000_TO_1970;
+ timeinSec = (hour * 60 + minute ) * 60 + second;
+ return Math.addExact(Math.multiplyExact(totalDays, 86400L), timeinSec - zoneOffset.getTotalSeconds());
+ }
+
+ /**
+ * Gets the number of days for the given month in the given year.
+ *
+ * @param year the year to represent, from MIN_YEAR to MAX_YEAR
+ * @param month the month-of-year to represent, from 1 to 12
+ * @return the number of days for the given month in the given year
+ */
+ private int numberOfDaysOfMonth(int year, int month) {
+ int dom;
+ switch (month) {
+ case 2:
+ dom = (IsoChronology.INSTANCE.isLeapYear(year) ? 29 : 28);
+ break;
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ dom = 30;
+ break;
+ default:
+ dom = 31;
+ break;
+ }
+ return dom;
+ }
+
+
/**
* Obtains an ISO local date-time from another date-time object.
* <p>
--- a/jdk/src/java.base/share/classes/java/time/temporal/ChronoField.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/time/temporal/ChronoField.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -270,6 +270,8 @@
* In lenient mode the value is not validated. It is combined with
* {@code AMPM_OF_DAY} to form {@code HOUR_OF_DAY} by multiplying
* the {AMPM_OF_DAY} value by 12.
+ * <p>
+ * See {@link #CLOCK_HOUR_OF_AMPM} for the related field that counts hours from 1 to 12.
*/
HOUR_OF_AMPM("HourOfAmPm", HOURS, HALF_DAYS, ValueRange.of(0, 11)),
/**
@@ -284,6 +286,8 @@
* 0 to 12 in smart mode. In lenient mode the value is not validated.
* The field is converted to an {@code HOUR_OF_AMPM} with the same value,
* unless the value is 12, in which case it is converted to 0.
+ * <p>
+ * See {@link #HOUR_OF_AMPM} for the related field that counts hours from 0 to 11.
*/
CLOCK_HOUR_OF_AMPM("ClockHourOfAmPm", HOURS, HALF_DAYS, ValueRange.of(1, 12)),
/**
@@ -299,12 +303,14 @@
* {@code NANO_OF_SECOND} to produce a {@code LocalTime}.
* In lenient mode, any excess days are added to the parsed date, or
* made available via {@link java.time.format.DateTimeFormatter#parsedExcessDays()}.
+ * <p>
+ * See {@link #CLOCK_HOUR_OF_DAY} for the related field that counts hours from 1 to 24.
*/
HOUR_OF_DAY("HourOfDay", HOURS, DAYS, ValueRange.of(0, 23), "hour"),
/**
* The clock-hour-of-day.
* <p>
- * This counts the hour within the AM/PM, from 1 to 24.
+ * This counts the hour within the day, from 1 to 24.
* This is the hour that would be observed on a 24-hour analog wall clock.
* This field has the same meaning for all calendar systems.
* <p>
@@ -313,6 +319,8 @@
* 0 to 24 in smart mode. In lenient mode the value is not validated.
* The field is converted to an {@code HOUR_OF_DAY} with the same value,
* unless the value is 24, in which case it is converted to 0.
+ * <p>
+ * See {@link #HOUR_OF_DAY} for the related field that counts hours from 0 to 23.
*/
CLOCK_HOUR_OF_DAY("ClockHourOfDay", HOURS, DAYS, ValueRange.of(1, 24)),
/**
--- a/jdk/src/java.base/share/classes/java/util/Deque.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/Deque.java Thu Apr 07 11:03:59 2016 -0700
@@ -174,7 +174,7 @@
* that do allow null elements are strongly encouraged <i>not</i> to
* take advantage of the ability to insert nulls. This is so because
* {@code null} is used as a special return value by various methods
- * to indicated that the deque is empty.
+ * to indicate that the deque is empty.
*
* <p>{@code Deque} implementations generally do not define
* element-based versions of the {@code equals} and {@code hashCode}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Thu Apr 07 11:03:59 2016 -0700
@@ -480,7 +480,7 @@
}
static void lazySetNext(Completion c, Completion next) {
- U.putOrderedObject(c, NEXT, next);
+ U.putObjectRelease(c, NEXT, next);
}
/**
@@ -583,9 +583,9 @@
*/
final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
if (a != null && a.stack != null) {
- if (mode < 0 || a.result == null)
+ if (a.result == null)
a.cleanStack();
- else
+ else if (mode >= 0)
a.postComplete();
}
if (result != null && stack != null) {
@@ -1107,9 +1107,9 @@
final CompletableFuture<T> postFire(CompletableFuture<?> a,
CompletableFuture<?> b, int mode) {
if (b != null && b.stack != null) { // clean second source
- if (mode < 0 || b.result == null)
+ if (b.result == null)
b.cleanStack();
- else
+ else if (mode >= 0)
b.postComplete();
}
return postFire(a, mode);
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Thu Apr 07 11:03:59 2016 -0700
@@ -628,10 +628,14 @@
volatile V val;
volatile Node<K,V> next;
- Node(int hash, K key, V val, Node<K,V> next) {
+ Node(int hash, K key, V val) {
this.hash = hash;
this.key = key;
this.val = val;
+ }
+
+ Node(int hash, K key, V val, Node<K,V> next) {
+ this(hash, key, val);
this.next = next;
}
@@ -1024,8 +1028,7 @@
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
- if (casTabAt(tab, i, null,
- new Node<K,V>(hash, key, value, null)))
+ if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value)))
break; // no lock when adding to empty bin
}
else if ((fh = f.hash) == MOVED)
@@ -1048,8 +1051,7 @@
}
Node<K,V> pred = e;
if ((e = e.next) == null) {
- pred.next = new Node<K,V>(hash, key,
- value, null);
+ pred.next = new Node<K,V>(hash, key, value);
break;
}
}
@@ -1709,7 +1711,7 @@
Node<K,V> node = null;
try {
if ((val = mappingFunction.apply(key)) != null)
- node = new Node<K,V>(h, key, val, null);
+ node = new Node<K,V>(h, key, val);
} finally {
setTabAt(tab, i, node);
}
@@ -1740,7 +1742,7 @@
if (pred.next != null)
throw new IllegalStateException("Recursive update");
added = true;
- pred.next = new Node<K,V>(h, key, val, null);
+ pred.next = new Node<K,V>(h, key, val);
}
break;
}
@@ -1909,7 +1911,7 @@
try {
if ((val = remappingFunction.apply(key, null)) != null) {
delta = 1;
- node = new Node<K,V>(h, key, val, null);
+ node = new Node<K,V>(h, key, val);
}
} finally {
setTabAt(tab, i, node);
@@ -1951,8 +1953,7 @@
if (pred.next != null)
throw new IllegalStateException("Recursive update");
delta = 1;
- pred.next =
- new Node<K,V>(h, key, val, null);
+ pred.next = new Node<K,V>(h, key, val);
}
break;
}
@@ -2030,7 +2031,7 @@
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
- if (casTabAt(tab, i, null, new Node<K,V>(h, key, value, null))) {
+ if (casTabAt(tab, i, null, new Node<K,V>(h, key, value))) {
delta = 1;
val = value;
break;
@@ -2065,8 +2066,7 @@
if ((e = e.next) == null) {
delta = 1;
val = value;
- pred.next =
- new Node<K,V>(h, key, val, null);
+ pred.next = new Node<K,V>(h, key, val);
break;
}
}
@@ -2227,7 +2227,7 @@
static final class ForwardingNode<K,V> extends Node<K,V> {
final Node<K,V>[] nextTable;
ForwardingNode(Node<K,V>[] tab) {
- super(MOVED, null, null, null);
+ super(MOVED, null, null);
this.nextTable = tab;
}
@@ -2263,7 +2263,7 @@
*/
static final class ReservationNode<K,V> extends Node<K,V> {
ReservationNode() {
- super(RESERVED, null, null, null);
+ super(RESERVED, null, null);
}
Node<K,V> find(int h, Object k) {
@@ -2690,12 +2690,12 @@
}
/**
- * Returns a list on non-TreeNodes replacing those in given list.
+ * Returns a list of non-TreeNodes replacing those in given list.
*/
static <K,V> Node<K,V> untreeify(Node<K,V> b) {
Node<K,V> hd = null, tl = null;
for (Node<K,V> q = b; q != null; q = q.next) {
- Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val, null);
+ Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val);
if (tl == null)
hd = p;
else
@@ -2801,7 +2801,7 @@
* Creates bin with initial set of nodes headed by b.
*/
TreeBin(TreeNode<K,V> b) {
- super(TREEBIN, null, null, null);
+ super(TREEBIN, null, null);
this.first = b;
TreeNode<K,V> r = null;
for (TreeNode<K,V> x = b, next; x != null; x = next) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Thu Apr 07 11:03:59 2016 -0700
@@ -309,7 +309,7 @@
}
void lazySetNext(Node<E> val) {
- U.putOrderedObject(this, NEXT, val);
+ U.putObjectRelease(this, NEXT, val);
}
boolean casNext(Node<E> cmp, Node<E> val) {
@@ -317,7 +317,7 @@
}
void lazySetPrev(Node<E> val) {
- U.putOrderedObject(this, PREV, val);
+ U.putObjectRelease(this, PREV, val);
}
boolean casPrev(Node<E> cmp, Node<E> val) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Thu Apr 07 11:03:59 2016 -0700
@@ -198,7 +198,7 @@
}
static <E> void lazySetNext(Node<E> node, Node<E> val) {
- U.putOrderedObject(node, NEXT, val);
+ U.putObjectRelease(node, NEXT, val);
}
static <E> boolean casNext(Node<E> node, Node<E> cmp, Node<E> val) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java Thu Apr 07 11:03:59 2016 -0700
@@ -239,7 +239,7 @@
* not to be as readily inlined by dynamic compilers when they are
* hidden behind other methods that would more nicely name and
* encapsulate the intended effects). This includes the use of
- * putOrderedX to clear fields of the per-thread Nodes between
+ * putXRelease to clear fields of the per-thread Nodes between
* uses. Note that field Node.item is not declared as volatile
* even though it is read by releasing threads, because they only
* do so after CAS operations that must precede access, and all
@@ -376,7 +376,7 @@
for (int h = p.hash, spins = SPINS;;) {
Object v = p.match;
if (v != null) {
- U.putOrderedObject(p, MATCH, null);
+ U.putObjectRelease(p, MATCH, null);
p.item = null; // clear for next use
p.hash = h;
return v;
@@ -507,7 +507,7 @@
break;
}
}
- U.putOrderedObject(p, MATCH, null);
+ U.putObjectRelease(p, MATCH, null);
p.item = null;
p.hash = h;
return v;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Thu Apr 07 11:03:59 2016 -0700
@@ -289,7 +289,7 @@
* on to try or create other queues -- they block only when
* creating and registering new queues. Because it is used only as
* a spinlock, unlocking requires only a "releasing" store (using
- * putOrderedInt). The qlock is also used during termination
+ * putIntRelease). The qlock is also used during termination
* detection, in which case it is forced to a negative
* non-lockable value.
*
@@ -1071,7 +1071,7 @@
popped = true;
top = s;
}
- U.putOrderedInt(this, QLOCK, 0);
+ U.putIntRelease(this, QLOCK, 0);
}
}
return popped;
@@ -1261,7 +1261,7 @@
popped = true;
top = s - 1;
}
- U.putOrderedInt(this, QLOCK, 0);
+ U.putIntRelease(this, QLOCK, 0);
if (popped)
return t;
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Thu Apr 07 11:03:59 2016 -0700
@@ -92,7 +92,7 @@
ForkJoinWorkerThread(ForkJoinPool pool, ThreadGroup threadGroup,
AccessControlContext acc) {
super(threadGroup, null, "aForkJoinWorkerThread");
- U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, acc);
+ U.putObjectRelease(this, INHERITEDACCESSCONTROLCONTEXT, acc);
eraseThreadLocals(); // clear before registering
this.pool = pool;
this.workQueue = pool.registerWorker(this);
--- a/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java Thu Apr 07 11:03:59 2016 -0700
@@ -174,7 +174,7 @@
if (t != null)
t.interrupt();
} finally { // final state
- U.putOrderedInt(this, STATE, INTERRUPTED);
+ U.putIntRelease(this, STATE, INTERRUPTED);
}
}
} finally {
@@ -230,7 +230,7 @@
protected void set(V v) {
if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {
outcome = v;
- U.putOrderedInt(this, STATE, NORMAL); // final state
+ U.putIntRelease(this, STATE, NORMAL); // final state
finishCompletion();
}
}
@@ -248,7 +248,7 @@
protected void setException(Throwable t) {
if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {
outcome = t;
- U.putOrderedInt(this, STATE, EXCEPTIONAL); // final state
+ U.putIntRelease(this, STATE, EXCEPTIONAL); // final state
finishCompletion();
}
}
--- a/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Thu Apr 07 11:03:59 2016 -0700
@@ -1496,7 +1496,7 @@
else if (((c & CONSUME) != 0 ||
U.compareAndSwapInt(this, CTL, c, c | CONSUME)) &&
U.compareAndSwapObject(a, i, x, null)) {
- U.putOrderedInt(this, HEAD, ++h);
+ U.putIntRelease(this, HEAD, ++h);
U.getAndAddLong(this, DEMAND, -1L);
if ((w = waiter) != null)
signalWaiter(w);
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Thu Apr 07 11:03:59 2016 -0700
@@ -136,7 +136,7 @@
* @since 1.6
*/
public final void lazySet(boolean newValue) {
- U.putOrderedInt(this, VALUE, (newValue ? 1 : 0));
+ U.putIntRelease(this, VALUE, (newValue ? 1 : 0));
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java Thu Apr 07 11:03:59 2016 -0700
@@ -108,7 +108,7 @@
* @since 1.6
*/
public final void lazySet(int newValue) {
- U.putOrderedInt(this, VALUE, newValue);
+ U.putIntRelease(this, VALUE, newValue);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Thu Apr 07 11:03:59 2016 -0700
@@ -136,7 +136,7 @@
* @since 1.6
*/
public final void lazySet(int i, int newValue) {
- U.putOrderedInt(array, checkedByteOffset(i), newValue);
+ U.putIntRelease(array, checkedByteOffset(i), newValue);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Thu Apr 07 11:03:59 2016 -0700
@@ -475,7 +475,7 @@
public final void lazySet(T obj, int newValue) {
accessCheck(obj);
- U.putOrderedInt(obj, offset, newValue);
+ U.putIntRelease(obj, offset, newValue);
}
public final int get(T obj) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java Thu Apr 07 11:03:59 2016 -0700
@@ -124,7 +124,7 @@
* @since 1.6
*/
public final void lazySet(long newValue) {
- U.putOrderedLong(this, VALUE, newValue);
+ U.putLongRelease(this, VALUE, newValue);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Thu Apr 07 11:03:59 2016 -0700
@@ -135,7 +135,7 @@
* @since 1.6
*/
public final void lazySet(int i, long newValue) {
- U.putOrderedLong(array, checkedByteOffset(i), newValue);
+ U.putLongRelease(array, checkedByteOffset(i), newValue);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Thu Apr 07 11:03:59 2016 -0700
@@ -457,7 +457,7 @@
public final void lazySet(T obj, long newValue) {
accessCheck(obj);
- U.putOrderedLong(obj, offset, newValue);
+ U.putLongRelease(obj, offset, newValue);
}
public final long get(T obj) {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java Thu Apr 07 11:03:59 2016 -0700
@@ -103,7 +103,7 @@
* @since 1.6
*/
public final void lazySet(V newValue) {
- U.putOrderedObject(this, VALUE, newValue);
+ U.putObjectRelease(this, VALUE, newValue);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Thu Apr 07 11:03:59 2016 -0700
@@ -147,7 +147,7 @@
* @since 1.6
*/
public final void lazySet(int i, E newValue) {
- U.putOrderedObject(array, checkedByteOffset(i), newValue);
+ U.putObjectRelease(array, checkedByteOffset(i), newValue);
}
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Thu Apr 07 11:03:59 2016 -0700
@@ -426,7 +426,7 @@
public final void lazySet(T obj, V newValue) {
accessCheck(obj);
valueCheck(newValue);
- U.putOrderedObject(obj, offset, newValue);
+ U.putObjectRelease(obj, offset, newValue);
}
@SuppressWarnings("unchecked")
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/decompressor/CompressIndexes.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/decompressor/CompressIndexes.java Thu Apr 07 11:03:59 2016 -0700
@@ -42,107 +42,95 @@
* to the jimage file provided by the shipped JDK by tools running on JDK 8.
*/
public class CompressIndexes {
- private static final int INTEGER_SIZE = 4;
+ private static final int COMPRESSED_FLAG = 1 << (Byte.SIZE - 1);
+ private static final int HEADER_WIDTH = 3;
+ private static final int HEADER_SHIFT = Byte.SIZE - HEADER_WIDTH;
public static List<Integer> decompressFlow(byte[] values) {
List<Integer> lst = new ArrayList<>();
- for (int i = 0; i < values.length;) {
- byte b = values[i];
- int length = isCompressed(b) ? getLength(b) : INTEGER_SIZE;
+
+ for (int i = 0; i < values.length; i += getHeaderLength(values[i])) {
int decompressed = decompress(values, i);
lst.add(decompressed);
- i += length;
}
+
return lst;
}
public static int readInt(DataInputStream cr) throws IOException {
- byte[] b = new byte[1];
- cr.readFully(b);
- byte firstByte = b[0];
- boolean compressed = CompressIndexes.isCompressed(firstByte);
- int toRead = 4;
- if(compressed) {
- toRead = CompressIndexes.getLength(firstByte);
+ // Get header byte.
+ byte header = cr.readByte();
+ // Determine size.
+ int size = getHeaderLength(header);
+ // Prepare result.
+ int result = getHeaderValue(header);
+
+ // For each value byte
+ for (int i = 1; i < size; i++) {
+ // Merge byte value.
+ result <<= Byte.SIZE;
+ result |= cr.readByte() & 0xFF;
}
- byte[] content = new byte[toRead-1];
- cr.readFully(content);
- ByteBuffer bb = ByteBuffer.allocate(content.length+1);
- bb.put(firstByte);
- bb.put(content);
- int index = CompressIndexes.decompress(bb.array(), 0);
- return index;
+
+ return result;
}
- public static int getLength(byte b) {
- return ((byte) (b & 0x60) >> 5);
+ private static boolean isCompressed(byte b) {
+ return (b & COMPRESSED_FLAG) != 0;
}
- public static boolean isCompressed(byte b) {
- return b < 0;
+ private static int getHeaderLength(byte b) {
+ return isCompressed(b) ? (b >> HEADER_SHIFT) & 3 : Integer.BYTES;
+ }
+
+ private static int getHeaderValue(byte b) {
+ return isCompressed(b) ? b & (1 << HEADER_SHIFT) - 1 : b;
}
public static int decompress(byte[] value, int offset) {
- byte b1 = value[offset];
- ByteBuffer buffer = ByteBuffer.allocate(INTEGER_SIZE);
- if (isCompressed(b1)) { // compressed
- int length = getLength(b1);
- byte clearedValue = (byte) (b1 & 0x1F);
+ // Get header byte.
+ byte header = value[offset];
+ // Determine size.
+ int size = getHeaderLength(header);
+ // Prepare result.
+ int result = getHeaderValue(header);
- int start = INTEGER_SIZE - length;
- buffer.put(start, clearedValue);
- for (int i = offset + 1; i < offset + length; i++) {
- buffer.put(++start, value[i]);
- }
- } else {
- buffer.put(value, offset, INTEGER_SIZE);
+ // For each value byte
+ for (int i = 1; i < size; i++) {
+ // Merge byte value.
+ result <<= Byte.SIZE;
+ result |= value[offset + i] & 0xFF;
}
- return buffer.getInt(0);
+
+ return result;
}
- public static byte[] compress(int val) {
- ByteBuffer result = ByteBuffer.allocate(4).putInt(val);
- byte[] array = result.array();
+ public static byte[] compress(int value) {
+ // Only positive values are supported.
+ if (value < 0) {
+ throw new IllegalArgumentException("value < 0");
+ }
+
+ // Determine number of significant digits.
+ int width = 32 - Integer.numberOfLeadingZeros(value);
+ // Determine number of byte to represent. Allow for header if
+ // compressed.
+ int size = Math.min(((width + HEADER_WIDTH - 1) >> 3) + 1, Integer.BYTES);
+
+ // Allocate result buffer.
+ byte[] result = new byte[size];
- if ((val & 0xFF000000) == 0) { // nothing on 4th
- if ((val & 0x00FF0000) == 0) { // nothing on 3rd
- if ((val & 0x0000FF00) == 0) { // nothing on 2nd
- if ((val & 0x000000E0) == 0) { // only in 1st, encode length in the byte.
- //sign bit and size 1 ==> 101X
- result = ByteBuffer.allocate(1);
- result.put((byte) (0xA0 | array[3]));
- } else { // add a byte for size
- //sign bit and size 2 ==> 110X
- result = ByteBuffer.allocate(2);
- result.put((byte) 0xC0);
- result.put(array[3]);
- }
- } else { // content in 2nd
- if ((val & 0x0000E000) == 0) {// encode length in the byte.
- //sign bit and size 2 ==> 110X
- result = ByteBuffer.allocate(2);
- result.put((byte) (0xC0 | array[2]));
- result.put(array[3]);
- } else { // add a byte for size
- //sign bit and size 3 ==> 111X
- result = ByteBuffer.allocate(3);
- result.put((byte) 0xE0);
- result.put(array[2]);
- result.put(array[3]);
- }
- }
- } else {// content in 3rd
- if ((val & 0x00E00000) == 0) {// encode length in the byte.
- //sign bit and size 3 ==> 111X
- result = ByteBuffer.allocate(3);
- result.put((byte) (0xE0 | array[1]));
- result.put(array[2]);
- result.put(array[3]);
- } else { // add a byte, useless
- //
- }
- }
+ // Insert significant bytes in result.
+ for (int i = 0; i < size; i++) {
+ result[i] = (byte)(value >> ((size - i - 1) * Byte.SIZE));
}
- return result.array();
+
+ // If compressed, mark and insert size.
+ if (size < Integer.BYTES) {
+ result[0] |= (byte)(COMPRESSED_FLAG | (size << HEADER_SHIFT));
+ }
+
+ return result;
}
+
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java Thu Apr 07 11:03:59 2016 -0700
@@ -86,8 +86,8 @@
private InnocuousThread(ThreadGroup group, Runnable target, String name, ClassLoader tccl) {
super(group, target, name, 0L, false);
- UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
- UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, tccl);
+ UNSAFE.putObjectRelease(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
+ UNSAFE.putObjectRelease(this, CONTEXTCLASSLOADER, tccl);
}
@Override
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Thu Apr 07 11:03:59 2016 -0700
@@ -1457,25 +1457,7 @@
@HotSpotIntrinsicCandidate
public native void putDoubleVolatile(Object o, long offset, double x);
- /**
- * Version of {@link #putObjectVolatile(Object, long, Object)}
- * that does not guarantee immediate visibility of the store to
- * other threads. This method is generally only useful if the
- * underlying field is a Java volatile (or if an array cell, one
- * that is otherwise only accessed using volatile accesses).
- *
- * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
- */
- @HotSpotIntrinsicCandidate
- public native void putOrderedObject(Object o, long offset, Object x);
- /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */
- @HotSpotIntrinsicCandidate
- public native void putOrderedInt(Object o, long offset, int x);
-
- /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
- @HotSpotIntrinsicCandidate
- public native void putOrderedLong(Object o, long offset, long x);
/** Acquire version of {@link #getObjectVolatile(Object, long)} */
@HotSpotIntrinsicCandidate
@@ -1531,6 +1513,16 @@
return getDoubleVolatile(o, offset);
}
+ /*
+ * Versions of {@link #putObjectVolatile(Object, long, Object)}
+ * that do not guarantee immediate visibility of the store to
+ * other threads. This method is generally only useful if the
+ * underlying field is a Java volatile (or if an array cell, one
+ * that is otherwise only accessed using volatile accesses).
+ *
+ * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
+ */
+
/** Release version of {@link #putObjectVolatile(Object, long, Object)} */
@HotSpotIntrinsicCandidate
public final void putObjectRelease(Object o, long offset, Object x) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/vm/VMSupport.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2005, 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 jdk.internal.vm;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.jar.Attributes;
+
+/*
+ * Support class used by JVMTI and VM attach mechanism.
+ */
+public class VMSupport {
+
+ private static Properties agentProps = null;
+ /**
+ * Returns the agent properties.
+ */
+ public static synchronized Properties getAgentProperties() {
+ if (agentProps == null) {
+ agentProps = new Properties();
+ initAgentProperties(agentProps);
+ }
+ return agentProps;
+ }
+ private static native Properties initAgentProperties(Properties props);
+
+ /**
+ * Write the given properties list to a byte array and return it. Properties with
+ * a key or value that is not a String is filtered out. The stream written to the byte
+ * array is ISO 8859-1 encoded.
+ */
+ private static byte[] serializePropertiesToByteArray(Properties p) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+
+ Properties props = new Properties();
+
+ // stringPropertyNames() returns a snapshot of the property keys
+ Set<String> keyset = p.stringPropertyNames();
+ for (String key : keyset) {
+ String value = p.getProperty(key);
+ props.put(key, value);
+ }
+
+ props.store(out, null);
+ return out.toByteArray();
+ }
+
+ public static byte[] serializePropertiesToByteArray() throws IOException {
+ return serializePropertiesToByteArray(System.getProperties());
+ }
+
+ public static byte[] serializeAgentPropertiesToByteArray() throws IOException {
+ return serializePropertiesToByteArray(getAgentProperties());
+ }
+
+ /*
+ * Returns true if the given JAR file has the Class-Path attribute in the
+ * main section of the JAR manifest. Throws RuntimeException if the given
+ * path is not a JAR file or some other error occurs.
+ */
+ public static boolean isClassPathAttributePresent(String path) {
+ try {
+ Manifest man = (new JarFile(path)).getManifest();
+ if (man != null) {
+ if (man.getMainAttributes().getValue(Attributes.Name.CLASS_PATH) != null) {
+ return true;
+ }
+ }
+ return false;
+ } catch (IOException ioe) {
+ throw new RuntimeException(ioe.getMessage());
+ }
+ }
+
+ /*
+ * Return the temporary directory that the VM uses for the attach
+ * and perf data files.
+ *
+ * It is important that this directory is well-known and the
+ * same for all VM instances. It cannot be affected by configuration
+ * variables such as java.io.tmpdir.
+ */
+ public static native String getVMTemporaryDirectory();
+}
--- a/jdk/src/java.base/share/classes/module-info.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/module-info.java Thu Apr 07 11:03:59 2016 -0700
@@ -182,6 +182,9 @@
java.desktop;
exports jdk.internal.util.jar to
jdk.jartool;
+ exports jdk.internal.vm to
+ java.management,
+ jdk.jvmstat;
exports sun.net to
java.httpclient;
exports sun.net.dns to
--- a/jdk/src/java.base/share/classes/sun/misc/GC.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,283 +0,0 @@
-/*
- * Copyright (c) 1998, 2008, 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 sun.misc;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-
-/**
- * Support for garbage-collection latency requests.
- *
- * @author Mark Reinhold
- * @since 1.2
- */
-
-public class GC {
-
- private GC() { } /* To prevent instantiation */
-
-
- /* Latency-target value indicating that there's no active target
- */
- private static final long NO_TARGET = Long.MAX_VALUE;
-
- /* The current latency target, or NO_TARGET if there is no target
- */
- private static long latencyTarget = NO_TARGET;
-
- /* The daemon thread that implements the latency-target mechanism,
- * or null if there is presently no daemon thread
- */
- private static Thread daemon = null;
-
- /* The lock object for the latencyTarget and daemon fields. The daemon
- * thread, if it exists, waits on this lock for notification that the
- * latency target has changed.
- */
- private static class LatencyLock extends Object { };
- private static Object lock = new LatencyLock();
-
-
- /**
- * Returns the maximum <em>object-inspection age</em>, which is the number
- * of real-time milliseconds that have elapsed since the
- * least-recently-inspected heap object was last inspected by the garbage
- * collector.
- *
- * <p> For simple stop-the-world collectors this value is just the time
- * since the most recent collection. For generational collectors it is the
- * time since the oldest generation was most recently collected. Other
- * collectors are free to return a pessimistic estimate of the elapsed
- * time, or simply the time since the last full collection was performed.
- *
- * <p> Note that in the presence of reference objects, a given object that
- * is no longer strongly reachable may have to be inspected multiple times
- * before it can be reclaimed.
- */
- public static native long maxObjectInspectionAge();
-
- private static class Daemon extends Thread {
-
- public void run() {
- for (;;) {
- long l;
- synchronized (lock) {
-
- l = latencyTarget;
- if (l == NO_TARGET) {
- /* No latency target, so exit */
- GC.daemon = null;
- return;
- }
-
- long d = maxObjectInspectionAge();
- if (d >= l) {
- /* Do a full collection. There is a remote possibility
- * that a full collection will occurr between the time
- * we sample the inspection age and the time the GC
- * actually starts, but this is sufficiently unlikely
- * that it doesn't seem worth the more expensive JVM
- * interface that would be required.
- */
- System.gc();
- d = 0;
- }
-
- /* Wait for the latency period to expire,
- * or for notification that the period has changed
- */
- try {
- lock.wait(l - d);
- } catch (InterruptedException x) {
- continue;
- }
- }
- }
- }
-
- private Daemon(ThreadGroup tg) {
- super(tg, null, "GC Daemon", 0L, false);
- }
-
- /* Create a new daemon thread in the root thread group */
- public static void create() {
- PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
- public Void run() {
- ThreadGroup tg = Thread.currentThread().getThreadGroup();
- for (ThreadGroup tgn = tg;
- tgn != null;
- tg = tgn, tgn = tg.getParent());
- Daemon d = new Daemon(tg);
- d.setDaemon(true);
- d.setPriority(Thread.MIN_PRIORITY + 1);
- d.start();
- GC.daemon = d;
- return null;
- }};
- AccessController.doPrivileged(pa);
- }
-
- }
-
-
- /* Sets the latency target to the given value.
- * Must be invoked while holding the lock.
- */
- private static void setLatencyTarget(long ms) {
- latencyTarget = ms;
- if (daemon == null) {
- /* Create a new daemon thread */
- Daemon.create();
- } else {
- /* Notify the existing daemon thread
- * that the lateency target has changed
- */
- lock.notify();
- }
- }
-
-
- /**
- * Represents an active garbage-collection latency request. Instances of
- * this class are created by the <code>{@link #requestLatency}</code>
- * method. Given a request, the only interesting operation is that of
- * cancellation.
- */
- public static class LatencyRequest
- implements Comparable<LatencyRequest> {
-
- /* Instance counter, used to generate unique identifers */
- private static long counter = 0;
-
- /* Sorted set of active latency requests */
- private static SortedSet<LatencyRequest> requests = null;
-
- /* Examine the request set and reset the latency target if necessary.
- * Must be invoked while holding the lock.
- */
- private static void adjustLatencyIfNeeded() {
- if ((requests == null) || requests.isEmpty()) {
- if (latencyTarget != NO_TARGET) {
- setLatencyTarget(NO_TARGET);
- }
- } else {
- LatencyRequest r = requests.first();
- if (r.latency != latencyTarget) {
- setLatencyTarget(r.latency);
- }
- }
- }
-
- /* The requested latency, or NO_TARGET
- * if this request has been cancelled
- */
- private long latency;
-
- /* Unique identifier for this request */
- private long id;
-
- private LatencyRequest(long ms) {
- if (ms <= 0) {
- throw new IllegalArgumentException("Non-positive latency: "
- + ms);
- }
- this.latency = ms;
- synchronized (lock) {
- this.id = ++counter;
- if (requests == null) {
- requests = new TreeSet<LatencyRequest>();
- }
- requests.add(this);
- adjustLatencyIfNeeded();
- }
- }
-
- /**
- * Cancels this latency request.
- *
- * @throws IllegalStateException
- * If this request has already been cancelled
- */
- public void cancel() {
- synchronized (lock) {
- if (this.latency == NO_TARGET) {
- throw new IllegalStateException("Request already"
- + " cancelled");
- }
- if (!requests.remove(this)) {
- throw new InternalError("Latency request "
- + this + " not found");
- }
- if (requests.isEmpty()) requests = null;
- this.latency = NO_TARGET;
- adjustLatencyIfNeeded();
- }
- }
-
- public int compareTo(LatencyRequest r) {
- long d = this.latency - r.latency;
- if (d == 0) d = this.id - r.id;
- return (d < 0) ? -1 : ((d > 0) ? +1 : 0);
- }
-
- public String toString() {
- return (LatencyRequest.class.getName()
- + "[" + latency + "," + id + "]");
- }
-
- }
-
-
- /**
- * Makes a new request for a garbage-collection latency of the given
- * number of real-time milliseconds. A low-priority daemon thread makes a
- * best effort to ensure that the maximum object-inspection age never
- * exceeds the smallest of the currently active requests.
- *
- * @param latency
- * The requested latency
- *
- * @throws IllegalArgumentException
- * If the given <code>latency</code> is non-positive
- */
- public static LatencyRequest requestLatency(long latency) {
- return new LatencyRequest(latency);
- }
-
-
- /**
- * Returns the current smallest garbage-collection latency request, or zero
- * if there are no active requests.
- */
- public static long currentLatencyTarget() {
- long t = latencyTarget;
- return (t == NO_TARGET) ? 0 : t;
- }
-
-}
--- a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Thu Apr 07 11:03:59 2016 -0700
@@ -1068,19 +1068,19 @@
*/
@ForceInline
public void putOrderedObject(Object o, long offset, Object x) {
- theInternalUnsafe.putOrderedObject(o, offset, x);
+ theInternalUnsafe.putObjectRelease(o, offset, x);
}
/** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */
@ForceInline
public void putOrderedInt(Object o, long offset, int x) {
- theInternalUnsafe.putOrderedInt(o, offset, x);
+ theInternalUnsafe.putIntRelease(o, offset, x);
}
/** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
@ForceInline
public void putOrderedLong(Object o, long offset, long x) {
- theInternalUnsafe.putOrderedLong(o, offset, x);
+ theInternalUnsafe.putLongRelease(o, offset, x);
}
/**
--- a/jdk/src/java.base/share/classes/sun/misc/VMSupport.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2005, 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 sun.misc;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Properties;
-import java.util.Set;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-import java.util.jar.Attributes;
-
-/*
- * Support class used by JVMTI and VM attach mechanism.
- */
-public class VMSupport {
-
- private static Properties agentProps = null;
- /**
- * Returns the agent properties.
- */
- public static synchronized Properties getAgentProperties() {
- if (agentProps == null) {
- agentProps = new Properties();
- initAgentProperties(agentProps);
- }
- return agentProps;
- }
- private static native Properties initAgentProperties(Properties props);
-
- /**
- * Write the given properties list to a byte array and return it. Properties with
- * a key or value that is not a String is filtered out. The stream written to the byte
- * array is ISO 8859-1 encoded.
- */
- private static byte[] serializePropertiesToByteArray(Properties p) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
-
- Properties props = new Properties();
-
- // stringPropertyNames() returns a snapshot of the property keys
- Set<String> keyset = p.stringPropertyNames();
- for (String key : keyset) {
- String value = p.getProperty(key);
- props.put(key, value);
- }
-
- props.store(out, null);
- return out.toByteArray();
- }
-
- public static byte[] serializePropertiesToByteArray() throws IOException {
- return serializePropertiesToByteArray(System.getProperties());
- }
-
- public static byte[] serializeAgentPropertiesToByteArray() throws IOException {
- return serializePropertiesToByteArray(getAgentProperties());
- }
-
- /*
- * Returns true if the given JAR file has the Class-Path attribute in the
- * main section of the JAR manifest. Throws RuntimeException if the given
- * path is not a JAR file or some other error occurs.
- */
- public static boolean isClassPathAttributePresent(String path) {
- try {
- Manifest man = (new JarFile(path)).getManifest();
- if (man != null) {
- if (man.getMainAttributes().getValue(Attributes.Name.CLASS_PATH) != null) {
- return true;
- }
- }
- return false;
- } catch (IOException ioe) {
- throw new RuntimeException(ioe.getMessage());
- }
- }
-
- /*
- * Return the temporary directory that the VM uses for the attach
- * and perf data files.
- *
- * It is important that this directory is well-known and the
- * same for all VM instances. It cannot be affected by configuration
- * variables such as java.io.tmpdir.
- */
- public static native String getVMTemporaryDirectory();
-}
--- a/jdk/src/java.base/share/classes/sun/net/TransferProtocolClient.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/TransferProtocolClient.java Thu Apr 07 11:03:59 2016 -0700
@@ -83,7 +83,7 @@
code = Integer.parseInt(response, 0, 3, 10);
} catch (NumberFormatException e) {
code = -1;
- } catch (StringIndexOutOfBoundsException e) {
+ } catch (IndexOutOfBoundsException e) {
/* this line doesn't contain a response code, so
we just completely ignore it */
continue;
--- a/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java Thu Apr 07 11:03:59 2016 -0700
@@ -440,7 +440,7 @@
code = Integer.parseInt(response, 0, 3, 10);
} catch (NumberFormatException e) {
code = -1;
- } catch (StringIndexOutOfBoundsException e) {
+ } catch (IndexOutOfBoundsException e) {
/* this line doesn't contain a response code, so
we just completely ignore it */
continue;
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2016, 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
@@ -299,6 +299,13 @@
// Just keep throwing for now.
throw e;
} catch (FtpProtocolException fe) {
+ if (ftp != null) {
+ try {
+ ftp.close();
+ } catch (IOException ioe) {
+ fe.addSuppressed(ioe);
+ }
+ }
throw new IOException(fe);
}
try {
@@ -481,11 +488,34 @@
msgh.add("content-type", "text/plain");
msgh.add("access-type", "directory");
} catch (IOException ex) {
- throw new FileNotFoundException(fullpath);
+ FileNotFoundException fnfe = new FileNotFoundException(fullpath);
+ if (ftp != null) {
+ try {
+ ftp.close();
+ } catch (IOException ioe) {
+ fnfe.addSuppressed(ioe);
+ }
+ }
+ throw fnfe;
} catch (FtpProtocolException ex2) {
- throw new FileNotFoundException(fullpath);
+ FileNotFoundException fnfe = new FileNotFoundException(fullpath);
+ if (ftp != null) {
+ try {
+ ftp.close();
+ } catch (IOException ioe) {
+ fnfe.addSuppressed(ioe);
+ }
+ }
+ throw fnfe;
}
} catch (FtpProtocolException ftpe) {
+ if (ftp != null) {
+ try {
+ ftp.close();
+ } catch (IOException ioe) {
+ ftpe.addSuppressed(ioe);
+ }
+ }
throw new IOException(ftpe);
}
setProperties(msgh);
--- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeMessage.java Thu Apr 07 11:03:59 2016 -0700
@@ -1198,8 +1198,9 @@
if (!localSupportedSignAlgs.contains(
preferableSignatureAlgorithm)) {
throw new SSLHandshakeException(
- "Unsupported SignatureAndHashAlgorithm in " +
- "ServerKeyExchange message");
+ "Unsupported SignatureAndHashAlgorithm in " +
+ "ServerKeyExchange message: " +
+ preferableSignatureAlgorithm);
}
} else {
this.preferableSignatureAlgorithm = null;
@@ -1232,7 +1233,8 @@
sig = RSASignature.getInstance();
break;
default:
- throw new SSLKeyException("neither an RSA or a DSA key");
+ throw new SSLKeyException(
+ "neither an RSA or a DSA key: " + algorithm);
}
}
@@ -1482,7 +1484,8 @@
preferableSignatureAlgorithm)) {
throw new SSLHandshakeException(
"Unsupported SignatureAndHashAlgorithm in " +
- "ServerKeyExchange message");
+ "ServerKeyExchange message: " +
+ preferableSignatureAlgorithm);
}
}
@@ -1522,7 +1525,8 @@
case "RSA":
return RSASignature.getInstance();
default:
- throw new NoSuchAlgorithmException("neither an RSA or a EC key");
+ throw new NoSuchAlgorithmException(
+ "neither an RSA or a EC key : " + keyAlgorithm);
}
}
@@ -1729,7 +1733,8 @@
algorithmsLen = input.getInt16();
if (algorithmsLen < 2) {
throw new SSLProtocolException(
- "Invalid supported_signature_algorithms field");
+ "Invalid supported_signature_algorithms field: " +
+ algorithmsLen);
}
algorithms = new ArrayList<SignatureAndHashAlgorithm>();
@@ -1748,7 +1753,8 @@
if (remains != 0) {
throw new SSLProtocolException(
- "Invalid supported_signature_algorithms field");
+ "Invalid supported_signature_algorithms field. remains: " +
+ remains);
}
} else {
algorithms = new ArrayList<SignatureAndHashAlgorithm>();
@@ -1765,7 +1771,8 @@
}
if (len != 0) {
- throw new SSLProtocolException("Bad CertificateRequest DN length");
+ throw new SSLProtocolException(
+ "Bad CertificateRequest DN length: " + len);
}
authorities = v.toArray(new DistinguishedName[v.size()]);
@@ -1995,8 +2002,8 @@
if (!localSupportedSignAlgs.contains(
preferableSignatureAlgorithm)) {
throw new SSLHandshakeException(
- "Unsupported SignatureAndHashAlgorithm in " +
- "CertificateVerify message");
+ "Unsupported SignatureAndHashAlgorithm in " +
+ "CertificateVerify message: " + preferableSignatureAlgorithm);
}
}
@@ -2364,7 +2371,8 @@
SecretKey prfKey = kg.generateKey();
if ("RAW".equals(prfKey.getFormat()) == false) {
throw new ProviderException(
- "Invalid PRF output, format must be RAW");
+ "Invalid PRF output, format must be RAW. " +
+ "Format received: " + prfKey.getFormat());
}
byte[] finished = prfKey.getEncoded();
return finished;
--- a/jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java Thu Apr 07 11:03:59 2016 -0700
@@ -68,7 +68,8 @@
ProtocolVersion maxVersion,
SecureRandom generator, PublicKey publicKey) throws IOException {
if (publicKey.getAlgorithm().equals("RSA") == false) {
- throw new SSLKeyException("Public key not of type RSA");
+ throw new SSLKeyException("Public key not of type RSA: " +
+ publicKey.getAlgorithm());
}
this.protocolVersion = protocolVersion;
@@ -100,7 +101,8 @@
int messageSize, PrivateKey privateKey) throws IOException {
if (privateKey.getAlgorithm().equals("RSA") == false) {
- throw new SSLKeyException("Private key not of type RSA");
+ throw new SSLKeyException("Private key not of type RSA: " +
+ privateKey.getAlgorithm());
}
if (currentVersion.useTLS10PlusSpec()) {
@@ -161,8 +163,8 @@
}
} catch (InvalidKeyException ibk) {
// the message is too big to process with RSA
- throw new SSLProtocolException(
- "Unable to process PreMasterSecret, may be too big");
+ throw new SSLException(
+ "Unable to process PreMasterSecret", ibk);
} catch (Exception e) {
// unlikely to happen, otherwise, must be a provider exception
if (debug != null && Debug.isOn("handshake")) {
--- a/jdk/src/java.base/share/native/libjava/GC.c Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 1998, 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.
- */
-
-#include <jni.h>
-#include <jvm.h>
-#include "sun_misc_GC.h"
-
-
-JNIEXPORT jlong JNICALL
-Java_sun_misc_GC_maxObjectInspectionAge(JNIEnv *env, jclass cls)
-{
- return JVM_MaxObjectInspectionAge();
-}
--- a/jdk/src/java.base/share/native/libjava/VMSupport.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/native/libjava/VMSupport.c Thu Apr 07 11:03:59 2016 -0700
@@ -27,36 +27,17 @@
#include "jni_util.h"
#include "jlong.h"
#include "jvm.h"
-#include "jdk_util.h"
-#include "sun_misc_VMSupport.h"
-
-typedef jobject (JNICALL *INIT_AGENT_PROPERTIES_FN)(JNIEnv *, jobject);
-
-static INIT_AGENT_PROPERTIES_FN InitAgentProperties_fp = NULL;
+#include "jdk_internal_vm_VMSupport.h"
JNIEXPORT jobject JNICALL
-Java_sun_misc_VMSupport_initAgentProperties(JNIEnv *env, jclass cls, jobject props)
+Java_jdk_internal_vm_VMSupport_initAgentProperties(JNIEnv *env, jclass cls, jobject props)
{
- if (InitAgentProperties_fp == NULL) {
- if (!JDK_InitJvmHandle()) {
- JNU_ThrowInternalError(env,
- "Handle for JVM not found for symbol lookup");
- return NULL;
- }
- InitAgentProperties_fp = (INIT_AGENT_PROPERTIES_FN)
- JDK_FindJvmEntry("JVM_InitAgentProperties");
- if (InitAgentProperties_fp == NULL) {
- JNU_ThrowInternalError(env,
- "Mismatched VM version: JVM_InitAgentProperties not found");
- return NULL;
- }
- }
- return (*InitAgentProperties_fp)(env, props);
+ return JVM_InitAgentProperties(env, props);
}
JNIEXPORT jstring JNICALL
-Java_sun_misc_VMSupport_getVMTemporaryDirectory(JNIEnv *env, jclass cls)
+Java_jdk_internal_vm_VMSupport_getVMTemporaryDirectory(JNIEnv *env, jclass cls)
{
return JVM_GetTemporaryDirectory(env);
}
--- a/jdk/src/java.base/share/native/libjli/java.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/native/libjli/java.c Thu Apr 07 11:03:59 2016 -0700
@@ -2003,16 +2003,21 @@
void *image_data = NULL;
float scale_factor = 1;
char *scaled_splash_name = NULL;
-
+ jboolean isImageScaled = JNI_FALSE;
+ size_t maxScaledImgNameLength = 0;
if (file_name == NULL){
return;
}
+ maxScaledImgNameLength = DoSplashGetScaledImgNameMaxPstfixLen(file_name);
- scaled_splash_name = DoSplashGetScaledImageName(
- jar_name, file_name, &scale_factor);
+ scaled_splash_name = JLI_MemAlloc(
+ maxScaledImgNameLength * sizeof(char));
+ isImageScaled = DoSplashGetScaledImageName(jar_name, file_name,
+ &scale_factor,
+ scaled_splash_name, maxScaledImgNameLength);
if (jar_name) {
- if (scaled_splash_name) {
+ if (isImageScaled) {
image_data = JLI_JarUnpackFile(
jar_name, scaled_splash_name, &data_size);
}
@@ -2030,17 +2035,14 @@
}
} else {
DoSplashInit();
- if (scaled_splash_name) {
+ if (isImageScaled) {
DoSplashSetScaleFactor(scale_factor);
DoSplashLoadFile(scaled_splash_name);
} else {
DoSplashLoadFile(file_name);
}
}
-
- if (scaled_splash_name) {
- JLI_MemFree(scaled_splash_name);
- }
+ JLI_MemFree(scaled_splash_name);
DoSplashSetFileJarName(file_name, jar_name);
--- a/jdk/src/java.base/share/native/libjli/splashscreen.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/native/libjli/splashscreen.h Thu Apr 07 11:03:59 2016 -0700
@@ -22,7 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
+#include "jni.h"
int DoSplashLoadMemory(void* pdata, int size); /* requires preloading the file */
int DoSplashLoadFile(const char* filename);
@@ -30,5 +30,6 @@
void DoSplashClose(void);
void DoSplashSetFileJarName(const char* fileName, const char* jarName);
void DoSplashSetScaleFactor(float scaleFactor);
-char* DoSplashGetScaledImageName(const char* jarName, const char* fileName,
- float* scaleFactor);
+jboolean DoSplashGetScaledImageName(const char* jarName, const char* fileName,
+ float* scaleFactor, char *scaleImageName, const size_t scaleImageNameLength);
+int DoSplashGetScaledImgNameMaxPstfixLen(const char *fileName);
--- a/jdk/src/java.base/share/native/libjli/splashscreen_stubs.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.base/share/native/libjli/splashscreen_stubs.c Thu Apr 07 11:03:59 2016 -0700
@@ -25,7 +25,7 @@
#include <stdio.h>
#include "splashscreen.h"
-
+#include "jni.h"
extern void* SplashProcAddress(const char* name); /* in java_md.c */
/*
@@ -38,8 +38,10 @@
typedef void (*SplashSetFileJarName_t)(const char* fileName,
const char* jarName);
typedef void (*SplashSetScaleFactor_t)(float scaleFactor);
-typedef char* (*SplashGetScaledImageName_t)(const char* fileName,
- const char* jarName, float* scaleFactor);
+typedef jboolean (*SplashGetScaledImageName_t)(const char* fileName,
+ const char* jarName, float* scaleFactor,
+ char *scaleImageName, const size_t scaleImageNameLength);
+typedef int (*SplashGetScaledImgNameMaxPstfixLen_t)(const char* filename);
/*
* This macro invokes a function from the shared lib.
@@ -60,6 +62,7 @@
#define INVOKE(name,def) _INVOKE(name,def,return)
#define INVOKEV(name) _INVOKE(name, ,;)
+
int DoSplashLoadMemory(void* pdata, int size) {
INVOKE(SplashLoadMemory, 0)(pdata, size);
}
@@ -84,7 +87,13 @@
INVOKEV(SplashSetScaleFactor)(scaleFactor);
}
-char* DoSplashGetScaledImageName(const char* fileName, const char* jarName,
- float* scaleFactor) {
- INVOKE(SplashGetScaledImageName, NULL)(fileName, jarName, scaleFactor);
+jboolean DoSplashGetScaledImageName(const char* fileName, const char* jarName,
+ float* scaleFactor, char *scaledImageName, const size_t scaledImageNameLength) {
+ INVOKE(SplashGetScaledImageName, 0)(fileName, jarName, scaleFactor,
+ scaledImageName, scaledImageNameLength);
}
+
+int DoSplashGetScaledImgNameMaxPstfixLen(const char *fileName) {
+ INVOKE(SplashGetScaledImgNameMaxPstfixLen, 0)(fileName);
+}
+
--- a/jdk/src/java.compact3/share/classes/module-info.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.compact3/share/classes/module-info.java Thu Apr 07 11:03:59 2016 -0700
@@ -26,7 +26,6 @@
module java.compact3 {
requires public java.compact2;
requires public java.compiler;
- requires public java.httpclient;
requires public java.instrument;
requires public java.management;
requires public java.naming;
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AboutHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.AboutEvent;
-
-/**
- * An implementor receives notification when the app is asked to show it's about dialog.
- *
- * @see Application#setAboutHandler(AboutHandler)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface AboutHandler {
- /**
- * Called when the application is asked to show it's about dialog.
- * @param e the request to show the about dialog.
- */
- public void handleAbout(final AboutEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppEvent.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, 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;
-
-import java.io.File;
-import java.net.URI;
-import java.util.*;
-import java.awt.Window;
-
-/**
- * AppEvents are sent to listeners and handlers installed on the {@link Application}.
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-@SuppressWarnings("serial") // JDK implementation class
-public abstract class AppEvent extends EventObject {
- AppEvent() {
- super(Application.getApplication());
- }
-
- /**
- * Contains a list of files.
- */
- @SuppressWarnings("serial") // JDK implementation class
- public abstract static class FilesEvent extends AppEvent {
- final List<File> files;
-
- FilesEvent(final List<File> files) {
- this.files = files;
- }
-
- /**
- * @return the list of files
- */
- public List<File> getFiles() {
- return files;
- }
- }
-
- /**
- * Event sent when the app is asked to open a list of files.
- *
- * @see OpenFilesHandler#openFiles(OpenFilesEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class OpenFilesEvent extends FilesEvent {
- final String searchTerm;
-
- OpenFilesEvent(final List<File> files, final String searchTerm) {
- super(files);
- this.searchTerm = searchTerm;
- }
-
- /**
- * If the files were opened using the Spotlight search menu or a Finder search window, this method obtains the search term used to find the files.
- * This is useful for highlighting the search term in the documents when they are opened.
- * @return the search term used to find the files
- */
- public String getSearchTerm() {
- return searchTerm;
- }
- }
-
- /**
- * Event sent when the app is asked to print a list of files.
- *
- * @see PrintFilesHandler#printFiles(PrintFilesEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class PrintFilesEvent extends FilesEvent {
- PrintFilesEvent(final List<File> files) {
- super(files);
- }
- }
-
- /**
- * Event sent when the app is asked to open a URI.
- *
- * @see OpenURIHandler#openURI(OpenURIEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class OpenURIEvent extends AppEvent {
- final URI uri;
-
- OpenURIEvent(final URI uri) {
- this.uri = uri;
- }
-
- /**
- * @return the URI the app was asked to open
- */
- public URI getURI() {
- return uri;
- }
- }
-
- /**
- * Event sent when the application is asked to open it's about window.
- *
- * @see AboutHandler#handleAbout()
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class AboutEvent extends AppEvent { AboutEvent() { } }
-
- /**
- * Event sent when the application is asked to open it's preferences window.
- *
- * @see PreferencesHandler#handlePreferences()
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class PreferencesEvent extends AppEvent { PreferencesEvent() { } }
-
- /**
- * Event sent when the application is asked to quit.
- *
- * @see QuitHandler#handleQuitRequestWith(QuitEvent, QuitResponse)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class QuitEvent extends AppEvent { QuitEvent() { } }
-
- /**
- * Event sent when the application is asked to re-open itself.
- *
- * @see AppReOpenedListener#appReOpened(AppReOpenedEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class AppReOpenedEvent extends AppEvent { AppReOpenedEvent() { } }
-
- /**
- * Event sent when the application has become the foreground app, and when it has resigned being the foreground app.
- *
- * @see AppForegroundListener#appRaisedToForeground(AppForegroundEvent)
- * @see AppForegroundListener#appMovedToBackground(AppForegroundEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class AppForegroundEvent extends AppEvent { AppForegroundEvent() { } }
-
- /**
- * Event sent when the application has been hidden or shown.
- *
- * @see AppHiddenListener#appHidden(AppHiddenEvent)
- * @see AppHiddenListener#appUnhidden(AppHiddenEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class AppHiddenEvent extends AppEvent { AppHiddenEvent() { } }
-
- /**
- * Event sent when the user session has been changed via Fast User Switching.
- *
- * @see UserSessionListener#userSessionActivated(UserSessionEvent)
- * @see UserSessionListener#userSessionDeactivated(UserSessionEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class UserSessionEvent extends AppEvent { UserSessionEvent() { } }
-
- /**
- * Event sent when the displays attached to the system enter and exit power save sleep.
- *
- * @see ScreenSleepListener#screenAboutToSleep(ScreenSleepEvent)
- * @see ScreenSleepListener#screenAwoke(ScreenSleepEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class ScreenSleepEvent extends AppEvent { ScreenSleepEvent() { } }
-
- /**
- * Event sent when the system enters and exits power save sleep.
- *
- * @see SystemSleepListener#systemAboutToSleep(SystemSleepEvent)
- * @see SystemSleepListener#systemAwoke(SystemSleepEvent)
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class SystemSleepEvent extends AppEvent { SystemSleepEvent() { } }
-
- /**
- * Event sent when a window is entering/exiting or has entered/exited full screen state.
- *
- * @see FullScreenUtilities
- *
- * @since Java for Mac OS X 10.7 Update 1
- */
- @SuppressWarnings("serial") // JDK implementation class
- public static class FullScreenEvent extends AppEvent {
- final Window window;
-
- FullScreenEvent(final Window window) {
- this.window = window;
- }
-
- /**
- * @return window transitioning between full screen states
- */
- public Window getWindow() {
- return window;
- }
- }
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppEventListener.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-/**
- * Common interface for all event listener sub-types.
- * Implementors may implement multiple sub-types, but only need to call {@link Application#addAppEventListener(AppEventListener)} once to receive all notifications.
- *
- * @see AppReOpenedListener
- * @see AppForegroundListener
- * @see AppHiddenListener
- * @see ScreenSleepListener
- * @see SystemSleepListener
- * @see UserSessionListener
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface AppEventListener { }
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppForegroundListener.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.AppForegroundEvent;
-
-/**
- * Implementors are notified when the app becomes the foreground app and when it resigns being the foreground app.
- * This notification is useful for hiding and showing transient UI like palette windows which should be hidden when the app is in the background.
- *
- * @see Application#addAppEventListener(AppEventListener)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface AppForegroundListener extends AppEventListener {
- /**
- * Called when the app becomes the foreground app.
- * @param e the app became foreground notification.
- */
- public void appRaisedToForeground(final AppForegroundEvent e);
-
- /**
- * Called when the app resigns to the background and another app becomes the foreground app.
- * @param e the app resigned foreground notification.
- */
- public void appMovedToBackground(final AppForegroundEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppHiddenListener.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.AppHiddenEvent;
-
-/**
- * Implementors are notified when the app is hidden or shown by the user.
- * This notification is helpful for discontinuing a costly animation if it's not visible to the user.
- *
- * @see Application#addAppEventListener(AppEventListener)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface AppHiddenListener extends AppEventListener {
- /**
- * Called the app is hidden.
- * @param e
- */
- public void appHidden(final AppHiddenEvent e);
-
- /**
- * Called when the hidden app is shown again (but not necessarily brought to the foreground).
- * @param e
- */
- public void appUnhidden(final AppHiddenEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/AppReOpenedListener.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.AppReOpenedEvent;
-
-/**
- * Implementors receive notification when the app has been asked to open again.
- * Re-open events occur when the user clicks on the running app's Dock icon.
- * Re-open events also occur when the app is double-clicked in the Finder and the app is already running.
- *
- * This notification is useful for showing a new document when your app has no open windows.
- *
- * @see Application#addAppEventListener(AppEventListener)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface AppReOpenedListener extends AppEventListener {
- /**
- * Called when the app has been re-opened (it's Dock icon was clicked on, or was double-clicked in the Finder)
- * @param e the request to re-open the app
- */
- public void appReOpened(final AppReOpenedEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/Application.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/Application.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -26,10 +26,10 @@
package com.apple.eawt;
import java.awt.Image;
-import java.awt.Point;
import java.awt.PopupMenu;
import java.awt.Toolkit;
import java.awt.Window;
+import java.awt.desktop.*;
import java.beans.Beans;
import javax.swing.JMenuBar;
@@ -104,38 +104,38 @@
}
/**
- * Adds sub-types of {@link AppEventListener} to listen for notifications from the native Mac OS X system.
+ * Adds sub-types of {@link SystemEventListener} to listen for notifications from the native Mac OS X system.
*
* @see AppForegroundListener
* @see AppHiddenListener
* @see AppReOpenedListener
- * @see ScreenSleepListener
- * @see SystemSleepListener
- * @see UserSessionListener
+ * @see AppScreenSleepListener
+ * @see AppSystemSleepListener
+ * @see AppUserSessionListener
*
* @param listener
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
- public void addAppEventListener(final AppEventListener listener) {
+ public void addAppEventListener(final SystemEventListener listener) {
eventHandler.addListener(listener);
}
/**
- * Removes sub-types of {@link AppEventListener} from listening for notifications from the native Mac OS X system.
+ * Removes sub-types of {@link SystemEventListener} from listening for notifications from the native Mac OS X system.
*
* @see AppForegroundListener
* @see AppHiddenListener
* @see AppReOpenedListener
- * @see ScreenSleepListener
- * @see SystemSleepListener
- * @see UserSessionListener
+ * @see AppScreenSleepListener
+ * @see AppSystemSleepListener
+ * @see AppUserSessionListener
*
* @param listener
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
- public void removeAppEventListener(final AppEventListener listener) {
+ public void removeAppEventListener(final SystemEventListener listener) {
eventHandler.removeListener(listener);
}
@@ -368,6 +368,17 @@
}
/**
+ * Displays a progress bar to this application's Dock icon.
+ * Acceptable values are from 0 to 100, any other disables progress indication.
+ *
+ * @param value progress value
+ * @since 1.9
+ */
+ public void setDockIconProgress(final int value) {
+ iconHandler.setDockIconProgress(value);
+ }
+
+ /**
* Sets the default menu bar to use when there are no active frames.
* Only used when the system property "apple.laf.useScreenMenuBar" is "true", and
* the Aqua Look and Feel is active.
@@ -397,168 +408,4 @@
((CPlatformWindow)platformWindow).toggleFullScreen();
}
-
- // -- DEPRECATED API --
-
- /**
- * Adds the specified ApplicationListener as a receiver of callbacks from this class.
- * This method throws a RuntimeException if the newer About, Preferences, Quit, etc handlers are installed.
- *
- * @param listener an implementation of ApplicationListener that handles ApplicationEvents
- *
- * @deprecated register individual handlers for each task (About, Preferences, Open, Print, Quit, etc)
- * @since 1.4
- */
- @SuppressWarnings("deprecation")
- @Deprecated
- public void addApplicationListener(final ApplicationListener listener) {
- eventHandler.legacyHandler.addLegacyAppListener(listener);
- }
-
- /**
- * Removes the specified ApplicationListener from being a receiver of callbacks from this class.
- * This method throws a RuntimeException if the newer About, Preferences, Quit, etc handlers are installed.
- *
- * @param listener an implementation of ApplicationListener that had previously been registered to handle ApplicationEvents
- *
- * @deprecated unregister individual handlers for each task (About, Preferences, Open, Print, Quit, etc)
- * @since 1.4
- */
- @SuppressWarnings("deprecation")
- @Deprecated
- public void removeApplicationListener(final ApplicationListener listener) {
- eventHandler.legacyHandler.removeLegacyAppListener(listener);
- }
-
- /**
- * Enables the Preferences item in the application menu. The ApplicationListener receives a callback for
- * selection of the Preferences item in the application menu only if this is set to {@code true}.
- *
- * If a Preferences item isn't present, this method adds and enables it.
- *
- * @param enable specifies whether the Preferences item in the application menu should be enabled ({@code true}) or not ({@code false})
- *
- * @deprecated no replacement
- * @since 1.4
- */
- @Deprecated
- public void setEnabledPreferencesMenu(final boolean enable) {
- menuBarHandler.setPreferencesMenuItemVisible(true);
- menuBarHandler.setPreferencesMenuItemEnabled(enable);
- }
-
- /**
- * Enables the About item in the application menu. The ApplicationListener receives a callback for
- * selection of the About item in the application menu only if this is set to {@code true}. Because AWT supplies
- * a standard About window when an application may not, by default this is set to {@code true}.
- *
- * If the About item isn't present, this method adds and enables it.
- *
- * @param enable specifies whether the About item in the application menu should be enabled ({@code true}) or not ({@code false})
- *
- * @deprecated no replacement
- * @since 1.4
- */
- @Deprecated
- public void setEnabledAboutMenu(final boolean enable) {
- menuBarHandler.setAboutMenuItemEnabled(enable);
- }
-
- /**
- * Determines if the Preferences item of the application menu is enabled.
- *
- * @deprecated no replacement
- * @since 1.4
- */
- @Deprecated
- public boolean getEnabledPreferencesMenu() {
- return menuBarHandler.isPreferencesMenuItemEnabled();
- }
-
- /**
- * Determines if the About item of the application menu is enabled.
- *
- * @deprecated no replacement
- * @since 1.4
- */
- @Deprecated
- public boolean getEnabledAboutMenu() {
- return menuBarHandler.isAboutMenuItemEnabled();
- }
-
- /**
- * Determines if the About item of the application menu is present.
- *
- * @deprecated no replacement
- * @since 1.4
- */
- @Deprecated
- public boolean isAboutMenuItemPresent() {
- return menuBarHandler.isAboutMenuItemVisible();
- }
-
- /**
- * Adds the About item to the application menu if the item is not already present.
- *
- * @deprecated use {@link #setAboutHandler(AboutHandler)} with a non-null {@link AboutHandler} parameter
- * @since 1.4
- */
- @Deprecated
- public void addAboutMenuItem() {
- menuBarHandler.setAboutMenuItemVisible(true);
- }
-
- /**
- * Removes the About item from the application menu if the item is present.
- *
- * @deprecated use {@link #setAboutHandler(AboutHandler)} with a null parameter
- * @since 1.4
- */
- @Deprecated
- public void removeAboutMenuItem() {
- menuBarHandler.setAboutMenuItemVisible(false);
- }
-
- /**
- * Determines if the About Preferences of the application menu is present. By default there is no Preferences menu item.
- *
- * @deprecated no replacement
- * @since 1.4
- */
- @Deprecated
- public boolean isPreferencesMenuItemPresent() {
- return menuBarHandler.isPreferencesMenuItemVisible();
- }
-
- /**
- * Adds the Preferences item to the application menu if the item is not already present.
- *
- * @deprecated use {@link #setPreferencesHandler(PreferencesHandler)} with a non-null {@link PreferencesHandler} parameter
- * @since 1.4
- */
- @Deprecated
- public void addPreferencesMenuItem() {
- menuBarHandler.setPreferencesMenuItemVisible(true);
- }
-
- /**
- * Removes the Preferences item from the application menu if that item is present.
- *
- * @deprecated use {@link #setPreferencesHandler(PreferencesHandler)} with a null parameter
- * @since 1.4
- */
- @Deprecated
- public void removePreferencesMenuItem() {
- menuBarHandler.setPreferencesMenuItemVisible(false);
- }
-
- /**
- * @deprecated Use {@code java.awt.MouseInfo.getPointerInfo().getLocation()}.
- *
- * @since 1.4
- */
- @Deprecated
- public static Point getMouseLocationOnScreen() {
- return java.awt.MouseInfo.getPointerInfo().getLocation();
- }
}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationAdapter.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationAdapter.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -46,7 +46,7 @@
* @see ScreenSleepListener
* @see SystemSleepListener
*
- * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse}.
+ * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link MacQuitResponse}.
* @since 1.4
*/
@SuppressWarnings("deprecation")
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationEvent.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -30,7 +30,7 @@
/**
* The class of events sent to the deprecated ApplicationListener callbacks.
*
- * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse}
+ * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link MacQuitResponse}
* @since 1.4
*/
@Deprecated
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationListener.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ApplicationListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -47,7 +47,7 @@
* @see SystemSleepListener
*
* @since 1.4
- * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse}
+ * @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link MacQuitResponse}
*/
@SuppressWarnings("deprecation")
@Deprecated
@@ -134,7 +134,7 @@
* {@code event}. To reject the quit, set {@code isHandled(false)}.
*
* @param event a Quit Application event
- * @deprecated use {@link QuitHandler} and {@link QuitResponse}
+ * @deprecated use {@link QuitHandler} and {@link MacQuitResponse}
*/
@Deprecated
public void handleQuit(ApplicationEvent event);
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenAdapter.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenAdapter.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -25,7 +25,7 @@
package com.apple.eawt;
-import com.apple.eawt.AppEvent.FullScreenEvent;
+import com.apple.eawt.event.FullScreenEvent;
/**
* Abstract adapter class for receiving fullscreen events. This class is provided
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -25,13 +25,13 @@
package com.apple.eawt;
+import com.apple.eawt.event.FullScreenEvent;
import java.awt.*;
import java.util.*;
import java.util.List;
import javax.swing.RootPaneContainer;
-import com.apple.eawt.AppEvent.FullScreenEvent;
import sun.awt.SunToolkit;
import java.lang.annotation.Native;
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenListener.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/FullScreenListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -25,9 +25,9 @@
package com.apple.eawt;
+import com.apple.eawt.event.FullScreenEvent;
import java.util.EventListener;
-import com.apple.eawt.AppEvent.FullScreenEvent;
/**
*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/MacQuitResponse.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, 2016, 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;
+
+import java.awt.desktop.QuitResponse;
+
+/**
+ * Used to respond to a request to quit the application.
+ * The QuitResponse may be used after the {@link QuitHandler#handleQuitRequestWith(AppEvent.QuitEvent, MacQuitResponse)} method has returned, and may be used from any thread.
+ *
+ * @see Application#setQuitHandler(QuitHandler)
+ * @see QuitHandler
+ * @see Application#setQuitStrategy(QuitStrategy)
+ *
+ * @since Java for Mac OS X 10.6 Update 3
+ * @since Java for Mac OS X 10.5 Update 8
+ */
+public class MacQuitResponse implements QuitResponse {
+ final _AppEventHandler appEventHandler;
+
+ MacQuitResponse(final _AppEventHandler appEventHandler) {
+ this.appEventHandler = appEventHandler;
+ }
+
+ /**
+ * Notifies the external quit requester that the quit will proceed, and performs the default {@link QuitStrategy}.
+ */
+ @Override
+ public void performQuit() {
+ if (appEventHandler.currentQuitResponse != this) return;
+ appEventHandler.performQuit();
+ }
+
+ /**
+ * Notifies the external quit requester that the user has explicitly canceled the pending quit, and leaves the application running.
+ * <b>Note: this will cancel a pending log-out, restart, or shutdown.</b>
+ */
+ @Override
+ public void cancelQuit() {
+ if (appEventHandler.currentQuitResponse != this) return;
+ appEventHandler.cancelQuit();
+ }
+}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/OpenFilesHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.OpenFilesEvent;
-
-/**
- * An implementor is notified when the application is asked to open a list of files.
- * This message is only sent if the application has registered that it handles CFBundleDocumentTypes in it's Info.plist.
- *
- * @see Application#setOpenFileHandler(OpenFilesHandler)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface OpenFilesHandler {
- /**
- * Called when the application is asked to open a list of files.
- * @param e the request to open a list of files, and the search term used to find them, if any.
- */
- public void openFiles(final OpenFilesEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/OpenURIHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.OpenURIEvent;
-
-/**
- * An implementor is notified when the application is asked to open a URI.
- * The application only sends {@link com.apple.eawt.EAWTEvent.OpenURIEvent}s when it has been launched as a bundled Mac application, and it's Info.plist claims URL schemes in it's {@code CFBundleURLTypes} entry.
- * See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a {@code CFBundleURLTypes} key to your app's Info.plist.
- *
- * @see Application#setOpenURIHandler(OpenURIHandler)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface OpenURIHandler {
- /**
- * Called when the application is asked to open a URI
- * @param e the request to open a URI
- */
- public void openURI(final OpenURIEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/PreferencesHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.PreferencesEvent;
-
-/**
- * An implementor is notified when the app is asked to show it's preferences UI.
- *
- * @see Application#setPreferencesHandler(PreferencesHandler)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface PreferencesHandler {
- /**
- * Called when the app is asked to show it's preferences UI.
- * @param e the request to show preferences.
- */
- public void handlePreferences(final PreferencesEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/PrintFilesHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.PrintFilesEvent;
-
-/**
- * An implementor can respond to requests to print documents that the app has been registered to handle.
- *
- * @see Application#setPrintFileHandler(PrintFilesHandler)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface PrintFilesHandler {
- /**
- * Called when the application is asked to print a list of files.
- * @param e the request to print a list of files.
- */
- public void printFiles(final PrintFilesEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.QuitEvent;
-
-/**
- * An implementor determines if requests to quit this application should proceed or cancel.
- *
- * @see Application#setQuitHandler(QuitHandler)
- * @see Application#setQuitStrategy(QuitStrategy)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface QuitHandler {
- /**
- * Invoked when the application is asked to quit.
- *
- * Implementors must call either {@link QuitResponse#cancelQuit()}, {@link QuitResponse#performQuit()}, or ensure the application terminates.
- * The process (or log-out) requesting this app to quit will be blocked until the {@link QuitResponse} is handled.
- * Apps that require complex UI to shutdown may call the {@link QuitResponse} from any thread.
- * Your app may be asked to quit multiple times before you have responded to the initial request.
- * This handler is called each time a quit is requested, and the same {@link QuitResponse} object is passed until it is handled.
- * Once used, the {@link QuitResponse} cannot be used again to change the decision.
- *
- * @param e the request to quit this application.
- * @param response the one-shot response object used to cancel or proceed with the quit action.
- */
- public void handleQuitRequestWith(final QuitEvent e, final QuitResponse response);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitResponse.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-/**
- * Used to respond to a request to quit the application.
- * The QuitResponse may be used after the {@link QuitHandler#handleQuitRequestWith(AppEvent.QuitEvent, QuitResponse)} method has returned, and may be used from any thread.
- *
- * @see Application#setQuitHandler(QuitHandler)
- * @see QuitHandler
- * @see Application#setQuitStrategy(QuitStrategy)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public class QuitResponse {
- final _AppEventHandler appEventHandler;
-
- QuitResponse(final _AppEventHandler appEventHandler) {
- this.appEventHandler = appEventHandler;
- }
-
- /**
- * Notifies the external quit requester that the quit will proceed, and performs the default {@link QuitStrategy}.
- */
- public void performQuit() {
- if (appEventHandler.currentQuitResponse != this) return;
- appEventHandler.performQuit();
- }
-
- /**
- * Notifies the external quit requester that the user has explicitly canceled the pending quit, and leaves the application running.
- * <b>Note: this will cancel a pending log-out, restart, or shutdown.</b>
- */
- public void cancelQuit() {
- if (appEventHandler.currentQuitResponse != this) return;
- appEventHandler.cancelQuit();
- }
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/QuitStrategy.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-/**
- * The strategy use to shut down the application, if Sudden Termination is not enabled.
- *
- * @see Application#setQuitHandler(QuitHandler)
- * @see Application#setQuitStrategy(QuitStrategy)
- * @see Application#enableSuddenTermination()
- * @see Application#disableSuddenTermination()
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public enum QuitStrategy {
- /**
- * Shuts down the application by calling {@code System.exit(0)}. This is the default strategy.
- */
- SYSTEM_EXIT_0,
-
- /**
- * Shuts down the application by closing each window from back-to-front.
- */
- CLOSE_ALL_WINDOWS
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/ScreenSleepListener.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.ScreenSleepEvent;
-
-/**
- * Implementors receive notification when the displays attached to the system have entered power save sleep.
- *
- * This notification is useful for discontinuing a costly animation, or indicating that the user is no longer present on a network service.
- *
- * This message is not sent on Mac OS X versions prior to 10.6.
- *
- * @see Application#addAppEventListener(AppEventListener)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface ScreenSleepListener extends AppEventListener {
- /**
- * Called when the system displays have entered power save sleep.
- * @param e the screen sleep event
- */
- public void screenAboutToSleep(final ScreenSleepEvent e);
-
- /**
- * Called when the system displays have awoke from power save sleep.
- * @param e the screen sleep event
- */
- public void screenAwoke(final ScreenSleepEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/SystemSleepListener.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.SystemSleepEvent;
-
-/**
- * Implementors receive notification as the system is entering sleep, and after the system wakes.
- *
- * This notification is useful for disconnecting from network services prior to sleep, or re-establishing a connection if the network configuration has changed during sleep.
- *
- * @see Application#addAppEventListener(AppEventListener)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface SystemSleepListener extends AppEventListener {
- /**
- * Called when the system is about to sleep.
- * Note: This message may not be delivered prior to the actual system sleep, and may be processed after the corresponding wake has occurred.
- * @param e the system sleep event
- */
- public void systemAboutToSleep(final SystemSleepEvent e);
-
- /**
- * Called after the system has awoke from sleeping.
- * @param e the system sleep event
- */
- public void systemAwoke(final SystemSleepEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/UserSessionListener.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, 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;
-
-import com.apple.eawt.AppEvent.UserSessionEvent;
-
-/**
- * Implementors receive notification when Fast User Switching changes the user session.
- *
- * This notification is useful for discontinuing a costly animation, or indicating that the user is no longer present on a network service.
- *
- * @see Application#addAppEventListener(AppEventListener)
- *
- * @since Java for Mac OS X 10.6 Update 3
- * @since Java for Mac OS X 10.5 Update 8
- */
-public interface UserSessionListener extends AppEventListener {
- /**
- * Called when the user session has been switched away.
- * @param e the user session switch event
- */
- public void userSessionDeactivated(final UserSessionEvent e);
-
- /**
- * Called when the user session has been switched to.
- * @param e the user session switch event
- */
- public void userSessionActivated(final UserSessionEvent e);
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppDockIconHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppDockIconHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -35,6 +35,7 @@
class _AppDockIconHandler {
private static native void nativeSetDockMenu(final long cmenu);
private static native void nativeSetDockIconImage(final long image);
+ private static native void nativeSetDockIconProgress(final int value);
private static native long nativeGetDockIconImage();
private static native void nativeSetDockIconBadge(final String badge);
@@ -93,6 +94,10 @@
nativeSetDockIconBadge(badge);
}
+ void setDockIconProgress(int value) {
+ nativeSetDockIconProgress(value);
+ }
+
static Creator getCImageCreator() {
try {
final Method getCreatorMethod = CImage.class.getDeclaredMethod("getCreator", new Class<?>[] {});
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -25,17 +25,47 @@
package com.apple.eawt;
-import java.awt.*;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import java.awt.desktop.AboutEvent;
+import java.awt.desktop.AboutHandler;
+import java.awt.desktop.AppForegroundEvent;
+import java.awt.desktop.AppForegroundListener;
+import java.awt.desktop.AppHiddenEvent;
+import java.awt.desktop.AppHiddenListener;
+import java.awt.desktop.AppReopenedEvent;
+import java.awt.desktop.AppReopenedListener;
+import java.awt.desktop.OpenFilesEvent;
+import java.awt.desktop.OpenFilesHandler;
+import java.awt.desktop.OpenURIEvent;
+import java.awt.desktop.OpenURIHandler;
+import java.awt.desktop.PreferencesEvent;
+import java.awt.desktop.PreferencesHandler;
+import java.awt.desktop.PrintFilesEvent;
+import java.awt.desktop.PrintFilesHandler;
+import java.awt.desktop.QuitEvent;
+import java.awt.desktop.QuitHandler;
+import java.awt.desktop.QuitStrategy;
+import java.awt.desktop.ScreenSleepEvent;
+import java.awt.desktop.ScreenSleepListener;
+import java.awt.desktop.SystemEventListener;
+import java.awt.desktop.SystemSleepEvent;
+import java.awt.desktop.SystemSleepListener;
+import java.awt.desktop.UserSessionEvent;
+import java.awt.desktop.UserSessionEvent.Reason;
+import java.awt.desktop.UserSessionListener;
import java.awt.event.WindowEvent;
import java.io.File;
-import java.net.*;
-import java.util.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
-import com.apple.eawt.AppEvent.*;
-
class _AppEventHandler {
private static final int NOTIFY_ABOUT = 1;
private static final int NOTIFY_PREFS = 2;
@@ -84,9 +114,7 @@
final _ScreenSleepDispatcher screenSleepDispatcher = new _ScreenSleepDispatcher();
final _SystemSleepDispatcher systemSleepDispatcher = new _SystemSleepDispatcher();
- final _AppEventLegacyHandler legacyHandler = new _AppEventLegacyHandler(this);
-
- QuitStrategy defaultQuitAction = QuitStrategy.SYSTEM_EXIT_0;
+ QuitStrategy defaultQuitAction = QuitStrategy.NORMAL_EXIT;
_AppEventHandler() {
final String strategyProp = System.getProperty("apple.eawt.quitStrategy");
@@ -94,15 +122,16 @@
if ("CLOSE_ALL_WINDOWS".equals(strategyProp)) {
setDefaultQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
- } else if ("SYSTEM_EXIT_O".equals(strategyProp)) {
- setDefaultQuitStrategy(QuitStrategy.SYSTEM_EXIT_0);
+ } else if ("SYSTEM_EXIT_O".equals(strategyProp)
+ || "NORMAL_EXIT".equals(strategyProp)) {
+ setDefaultQuitStrategy(QuitStrategy.NORMAL_EXIT);
} else {
System.err.println("unrecognized apple.eawt.quitStrategy: " + strategyProp);
}
}
- void addListener(final AppEventListener listener) {
- if (listener instanceof AppReOpenedListener) reOpenAppDispatcher.addListener((AppReOpenedListener)listener);
+ void addListener(final SystemEventListener listener) {
+ if (listener instanceof AppReopenedListener) reOpenAppDispatcher.addListener((AppReopenedListener)listener);
if (listener instanceof AppForegroundListener) foregroundAppDispatcher.addListener((AppForegroundListener)listener);
if (listener instanceof AppHiddenListener) hiddenAppDispatcher.addListener((AppHiddenListener)listener);
if (listener instanceof UserSessionListener) userSessionDispatcher.addListener((UserSessionListener)listener);
@@ -110,8 +139,8 @@
if (listener instanceof SystemSleepListener) systemSleepDispatcher.addListener((SystemSleepListener)listener);
}
- void removeListener(final AppEventListener listener) {
- if (listener instanceof AppReOpenedListener) reOpenAppDispatcher.removeListener((AppReOpenedListener)listener);
+ void removeListener(final SystemEventListener listener) {
+ if (listener instanceof AppReopenedListener) reOpenAppDispatcher.removeListener((AppReopenedListener)listener);
if (listener instanceof AppForegroundListener) foregroundAppDispatcher.removeListener((AppForegroundListener)listener);
if (listener instanceof AppHiddenListener) hiddenAppDispatcher.removeListener((AppHiddenListener)listener);
if (listener instanceof UserSessionListener) userSessionDispatcher.removeListener((UserSessionListener)listener);
@@ -127,10 +156,10 @@
this.defaultQuitAction = defaultQuitAction;
}
- QuitResponse currentQuitResponse;
- synchronized QuitResponse obtainQuitResponse() {
+ MacQuitResponse currentQuitResponse;
+ synchronized MacQuitResponse obtainQuitResponse() {
if (currentQuitResponse != null) return currentQuitResponse;
- return currentQuitResponse = new QuitResponse(this);
+ return currentQuitResponse = new MacQuitResponse(this);
}
synchronized void cancelQuit() {
@@ -142,7 +171,7 @@
currentQuitResponse = null;
try {
- if (defaultQuitAction == QuitStrategy.SYSTEM_EXIT_0) System.exit(0);
+ if (defaultQuitAction == QuitStrategy.NORMAL_EXIT) System.exit(0);
if (defaultQuitAction != QuitStrategy.CLOSE_ALL_WINDOWS) {
throw new RuntimeException("Unknown quit action");
@@ -270,10 +299,10 @@
}
}
- class _AppReOpenedDispatcher extends _AppEventMultiplexor<AppReOpenedListener> {
- void performOnListener(AppReOpenedListener listener, final _NativeEvent event) {
- final AppReOpenedEvent e = new AppReOpenedEvent();
- listener.appReOpened(e);
+ class _AppReOpenedDispatcher extends _AppEventMultiplexor<AppReopenedListener> {
+ void performOnListener(AppReopenedListener listener, final _NativeEvent event) {
+ final AppReopenedEvent e = new AppReopenedEvent();
+ listener.appReopened(e);
}
}
@@ -302,7 +331,9 @@
}
class _UserSessionDispatcher extends _BooleanAppEventMultiplexor<UserSessionListener, UserSessionEvent> {
- UserSessionEvent createEvent(final boolean isTrue) { return new UserSessionEvent(); }
+ UserSessionEvent createEvent(final boolean isTrue) {
+ return new UserSessionEvent(Reason.UNSPECIFIED);
+ }
void performFalseEventOn(final UserSessionListener listener, final UserSessionEvent e) {
listener.userSessionDeactivated(e);
@@ -391,7 +422,7 @@
}
void performUsing(final QuitHandler handler, final _NativeEvent event) {
- final QuitResponse response = obtainQuitResponse(); // obtains the "current" quit response
+ final MacQuitResponse response = obtainQuitResponse(); // obtains the "current" quit response
handler.handleQuitRequestWith(new QuitEvent(), response);
}
}
@@ -524,9 +555,6 @@
setHandlerContext(AppContext.getAppContext());
- // if a new handler is installed, block addition of legacy ApplicationListeners
- if (handler == legacyHandler) return;
- legacyHandler.blockLegacyAPI();
}
void performDefaultAction(final _NativeEvent event) { } // by default, do nothing
@@ -574,10 +602,6 @@
}
}
}
-
- // if a new handler is installed, block addition of legacy ApplicationListeners
- if (handler == legacyHandler) return;
- legacyHandler.blockLegacyAPI();
}
}
}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppEventLegacyHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/*
- * 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
- * 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;
-
-import java.awt.Toolkit;
-import java.io.File;
-import java.util.*;
-
-import com.apple.eawt.AppEvent.*;
-
-@SuppressWarnings("deprecation")
-class _AppEventLegacyHandler implements AboutHandler, PreferencesHandler, _OpenAppHandler, AppReOpenedListener, OpenFilesHandler, PrintFilesHandler, QuitHandler {
- final _AppEventHandler parent;
- final Vector<ApplicationListener> legacyAppListeners = new Vector<ApplicationListener>();
- boolean blockLegacyAPI;
- boolean initializedParentDispatchers;
-
- _AppEventLegacyHandler(final _AppEventHandler parent) {
- this.parent = parent;
- }
-
- void blockLegacyAPI() {
- blockLegacyAPI = true;
- }
-
- void checkIfLegacyAPIBlocked() {
- if (!blockLegacyAPI) return;
- throw new IllegalStateException("Cannot add com.apple.eawt.ApplicationListener after installing an app event handler");
- }
-
- void addLegacyAppListener(final ApplicationListener listener) {
- checkIfLegacyAPIBlocked();
-
- if (!initializedParentDispatchers) {
- final _AppMenuBarHandler menuBarHandler = Application.getApplication().menuBarHandler;
- final boolean prefsMenuAlreadyExplicitlySet = menuBarHandler.prefsMenuItemExplicitlySet;
-
- parent.aboutDispatcher.setHandler(this);
- parent.preferencesDispatcher.setHandler(this);
- if (!prefsMenuAlreadyExplicitlySet) {
- menuBarHandler.setPreferencesMenuItemVisible(false); // default behavior is not to have a preferences item
- }
- parent.openAppDispatcher.setHandler(this);
- parent.reOpenAppDispatcher.addListener(this);
- parent.openFilesDispatcher.setHandler(this);
- parent.printFilesDispatcher.setHandler(this);
- parent.quitDispatcher.setHandler(this);
-
- initializedParentDispatchers = true;
- }
-
- synchronized (legacyAppListeners) {
- legacyAppListeners.addElement(listener);
- }
- }
-
- public void removeLegacyAppListener(final ApplicationListener listener) {
- checkIfLegacyAPIBlocked();
-
- synchronized (legacyAppListeners) {
- legacyAppListeners.removeElement(listener);
- }
- }
-
- @Override
- public void handleAbout(final AboutEvent e) {
- final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
- sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
- public void dispatchEvent(final ApplicationListener listener) {
- listener.handleAbout(ae);
- }
- });
-
- if (ae.isHandled()) return;
- parent.openCocoaAboutWindow();
- }
-
- @Override
- public void handlePreferences(final PreferencesEvent e) {
- final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
- sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
- public void dispatchEvent(final ApplicationListener listener) {
- listener.handlePreferences(ae);
- }
- });
- }
-
- @Override
- public void handleOpenApp() {
- final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
- sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
- public void dispatchEvent(final ApplicationListener listener) {
- listener.handleOpenApplication(ae);
- }
- });
- }
-
- @Override
- public void appReOpened(final AppReOpenedEvent e) {
- final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
- sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
- public void dispatchEvent(final ApplicationListener listener) {
- listener.handleReOpenApplication(ae);
- }
- });
- }
-
- @Override
- public void openFiles(final OpenFilesEvent e) {
- final List<File> files = e.getFiles();
- for (final File file : files) { // legacy ApplicationListeners only understood one file at a time
- final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit(), file.getAbsolutePath());
- sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
- public void dispatchEvent(final ApplicationListener listener) {
- listener.handleOpenFile(ae);
- }
- });
- }
- }
-
- @Override
- public void printFiles(PrintFilesEvent e) {
- final List<File> files = e.getFiles();
- for (final File file : files) { // legacy ApplicationListeners only understood one file at a time
- final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit(), file.getAbsolutePath());
- sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
- public void dispatchEvent(final ApplicationListener listener) {
- listener.handlePrintFile(ae);
- }
- });
- }
- }
-
- @Override
- public void handleQuitRequestWith(final QuitEvent e, final QuitResponse response) {
- final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
- sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
- public void dispatchEvent(final ApplicationListener listener) {
- listener.handleQuit(ae);
- }
- });
-
- if (ae.isHandled()) {
- parent.performQuit();
- } else {
- parent.cancelQuit();
- }
- }
-
- interface EventDispatcher {
- void dispatchEvent(final ApplicationListener listener);
- }
-
- // helper that cycles through the loop and aborts if the event is handled, or there are no listeners
- void sendEventToEachListenerUntilHandled(final ApplicationEvent event, final EventDispatcher dispatcher) {
- synchronized (legacyAppListeners) {
- if (legacyAppListeners.size() == 0) return;
-
- final Enumeration<ApplicationListener> e = legacyAppListeners.elements();
- while (e.hasMoreElements() && !event.isHandled()) {
- dispatcher.dispatchEvent(e.nextElement());
- }
- }
- }
-}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -26,7 +26,6 @@
package com.apple.eawt;
import java.awt.Frame;
-import java.awt.peer.MenuComponentPeer;
import javax.swing.*;
import javax.swing.plaf.MenuBarUI;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/eawt/event/FullScreenEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016, 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.event;
+
+import com.apple.eawt.Application;
+import java.awt.Window;
+import java.util.EventObject;
+
+@SuppressWarnings("serial") // JDK implementation class
+public class FullScreenEvent extends EventObject {
+
+ final Window window;
+
+ /**
+ * @param window window
+ */
+ public FullScreenEvent(final Window window) {
+ super(Application.getApplication());
+ this.window = window;
+ }
+
+ /**
+ * @return window transitioning between full screen states
+ */
+ public Window getWindow() {
+ return window;
+ }
+}
--- a/jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java Thu Apr 07 11:03:59 2016 -0700
@@ -32,7 +32,7 @@
import java.awt.Insets;
import java.awt.Window;
import java.util.Objects;
-
+import sun.java2d.SunGraphicsEnvironment;
import sun.java2d.opengl.CGLGraphicsConfig;
public final class CGraphicsDevice extends GraphicsDevice
@@ -140,7 +140,7 @@
public void displayChanged() {
xResolution = nativeGetXResolution(displayID);
yResolution = nativeGetYResolution(displayID);
- scale = (int) nativeGetScaleFactor(displayID);
+ initScaleFactor();
//TODO configs/fullscreenWindow/modes?
}
@@ -249,6 +249,17 @@
return nativeGetDisplayModes(displayID);
}
+ private void initScaleFactor() {
+ if (SunGraphicsEnvironment.isUIScaleEnabled()) {
+ double debugScale = SunGraphicsEnvironment.getDebugScale();
+ scale = (int) (debugScale >= 1
+ ? Math.round(debugScale)
+ : nativeGetScaleFactor(displayID));
+ } else {
+ scale = 1;
+ }
+ }
+
private static native double nativeGetScaleFactor(int displayID);
private static native void nativeSetDisplayMode(int displayID, int w, int h, int bpp, int refrate);
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java Thu Apr 07 11:03:59 2016 -0700
@@ -142,94 +142,6 @@
}
}
- @Override
- public Font2D createFont2D(File fontFile, int fontFormat, boolean isCopy, CreatedFontTracker tracker) throws FontFormatException {
-
- String fontFilePath = fontFile.getPath();
- Font2D font2D = null;
- final File fFile = fontFile;
- final CreatedFontTracker _tracker = tracker;
- try {
- switch (fontFormat) {
- case Font.TRUETYPE_FONT:
- font2D = new TrueTypeFont(fontFilePath, null, 0, true);
- break;
- case Font.TYPE1_FONT:
- font2D = new Type1Font(fontFilePath, null, isCopy);
- break;
- default:
- throw new FontFormatException("Unrecognised Font Format");
- }
- } catch (FontFormatException e) {
- if (isCopy) {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Object>() {
- public Object run() {
- if (_tracker != null) {
- _tracker.subBytes((int)fFile.length());
- }
- fFile.delete();
- return null;
- }
- });
- }
- throw(e);
- }
- if (isCopy) {
- FileFont.setFileToRemove(font2D, fontFile, tracker);
- synchronized (FontManager.class) {
-
- if (tmpFontFiles == null) {
- tmpFontFiles = new Vector<File>();
- }
- tmpFontFiles.add(fontFile);
-
- if (fileCloser == null) {
- final Runnable fileCloserRunnable = new Runnable() {
- public void run() {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Object>() {
- public Object run() {
-
- for (int i=0;i<CHANNELPOOLSIZE;i++) {
- if (fontFileCache[i] != null) {
- try {
- fontFileCache[i].close();
- } catch (Exception e) {}
- }
- }
- if (tmpFontFiles != null) {
- File[] files = new File[tmpFontFiles.size()];
- files = tmpFontFiles.toArray(files);
- for (int f=0; f<files.length;f++) {
- try {
- files[f].delete();
- } catch (Exception e) {}
- }
- }
- return null;
- }
- });
- }
- };
- AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
- /* The thread must be a member of a thread group
- * which will not get GCed before VM exit.
- * Make its parent the top-level thread group.
- */
- ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup();
- fileCloser = new ManagedLocalsThread(rootTG, fileCloserRunnable);
- fileCloser.setContextClassLoader(null);
- Runtime.getRuntime().addShutdownHook(fileCloser);
- return null;
- }
- );
- }
- }
- }
- return font2D;
- }
-
protected void registerFontsInDir(String dirName, boolean useJavaRasterizer, int fontRank, boolean defer, boolean resolveSymLinks) {
loadNativeDirFonts(dirName);
super.registerFontsInDir(dirName, useJavaRasterizer, fontRank, defer, resolveSymLinks);
--- a/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXOffScreenSurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXOffScreenSurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -478,13 +478,9 @@
// <rdar://problem/4488745> For the Sun2D renderer we should rely on the implementation of the super class.
// BufImageSurfaceData.java doesn't have an implementation of copyArea() and relies on the super class.
- int offsetX = 0;
- int offsetY = 0;
- if (sg2d.transformState == SunGraphics2D.TRANSFORM_ANY_TRANSLATE ||
- sg2d.transformState == SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
- offsetX = (int) sg2d.transform.getTranslateX();
- offsetY = (int) sg2d.transform.getTranslateY();
- } else if (sg2d.transformState != SunGraphics2D.TRANSFORM_ISIDENT) { return false; }
+ if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
+ return false;
+ }
// reset the clip (this is how it works on windows)
// we actually can handle a case with any clips but windows ignores the light clip
@@ -498,18 +494,23 @@
return true;
}
- // the rectangle returned from clipCopyArea() is in the coordinate space of the surface (image)
- // we need to substract the offsetX and offsetY to move it to the coordinate space of the graphics2d.
- // sg2d.drawImage expects the destination rect to be in the coord space of the graphics2d. <rdar://3746194>
- // (vm)
- x = clippedCopyAreaRect.x - offsetX;
- y = clippedCopyAreaRect.y - offsetY;
+ // the rectangle returned from clipCopyArea() is in the coordinate space
+ // of the surface (image)
+ x = clippedCopyAreaRect.x;
+ y = clippedCopyAreaRect.y;
w = clippedCopyAreaRect.width;
h = clippedCopyAreaRect.height;
- // copy (dst coordinates are in the coord space of the graphics2d, and src coordinates are
- // in the coordinate space of the image)
- sg2d.drawImage(this.bim, x + dx, y + dy, x + dx + w, y + dy + h, x + offsetX, y + offsetY, x + w + offsetX, y + h + offsetY, null);
+ // copy (dst coordinates are in the coord space of the graphics2d, and
+ // src coordinates are in the coordinate space of the image)
+ // sg2d.drawImage expects the destination rect to be in the coord space
+ // of the graphics2d. <rdar://3746194> (vm)
+ // we need to substract the transX and transY to move it
+ // to the coordinate space of the graphics2d.
+ int dstX = x + dx - sg2d.transX;
+ int dstY = y + dy - sg2d.transY;
+ sg2d.drawImage(this.bim, dstX, dstY, dstX + w, dstY + h,
+ x, y, x + w, y + h, null);
// restore the clip
sg2d.setClip(clip);
--- a/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/OSXSurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -1094,19 +1094,13 @@
}
/**
- * Clips the copy area to the heavywieght bounds and returns the cliped rectangle. The tricky part here is the
- * passed arguments x, y are in the coordinate space of the sg2d/lightweight comp. In order to do the clipping we
- * translate them to the coordinate space of the surface, and the returned clipped rectangle is in the coordinate
- * space of the surface.
+ * Clips the copy area to the heavyweight bounds and returns the clipped rectangle.
+ * The returned clipped rectangle is in the coordinate space of the surface.
*/
protected Rectangle clipCopyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy) {
// we need to clip against the heavyweight bounds
copyAreaBounds.setBounds(sg2d.devClip.getLoX(), sg2d.devClip.getLoY(), sg2d.devClip.getWidth(), sg2d.devClip.getHeight());
- // put src rect into surface coordinate space
- x += sg2d.transX;
- y += sg2d.transY;
-
// clip src rect
srcCopyAreaRect.setBounds(x, y, w, h);
intersection(srcCopyAreaRect, copyAreaBounds, srcCopyAreaRect);
--- a/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -175,31 +175,6 @@
return scale;
}
- @Override
- public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
- int dx, int dy) {
- final int state = sg2d.transformState;
- if (state > SunGraphics2D.TRANSFORM_TRANSLATESCALE
- || sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
- return false;
- }
- if (state <= SunGraphics2D.TRANSFORM_ANY_TRANSLATE) {
- x += sg2d.transX;
- y += sg2d.transY;
- } else if (state == SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
- final double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
- sg2d.transform.transform(coords, 0, coords, 0, 3);
- x = (int) Math.ceil(coords[0] - 0.5);
- y = (int) Math.ceil(coords[1] - 0.5);
- w = ((int) Math.ceil(coords[2] - 0.5)) - x;
- h = ((int) Math.ceil(coords[3] - 0.5)) - y;
- dx = ((int) Math.ceil(coords[4] - 0.5)) - x;
- dy = ((int) Math.ceil(coords[5] - 0.5)) - y;
- }
- oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
- return true;
- }
-
protected native void clearWindow();
public static class CGLWindowSurfaceData extends CGLSurfaceData {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -371,6 +371,11 @@
}
@Override
+ public final boolean isTaskbarSupported() {
+ return true;
+ }
+
+ @Override
public final KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
return LWKeyboardFocusManagerPeer.getInstance();
}
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDesktopPeer.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDesktopPeer.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -25,9 +25,14 @@
package sun.lwawt.macosx;
+import com.apple.eawt.Application;
+
+import javax.swing.*;
import java.awt.Desktop.Action;
+import java.awt.desktop.*;
import java.awt.peer.DesktopPeer;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
@@ -37,34 +42,126 @@
*
* @see DesktopPeer
*/
-public class CDesktopPeer implements DesktopPeer {
+final public class CDesktopPeer implements DesktopPeer {
+ @Override
public boolean isSupported(Action action) {
- // OPEN, EDIT, PRINT, MAIL, BROWSE all supported.
- // Though we don't really differentiate between OPEN / EDIT
return true;
}
+ @Override
public void open(File file) throws IOException {
this.lsOpenFile(file, false);
}
+ @Override
public void edit(File file) throws IOException {
this.lsOpenFile(file, false);
}
+ @Override
public void print(File file) throws IOException {
this.lsOpenFile(file, true);
}
+ @Override
public void mail(URI uri) throws IOException {
this.lsOpen(uri);
}
+ @Override
public void browse(URI uri) throws IOException {
this.lsOpen(uri);
}
+ @Override
+ public void addAppEventListener(SystemEventListener listener) {
+ Application.getApplication().addAppEventListener(listener);
+ }
+
+ @Override
+ public void removeAppEventListener(SystemEventListener listener) {
+ Application.getApplication().removeAppEventListener(listener);
+ }
+
+ @Override
+ public void setAboutHandler(AboutHandler aboutHandler) {
+ Application.getApplication().setAboutHandler(aboutHandler);
+ }
+
+ @Override
+ public void setPreferencesHandler(PreferencesHandler preferencesHandler) {
+ Application.getApplication().setPreferencesHandler(preferencesHandler);
+ }
+
+ @Override
+ public void setOpenFileHandler(OpenFilesHandler openFileHandler) {
+ Application.getApplication().setOpenFileHandler(openFileHandler);
+ }
+
+ @Override
+ public void setPrintFileHandler(PrintFilesHandler printFileHandler) {
+ Application.getApplication().setPrintFileHandler(printFileHandler);
+ }
+
+ @Override
+ public void setOpenURIHandler(OpenURIHandler openURIHandler) {
+ Application.getApplication().setOpenURIHandler(openURIHandler);
+ }
+
+ @Override
+ public void setQuitHandler(QuitHandler quitHandler) {
+ Application.getApplication().setQuitHandler(quitHandler);
+ }
+
+ @Override
+ public void setQuitStrategy(QuitStrategy strategy) {
+ Application.getApplication().setQuitStrategy(strategy);
+ }
+
+ @Override
+ public void enableSuddenTermination() {
+ Application.getApplication().enableSuddenTermination();
+ }
+
+ @Override
+ public void disableSuddenTermination() {
+ Application.getApplication().disableSuddenTermination();
+ }
+
+ @Override
+ public void requestForeground(boolean allWindows) {
+ Application.getApplication().requestForeground(allWindows);
+ }
+
+ @Override
+ public void openHelpViewer() {
+ Application.getApplication().openHelpViewer();
+ }
+
+ @Override
+ public void setDefaultMenuBar(JMenuBar menuBar) {
+ Application.getApplication().setDefaultMenuBar(menuBar);
+ }
+
+ @Override
+ public boolean browseFileDirectory(File file) {
+ try {
+ return com.apple.eio.FileManager.revealInFinder(file);
+ } catch (FileNotFoundException ex) {
+ return false; //handled in java.awt.Desktop
+ }
+ }
+
+ @Override
+ public boolean moveToTrash(File file) {
+ try {
+ return com.apple.eio.FileManager.moveToTrash(file);
+ } catch (FileNotFoundException ex) {
+ return false; //handled in java.awt.Desktop
+ }
+ }
+
private void lsOpen(URI uri) throws IOException {
int status = _lsOpenURI(uri.toString());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTaskbarPeer.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, 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 sun.lwawt.macosx;
+
+import com.apple.eawt.Application;
+import java.awt.Image;
+import java.awt.PopupMenu;
+import java.awt.Taskbar.Feature;
+import java.awt.peer.TaskbarPeer;
+
+final public class CTaskbarPeer implements TaskbarPeer {
+
+ CTaskbarPeer() {}
+
+ @Override
+ public boolean isSupported(Feature feature) {
+ switch(feature) {
+ case ICON_BADGE_TEXT:
+ case ICON_BADGE_NUMBER:
+ case ICON_IMAGE:
+ case MENU:
+ case PROGRESS_VALUE:
+ case USER_ATTENTION:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public void setProgressValue(int value) {
+ Application.getApplication().setDockIconProgress(value);
+ }
+
+ @Override
+ public void setIconBadge(String badge) {
+ Application.getApplication().setDockIconBadge(badge);
+ }
+
+ @Override
+ public Image getIconImage() {
+ return Application.getApplication().getDockIconImage();
+ }
+
+ @Override
+ public void setIconImage(Image image) {
+ Application.getApplication().setDockIconImage(image);
+ }
+
+ @Override
+ public PopupMenu getMenu() {
+ return Application.getApplication().getDockMenu();
+ }
+
+ @Override
+ public void setMenu(PopupMenu menu) {
+ Application.getApplication().setDockMenu(menu);
+ }
+
+ @Override
+ public void requestUserAttention(boolean enabled, boolean critical) {
+ if (enabled) {
+ Application.getApplication().requestUserAttention(critical);
+ }
+ }
+}
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -25,6 +25,7 @@
package sun.lwawt.macosx;
+import java.awt.peer.TaskbarPeer;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.dnd.*;
@@ -294,6 +295,11 @@
}
@Override
+ public TaskbarPeer createTaskbarPeer(Taskbar target) {
+ return new CTaskbarPeer();
+ }
+
+ @Override
public LWCursorManager getCursorManager() {
return CCursorManager.getInstance();
}
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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,6 +43,7 @@
-(void) resetTrackingArea;
-(void) deliverJavaKeyEventHelper: (NSEvent*) event;
-(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint;
+-(NSMutableString *) parseString : (id) complexString;
@end
// Uncomment this line to see fprintfs of each InputMethod API being called on this View
@@ -66,26 +67,26 @@
// Note: Must be called on main (AppKit) thread only
- (id) initWithRect: (NSRect) rect
platformView: (jobject) cPlatformView
- windowLayer: (CALayer*) windowLayer
+ windowLayer: (CALayer*) windowLayer
{
-AWT_ASSERT_APPKIT_THREAD;
+ AWT_ASSERT_APPKIT_THREAD;
// Initialize ourselves
self = [super initWithFrame: rect];
if (self == nil) return self;
-
+
m_cPlatformView = cPlatformView;
fInputMethodLOCKABLE = NULL;
fKeyEventsNeeded = NO;
fProcessingKeystroke = NO;
-
+
fEnablePressAndHold = shouldUsePressAndHold();
fInPressAndHold = NO;
fPAHNeedsToSelect = NO;
-
+
mouseIsOver = NO;
[self resetTrackingArea];
[self setAutoresizesSubviews:NO];
-
+
if (windowLayer != nil) {
self.cglLayer = windowLayer;
//Layer hosting view
@@ -96,7 +97,7 @@
//[self setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize];
//[self setLayerContentsPlacement: NSViewLayerContentsPlacementTopLeft];
//[self setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
-
+
#ifdef REMOTELAYER
CGLLayer *parentLayer = (CGLLayer*)self.cglLayer;
parentLayer.parentLayer = NULL;
@@ -118,36 +119,36 @@
}
#endif /* REMOTELAYER */
}
-
+
return self;
}
- (void) dealloc {
-AWT_ASSERT_APPKIT_THREAD;
-
+ AWT_ASSERT_APPKIT_THREAD;
+
self.cglLayer = nil;
-
+
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
(*env)->DeleteGlobalRef(env, m_cPlatformView);
m_cPlatformView = NULL;
-
+
if (fInputMethodLOCKABLE != NULL)
{
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
-
+
JNFDeleteGlobalRef(env, fInputMethodLOCKABLE);
fInputMethodLOCKABLE = NULL;
}
-
-
+
+
[super dealloc];
}
- (void) viewDidMoveToWindow {
-AWT_ASSERT_APPKIT_THREAD;
-
+ AWT_ASSERT_APPKIT_THREAD;
+
[AWTToolkit eventCountPlusPlus];
-
+
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^() {
[[self window] makeFirstResponder: self];
}];
@@ -231,7 +232,7 @@
NSPoint eventLocation = [event locationInWindow];
NSPoint localPoint = [self convertPoint: eventLocation fromView: nil];
-
+
if ([self mouse: localPoint inRect: [self bounds]]) {
[self deliverJavaMouseEvent: event];
} else {
@@ -275,10 +276,10 @@
- (void) keyDown: (NSEvent *)event {
fProcessingKeystroke = YES;
fKeyEventsNeeded = YES;
-
+
// Allow TSM to look at the event and potentially send back NSTextInputClient messages.
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
-
+
if (fEnablePressAndHold && [event willBeHandledByComplexInputMethod]) {
fProcessingKeystroke = NO;
if (!fInPressAndHold) {
@@ -287,14 +288,14 @@
}
return;
}
-
+
NSString *eventCharacters = [event characters];
BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0);
-
+
if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) {
[self deliverJavaKeyEventHelper: event];
}
-
+
fProcessingKeystroke = NO;
}
@@ -307,15 +308,15 @@
}
- (BOOL) performKeyEquivalent: (NSEvent *) event {
- // if IM is active key events should be ignored
+ // if IM is active key events should be ignored
if (![self hasMarkedText] && !fInPressAndHold) {
[self deliverJavaKeyEventHelper: event];
}
-
- // Workaround for 8020209: special case for "Cmd =" and "Cmd ."
- // because Cocoa calls performKeyEquivalent twice for these keystrokes
- NSUInteger modFlags = [event modifierFlags] &
- (NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask);
+
+ // Workaround for 8020209: special case for "Cmd =" and "Cmd ."
+ // because Cocoa calls performKeyEquivalent twice for these keystrokes
+ NSUInteger modFlags = [event modifierFlags] &
+ (NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask);
if (modFlags == NSCommandKeyMask) {
NSString *eventChars = [event charactersIgnoringModifiers];
if ([eventChars length] == 1) {
@@ -325,9 +326,9 @@
return YES;
}
}
-
+
}
-
+
return NO;
}
@@ -341,36 +342,36 @@
if ([window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]]) {
isEnabled = [(AWTWindow*)[window delegate] isEnabled];
}
-
+
if (!isEnabled) {
return;
}
-
+
NSEventType type = [event type];
-
+
// check synthesized mouse entered/exited events
if ((type == NSMouseEntered && mouseIsOver) || (type == NSMouseExited && !mouseIsOver)) {
return;
}else if ((type == NSMouseEntered && !mouseIsOver) || (type == NSMouseExited && mouseIsOver)) {
mouseIsOver = !mouseIsOver;
}
-
+
[AWTToolkit eventCountPlusPlus];
-
+
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
NSPoint eventLocation = [event locationInWindow];
NSPoint localPoint = [self convertPoint: eventLocation fromView: nil];
NSPoint absP = [NSEvent mouseLocation];
-
+
// Convert global numbers between Cocoa's coordinate system and Java.
// TODO: need consitent way for doing that both with global as well as with local coordinates.
// The reason to do it here is one more native method for getting screen dimension otherwise.
-
+
NSRect screenRect = [[[NSScreen screens] objectAtIndex:0] frame];
absP.y = screenRect.size.height - absP.y;
jint clickCount;
-
+
if (type == NSMouseEntered ||
type == NSMouseExited ||
type == NSScrollWheel ||
@@ -379,7 +380,7 @@
} else {
clickCount = [event clickCount];
}
-
+
static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IIIIIIIIDD)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent,
@@ -392,7 +393,7 @@
[event deltaY],
[event deltaX]);
CHECK_NULL(jEvent);
-
+
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverMouseEvent, jc_PlatformView, "deliverMouseEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent);
@@ -404,10 +405,10 @@
[self removeTrackingArea:rolloverTrackingArea];
[rolloverTrackingArea release];
}
-
+
int options = (NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag);
-
+
rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
options: options
owner:self
@@ -434,17 +435,17 @@
}
[sLastKeyEvent release];
sLastKeyEvent = [event retain];
-
+
[AWTToolkit eventCountPlusPlus];
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
jstring characters = NULL;
jstring charactersIgnoringModifiers = NULL;
if ([event type] != NSFlagsChanged) {
characters = JNFNSToJavaString(env, [event characters]);
charactersIgnoringModifiers = JNFNSToJavaString(env, [event charactersIgnoringModifiers]);
}
-
+
static JNF_CLASS_CACHE(jc_NSEvent, "sun/lwawt/macosx/NSEvent");
static JNF_CTOR_CACHE(jctor_NSEvent, jc_NSEvent, "(IISLjava/lang/String;Ljava/lang/String;)V");
jobject jEvent = JNFNewObject(env, jctor_NSEvent,
@@ -454,12 +455,12 @@
characters,
charactersIgnoringModifiers);
CHECK_NULL(jEvent);
-
+
static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverKeyEvent, jc_PlatformView,
"deliverKeyEvent", "(Lsun/lwawt/macosx/NSEvent;)V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverKeyEvent, jEvent);
-
+
if (characters != NULL) {
(*env)->DeleteLocalRef(env, characters);
}
@@ -479,34 +480,34 @@
- (void) drawRect:(NSRect)dirtyRect {
-AWT_ASSERT_APPKIT_THREAD;
-
+ AWT_ASSERT_APPKIT_THREAD;
+
[super drawRect:dirtyRect];
JNIEnv *env = [ThreadUtilities getJNIEnv];
if (env != NULL) {
-/*
- if ([self inLiveResize]) {
- NSRect rs[4];
- NSInteger count;
- [self getRectsExposedDuringLiveResize:rs count:&count];
- for (int i = 0; i < count; i++) {
- JNU_CallMethodByName(env, NULL, [m_awtWindow cPlatformView],
- "deliverWindowDidExposeEvent", "(FFFF)V",
- (jfloat)rs[i].origin.x, (jfloat)rs[i].origin.y,
- (jfloat)rs[i].size.width, (jfloat)rs[i].size.height);
- if ((*env)->ExceptionOccurred(env)) {
- (*env)->ExceptionDescribe(env);
- (*env)->ExceptionClear(env);
- }
- }
- } else {
-*/
+ /*
+ if ([self inLiveResize]) {
+ NSRect rs[4];
+ NSInteger count;
+ [self getRectsExposedDuringLiveResize:rs count:&count];
+ for (int i = 0; i < count; i++) {
+ JNU_CallMethodByName(env, NULL, [m_awtWindow cPlatformView],
+ "deliverWindowDidExposeEvent", "(FFFF)V",
+ (jfloat)rs[i].origin.x, (jfloat)rs[i].origin.y,
+ (jfloat)rs[i].size.width, (jfloat)rs[i].size.height);
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ }
+ }
+ } else {
+ */
static JNF_CLASS_CACHE(jc_CPlatformView, "sun/lwawt/macosx/CPlatformView");
static JNF_MEMBER_CACHE(jm_deliverWindowDidExposeEvent, jc_CPlatformView, "deliverWindowDidExposeEvent", "()V");
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverWindowDidExposeEvent);
-/*
- }
-*/
+ /*
+ }
+ */
}
}
@@ -518,6 +519,15 @@
return NO;
}
+-(NSMutableString *) parseString : (id) complexString {
+ if ([complexString isKindOfClass:[NSString class]]) {
+ return [complexString mutableCopy];
+ }
+ else {
+ return [complexString mutableString];
+ }
+}
+
// NSAccessibility support
- (jobject)awtComponent:(JNIEnv*)env
{
@@ -557,17 +567,17 @@
- (id)accessibilityAttributeValue:(NSString *)attribute
{
AWT_ASSERT_APPKIT_THREAD;
-
+
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute])
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
(*env)->PushLocalFrame(env, 4);
-
+
id result = NSAccessibilityUnignoredChildrenForOnlyChild([self getAxData:env]);
-
+
(*env)->PopLocalFrame(env, NULL);
-
+
return result;
}
else
@@ -584,28 +594,28 @@
{
AWT_ASSERT_APPKIT_THREAD;
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
(*env)->PushLocalFrame(env, 4);
-
+
id result = [[self getAxData:env] accessibilityHitTest:point withEnv:env];
-
+
(*env)->PopLocalFrame(env, NULL);
-
+
return result;
}
- (id)accessibilityFocusedUIElement
{
AWT_ASSERT_APPKIT_THREAD;
-
+
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
(*env)->PushLocalFrame(env, 4);
-
+
id result = [[self getAxData:env] accessibilityFocusedUIElement];
-
+
(*env)->PopLocalFrame(env, NULL);
-
+
return result;
}
@@ -625,7 +635,8 @@
NSString *selectedText = [self accessibleSelectedText];
NSAttributedString *styledText = [[NSAttributedString alloc] initWithString:selectedText];
NSData *rtfdData = [styledText RTFDFromRange:NSMakeRange(0, [styledText length])
- documentAttributes:@{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType}];
+ documentAttributes:
+ @{NSDocumentTypeDocumentAttribute: NSRTFTextDocumentType}];
[styledText release];
return rtfdData;
}
@@ -643,12 +654,12 @@
- (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
{
if ([[self window] firstResponder] != self) return nil; // let AWT components handle themselves
-
+
if ([sendType isEqual:NSStringPboardType] || [returnType isEqual:NSStringPboardType]) {
NSString *selectedText = [self accessibleSelectedText];
if (selectedText) return self;
}
-
+
return nil;
}
@@ -660,13 +671,13 @@
[pboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
return [pboard setString:[self accessibleSelectedText] forType:NSStringPboardType];
}
-
+
if ([types containsObject:NSRTFDPboardType])
{
[pboard declareTypes:[NSArray arrayWithObject:NSRTFDPboardType] owner:nil];
return [pboard setData:[self accessibleSelectedTextAsRTFD] forType:NSRTFDPboardType];
}
-
+
return NO;
}
@@ -678,17 +689,17 @@
NSString *text = [pboard stringForType:NSStringPboardType];
return [self replaceAccessibleTextSelection:text];
}
-
+
if ([[pboard types] containsObject:NSRTFDPboardType])
{
NSData *rtfdData = [pboard dataForType:NSRTFDPboardType];
NSAttributedString *styledText = [[NSAttributedString alloc] initWithRTFD:rtfdData documentAttributes:NULL];
NSString *text = [styledText string];
[styledText release];
-
+
return [self replaceAccessibleTextSelection:text];
}
-
+
return NO;
}
@@ -710,12 +721,12 @@
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
NSDragOperation dragOp = NSDragOperationNone;
-
+
if (dragSource != nil)
dragOp = [dragSource draggingSourceOperationMaskForLocal:flag];
else if ([super respondsToSelector:@selector(draggingSourceOperationMaskForLocal:)])
dragOp = [super draggingSourceOperationMaskForLocal:flag];
-
+
return dragOp;
}
@@ -724,12 +735,12 @@
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
NSArray* array = nil;
-
+
if (dragSource != nil)
array = [dragSource namesOfPromisedFilesDroppedAtDestination:dropDestination];
else if ([super respondsToSelector:@selector(namesOfPromisedFilesDroppedAtDestination:)])
array = [super namesOfPromisedFilesDroppedAtDestination:dropDestination];
-
+
return array;
}
@@ -737,7 +748,7 @@
{
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
-
+
if (dragSource != nil)
[dragSource draggedImage:image beganAt:screenPoint];
else if ([super respondsToSelector:@selector(draggedImage::)])
@@ -748,7 +759,7 @@
{
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
-
+
if (dragSource != nil)
[dragSource draggedImage:image endedAt:screenPoint operation:operation];
else if ([super respondsToSelector:@selector(draggedImage:::)])
@@ -759,7 +770,7 @@
{
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
-
+
if (dragSource != nil)
[dragSource draggedImage:image movedTo:screenPoint];
else if ([super respondsToSelector:@selector(draggedImage::)])
@@ -771,12 +782,12 @@
// If draggingSource is nil route the message to the superclass (if responding to the selector):
CDragSource *dragSource = self._dragSource;
BOOL result = FALSE;
-
+
if (dragSource != nil)
result = [dragSource ignoreModifierKeysWhileDragging];
else if ([super respondsToSelector:@selector(ignoreModifierKeysWhileDragging)])
result = [super ignoreModifierKeysWhileDragging];
-
+
return result;
}
@@ -789,12 +800,12 @@
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
NSDragOperation dragOp = NSDragOperationNone;
-
+
if (dropTarget != nil)
dragOp = [dropTarget draggingEntered:sender];
else if ([super respondsToSelector:@selector(draggingEntered:)])
dragOp = [super draggingEntered:sender];
-
+
return dragOp;
}
@@ -803,12 +814,12 @@
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
NSDragOperation dragOp = NSDragOperationNone;
-
+
if (dropTarget != nil)
dragOp = [dropTarget draggingUpdated:sender];
else if ([super respondsToSelector:@selector(draggingUpdated:)])
dragOp = [super draggingUpdated:sender];
-
+
return dragOp;
}
@@ -816,7 +827,7 @@
{
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
-
+
if (dropTarget != nil)
[dropTarget draggingExited:sender];
else if ([super respondsToSelector:@selector(draggingExited:)])
@@ -828,12 +839,12 @@
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
BOOL result = FALSE;
-
+
if (dropTarget != nil)
result = [dropTarget prepareForDragOperation:sender];
else if ([super respondsToSelector:@selector(prepareForDragOperation:)])
result = [super prepareForDragOperation:sender];
-
+
return result;
}
@@ -842,12 +853,12 @@
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
BOOL result = FALSE;
-
+
if (dropTarget != nil)
result = [dropTarget performDragOperation:sender];
else if ([super respondsToSelector:@selector(performDragOperation:)])
result = [super performDragOperation:sender];
-
+
return result;
}
@@ -855,7 +866,7 @@
{
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
-
+
if (dropTarget != nil)
[dropTarget concludeDragOperation:sender];
else if ([super respondsToSelector:@selector(concludeDragOperation:)])
@@ -866,7 +877,7 @@
{
// If draggingDestination is nil route the message to the superclass:
CDropTarget *dropTarget = self._dropTarget;
-
+
if (dropTarget != nil)
[dropTarget draggingEnded:sender];
else if ([super respondsToSelector:@selector(draggingEnded:)])
@@ -885,49 +896,49 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [insertText]: %s\n", [aString UTF8String]);
#endif // IM_DEBUG
-
+
if (fInputMethodLOCKABLE == NULL) {
return;
}
-
+
// Insert happens at the end of PAH
fInPressAndHold = NO;
-
+
// insertText gets called when the user commits text generated from an input method. It also gets
// called during ordinary input as well. We only need to send an input method event when we have marked
// text, or 'text in progress'. We also need to send the event if we get an insert text out of the blue!
// (i.e., when the user uses the Character palette or Inkwell), or when the string to insert is a complex
// Unicode value.
- NSUInteger utf16Length = [aString lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
- NSUInteger utf8Length = [aString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+
+ NSMutableString * useString = [self parseString:aString];
+ NSUInteger utf16Length = [useString lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
+ NSUInteger utf8Length = [useString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
BOOL aStringIsComplex = NO;
if ((utf16Length > 2) ||
- ((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:[aString characterAtIndex:0]])) {
+ ((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:[useString characterAtIndex:0]])) {
aStringIsComplex = YES;
}
-
+
if ([self hasMarkedText] || !fProcessingKeystroke || aStringIsComplex) {
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
// We need to select the previous glyph so that it is overwritten.
if (fPAHNeedsToSelect) {
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph);
fPAHNeedsToSelect = NO;
}
-
+
static JNF_MEMBER_CACHE(jm_insertText, jc_CInputMethod, "insertText", "(Ljava/lang/String;)V");
- jstring insertedText = JNFNSToJavaString(env, aString);
+ jstring insertedText = JNFNSToJavaString(env, useString);
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_insertText, insertedText); // AWT_THREADING Safe (AWTRunLoopMode)
(*env)->DeleteLocalRef(env, insertedText);
-
+
// The input method event will create psuedo-key events for each character in the committed string.
// We also don't want to send the character that triggered the insertText, usually a return. [3337563]
fKeyEventsNeeded = NO;
}
-
fPAHNeedsToSelect = NO;
-
}
- (void) doCommandBySelector:(SEL)aSelector
@@ -947,7 +958,7 @@
{
if (!fInputMethodLOCKABLE)
return;
-
+
BOOL isAttributedString = [aString isKindOfClass:[NSAttributedString class]];
NSAttributedString *attrString = (isAttributedString ? (NSAttributedString *)aString : nil);
NSString *incomingString = (isAttributedString ? [aString string] : aString);
@@ -958,14 +969,14 @@
static JNF_MEMBER_CACHE(jm_addAttribute, jc_CInputMethod, "addAttribute", "(ZZII)V");
static JNF_MEMBER_CACHE(jm_dispatchText, jc_CInputMethod, "dispatchText", "(IIZ)V");
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
// NSInputContext already did the analysis of the TSM event and created attributes indicating
// the underlining and color that should be done to the string. We need to look at the underline
// style and color to determine what kind of Java hilighting needs to be done.
jstring inProcessText = JNFNSToJavaString(env, incomingString);
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_startIMUpdate, inProcessText); // AWT_THREADING Safe (AWTRunLoopMode)
(*env)->DeleteLocalRef(env, inProcessText);
-
+
if (isAttributedString) {
NSUInteger length;
NSRange effectiveRange;
@@ -981,25 +992,25 @@
(NSNumber *)[attributes objectForKey:NSUnderlineStyleAttributeName];
NSInteger underlineSize = [underlineSizeObj integerValue];
isThickUnderline = (underlineSize > 1);
-
+
NSColor *underlineColorObj =
(NSColor *)[attributes objectForKey:NSUnderlineColorAttributeName];
isGray = !([underlineColorObj isEqual:[NSColor blackColor]]);
-
+
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_addAttribute, isThickUnderline, isGray, effectiveRange.location, effectiveRange.length); // AWT_THREADING Safe (AWTRunLoopMode)
}
}
}
-
+
static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
// We need to select the previous glyph so that it is overwritten.
if (fPAHNeedsToSelect) {
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_selectPreviousGlyph);
fPAHNeedsToSelect = NO;
}
-
+
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_dispatchText, selectionRange.location, selectionRange.length, JNI_FALSE); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
// If the marked text is being cleared (zero-length string) don't handle the key event.
if ([incomingString length] == 0) {
fKeyEventsNeeded = NO;
@@ -1011,16 +1022,16 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [unmarkText]\n");
#endif // IM_DEBUG
-
+
if (!fInputMethodLOCKABLE) {
return;
}
-
+
// unmarkText cancels any input in progress and commits it to the text field.
static JNF_MEMBER_CACHE(jm_unmarkText, jc_CInputMethod, "unmarkText", "()V");
JNIEnv *env = [ThreadUtilities getJNIEnv];
JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_unmarkText); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
}
- (BOOL) hasMarkedText
@@ -1028,24 +1039,24 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [hasMarkedText]\n");
#endif // IM_DEBUG
-
+
if (!fInputMethodLOCKABLE) {
return NO;
}
-
+
static JNF_MEMBER_CACHE(jf_fCurrentText, jc_CInputMethod, "fCurrentText", "Ljava/text/AttributedString;");
static JNF_MEMBER_CACHE(jf_fCurrentTextLength, jc_CInputMethod, "fCurrentTextLength", "I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject currentText = JNFGetObjectField(env, fInputMethodLOCKABLE, jf_fCurrentText);
-
+
jint currentTextLength = JNFGetIntField(env, fInputMethodLOCKABLE, jf_fCurrentTextLength);
-
+
BOOL hasMarkedText = (currentText != NULL && currentTextLength > 0);
-
+
if (currentText != NULL) {
(*env)->DeleteLocalRef(env, currentText);
}
-
+
return hasMarkedText;
}
@@ -1054,7 +1065,7 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [conversationIdentifier]\n");
#endif // IM_DEBUG
-
+
return (NSInteger) self;
}
@@ -1066,16 +1077,16 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [attributedSubstringFromRange] location=%lu, length=%lu\n", (unsigned long)theRange.location, (unsigned long)theRange.length);
#endif // IM_DEBUG
-
+
static JNF_MEMBER_CACHE(jm_substringFromRange, jc_CInputMethod, "attributedSubstringFromRange", "(II)Ljava/lang/String;");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject theString = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_substringFromRange, theRange.location, theRange.length); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
id result = [[[NSAttributedString alloc] initWithString:JNFJavaToNSString(env, theString)] autorelease];
#ifdef IM_DEBUG
NSLog(@"attributedSubstringFromRange returning \"%@\"", result);
#endif // IM_DEBUG
-
+
(*env)->DeleteLocalRef(env, theString);
return result;
}
@@ -1085,24 +1096,24 @@
*/
- (NSRange) markedRange
{
-
+
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [markedRange]\n");
#endif // IM_DEBUG
-
+
if (!fInputMethodLOCKABLE) {
return NSMakeRange(NSNotFound, 0);
}
-
+
static JNF_MEMBER_CACHE(jm_markedRange, jc_CInputMethod, "markedRange", "()[I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jarray array;
jboolean isCopy;
jint *_array;
NSRange range = NSMakeRange(NSNotFound, 0);
-
+
array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_markedRange); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
if (array) {
_array = (*env)->GetIntArrayElements(env, array, &isCopy);
if (_array != NULL) {
@@ -1116,7 +1127,7 @@
}
(*env)->DeleteLocalRef(env, array);
}
-
+
return range;
}
@@ -1128,18 +1139,18 @@
if (!fInputMethodLOCKABLE) {
return NSMakeRange(NSNotFound, 0);
}
-
+
static JNF_MEMBER_CACHE(jm_selectedRange, jc_CInputMethod, "selectedRange", "()[I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jarray array;
jboolean isCopy;
jint *_array;
NSRange range = NSMakeRange(NSNotFound, 0);
-
+
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [selectedRange]\n");
#endif // IM_DEBUG
-
+
array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_selectedRange); // AWT_THREADING Safe (AWTRunLoopMode)
if (array) {
_array = (*env)->GetIntArrayElements(env, array, &isCopy);
@@ -1150,7 +1161,7 @@
}
(*env)->DeleteLocalRef(env, array);
}
-
+
return range;
}
@@ -1161,7 +1172,7 @@
if (!fInputMethodLOCKABLE) {
return NSZeroRect;
}
-
+
static JNF_MEMBER_CACHE(jm_firstRectForCharacterRange, jc_CInputMethod,
"firstRectForCharacterRange", "(I)[I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
@@ -1169,16 +1180,16 @@
jboolean isCopy;
jint *_array;
NSRect rect;
-
+
#ifdef IM_DEBUG
fprintf(stderr,
"AWTView InputMethod Selector Called : [firstRectForCharacterRange:] location=%lu, length=%lu\n",
(unsigned long)theRange.location, (unsigned long)theRange.length);
#endif // IM_DEBUG
-
+
array = JNFCallObjectMethod(env, fInputMethodLOCKABLE, jm_firstRectForCharacterRange,
theRange.location); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
_array = (*env)->GetIntArrayElements(env, array, &isCopy);
if (_array) {
rect = ConvertNSScreenRect(env, NSMakeRect(_array[0], _array[1], _array[2], _array[3]));
@@ -1187,7 +1198,7 @@
rect = NSZeroRect;
}
(*env)->DeleteLocalRef(env, array);
-
+
#ifdef IM_DEBUG
fprintf(stderr,
"firstRectForCharacterRange returning x=%f, y=%f, width=%f, height=%f\n",
@@ -1204,23 +1215,23 @@
if (!fInputMethodLOCKABLE) {
return NSNotFound;
}
-
+
static JNF_MEMBER_CACHE(jm_characterIndexForPoint, jc_CInputMethod,
"characterIndexForPoint", "(II)I");
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
NSPoint flippedLocation = ConvertNSScreenPoint(env, thePoint);
-
+
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [characterIndexForPoint:(NSPoint)thePoint] x=%f, y=%f\n", flippedLocation.x, flippedLocation.y);
#endif // IM_DEBUG
-
+
jint index = JNFCallIntMethod(env, fInputMethodLOCKABLE, jm_characterIndexForPoint, (jint)flippedLocation.x, (jint)flippedLocation.y); // AWT_THREADING Safe (AWTRunLoopMode)
-
+
#ifdef IM_DEBUG
fprintf(stderr, "characterIndexForPoint returning %ld\n", index);
#endif // IM_DEBUG
-
+
if (index == -1) {
return NSNotFound;
} else {
@@ -1233,7 +1244,7 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [validAttributesForMarkedText]\n");
#endif // IM_DEBUG
-
+
return [NSArray array];
}
@@ -1242,14 +1253,14 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [setInputMethod]\n");
#endif // IM_DEBUG
-
+
JNIEnv *env = [ThreadUtilities getJNIEnv];
-
+
// Get rid of the old one
if (fInputMethodLOCKABLE) {
JNFDeleteGlobalRef(env, fInputMethodLOCKABLE);
}
-
+
// Save a global ref to the new input method.
if (inputMethod != NULL)
fInputMethodLOCKABLE = JNFNewGlobalRef(env, inputMethod);
@@ -1262,7 +1273,7 @@
#ifdef IM_DEBUG
fprintf(stderr, "AWTView InputMethod Selector Called : [abandonInput]\n");
#endif // IM_DEBUG
-
+
[ThreadUtilities performOnMainThread:@selector(markedTextAbandoned:) on:[NSInputManager currentInputManager] withObject:self waitUntilDone:YES];
[self unmarkText];
}
@@ -1284,22 +1295,22 @@
(JNIEnv *env, jobject obj, jint originX, jint originY, jint width, jint height, jlong windowLayerPtr)
{
__block AWTView *newView = nil;
-
-JNF_COCOA_ENTER(env);
-
+
+ JNF_COCOA_ENTER(env);
+
NSRect rect = NSMakeRect(originX, originY, width, height);
jobject cPlatformView = (*env)->NewGlobalRef(env, obj);
-
+
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-
+
CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
newView = [[AWTView alloc] initWithRect:rect
platformView:cPlatformView
windowLayer:windowLayer];
}];
-
-JNF_COCOA_EXIT(env);
-
+
+ JNF_COCOA_EXIT(env);
+
return ptr_to_jlong(newView);
}
@@ -1313,24 +1324,24 @@
Java_sun_lwawt_macosx_CPlatformView_nativeSetAutoResizable
(JNIEnv *env, jclass cls, jlong viewPtr, jboolean toResize)
{
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
+
+ NSView *view = (NSView *)jlong_to_ptr(viewPtr);
- NSView *view = (NSView *)jlong_to_ptr(viewPtr);
-
- [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
-
- if (toResize) {
- [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
- } else {
- [view setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin];
- }
-
- if ([view superview] != nil) {
- [[view superview] setAutoresizesSubviews:(BOOL)toResize];
- }
-
+ [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
+
+ if (toResize) {
+ [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
+ } else {
+ [view setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin];
+ }
+
+ if ([view superview] != nil) {
+ [[view superview] setAutoresizesSubviews:(BOOL)toResize];
+ }
+
}];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
}
/*
@@ -1345,17 +1356,17 @@
{
__block jint ret; //CGDirectDisplayID
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
- NSView *view = (NSView *)jlong_to_ptr(viewPtr);
+ NSView *view = (NSView *)jlong_to_ptr(viewPtr);
NSWindow *window = [view window];
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-
- ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
+
+ ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
}];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
return ret;
}
@@ -1372,13 +1383,13 @@
{
jobject jRect = NULL;
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
__block NSRect rect = NSZeroRect;
- NSView *view = (NSView *)jlong_to_ptr(viewPtr);
+ NSView *view = (NSView *)jlong_to_ptr(viewPtr);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-
+
NSRect viewBounds = [view bounds];
NSRect frameInWindow = [view convertRect:viewBounds toView:nil];
rect = [[view window] convertRectToScreen:frameInWindow];
@@ -1388,7 +1399,7 @@
}];
jRect = NSToJavaRect(env, rect);
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
return jRect;
}
@@ -1404,16 +1415,16 @@
{
__block jboolean underMouse = JNI_FALSE;
-JNF_COCOA_ENTER(env);
+ JNF_COCOA_ENTER(env);
NSView *nsView = OBJC(viewPtr);
- [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
- NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream];
- NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil];
- underMouse = [nsView hitTest:ptViewCoords] != nil;
+ [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+ NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream];
+ NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil];
+ underMouse = [nsView hitTest:ptViewCoords] != nil;
}];
-JNF_COCOA_EXIT(env);
+ JNF_COCOA_EXIT(env);
return underMouse;
}
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.h Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -40,6 +40,8 @@
NSMenu *fDockMenu;
CMenuBar *fDefaultMenuBar;
+ NSProgressIndicator *fProgressIndicator;
+
BOOL fHandlesDocumentTypes;
BOOL fHandlesURLTypes;
}
@@ -47,6 +49,8 @@
@property (nonatomic, retain) NSMenuItem *fPreferencesMenu;
@property (nonatomic, retain) NSMenuItem *fAboutMenu;
+@property (nonatomic, retain) NSProgressIndicator *fProgressIndicator;
+
@property (nonatomic, retain) NSMenu *fDockMenu;
@property (nonatomic, retain) CMenuBar *fDefaultMenuBar;
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/ApplicationDelegate.m Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -100,6 +100,7 @@
@synthesize fPreferencesMenu;
@synthesize fAboutMenu;
+@synthesize fProgressIndicator;
@synthesize fDockMenu;
@synthesize fDefaultMenuBar;
@@ -200,6 +201,18 @@
self.fPreferencesMenu = (NSMenuItem*)[appMenu itemWithTag:PREFERENCES_TAG];
self.fAboutMenu = (NSMenuItem*)[appMenu itemAtIndex:0];
+
+ NSDockTile *dockTile = [NSApp dockTile];
+ self.fProgressIndicator = [[NSProgressIndicator alloc]
+ initWithFrame:NSMakeRect(3.f, 0.f, dockTile.size.width - 6.f, 20.f)];
+
+ [fProgressIndicator setStyle:NSProgressIndicatorBarStyle];
+ [fProgressIndicator setIndeterminate:NO];
+ [[dockTile contentView] addSubview:fProgressIndicator];
+ [fProgressIndicator setMinValue:0];
+ [fProgressIndicator setMaxValue:100];
+ [fProgressIndicator setHidden:YES];
+ [fProgressIndicator release];
// If the java application has a bundle with an Info.plist file with
// a CFBundleDocumentTypes entry, then it is set up to handle Open Doc
@@ -252,6 +265,7 @@
self.fAboutMenu = nil;
self.fDockMenu = nil;
self.fDefaultMenuBar = nil;
+ self.fProgressIndicator = nil;
[super dealloc];
}
@@ -468,6 +482,9 @@
[dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown];
[dockImageView setImage:image];
+ [[ApplicationDelegate sharedDelegate].fProgressIndicator removeFromSuperview];
+ [dockImageView addSubview:[ApplicationDelegate sharedDelegate].fProgressIndicator];
+
// add it to the NSDockTile
[dockTile setContentView: dockImageView];
[dockTile display];
@@ -475,6 +492,20 @@
[dockImageView release];
}
++ (void)_setDockIconProgress:(NSNumber *)value {
+AWT_ASSERT_APPKIT_THREAD;
+
+ ApplicationDelegate *delegate = [ApplicationDelegate sharedDelegate];
+ if ([value doubleValue] >= 0 && [value doubleValue] <=100) {
+ [delegate.fProgressIndicator setDoubleValue:[value doubleValue]];
+ [delegate.fProgressIndicator setHidden:NO];
+ } else {
+ [delegate.fProgressIndicator setHidden:YES];
+ }
+
+ [[NSApp dockTile] display];
+}
+
// Obtains the image of the Dock icon, either manually set, a drawn copy, or the default NSApplicationIcon
+ (NSImage *)_dockIconImage {
AWT_ASSERT_APPKIT_THREAD;
@@ -610,6 +641,24 @@
/*
* Class: com_apple_eawt__AppDockIconHandler
+ * Method: nativeSetDockIconProgress
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_com_apple_eawt__1AppDockIconHandler_nativeSetDockIconProgress
+ (JNIEnv *env, jclass clz, jint value)
+{
+ JNF_COCOA_ENTER(env);
+
+ [ThreadUtilities performOnMainThread:@selector(_setDockIconProgress:)
+ on:[ApplicationDelegate class]
+ withObject:[NSNumber numberWithInt:value]
+ waitUntilDone:NO];
+
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: com_apple_eawt__AppDockIconHandler
* Method: nativeGetDockIconImage
* Signature: ()J
*/
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -29,12 +29,12 @@
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import <ApplicationServices/ApplicationServices.h>
+#import "CRobotKeyCode.h"
#import "LWCToolkit.h"
#import "sun_lwawt_macosx_CRobot.h"
#import "java_awt_event_InputEvent.h"
#import "sizecalc.h"
-
// Starting number for event numbers generated by Robot.
// Apple docs don't mention at all what are the requirements
// for these numbers. It seems that they must be higher
@@ -354,241 +354,10 @@
}
}
-// NOTE: Don't modify this table directly. It is machine generated. See below.
-static const unsigned char javaToMacKeyCode[] = {
- 127, // 0 0 VK_UNDEFINED No_Equivalent
- 127, // 1 0x1 Not_Used
- 127, // 2 0x2 Not_Used
- 127, // 3 0x3 VK_CANCEL No_Equivalent
- 127, // 4 0x4 Not_Used
- 127, // 5 0x5 Not_Used
- 127, // 6 0x6 Not_Used
- 127, // 7 0x7 Not_Used
- 51, // 8 0x8 VK_BACK_SPACE
- 48, // 9 0x9 VK_TAB
- 36, // 10 0xa VK_ENTER
- 127, // 11 0xb Not_Used
- 71, // 12 0xc VK_CLEAR
- 127, // 13 0xd Not_Used
- 127, // 14 0xe Not_Used
- 127, // 15 0xf Not_Used
- 56, // 16 0x10 VK_SHIFT
- 59, // 17 0x11 VK_CONTROL
- 58, // 18 0x12 VK_ALT
- 113, // 19 0x13 VK_PAUSE
- 57, // 20 0x14 VK_CAPS_LOCK
- 127, // 21 0x15 VK_KANA No_Equivalent
- 127, // 22 0x16 Not_Used
- 127, // 23 0x17 Not_Used
- 127, // 24 0x18 VK_FINAL No_Equivalent
- 127, // 25 0x19 VK_KANJI No_Equivalent
- 127, // 26 0x1a Not_Used
- 53, // 27 0x1b VK_ESCAPE
- 127, // 28 0x1c VK_CONVERT No_Equivalent
- 127, // 29 0x1d VK_NONCONVERT No_Equivalent
- 127, // 30 0x1e VK_ACCEPT No_Equivalent
- 127, // 31 0x1f VK_MODECHANGE No_Equivalent
- 49, // 32 0x20 VK_SPACE
- 116, // 33 0x21 VK_PAGE_UP
- 121, // 34 0x22 VK_PAGE_DOWN
- 119, // 35 0x23 VK_END
- 115, // 36 0x24 VK_HOME
- 123, // 37 0x25 VK_LEFT
- 126, // 38 0x26 VK_UP
- 124, // 39 0x27 VK_RIGHT
- 125, // 40 0x28 VK_DOWN
- 127, // 41 0x29 Not_Used
- 127, // 42 0x2a Not_Used
- 127, // 43 0x2b Not_Used
- 43, // 44 0x2c VK_COMMA
- 27, // 45 0x2d VK_MINUS
- 47, // 46 0x2e VK_PERIOD
- 44, // 47 0x2f VK_SLASH
- 29, // 48 0x30 VK_0
- 18, // 49 0x31 VK_1
- 19, // 50 0x32 VK_2
- 20, // 51 0x33 VK_3
- 21, // 52 0x34 VK_4
- 23, // 53 0x35 VK_5
- 22, // 54 0x36 VK_6
- 26, // 55 0x37 VK_7
- 28, // 56 0x38 VK_8
- 25, // 57 0x39 VK_9
- 127, // 58 0x3a Not_Used
- 41, // 59 0x3b VK_SEMICOLON
- 127, // 60 0x3c Not_Used
- 24, // 61 0x3d VK_EQUALS
- 127, // 62 0x3e Not_Used
- 127, // 63 0x3f Not_Used
- 127, // 64 0x40 Not_Used
- 0, // 65 0x41 VK_A
- 11, // 66 0x42 VK_B
- 8, // 67 0x43 VK_C
- 2, // 68 0x44 VK_D
- 14, // 69 0x45 VK_E
- 3, // 70 0x46 VK_F
- 5, // 71 0x47 VK_G
- 4, // 72 0x48 VK_H
- 34, // 73 0x49 VK_I
- 38, // 74 0x4a VK_J
- 40, // 75 0x4b VK_K
- 37, // 76 0x4c VK_L
- 46, // 77 0x4d VK_M
- 45, // 78 0x4e VK_N
- 31, // 79 0x4f VK_O
- 35, // 80 0x50 VK_P
- 12, // 81 0x51 VK_Q
- 15, // 82 0x52 VK_R
- 1, // 83 0x53 VK_S
- 17, // 84 0x54 VK_T
- 32, // 85 0x55 VK_U
- 9, // 86 0x56 VK_V
- 13, // 87 0x57 VK_W
- 7, // 88 0x58 VK_X
- 16, // 89 0x59 VK_Y
- 6, // 90 0x5a VK_Z
- 33, // 91 0x5b VK_OPEN_BRACKET
- 42, // 92 0x5c VK_BACK_SLASH
- 30, // 93 0x5d VK_CLOSE_BRACKET
- 127, // 94 0x5e Not_Used
- 127, // 95 0x5f Not_Used
- 82, // 96 0x60 VK_NUMPAD0
- 83, // 97 0x61 VK_NUMPAD1
- 84, // 98 0x62 VK_NUMPAD2
- 85, // 99 0x63 VK_NUMPAD3
- 86, // 100 0x64 VK_NUMPAD4
- 87, // 101 0x65 VK_NUMPAD5
- 88, // 102 0x66 VK_NUMPAD6
- 89, // 103 0x67 VK_NUMPAD7
- 91, // 104 0x68 VK_NUMPAD8
- 92, // 105 0x69 VK_NUMPAD9
- 67, // 106 0x6a VK_MULTIPLY
- 69, // 107 0x6b VK_ADD
- 127, // 108 0x6c VK_SEPARATER No_Equivalent
- 78, // 109 0x6d VK_SUBTRACT
- 65, // 110 0x6e VK_DECIMAL
- 75, // 111 0x6f VK_DIVIDE
- 122, // 112 0x70 VK_F1
- 120, // 113 0x71 VK_F2
- 99, // 114 0x72 VK_F3
- 118, // 115 0x73 VK_F4
- 96, // 116 0x74 VK_F5
- 97, // 117 0x75 VK_F6
- 98, // 118 0x76 VK_F7
- 100, // 119 0x77 VK_F8
- 101, // 120 0x78 VK_F9
- 109, // 121 0x79 VK_F10
- 103, // 122 0x7a VK_F11
- 111, // 123 0x7b VK_F12
- 127, // 124 0x7c Not_Used
- 127, // 125 0x7d Not_Used
- 127, // 126 0x7e Not_Used
- 117, // 127 0x7f VK_DELETE
- 127, // 128 0x80 VK_DEAD_GRAVE No_Equivalent
- 127, // 129 0x81 VK_DEAD_ACUTE No_Equivalent
- 127, // 130 0x82 VK_DEAD_CIRCUMFLEX No_Equivalent
- 127, // 131 0x83 VK_DEAD_TILDE No_Equivalent
- 127, // 132 0x84 VK_DEAD_MACRON No_Equivalent
- 127, // 133 0x85 VK_DEAD_BREVE No_Equivalent
- 127, // 134 0x86 VK_DEAD_ABOVEDOT No_Equivalent
- 127, // 135 0x87 VK_DEAD_DIAERESIS No_Equivalent
- 127, // 136 0x88 VK_DEAD_ABOVERING No_Equivalent
- 127, // 137 0x89 VK_DEAD_DOUBLEACUTE No_Equivalent
- 127, // 138 0x8a VK_DEAD_CARON No_Equivalent
- 127, // 139 0x8b VK_DEAD_CEDILLA No_Equivalent
- 127, // 140 0x8c VK_DEAD_OGONEK No_Equivalent
- 127, // 141 0x8d VK_DEAD_IOTA No_Equivalent
- 127, // 142 0x8e VK_DEAD_VOICED_SOUND No_Equivalent
- 127, // 143 0x8f VK_DEAD_SEMIVOICED_SOUND No_Equivalent
- 127, // 144 0x90 VK_NUM_LOCK No_Equivalent
- 107, // 145 0x91 VK_SCROLL_LOCK
- 127, // 146 0x92 Not_Used
- 127, // 147 0x93 Not_Used
- 127, // 148 0x94 Not_Used
- 127, // 149 0x95 Not_Used
- 127, // 150 0x96 VK_AMPERSAND No_Equivalent
- 127, // 151 0x97 VK_ASTERISK No_Equivalent
- 127, // 152 0x98 VK_QUOTEDBL No_Equivalent
- 127, // 153 0x99 VK_LESS No_Equivalent
- 105, // 154 0x9a VK_PRINTSCREEN
- 127, // 155 0x9b VK_INSERT No_Equivalent
- 114, // 156 0x9c VK_HELP
- 55, // 157 0x9d VK_META
- 127, // 158 0x9e Not_Used
- 127, // 159 0x9f Not_Used
- 127, // 160 0xa0 VK_GREATER No_Equivalent
- 127, // 161 0xa1 VK_BRACELEFT No_Equivalent
- 127, // 162 0xa2 VK_BRACERIGHT No_Equivalent
- 127, // 163 0xa3 Not_Used
- 127, // 164 0xa4 Not_Used
- 127, // 165 0xa5 Not_Used
- 127, // 166 0xa6 Not_Used
- 127, // 167 0xa7 Not_Used
- 127, // 168 0xa8 Not_Used
- 127, // 169 0xa9 Not_Used
- 127, // 170 0xaa Not_Used
- 127, // 171 0xab Not_Used
- 127, // 172 0xac Not_Used
- 127, // 173 0xad Not_Used
- 127, // 174 0xae Not_Used
- 127, // 175 0xaf Not_Used
- 127, // 176 0xb0 Not_Used
- 127, // 177 0xb1 Not_Used
- 127, // 178 0xb2 Not_Used
- 127, // 179 0xb3 Not_Used
- 127, // 180 0xb4 Not_Used
- 127, // 181 0xb5 Not_Used
- 127, // 182 0xb6 Not_Used
- 127, // 183 0xb7 Not_Used
- 127, // 184 0xb8 Not_Used
- 127, // 185 0xb9 Not_Used
- 127, // 186 0xba Not_Used
- 127, // 187 0xbb Not_Used
- 127, // 188 0xbc Not_Used
- 127, // 189 0xbd Not_Used
- 127, // 190 0xbe Not_Used
- 127, // 191 0xbf Not_Used
- 50, // 192 0xc0 VK_BACK_QUOTE
- 127, // 193 0xc1 Not_Used
- 127, // 194 0xc2 Not_Used
- 127, // 195 0xc3 Not_Used
- 127, // 196 0xc4 Not_Used
- 127, // 197 0xc5 Not_Used
- 127, // 198 0xc6 Not_Used
- 127, // 199 0xc7 Not_Used
- 127, // 200 0xc8 Not_Used
- 127, // 201 0xc9 Not_Used
- 127, // 202 0xca Not_Used
- 127, // 203 0xcb Not_Used
- 127, // 204 0xcc Not_Used
- 127, // 205 0xcd Not_Used
- 127, // 206 0xce Not_Used
- 127, // 207 0xcf Not_Used
- 127, // 208 0xd0 Not_Used
- 127, // 209 0xd1 Not_Used
- 127, // 210 0xd2 Not_Used
- 127, // 211 0xd3 Not_Used
- 127, // 212 0xd4 Not_Used
- 127, // 213 0xd5 Not_Used
- 127, // 214 0xd6 Not_Used
- 127, // 215 0xd7 Not_Used
- 127, // 216 0xd8 Not_Used
- 127, // 217 0xd9 Not_Used
- 127, // 218 0xda Not_Used
- 127, // 219 0xdb Not_Used
- 127, // 220 0xdc Not_Used
- 127, // 221 0xdd Not_Used
- 39 // 222 0xde VK_QUOTE
-};
-
-// NOTE: All values above 222 don't have an equivalent on MacOSX.
static inline CGKeyCode GetCGKeyCode(jint javaKeyCode)
{
- if (javaKeyCode > 222) {
- return 127;
- } else {
- return javaToMacKeyCode[javaKeyCode];
- }
+ CRobotKeyCodeMapping *keyCodeMapping = [CRobotKeyCodeMapping sharedInstance];
+ return [keyCodeMapping getOSXKeyCodeForJavaKey:javaKeyCode];
}
static int GetClickCount(BOOL isDown) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.h Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+#import <Foundation/Foundation.h>
+
+#ifndef KeyCodeConverter_CRobotKeyCode_h
+#define KeyCodeConverter_CRobotKeyCode_h
+
+const static int OSX_kVK_ANSI_A = 0x00;
+const static int OSX_kVK_ANSI_S = 0x01;
+const static int OSX_kVK_ANSI_D = 0x02;
+const static int OSX_kVK_ANSI_F = 0x03;
+const static int OSX_kVK_ANSI_H = 0x04;
+const static int OSX_kVK_ANSI_G = 0x05;
+const static int OSX_kVK_ANSI_Z = 0x06;
+const static int OSX_kVK_ANSI_X = 0x07;
+const static int OSX_kVK_ANSI_C = 0x08;
+const static int OSX_kVK_ANSI_V = 0x09;
+const static int OSX_kVK_ISO_Section = 0x0A;
+const static int OSX_kVK_ANSI_B = 0x0B;
+const static int OSX_kVK_ANSI_Q = 0x0C;
+const static int OSX_kVK_ANSI_W = 0x0D;
+const static int OSX_kVK_ANSI_E = 0x0E;
+const static int OSX_kVK_ANSI_R = 0x0F;
+const static int OSX_kVK_ANSI_Y = 0x10;
+const static int OSX_kVK_ANSI_T = 0x11;
+const static int OSX_kVK_ANSI_1 = 0x12;
+const static int OSX_kVK_ANSI_2 = 0x13;
+const static int OSX_kVK_ANSI_3 = 0x14;
+const static int OSX_kVK_ANSI_4 = 0x15;
+const static int OSX_kVK_ANSI_6 = 0x16;
+const static int OSX_kVK_ANSI_5 = 0x17;
+const static int OSX_kVK_ANSI_Equal = 0x18;
+const static int OSX_kVK_ANSI_9 = 0x19;
+const static int OSX_kVK_ANSI_7 = 0x1A;
+const static int OSX_kVK_ANSI_Minus = 0x1B;
+const static int OSX_kVK_ANSI_8 = 0x1C;
+const static int OSX_kVK_ANSI_0 = 0x1D;
+const static int OSX_kVK_ANSI_RightBracket = 0x1E;
+const static int OSX_kVK_ANSI_O = 0x1F;
+const static int OSX_kVK_ANSI_U = 0x20;
+const static int OSX_kVK_ANSI_LeftBracket = 0x21;
+const static int OSX_kVK_ANSI_I = 0x22;
+const static int OSX_kVK_ANSI_P = 0x23;
+const static int OSX_kVK_ANSI_L = 0x25;
+const static int OSX_kVK_ANSI_J = 0x26;
+const static int OSX_kVK_ANSI_Quote = 0x27;
+const static int OSX_kVK_ANSI_K = 0x28;
+const static int OSX_kVK_ANSI_Semicolon = 0x29;
+const static int OSX_kVK_ANSI_Backslash = 0x2A;
+const static int OSX_kVK_ANSI_Comma = 0x2B;
+const static int OSX_kVK_ANSI_Slash = 0x2C;
+const static int OSX_kVK_ANSI_N = 0x2D;
+const static int OSX_kVK_ANSI_M = 0x2E;
+const static int OSX_kVK_ANSI_Period = 0x2F;
+const static int OSX_kVK_ANSI_Grave = 0x32;
+const static int OSX_kVK_ANSI_KeypadDecimal = 0x41;
+const static int OSX_kVK_ANSI_KeypadMultiply = 0x43;
+const static int OSX_kVK_ANSI_KeypadPlus = 0x45;
+const static int OSX_kVK_ANSI_KeypadClear = 0x47;
+const static int OSX_kVK_ANSI_KeypadDivide = 0x4B;
+const static int OSX_kVK_ANSI_KeypadEnter = 0x4C;
+const static int OSX_kVK_ANSI_KeypadMinus = 0x4E;
+const static int OSX_kVK_ANSI_KeypadEquals = 0x51;
+const static int OSX_kVK_ANSI_Keypad0 = 0x52;
+const static int OSX_kVK_ANSI_Keypad1 = 0x53;
+const static int OSX_kVK_ANSI_Keypad2 = 0x54;
+const static int OSX_kVK_ANSI_Keypad3 = 0x55;
+const static int OSX_kVK_ANSI_Keypad4 = 0x56;
+const static int OSX_kVK_ANSI_Keypad5 = 0x57;
+const static int OSX_kVK_ANSI_Keypad6 = 0x58;
+const static int OSX_kVK_ANSI_Keypad7 = 0x59;
+const static int OSX_kVK_ANSI_Keypad8 = 0x5B;
+const static int OSX_kVK_ANSI_Keypad9 = 0x5C;
+const static int OSX_kVK_Return = 0x24;
+const static int OSX_kVK_Tab = 0x30;
+const static int OSX_kVK_Space = 0x31;
+const static int OSX_Delete = 0x33;
+const static int OSX_Escape = 0x35;
+const static int OSX_Command = 0x37;
+const static int OSX_Shift = 0x38;
+const static int OSX_CapsLock = 0x39;
+const static int OSX_Option = 0x3A;
+const static int OSX_Control = 0x3B;
+const static int OSX_RightShift = 0x3C;
+const static int OSX_RightOption = 0x3D;
+const static int OSX_RightControl = 0x3E;
+const static int OSX_Function = 0x3F;
+const static int OSX_F17 = 0x40;
+const static int OSX_VolumeUp = 0x48;
+const static int OSX_VolumeDown = 0x49;
+const static int OSX_Mute = 0x4A;
+const static int OSX_F18 = 0x4F;
+const static int OSX_F19 = 0x50;
+const static int OSX_F20 = 0x5A;
+const static int OSX_F5 = 0x60;
+const static int OSX_F6 = 0x61;
+const static int OSX_F7 = 0x62;
+const static int OSX_F3 = 0x63;
+const static int OSX_F8 = 0x64;
+const static int OSX_F9 = 0x65;
+const static int OSX_F11 = 0x67;
+const static int OSX_F13 = 0x69;
+const static int OSX_F16 = 0x6A;
+const static int OSX_F14 = 0x6B;
+const static int OSX_F10 = 0x6D;
+const static int OSX_F12 = 0x6F;
+const static int OSX_F15 = 0x71;
+const static int OSX_Help = 0x72;
+const static int OSX_Home = 0x73;
+const static int OSX_PageUp = 0x74;
+const static int OSX_ForwardDelete = 0x75;
+const static int OSX_F4 = 0x76;
+const static int OSX_End = 0x77;
+const static int OSX_F2 = 0x78;
+const static int OSX_PageDown = 0x79;
+const static int OSX_F1 = 0x7A;
+const static int OSX_LeftArrow = 0x7B;
+const static int OSX_RightArrow = 0x7C;
+const static int OSX_DownArrow = 0x7D;
+const static int OSX_UpArrow = 0x7E;
+const static int OSX_Undefined = 0x7F;
+
+@interface CRobotKeyCodeMapping : NSObject {
+
+}
+
+@property (readwrite, retain) NSDictionary *javaToMacKeyMap;
+
++ (CRobotKeyCodeMapping *)sharedInstance ;
+- (int)getOSXKeyCodeForJavaKey:(int) javaKey;
+
+@end
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobotKeyCode.m Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+#import "CRobotKeyCode.h"
+#import "java_awt_event_KeyEvent.h"
+
+@implementation CRobotKeyCodeMapping
+
+@synthesize javaToMacKeyMap;
+
++(CRobotKeyCodeMapping *) sharedInstance {
+ static CRobotKeyCodeMapping *instance = nil;
+ static dispatch_once_t executeOnce;
+
+ dispatch_once(&executeOnce, ^{
+ instance = [[CRobotKeyCodeMapping alloc] init];
+ });
+
+ return instance;
+}
+
+-(id) init {
+ self = [super init];
+
+ if (nil != self) {
+ javaToMacKeyMap = [NSDictionary dictionaryWithObjectsAndKeys :
+ [NSNumber numberWithInt : OSX_Delete], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_BACK_SPACE],
+ [NSNumber numberWithInt : OSX_kVK_Tab], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_TAB],
+ [NSNumber numberWithInt : OSX_kVK_Return], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ENTER],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadClear], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_CLEAR],
+ [NSNumber numberWithInt : OSX_Shift], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SHIFT],
+ [NSNumber numberWithInt : OSX_Control], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_CONTROL],
+ [NSNumber numberWithInt : OSX_Option], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ALT],
+ [NSNumber numberWithInt : OSX_CapsLock], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_CAPS_LOCK],
+ [NSNumber numberWithInt : OSX_Escape], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ESCAPE],
+ [NSNumber numberWithInt : OSX_kVK_Space], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SPACE],
+ [NSNumber numberWithInt : OSX_PageUp], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_PAGE_UP],
+ [NSNumber numberWithInt : OSX_PageDown], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_PAGE_DOWN],
+ [NSNumber numberWithInt : OSX_End], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_END],
+ [NSNumber numberWithInt : OSX_Home], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_HOME],
+ [NSNumber numberWithInt : OSX_LeftArrow], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_LEFT],
+ [NSNumber numberWithInt : OSX_UpArrow], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_UP],
+ [NSNumber numberWithInt : OSX_RightArrow], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_RIGHT],
+ [NSNumber numberWithInt : OSX_DownArrow], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_DOWN],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Comma], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_COMMA],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Minus], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_MINUS],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Period], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_PERIOD],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Slash], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SLASH],
+
+ [NSNumber numberWithInt : OSX_kVK_ANSI_0], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_0],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_1], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_1],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_2], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_2],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_3], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_3],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_4], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_4],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_5], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_5],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_6], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_6],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_7], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_7],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_8], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_8],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_9], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_9],
+
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Semicolon], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SEMICOLON],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Equal], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_EQUALS],
+
+ [NSNumber numberWithInt : OSX_kVK_ANSI_A], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_A],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_B], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_B],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_C], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_C],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_D], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_D],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_E], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_E],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_F], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_G], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_G],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_H], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_H],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_I], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_I],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_J], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_J],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_K], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_K],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_L], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_L],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_M], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_M],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_N], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_N],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_O], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_O],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_P], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_P],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Q], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_Q],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_R], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_R],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_S], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_S],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_T], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_T],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_U], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_U],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_V], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_V],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_W], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_W],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_X], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_X],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Y], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_Y],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Z], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_Z],
+
+ [NSNumber numberWithInt : OSX_kVK_ANSI_LeftBracket], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_OPEN_BRACKET],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Backslash], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_BACK_SLASH],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_RightBracket], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_CLOSE_BRACKET],
+
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad0], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD0],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad1], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD1],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad2], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD2],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad3], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD3],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad4], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD4],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad5], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD5],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad6], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD6],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad7], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD7],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad8], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD8],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Keypad9], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_NUMPAD9],
+
+ [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadMultiply], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_MULTIPLY],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadPlus], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_ADD],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadMinus], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_SUBTRACT],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadDecimal], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_DECIMAL],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_KeypadDivide], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_DIVIDE],
+
+ [NSNumber numberWithInt : OSX_F1], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F1],
+ [NSNumber numberWithInt : OSX_F2], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F2],
+ [NSNumber numberWithInt : OSX_F3], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F3],
+ [NSNumber numberWithInt : OSX_F4], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F4],
+ [NSNumber numberWithInt : OSX_F5], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F5],
+ [NSNumber numberWithInt : OSX_F6], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F6],
+ [NSNumber numberWithInt : OSX_F7], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F7],
+ [NSNumber numberWithInt : OSX_F8], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F8],
+ [NSNumber numberWithInt : OSX_F9], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F9],
+ [NSNumber numberWithInt : OSX_F10], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F10],
+ [NSNumber numberWithInt : OSX_F11], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F11],
+ [NSNumber numberWithInt : OSX_F12], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F12],
+
+ [NSNumber numberWithInt : OSX_ForwardDelete], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_DELETE],
+ [NSNumber numberWithInt : OSX_Help], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_HELP],
+ [NSNumber numberWithInt : OSX_Command], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_META],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Grave], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_BACK_QUOTE],
+ [NSNumber numberWithInt : OSX_kVK_ANSI_Quote], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_QUOTE],
+
+ [NSNumber numberWithInt : OSX_F13], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F13],
+ [NSNumber numberWithInt : OSX_F14], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F14],
+ [NSNumber numberWithInt : OSX_F15], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F15],
+ [NSNumber numberWithInt : OSX_F16], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F16],
+ [NSNumber numberWithInt : OSX_F17], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F17],
+ [NSNumber numberWithInt : OSX_F18], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F18],
+ [NSNumber numberWithInt : OSX_F19], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F19],
+ [NSNumber numberWithInt : OSX_F20], [NSNumber numberWithInt : java_awt_event_KeyEvent_VK_F20],
+
+ nil];
+ }
+
+ return self;
+}
+
+-(int) getOSXKeyCodeForJavaKey : (int) javaKey {
+ id val = [javaToMacKeyMap objectForKey : [NSNumber numberWithInt : javaKey]];
+
+ if (nil != val) {
+ return [val intValue];
+ } else {
+ return OSX_Undefined;
+ }
+}
+
+@end
--- a/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m Thu Apr 07 11:03:59 2016 -0700
@@ -133,16 +133,16 @@
return getenv(envVar) != NULL;
}
-char* SplashGetScaledImageName(const char* jar, const char* file,
- float *scaleFactor) {
+jboolean SplashGetScaledImageName(const char* jar, const char* file,
+ float *scaleFactor, char *scaledFile,
+ const size_t scaledImageLength) {
*scaleFactor = 1;
if(isSWTRunning()){
- return nil;
+ return JNI_FALSE;
}
NSAutoreleasePool *pool = [NSAutoreleasePool new];
- char* scaledFile = nil;
__block float screenScaleFactor = 1;
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
@@ -170,12 +170,18 @@
if ((fileName2x != nil) && (jar || [[NSFileManager defaultManager]
fileExistsAtPath: fileName2x])){
+ if (strlen([fileName2x UTF8String]) > scaledImageLength) {
+ [pool drain];
+ return JNI_FALSE;
+ }
*scaleFactor = 2;
- scaledFile = strdup([fileName2x UTF8String]);
+ strcpy(scaledFile, [fileName2x UTF8String]);
+ [pool drain];
+ return JNI_TRUE;
}
}
[pool drain];
- return scaledFile;
+ return JNI_FALSE;
}
void
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java Thu Apr 07 11:03:59 2016 -0700
@@ -698,7 +698,7 @@
// DeskTop.
"Desktop.background", new DesktopProperty(
- "win.desktop.backgroundColor",
+ "win.mdi.backgroundColor",
table.get("desktop")),
"Desktop.ancestorInputMap",
new UIDefaults.LazyInputMap(new Object[] {
@@ -1810,6 +1810,11 @@
LazyValue menuArrowIcon = t -> WindowsIconFactory.getMenuArrowIcon();
+ Color highlight = (Color) Toolkit.getDefaultToolkit().
+ getDesktopProperty("win.3d.highlightColor");
+
+ Color shadow = (Color) Toolkit.getDefaultToolkit().
+ getDesktopProperty("win.3d.shadowColor");
Object[] lazyDefaults = {
"Button.border", buttonBorder,
@@ -1838,8 +1843,12 @@
"TextArea.margin", textFieldMargin,
"TextField.border", textFieldBorder,
"TextField.margin", textFieldMargin,
- "TitledBorder.border",
- new XPBorderValue(Part.BP_GROUPBOX, etchedBorder),
+ "TitledBorder.border", new UIDefaults.LazyValue() {
+ public Object createValue(UIDefaults table) {
+ return new BorderUIResource.
+ EtchedBorderUIResource(highlight, shadow);
+ }
+ },
"ToggleButton.border", radioButtonBorder,
"ToolBar.border", toolBarBorder,
"ToolTip.border", toolTipBorder,
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileFormat.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileFormat.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -45,11 +45,12 @@
static final int AU_LINEAR_24 = 4; /* 24-bit linear PCM */
static final int AU_LINEAR_32 = 5; /* 32-bit linear PCM */
static final int AU_FLOAT = 6; /* 32-bit IEEE floating point */
- static final int AU_DOUBLE = 7; /* 64-bit IEEE floating point */
- static final int AU_ADPCM_G721 = 23; /* 4-bit CCITT g.721 ADPCM */
- static final int AU_ADPCM_G722 = 24; /* CCITT g.722 ADPCM */
- static final int AU_ADPCM_G723_3 = 25; /* CCITT g.723 3-bit ADPCM */
- static final int AU_ADPCM_G723_5 = 26; /* CCITT g.723 5-bit ADPCM */
+// we don't support these ...
+// static final int AU_DOUBLE = 7; /* 64-bit IEEE floating point */
+// static final int AU_ADPCM_G721 = 23; /* 4-bit CCITT g.721 ADPCM */
+// static final int AU_ADPCM_G722 = 24; /* CCITT g.722 ADPCM */
+// static final int AU_ADPCM_G723_3 = 25; /* CCITT g.723 3-bit ADPCM */
+// static final int AU_ADPCM_G723_5 = 26; /* CCITT g.723 5-bit ADPCM */
static final int AU_ALAW_8 = 27; /* 8-bit ISDN A-law */
static final int AU_HEADERSIZE = 24;
@@ -64,24 +65,28 @@
auType = -1;
- if( AudioFormat.Encoding.ALAW.equals(encoding) ) {
- if( format.getSampleSizeInBits()==8 ) {
+ if (AudioFormat.Encoding.ALAW.equals(encoding)) {
+ if (format.getSampleSizeInBits() == 8) {
auType = AU_ALAW_8;
}
- } else if( AudioFormat.Encoding.ULAW.equals(encoding) ) {
- if( format.getSampleSizeInBits()==8 ) {
+ } else if (AudioFormat.Encoding.ULAW.equals(encoding)) {
+ if (format.getSampleSizeInBits() == 8) {
auType = AU_ULAW_8;
}
- } else if( AudioFormat.Encoding.PCM_SIGNED.equals(encoding) ) {
- if( format.getSampleSizeInBits()==8 ) {
+ } else if (AudioFormat.Encoding.PCM_SIGNED.equals(encoding)) {
+ if (format.getSampleSizeInBits() == 8) {
auType = AU_LINEAR_8;
- } else if( format.getSampleSizeInBits()==16 ) {
+ } else if (format.getSampleSizeInBits() == 16) {
auType = AU_LINEAR_16;
- } else if( format.getSampleSizeInBits()==24 ) {
+ } else if (format.getSampleSizeInBits() == 24) {
auType = AU_LINEAR_24;
- } else if( format.getSampleSizeInBits()==32 ) {
+ } else if (format.getSampleSizeInBits() == 32) {
auType = AU_LINEAR_32;
}
+ } else if (AudioFormat.Encoding.PCM_FLOAT.equals(encoding)) {
+ if (format.getSampleSizeInBits() == 32) {
+ auType = AU_FLOAT;
+ }
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileReader.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -30,6 +30,7 @@
import java.io.InputStream;
import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFileFormat.Type;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
@@ -56,7 +57,7 @@
final int headerSize = dis.readInt();
final int dataSize = dis.readInt();
- final int encoding_local = dis.readInt();
+ final int auType = dis.readInt();
final int sampleRate = dis.readInt();
final int channels = dis.readInt();
if (channels <= 0) {
@@ -65,40 +66,38 @@
final int sampleSizeInBits;
final AudioFormat.Encoding encoding;
- switch (encoding_local) {
- case AuFileFormat.AU_ULAW_8:
- encoding = AudioFormat.Encoding.ULAW;
- sampleSizeInBits = 8;
- break;
- case AuFileFormat.AU_ALAW_8:
- encoding = AudioFormat.Encoding.ALAW;
- sampleSizeInBits = 8;
- break;
- case AuFileFormat.AU_LINEAR_8:
- // $$jb: 04.29.99: 8bit linear is *signed*, not *unsigned*
- encoding = AudioFormat.Encoding.PCM_SIGNED;
- sampleSizeInBits = 8;
- break;
- case AuFileFormat.AU_LINEAR_16:
- encoding = AudioFormat.Encoding.PCM_SIGNED;
- sampleSizeInBits = 16;
- break;
- case AuFileFormat.AU_LINEAR_24:
- encoding = AudioFormat.Encoding.PCM_SIGNED;
-
- sampleSizeInBits = 24;
- break;
- case AuFileFormat.AU_LINEAR_32:
- encoding = AudioFormat.Encoding.PCM_SIGNED;
-
- sampleSizeInBits = 32;
- break;
- // $jb: 03.19.99: we don't support these ...
- /* case AuFileFormat.AU_FLOAT:
- encoding = new AudioFormat.FLOAT;
- sampleSizeInBits = 32;
- break;
- case AuFileFormat.AU_DOUBLE:
+ switch (auType) {
+ case AuFileFormat.AU_ULAW_8:
+ encoding = AudioFormat.Encoding.ULAW;
+ sampleSizeInBits = 8;
+ break;
+ case AuFileFormat.AU_ALAW_8:
+ encoding = AudioFormat.Encoding.ALAW;
+ sampleSizeInBits = 8;
+ break;
+ case AuFileFormat.AU_LINEAR_8:
+ // $$jb: 04.29.99: 8bit linear is *signed*, not *unsigned*
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+ sampleSizeInBits = 8;
+ break;
+ case AuFileFormat.AU_LINEAR_16:
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+ sampleSizeInBits = 16;
+ break;
+ case AuFileFormat.AU_LINEAR_24:
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+ sampleSizeInBits = 24;
+ break;
+ case AuFileFormat.AU_LINEAR_32:
+ encoding = AudioFormat.Encoding.PCM_SIGNED;
+ sampleSizeInBits = 32;
+ break;
+ case AuFileFormat.AU_FLOAT:
+ encoding = AudioFormat.Encoding.PCM_FLOAT;
+ sampleSizeInBits = 32;
+ break;
+ // we don't support these ...
+ /* case AuFileFormat.AU_DOUBLE:
encoding = new AudioFormat.DOUBLE;
sampleSizeInBits = 8;
break;
@@ -117,9 +116,9 @@
SamplePerUnit = 8;
break;
*/
- default:
- // unsupported filetype, throw exception
- throw new UnsupportedAudioFileException("not a valid AU file");
+ default:
+ // unsupported filetype, throw exception
+ throw new UnsupportedAudioFileException("not a valid AU file");
}
final int frameSize = calculatePCMFrameSize(sampleSizeInBits, channels);
@@ -136,7 +135,6 @@
final AudioFormat format = new AudioFormat(encoding, sampleRate,
sampleSizeInBits, channels,
frameSize, sampleRate, true);
- return new AuFileFormat(AudioFileFormat.Type.AU, dataSize + headerSize,
- format, length);
+ return new AuFileFormat(Type.AU, dataSize + headerSize, format, length);
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/AuFileWriter.java Thu Apr 07 11:03:59 2016 -0700
@@ -39,6 +39,7 @@
import java.util.Objects;
import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFileFormat.Type;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
@@ -59,32 +60,32 @@
* Constructs a new AuFileWriter object.
*/
public AuFileWriter() {
- super(new AudioFileFormat.Type[]{AudioFileFormat.Type.AU});
+ super(new Type[]{Type.AU});
}
@Override
- public AudioFileFormat.Type[] getAudioFileTypes(AudioInputStream stream) {
+ public Type[] getAudioFileTypes(AudioInputStream stream) {
- AudioFileFormat.Type[] filetypes = new AudioFileFormat.Type[types.length];
+ Type[] filetypes = new Type[types.length];
System.arraycopy(types, 0, filetypes, 0, types.length);
// make sure we can write this stream
AudioFormat format = stream.getFormat();
AudioFormat.Encoding encoding = format.getEncoding();
- if( (AudioFormat.Encoding.ALAW.equals(encoding)) ||
- (AudioFormat.Encoding.ULAW.equals(encoding)) ||
- (AudioFormat.Encoding.PCM_SIGNED.equals(encoding)) ||
- (AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding)) ) {
-
+ if (AudioFormat.Encoding.ALAW.equals(encoding)
+ || AudioFormat.Encoding.ULAW.equals(encoding)
+ || AudioFormat.Encoding.PCM_SIGNED.equals(encoding)
+ || AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding)
+ || AudioFormat.Encoding.PCM_FLOAT.equals(encoding)) {
return filetypes;
}
- return new AudioFileFormat.Type[0];
+ return new Type[0];
}
@Override
- public int write(AudioInputStream stream, AudioFileFormat.Type fileType, OutputStream out) throws IOException {
+ public int write(AudioInputStream stream, Type fileType, OutputStream out) throws IOException {
Objects.requireNonNull(stream);
Objects.requireNonNull(fileType);
Objects.requireNonNull(out);
@@ -101,7 +102,7 @@
}
@Override
- public int write(AudioInputStream stream, AudioFileFormat.Type fileType, File out) throws IOException {
+ public int write(AudioInputStream stream, Type fileType, File out) throws IOException {
Objects.requireNonNull(stream);
Objects.requireNonNull(fileType);
Objects.requireNonNull(out);
@@ -141,61 +142,35 @@
* Returns the AudioFileFormat describing the file that will be written from this AudioInputStream.
* Throws IllegalArgumentException if not supported.
*/
- private AudioFileFormat getAudioFileFormat(AudioFileFormat.Type type, AudioInputStream stream) {
+ private AudioFileFormat getAudioFileFormat(Type type, AudioInputStream stream) {
if (!isFileTypeSupported(type, stream)) {
throw new IllegalArgumentException("File type " + type + " not supported.");
}
- AudioFormat format = null;
- AuFileFormat fileFormat = null;
- AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
-
AudioFormat streamFormat = stream.getFormat();
- AudioFormat.Encoding streamEncoding = streamFormat.getEncoding();
-
-
- int sampleSizeInBits;
- int fileSize;
+ AudioFormat.Encoding encoding = streamFormat.getEncoding();
- if( (AudioFormat.Encoding.ALAW.equals(streamEncoding)) ||
- (AudioFormat.Encoding.ULAW.equals(streamEncoding)) ) {
-
- encoding = streamEncoding;
- sampleSizeInBits = streamFormat.getSampleSizeInBits();
-
- } else if ( streamFormat.getSampleSizeInBits()==8 ) {
-
+ if (AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding)) {
encoding = AudioFormat.Encoding.PCM_SIGNED;
- sampleSizeInBits=8;
-
- } else {
-
- encoding = AudioFormat.Encoding.PCM_SIGNED;
- sampleSizeInBits=streamFormat.getSampleSizeInBits();
}
+ // We always write big endian au files, this is by far the standard
+ AudioFormat format = new AudioFormat(encoding,
+ streamFormat.getSampleRate(),
+ streamFormat.getSampleSizeInBits(),
+ streamFormat.getChannels(),
+ streamFormat.getFrameSize(),
+ streamFormat.getFrameRate(), true);
- format = new AudioFormat( encoding,
- streamFormat.getSampleRate(),
- sampleSizeInBits,
- streamFormat.getChannels(),
- streamFormat.getFrameSize(),
- streamFormat.getFrameRate(),
- true); // AU is always big endian
-
-
- if( stream.getFrameLength()!=AudioSystem.NOT_SPECIFIED ) {
+ int fileSize;
+ if (stream.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
fileSize = (int)stream.getFrameLength()*streamFormat.getFrameSize() + AuFileFormat.AU_HEADERSIZE;
} else {
fileSize = AudioSystem.NOT_SPECIFIED;
}
- fileFormat = new AuFileFormat( AudioFileFormat.Type.AU,
- fileSize,
- format,
- (int)stream.getFrameLength() );
-
- return fileFormat;
+ return new AuFileFormat(Type.AU, fileSize, format,
+ (int) stream.getFrameLength());
}
private InputStream getFileStream(AuFileFormat auFileFormat, AudioInputStream audioStream) throws IOException {
@@ -212,7 +187,7 @@
if (dataSizeInBytes>0x7FFFFFFFl) {
dataSizeInBytes=UNKNOWN_SIZE;
}
- int encoding_local = auFileFormat.getAuType();
+ int auType = auFileFormat.getAuType();
int sampleRate = (int)format.getSampleRate();
int channels = format.getChannels();
@@ -222,43 +197,17 @@
DataOutputStream dos = null;
SequenceInputStream auStream = null;
- AudioFormat audioStreamFormat = null;
- AudioFormat.Encoding encoding = null;
- InputStream codedAudioStream = audioStream;
-
- // if we need to do any format conversion, do it here.
-
- codedAudioStream = audioStream;
-
- audioStreamFormat = audioStream.getFormat();
- encoding = audioStreamFormat.getEncoding();
-
+ // if we need to do any format conversion, we do it here.
//$$ fb 2001-07-13: Bug 4391108
- if( (AudioFormat.Encoding.PCM_UNSIGNED.equals(encoding)) ||
- (AudioFormat.Encoding.PCM_SIGNED.equals(encoding)
- && !audioStreamFormat.isBigEndian()) ) {
- // We always write big endian au files, this is by far the standard
- codedAudioStream = AudioSystem.getAudioInputStream( new AudioFormat (
- AudioFormat.Encoding.PCM_SIGNED,
- audioStreamFormat.getSampleRate(),
- audioStreamFormat.getSampleSizeInBits(),
- audioStreamFormat.getChannels(),
- audioStreamFormat.getFrameSize(),
- audioStreamFormat.getFrameRate(),
- true),
- audioStream );
-
-
- }
+ audioStream = AudioSystem.getAudioInputStream(format, audioStream);
baos = new ByteArrayOutputStream();
dos = new DataOutputStream(baos);
-
dos.writeInt(AuFileFormat.AU_SUN_MAGIC);
dos.writeInt(headerSize);
dos.writeInt((int)dataSizeInBytes);
- dos.writeInt(encoding_local);
+ dos.writeInt(auType);
dos.writeInt(sampleRate);
dos.writeInt(channels);
@@ -269,7 +218,7 @@
header = baos.toByteArray();
headerStream = new ByteArrayInputStream( header );
auStream = new SequenceInputStream(headerStream,
- new NoCloseInputStream(codedAudioStream));
+ new NoCloseInputStream(audioStream));
return auStream;
}
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/RIFFReader.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/RIFFReader.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, 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
@@ -39,12 +39,12 @@
private long filepointer = 0;
private final String fourcc;
private String riff_type = null;
- private long ckSize = Integer.MAX_VALUE;
+ private final long ckSize;
private InputStream stream;
- private long avail = Integer.MAX_VALUE;
+ private long avail = 0xffffffffL; // MAX_UNSIGNED_INT
private RIFFReader lastiterator = null;
- public RIFFReader(InputStream stream) throws IOException {
+ public RIFFReader(final InputStream stream) throws IOException {
if (stream instanceof RIFFReader) {
root = ((RIFFReader) stream).root;
@@ -63,11 +63,13 @@
// because it is expected to
// always contain a string value
riff_type = null;
+ ckSize = 0;
avail = 0;
return;
}
- if (b != 0)
+ if (b != 0) {
break;
+ }
}
byte[] fourcc = new byte[4];
@@ -78,9 +80,6 @@
avail = ckSize;
if (getFormat().equals("RIFF") || getFormat().equals("LIST")) {
- if (avail > Integer.MAX_VALUE) {
- throw new RIFFInvalidDataException("Chunk size too big");
- }
byte[] format = new byte[4];
readFully(format);
this.riff_type = new String(format, "ascii");
@@ -207,7 +206,7 @@
@Override
public int available() {
- return (int)avail;
+ return avail > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) avail;
}
public void finish() throws IOException {
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveExtensibleFileReader.java Thu Apr 07 11:03:59 2016 -0700
@@ -184,6 +184,7 @@
// long framerate = 1;
int framesize = 1;
int bits = 1;
+ long dataSize = 0;
int validBitsPerSample = 1;
long channelMask = 0;
GUID subFormat = null;
@@ -214,6 +215,7 @@
}
if (chunk.getFormat().equals("data")) {
+ dataSize = chunk.getSize();
data_found = true;
break;
}
@@ -247,8 +249,12 @@
} else {
throw new UnsupportedAudioFileException();
}
+ long frameLength = dataSize / audioformat.getFrameSize();
+ if (frameLength > Integer.MAX_VALUE) {
+ frameLength = AudioSystem.NOT_SPECIFIED;
+ }
return new AudioFileFormat(AudioFileFormat.Type.WAVE, audioformat,
- AudioSystem.NOT_SPECIFIED);
+ (int) frameLength);
}
@Override
--- a/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/media/sound/WaveFloatFileReader.java Thu Apr 07 11:03:59 2016 -0700
@@ -59,10 +59,10 @@
long samplerate = 1;
int framesize = 1;
int bits = 1;
+ long dataSize = 0;
while (riffiterator.hasNextChunk()) {
RIFFReader chunk = riffiterator.nextChunk();
-
if (chunk.getFormat().equals("fmt ")) {
fmt_found = true;
@@ -77,6 +77,7 @@
bits = chunk.readUnsignedShort();
}
if (chunk.getFormat().equals("data")) {
+ dataSize = chunk.getSize();
data_found = true;
break;
}
@@ -87,8 +88,13 @@
AudioFormat audioformat = new AudioFormat(
Encoding.PCM_FLOAT, samplerate, bits, channels,
framesize, samplerate, false);
+ long frameLength = dataSize / audioformat.getFrameSize();
+ if (frameLength > Integer.MAX_VALUE) {
+ frameLength = AudioSystem.NOT_SPECIFIED;
+ }
+
return new AudioFileFormat(AudioFileFormat.Type.WAVE, audioformat,
- AudioSystem.NOT_SPECIFIED);
+ (int) frameLength);
}
@Override
--- a/jdk/src/java.desktop/share/classes/java/awt/Desktop.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/Desktop.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -25,6 +25,14 @@
package java.awt;
+import java.awt.desktop.AboutHandler;
+import java.awt.desktop.OpenFilesHandler;
+import java.awt.desktop.OpenURIHandler;
+import java.awt.desktop.PreferencesHandler;
+import java.awt.desktop.PrintFilesHandler;
+import java.awt.desktop.QuitHandler;
+import java.awt.desktop.QuitStrategy;
+import java.awt.desktop.SystemEventListener;
import java.awt.peer.DesktopPeer;
import java.io.File;
import java.io.FilePermission;
@@ -35,12 +43,11 @@
import java.net.URL;
import sun.awt.SunToolkit;
+import javax.swing.JMenuBar;
import sun.security.util.SecurityConstants;
/**
- * The {@code Desktop} class allows a Java application to launch
- * associated applications registered on the native desktop to handle
- * a {@link java.net.URI} or a file.
+ * The {@code Desktop} class allows interact with various desktop capabilities.
*
* <p> Supported operations include:
* <ul>
@@ -58,9 +65,11 @@
* or file. If there is no associated application or the associated
* application fails to be launched, an exception is thrown.
*
- * <p> An application is registered to a URI or file type; for
- * example, the {@code "sxi"} file extension is typically registered
- * to StarOffice. The mechanism of registering, accessing, and
+ * Please see {@link Desktop.Action} for the full list of supported operations
+ * and capabilities.
+ *
+ * <p> An application is registered to a URI or file type.
+ * The mechanism of registering, accessing, and
* launching the associated application is platform-dependent.
*
* <p> Each operation is an action type represented by the {@link
@@ -70,6 +79,8 @@
* application is executed, it will be executed on the same system as
* the one on which the Java application was launched.
*
+ * @see Action
+ *
* @since 1.6
* @author Armin Chen
* @author George Zhang
@@ -106,11 +117,145 @@
* @see Desktop#mail(java.net.URI)
*/
MAIL,
+
/**
* Represents a "browse" action.
* @see Desktop#browse(java.net.URI)
*/
- BROWSE
+ BROWSE,
+
+ /**
+ * Represents an AppForegroundListener
+ * @see java.awt.desktop.AppForegroundListener
+ * @since 9
+ */
+ APP_EVENT_FOREGROUND,
+
+ /**
+ * Represents an AppHiddenListener
+ * @see java.awt.desktop.AppHiddenListener
+ * @since 9
+ */
+ APP_EVENT_HIDDEN,
+
+ /**
+ * Represents an AppReopenedListener
+ * @see java.awt.desktop.AppReopenedListener
+ * @since 9
+ */
+ APP_EVENT_REOPENED,
+
+ /**
+ * Represents a ScreenSleepListener
+ * @see java.awt.desktop.ScreenSleepListener
+ * @since 9
+ */
+ APP_EVENT_SCREEN_SLEEP,
+
+ /**
+ * Represents a SystemSleepListener
+ * @see java.awt.desktop.SystemSleepListener
+ * @since 9
+ */
+ APP_EVENT_SYSTEM_SLEEP,
+
+ /**
+ * Represents a UserSessionListener
+ * @see java.awt.desktop.UserSessionListener
+ * @since 9
+ */
+ APP_EVENT_USER_SESSION,
+
+ /**
+ * Represents an AboutHandler
+ * @see #setAboutHandler(java.awt.desktop.AboutHandler)
+ * @since 9
+ */
+ APP_ABOUT,
+
+ /**
+ * Represents a PreferencesHandler
+ * @see #setPreferencesHandler(java.awt.desktop.PreferencesHandler)
+ * @since 9
+ */
+ APP_PREFERENCES,
+
+ /**
+ * Represents an OpenFilesHandler
+ * @see #setOpenFileHandler(java.awt.desktop.OpenFilesHandler)
+ * @since 9
+ */
+ APP_OPEN_FILE,
+
+ /**
+ * Represents a PrintFilesHandler
+ * @see #setPrintFileHandler(java.awt.desktop.PrintFilesHandler)
+ * @since 9
+ */
+ APP_PRINT_FILE,
+
+ /**
+ * Represents an OpenURIHandler
+ * @see #setOpenURIHandler(java.awt.desktop.OpenURIHandler)
+ * @since 9
+ */
+ APP_OPEN_URI,
+
+ /**
+ * Represents a QuitHandler
+ * @see #setQuitHandler(java.awt.desktop.QuitHandler)
+ * @since 9
+ */
+ APP_QUIT_HANDLER,
+
+ /**
+ * Represents a QuitStrategy
+ * @see #setQuitStrategy(java.awt.desktop.QuitStrategy)
+ * @since 9
+ */
+ APP_QUIT_STRATEGY,
+
+ /**
+ * Represents a SuddenTermination
+ * @see #enableSuddenTermination()
+ * @since 9
+ */
+ APP_SUDDEN_TERMINATION,
+
+ /**
+ * Represents a requestForeground
+ * @see #requestForeground(boolean)
+ * @since 9
+ */
+ APP_REQUEST_FOREGROUND,
+
+ /**
+ * Represents a HelpViewer
+ * @see #openHelpViewer()
+ * @since 9
+ */
+ APP_HELP_VIEWER,
+
+ /**
+ * Represents a menu bar
+ * @see #setDefaultMenuBar(javax.swing.JMenuBar)
+ * @since 9
+ */
+ APP_MENU_BAR,
+
+ /**
+ * Represents a browse file directory
+ * @see #browseFileDirectory(java.io.File)
+ * @since 9
+ */
+ BROWSE_FILE_DIR,
+
+ /**
+ * Represents a move to trash
+ * @see #moveToTrash(java.io.File)
+ * @since 9
+ */
+ MOVE_TO_TRASH
};
private DesktopPeer peer;
@@ -128,10 +273,10 @@
/**
* Returns the {@code Desktop} instance of the current
- * browser context. On some platforms the Desktop API may not be
+ * desktop context. On some platforms the Desktop API may not be
* supported; use the {@link #isDesktopSupported} method to
* determine if the current desktop is supported.
- * @return the Desktop instance of the current browser context
+ * @return the Desktop instance
* @throws HeadlessException if {@link
* GraphicsEnvironment#isHeadless()} returns {@code true}
* @throws UnsupportedOperationException if this class is not
@@ -208,7 +353,7 @@
if (!file.exists()) {
throw new IllegalArgumentException("The file: "
- + file.getPath() + " doesn't exist.");
+ + file.getPath() + " doesn't exist.");
}
file.canRead();
@@ -224,7 +369,7 @@
private void checkActionSupport(Action actionType){
if (!isSupported(actionType)) {
throw new UnsupportedOperationException("The " + actionType.name()
- + " action is not supported on the current platform!");
+ + " action is not supported on the current platform!");
}
}
@@ -238,7 +383,7 @@
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new AWTPermission(
- "showWindowWithoutWarningBanner"));
+ "showWindowWithoutWarningBanner"));
}
}
@@ -479,7 +624,409 @@
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new FilePermission("<<ALL FILES>>",
- SecurityConstants.FILE_EXECUTE_ACTION));
+ SecurityConstants.FILE_EXECUTE_ACTION));
+ }
+ }
+
+ private void checkRead() throws SecurityException {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new FilePermission("<<ALL FILES>>",
+ SecurityConstants.FILE_READ_ACTION));
+ }
+ }
+
+ private void checkDelete() throws SecurityException {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new FilePermission("<<ALL FILES>>",
+ SecurityConstants.FILE_DELETE_ACTION));
+ }
+ }
+
+ private void checkQuitPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkExit(0);
}
}
+
+ /**
+ * Adds sub-types of {@link SystemEventListener} to listen for notifications
+ * from the native system.
+ *
+ * Has no effect if SystemEventListener's sub-type is unsupported on the current
+ * platform.
+ *
+ * @param listener listener
+ *
+ * @throws SecurityException if a security manager exists and it
+ * denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}
+ * permission
+ *
+ * @see java.awt.desktop.AppForegroundListener
+ * @see java.awt.desktop.AppHiddenListener
+ * @see java.awt.desktop.AppReopenedListener
+ * @see java.awt.desktop.ScreenSleepListener
+ * @see java.awt.desktop.SystemSleepListener
+ * @see java.awt.desktop.UserSessionListener
+ * @since 9
+ */
+ public void addAppEventListener(final SystemEventListener listener) {
+ checkAWTPermission();
+ peer.addAppEventListener(listener);
+ }
+
+ /**
+ * Removes sub-types of {@link SystemEventListener} to listen for notifications
+ * from the native system.
+ *
+ * Has no effect if SystemEventListener's sub-type is unsupported on the current
+ * platform.
+ *
+ * @param listener listener
+ *
+ * @throws SecurityException if a security manager exists and it
+ * denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}
+ * permission
+ *
+ * @see java.awt.desktop.AppForegroundListener
+ * @see java.awt.desktop.AppHiddenListener
+ * @see java.awt.desktop.AppReopenedListener
+ * @see java.awt.desktop.ScreenSleepListener
+ * @see java.awt.desktop.SystemSleepListener
+ * @see java.awt.desktop.UserSessionListener
+ * @since 9
+ */
+ public void removeAppEventListener(final SystemEventListener listener) {
+ checkAWTPermission();
+ peer.removeAppEventListener(listener);
+ }
+
+ /**
+ * Installs a handler to show a custom About window for your application.
+ * <p>
+ * Setting the {@link java.awt.desktop.AboutHandler} to {@code null} reverts it to the
+ * default behavior.
+ *
+ * @param aboutHandler the handler to respond to the
+ * {@link java.awt.desktop.AboutHandler#handleAbout} )} message
+ *
+ * @throws SecurityException if a security manager exists and it
+ * denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}
+ * permission
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_ABOUT} action
+ *
+ * @since 9
+ */
+ public void setAboutHandler(final AboutHandler aboutHandler) {
+ checkAWTPermission();
+ checkActionSupport(Action.APP_ABOUT);
+ peer.setAboutHandler(aboutHandler);
+ }
+
+ /**
+ * Installs a handler to show a custom Preferences window for your
+ * application.
+ * <p>
+ * Setting the {@link PreferencesHandler} to {@code null} reverts it to
+ * the default behavior
+ *
+ * @param preferencesHandler the handler to respond to the
+ * {@link PreferencesHandler#handlePreferences(PreferencesEvent)}
+ *
+ * @throws SecurityException if a security manager exists and it
+ * denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}
+ * permission
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_PREFERENCES} action
+ * @since 9
+ */
+ public void setPreferencesHandler(final PreferencesHandler preferencesHandler) {
+ checkAWTPermission();
+ checkActionSupport(Action.APP_PREFERENCES);
+ peer.setPreferencesHandler(preferencesHandler);
+ }
+
+ /**
+ * Installs the handler which is notified when the application is asked to
+ * open a list of files.
+ *
+ * @implNote Please note that for Mac OS, notifications
+ * are only sent if the Java app is a bundled application,
+ * with a {@code CFBundleDocumentTypes} array present in its
+ * Info.plist. See the
+ * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
+ * Info.plist Key Reference</a> for more information about adding a
+ * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+ *
+ * @param openFileHandler handler
+ *
+ * @throws SecurityException if a security manager exists and its
+ * {@link java.lang.SecurityManager#checkRead(java.lang.String)}
+ * method denies read access to the files, or it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}
+ * permission, or the calling thread is not allowed to create a
+ * subprocess
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_OPEN_FILE} action
+ * @since 9
+ */
+ public void setOpenFileHandler(final OpenFilesHandler openFileHandler) {
+ checkAWTPermission();
+ checkExec();
+ checkRead();
+ checkActionSupport(Action.APP_OPEN_FILE);
+ peer.setOpenFileHandler(openFileHandler);
+ }
+
+ /**
+ * Installs the handler which is notified when the application is asked to
+ * print a list of files.
+ *
+ * @implNote Please note that for Mac OS, notifications
+ * are only sent if the Java app is a bundled application,
+ * with a {@code CFBundleDocumentTypes} array present in its
+ * Info.plist. See the
+ * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
+ * Info.plist Key Reference</a> for more information about adding a
+ * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+ *
+ * @param printFileHandler handler
+ * @throws SecurityException if a security manager exists and its
+ * {@link java.lang.SecurityManager#checkPrintJobAccess()} method denies
+ * the permission to print.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_PRINT_FILE} action
+ * @since 9
+ */
+ public void setPrintFileHandler(final PrintFilesHandler printFileHandler) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPrintJobAccess();
+ }
+ checkActionSupport(Action.APP_PRINT_FILE);
+ peer.setPrintFileHandler(printFileHandler);
+ }
+
+ /**
+ * Installs the handler which is notified when the application is asked to
+ * open a URL.
+ *
+ * Setting the handler to {@code null} causes all
+ * {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} requests to be
+ * enqueued until another handler is set.
+ *
+ * @implNote Please note that for Mac OS, notifications
+ * are only sent if the Java app is a bundled application,
+ * with a {@code CFBundleDocumentTypes} array present in its
+ * Info.plist. See the
+ * <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">
+ * Info.plist Key Reference</a> for more information about adding a
+ * {@code CFBundleDocumentTypes} key to your app's Info.plist.
+ *
+ * @param openURIHandler handler
+ *
+ * {@code AWTPermission("showWindowWithoutWarningBanner")}
+ * permission, or the calling thread is not allowed to create a
+ * subprocess
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_OPEN_URI} action
+ * @since 9
+ */
+ public void setOpenURIHandler(final OpenURIHandler openURIHandler) {
+ checkAWTPermission();
+ checkExec();
+ checkActionSupport(Action.APP_OPEN_URI);
+ peer.setOpenURIHandler(openURIHandler);
+ }
+
+ /**
+ * Installs the handler which determines if the application should quit. The
+ * handler is passed a one-shot {@link java.awt.desktop.QuitResponse} which can cancel or
+ * proceed with the quit. Setting the handler to {@code null} causes
+ * all quit requests to directly perform the default {@link QuitStrategy}.
+ *
+ * @param quitHandler the handler that is called when the application is
+ * asked to quit
+ *
+ * @throws SecurityException if a security manager exists and it
+ * will not allow the caller to invoke {@code System.exit}
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_QUIT_HANDLER} action
+ * @since 9
+ */
+ public void setQuitHandler(final QuitHandler quitHandler) {
+ checkQuitPermission();
+ checkActionSupport(Action.APP_QUIT_HANDLER);
+ peer.setQuitHandler(quitHandler);
+ }
+
+ /**
+ * Sets the default strategy used to quit this application. The default is
+ * calling SYSTEM_EXIT_0.
+ *
+ * @param strategy the way this application should be shutdown
+ *
+ * @throws SecurityException if a security manager exists and it
+ * will not allow the caller to invoke {@code System.exit}
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_QUIT_STRATEGY} action
+ * @see QuitStrategy
+ * @since 9
+ */
+ public void setQuitStrategy(final QuitStrategy strategy) {
+ checkQuitPermission();
+ checkActionSupport(Action.APP_QUIT_STRATEGY);
+ peer.setQuitStrategy(strategy);
+ }
+
+ /**
+ * Enables this application to be suddenly terminated.
+ *
+ * Call this method to indicate your application's state is saved, and
+ * requires no notification to be terminated. Letting your application
+ * remain terminatable improves the user experience by avoiding re-paging in
+ * your application when it's asked to quit.
+ *
+ * <b>Note: enabling sudden termination will allow your application to be
+ * quit without notifying your QuitHandler, or running any shutdown
+ * hooks.</b>
+ * E.g. user-initiated Cmd-Q, logout, restart, or shutdown requests will
+ * effectively "kill -KILL" your application.
+ *
+ * @throws SecurityException if a security manager exists and it
+ * will not allow the caller to invoke {@code System.exit}
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_SUDDEN_TERMINATION} action
+ * @see #disableSuddenTermination()
+ * @since 9
+ */
+ public void enableSuddenTermination() {
+ checkQuitPermission();
+ checkActionSupport(Action.APP_SUDDEN_TERMINATION);
+ peer.enableSuddenTermination();
+ }
+
+ /**
+ * Prevents this application from being suddenly terminated.
+ *
+ * Call this method to indicate that your application has unsaved state, and
+ * may not be terminated without notification.
+ *
+ * @throws SecurityException if a security manager exists and it
+ * will not allow the caller to invoke {@code System.exit}
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_SUDDEN_TERMINATION} action
+ * @see #enableSuddenTermination()
+ * @since 9
+ */
+ public void disableSuddenTermination() {
+ checkQuitPermission();
+ checkActionSupport(Action.APP_SUDDEN_TERMINATION);
+ peer.disableSuddenTermination();
+ }
+
+ /**
+ * Requests this application to move to the foreground.
+ *
+ * @param allWindows if all windows of this application should be moved to
+ * the foreground, or only the foremost one
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_REQUEST_FOREGROUND} action
+ * @since 9
+ */
+ public void requestForeground(final boolean allWindows) {
+ checkAWTPermission();
+ checkActionSupport(Action.APP_REQUEST_FOREGROUND);
+ peer.requestForeground(allWindows);
+ }
+
+ /**
+ * Opens the native help viewer application.
+ *
+ * @implNote Please note that for Mac OS, it opens the native help viewer
+ * application if a Help Book has been added to the application bundler
+ * and registered in the Info.plist with CFBundleHelpBookFolder
+ *
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_HELP_VIEWER} action
+ * @since 9
+ */
+ public void openHelpViewer() {
+ checkAWTPermission();
+ checkActionSupport(Action.APP_HELP_VIEWER);
+ peer.openHelpViewer();
+ }
+
+ /**
+ * Sets the default menu bar to use when there are no active frames.
+ *
+ * @implNote Aqua Look and Feel should be active to support this on Mac OS.
+ *
+ * @param menuBar to use when no other frames are active
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#APP_MENU_BAR} action
+ * @since 9
+ */
+ public void setDefaultMenuBar(final JMenuBar menuBar) {
+ checkAWTPermission();
+ checkActionSupport(Action.APP_MENU_BAR);
+ peer.setDefaultMenuBar(menuBar);
+ }
+
+ /**
+ * Opens a folder containing the {@code file} and selects it
+ * in a default system file manager.
+ * @param file the file
+ * @throws SecurityException If a security manager exists and its
+ * {@link SecurityManager#checkRead(java.lang.String)} method
+ * denies read access to the file
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#BROWSE_FILE_DIR} action
+ * @throws NullPointerException if {@code file} is {@code null}
+ * @throws IllegalArgumentException if the specified file doesn't
+ * exist
+ * @since 9
+ */
+ public void browseFileDirectory(File file) {
+ checkRead();
+ checkActionSupport(Action.BROWSE_FILE_DIR);
+ checkFileValidation(file);
+ peer.browseFileDirectory(file);
+ }
+
+ /**
+ * Moves the specified file to the trash.
+ *
+ * @param file the file
+ * @return returns true if successfully moved the file to the trash.
+ * @throws SecurityException If a security manager exists and its
+ * {@link SecurityManager#checkWrite(java.lang.String)} method
+ * denies write access to the file
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Desktop.Action#MOVE_TO_TRASH} action
+ * @throws NullPointerException if {@code file} is {@code null}
+ * @throws IllegalArgumentException if the specified file doesn't
+ * exist
+ *
+ * @since 9
+ */
+ public boolean moveToTrash(final File file) {
+ checkDelete();
+ checkActionSupport(Action.MOVE_TO_TRASH);
+ checkFileValidation(file);
+ return peer.moveToTrash(file);
+ }
}
--- a/jdk/src/java.desktop/share/classes/java/awt/Font.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/Font.java Thu Apr 07 11:03:59 2016 -0700
@@ -611,8 +611,9 @@
* so that when the Font2D is GC'd it can also remove the file.
*/
FontManager fm = FontManagerFactory.getInstance();
- this.font2DHandle = fm.createFont2D(fontFile, fontFormat, isCopy,
- tracker).handle;
+ Font2D[] fonts =
+ fm.createFont2D(fontFile, fontFormat, false, isCopy, tracker);
+ this.font2DHandle = fonts[0].handle;
this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
this.style = Font.PLAIN;
this.size = 1;
@@ -841,6 +842,132 @@
return hasPerm;
}
+
+ /**
+ * Returns a new array of {@code Font} decoded from the specified stream.
+ * The returned {@code Font[]} will have at least one element.
+ * <p>
+ * The explicit purpose of this variation on the
+ * {@code createFont(int, InputStream)} method is to support font
+ * sources which represent a TrueType/OpenType font collection and
+ * be able to return all individual fonts in that collection.
+ * Consequently this method will throw {@code FontFormatException}
+ * if the data source does not contain at least one TrueType/OpenType
+ * font. The same exception will also be thrown if any of the fonts in
+ * the collection does not contain the required font tables.
+ * <p>
+ * The condition "at least one", allows for the stream to represent
+ * a single OpenType/TrueType font. That is, it does not have to be
+ * a collection.
+ * Each {@code Font} element of the returned array is
+ * created with a point size of 1 and style {@link #PLAIN PLAIN}.
+ * This base font can then be used with the {@code deriveFont}
+ * methods in this class to derive new {@code Font} objects with
+ * varying sizes, styles, transforms and font features.
+ * <p>This method does not close the {@link InputStream}.
+ * <p>
+ * To make each {@code Font} available to Font constructors it
+ * must be registered in the {@code GraphicsEnvironment} by calling
+ * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}.
+ * @param fontStream an {@code InputStream} object representing the
+ * input data for the font or font collection.
+ * @return a new {@code Font[]}.
+ * @throws FontFormatException if the {@code fontStream} data does
+ * not contain the required font tables for any of the elements of
+ * the collection, or if it contains no fonts at all.
+ * @throws IOException if the {@code fontStream} cannot be completely read.
+ * @see GraphicsEnvironment#registerFont(Font)
+ * @since 9
+ */
+ public static Font[] createFonts(InputStream fontStream)
+ throws FontFormatException, IOException {
+
+ final int fontFormat = Font.TRUETYPE_FONT;
+ if (hasTempPermission()) {
+ return createFont0(fontFormat, fontStream, true, null);
+ }
+
+ // Otherwise, be extra conscious of pending temp file creation and
+ // resourcefully handle the temp file resources, among other things.
+ CreatedFontTracker tracker = CreatedFontTracker.getTracker();
+ boolean acquired = false;
+ try {
+ acquired = tracker.acquirePermit();
+ if (!acquired) {
+ throw new IOException("Timed out waiting for resources.");
+ }
+ return createFont0(fontFormat, fontStream, true, tracker);
+ } catch (InterruptedException e) {
+ throw new IOException("Problem reading font data.");
+ } finally {
+ if (acquired) {
+ tracker.releasePermit();
+ }
+ }
+ }
+
+ /* used to implement Font.createFont */
+ private Font(Font2D font2D) {
+
+ this.createdFont = true;
+ this.font2DHandle = font2D.handle;
+ this.name = font2D.getFontName(Locale.getDefault());
+ this.style = Font.PLAIN;
+ this.size = 1;
+ this.pointSize = 1f;
+ }
+
+ /**
+ * Returns a new array of {@code Font} decoded from the specified file.
+ * The returned {@code Font[]} will have at least one element.
+ * <p>
+ * The explicit purpose of this variation on the
+ * {@code createFont(int, File)} method is to support font
+ * sources which represent a TrueType/OpenType font collection and
+ * be able to return all individual fonts in that collection.
+ * Consequently this method will throw {@code FontFormatException}
+ * if the data source does not contain at least one TrueType/OpenType
+ * font. The same exception will also be thrown if any of the fonts in
+ * the collection does not contain the required font tables.
+ * <p>
+ * The condition "at least one", allows for the stream to represent
+ * a single OpenType/TrueType font. That is, it does not have to be
+ * a collection.
+ * Each {@code Font} element of the returned array is
+ * created with a point size of 1 and style {@link #PLAIN PLAIN}.
+ * This base font can then be used with the {@code deriveFont}
+ * methods in this class to derive new {@code Font} objects with
+ * varying sizes, styles, transforms and font features.
+ * <p>
+ * To make each {@code Font} available to Font constructors it
+ * must be registered in the {@code GraphicsEnvironment} by calling
+ * {@link GraphicsEnvironment#registerFont(Font) registerFont(Font)}.
+ * @param fontFile a {@code File} object containing the
+ * input data for the font or font collection.
+ * @return a new {@code Font[]}.
+ * @throws FontFormatException if the {@code File} does
+ * not contain the required font tables for any of the elements of
+ * the collection, or if it contains no fonts at all.
+ * @throws IOException if the {@code fontFile} cannot be read.
+ * @see GraphicsEnvironment#registerFont(Font)
+ * @since 9
+ */
+ public static Font[] createFonts(File fontFile)
+ throws FontFormatException, IOException
+ {
+ int fontFormat = Font.TRUETYPE_FONT;
+ fontFile = checkFontFile(fontFormat, fontFile);
+ FontManager fm = FontManagerFactory.getInstance();
+ Font2D[] font2DArr =
+ fm.createFont2D(fontFile, fontFormat, true, false, null);
+ int num = font2DArr.length;
+ Font[] fonts = new Font[num];
+ for (int i = 0; i < num; i++) {
+ fonts[i] = new Font(font2DArr[i]);
+ }
+ return fonts;
+ }
+
/**
* Returns a new {@code Font} using the specified font type
* and input data. The new {@code Font} is
@@ -873,7 +1000,7 @@
throws java.awt.FontFormatException, java.io.IOException {
if (hasTempPermission()) {
- return createFont0(fontFormat, fontStream, null);
+ return createFont0(fontFormat, fontStream, false, null)[0];
}
// Otherwise, be extra conscious of pending temp file creation and
@@ -885,7 +1012,7 @@
if (!acquired) {
throw new IOException("Timed out waiting for resources.");
}
- return createFont0(fontFormat, fontStream, tracker);
+ return createFont0(fontFormat, fontStream, false, tracker)[0];
} catch (InterruptedException e) {
throw new IOException("Problem reading font data.");
} finally {
@@ -895,8 +1022,9 @@
}
}
- private static Font createFont0(int fontFormat, InputStream fontStream,
- CreatedFontTracker tracker)
+ private static Font[] createFont0(int fontFormat, InputStream fontStream,
+ boolean allFonts,
+ CreatedFontTracker tracker)
throws java.awt.FontFormatException, java.io.IOException {
if (fontFormat != Font.TRUETYPE_FONT &&
@@ -965,8 +1093,15 @@
* without waiting for the results of that constructor.
*/
copiedFontData = true;
- Font font = new Font(tFile, fontFormat, true, tracker);
- return font;
+ FontManager fm = FontManagerFactory.getInstance();
+ Font2D[] font2DArr =
+ fm.createFont2D(tFile, fontFormat, allFonts, true, tracker);
+ int num = font2DArr.length;
+ Font[] fonts = new Font[num];
+ for (int i = 0; i < num; i++) {
+ fonts[i] = new Font(font2DArr[i]);
+ }
+ return fonts;
} finally {
if (tracker != null) {
tracker.remove(tFile);
@@ -1037,6 +1172,13 @@
public static Font createFont(int fontFormat, File fontFile)
throws java.awt.FontFormatException, java.io.IOException {
+ fontFile = checkFontFile(fontFormat, fontFile);
+ return new Font(fontFile, fontFormat, false, null);
+ }
+
+ private static File checkFontFile(int fontFormat, File fontFile)
+ throws FontFormatException, IOException {
+
fontFile = new File(fontFile.getPath());
if (fontFormat != Font.TRUETYPE_FONT &&
@@ -1052,7 +1194,7 @@
if (!fontFile.canRead()) {
throw new IOException("Can't read " + fontFile);
}
- return new Font(fontFile, fontFormat, false, null);
+ return fontFile;
}
/**
--- a/jdk/src/java.desktop/share/classes/java/awt/Frame.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/Frame.java Thu Apr 07 11:03:59 2016 -0700
@@ -38,6 +38,7 @@
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleState;
import javax.accessibility.AccessibleStateSet;
+import javax.swing.WindowConstants;
import sun.awt.AWTAccessor;
import sun.awt.SunToolkit;
--- a/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/SplashScreen.java Thu Apr 07 11:03:59 2016 -0700
@@ -251,7 +251,7 @@
assert scale > 0;
if (scale > 0 && scale != 1) {
bounds.setSize((int) (bounds.getWidth() / scale),
- (int) (bounds.getWidth() / scale));
+ (int) (bounds.getHeight() / scale));
}
return bounds;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/Taskbar.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2016, 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.awt;
+
+import java.awt.peer.TaskbarPeer;
+import sun.awt.SunToolkit;
+
+/**
+ * The {@code Taskbar} class allows a Java application to interact with
+ * the system task area (taskbar, Dock, etc.).
+ *
+ * <p>
+ * There are a variety of interactions depending on the current platform such as
+ * displaying progress of some task, appending user-specified menu to the application
+ * icon context menu, etc.
+ *
+ * @implNote Linux support is currently limited to Unity. However to make these
+ * features work on Unity, the app should be run from a .desktop file with
+ * specified {@code java.desktop.appName} system property set to this .desktop
+ * file name:
+ * {@code Exec=java -Djava.desktop.appName=MyApp.desktop -jar /path/to/myapp.jar}
+ * see <a href="https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles">
+ * https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles</a>
+ *
+ * @since 9
+ */
+
+public class Taskbar {
+
+ /**
+ * List of provided features. Each platform supports a different
+ * set of features. You may use the {@link Taskbar#isSupported}
+ * method to determine if the given feature is supported by the
+ * current platform.
+ */
+ public static enum Feature {
+
+ /**
+ * Represents a textual icon badge feature.
+ * @see #setIconBadge(java.lang.String)
+ */
+ ICON_BADGE_TEXT,
+
+ /**
+ * Represents a numerical icon badge feature.
+ * @see #setIconBadge(java.lang.String)
+ */
+ ICON_BADGE_NUMBER,
+
+ /**
+ * Represents a graphical icon badge feature for a window.
+ * @see #setWindowIconBadge(java.awt.Window, java.awt.Image)
+ */
+ ICON_BADGE_IMAGE_WINDOW,
+
+ /**
+ * Represents an icon feature.
+ * @see #setIconImage(java.awt.Image)
+ */
+ ICON_IMAGE,
+
+ /**
+ * Represents a menu feature.
+ * @see #setMenu(java.awt.PopupMenu)
+ * @see #getMenu()
+ */
+ MENU,
+
+ /**
+ * Represents a progress state feature for a specified window.
+ * @see #setWindowProgressState(java.awt.Window, State)
+ */
+ PROGRESS_STATE_WINDOW,
+
+ /**
+ * Represents a progress value feature.
+ * @see #setProgressValue(int)
+ */
+ PROGRESS_VALUE,
+
+ /**
+ * Represents a progress value feature for a specified window.
+ * @see #setWindowProgressValue(java.awt.Window, int)
+ */
+ PROGRESS_VALUE_WINDOW,
+
+ /**
+ * Represents a user attention request feature.
+ * @see #requestUserAttention(boolean, boolean)
+ */
+ USER_ATTENTION,
+
+ /**
+ * Represents a user attention request feature for a specified window.
+ * @see #requestWindowUserAttention(java.awt.Window)
+ */
+ USER_ATTENTION_WINDOW
+ }
+
+ /**
+ * Kinds of available window progress states.
+ *
+ * @see #setWindowProgressState(java.awt.Window, java.awt.Taskbar.State)
+ */
+ public static enum State {
+ /**
+ * Stops displaying the progress.
+ */
+ OFF,
+ /**
+ * The progress indicator displays with normal color and determinate
+ * mode.
+ */
+ NORMAL,
+ /**
+ * Shows progress as paused, progress can be resumed by the user.
+ * Switches to the determinate display.
+ */
+ PAUSED,
+ /**
+ * The progress indicator displays activity without specifying what
+ * proportion of the progress is complete.
+ */
+ INDETERMINATE,
+ /**
+ * Shows that an error has occurred. Switches to the determinate
+ * display.
+ */
+ ERROR
+ }
+
+ private TaskbarPeer peer;
+
+ /**
+ * Tests whether a {@code Feature} is supported on the current platform.
+ * @param feature the specified {@link Feature}
+ * @return true if the specified feature is supported on the current platform
+ */
+ public boolean isSupported(Feature feature) {
+ return peer.isSupported(feature);
+ }
+
+ /**
+ * Checks if the feature type is supported.
+ *
+ * @param featureType the action type in question
+ * @throws UnsupportedOperationException if the specified action type is not
+ * supported on the current platform
+ */
+ private void checkFeatureSupport(Feature featureType){
+ if (!isSupported(featureType)) {
+ throw new UnsupportedOperationException("The " + featureType.name()
+ + " feature is not supported on the current platform!");
+ }
+ }
+
+ /**
+ * Calls to the security manager's {@code checkPermission} method with
+ * an {@code AWTPermission("showWindowWithoutWarningBanner")}
+ * permission.
+ */
+ private void checkAWTPermission(){
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new AWTPermission(
+ "showWindowWithoutWarningBanner"));
+ }
+ }
+
+ private Taskbar() {
+ Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
+ if (defaultToolkit instanceof SunToolkit) {
+ peer = ((SunToolkit) defaultToolkit).createTaskbarPeer(this);
+ }
+ }
+
+ /**
+ * Returns the {@code Taskbar} instance of the current
+ * taskbar context. On some platforms the Taskbar API may not be
+ * supported; use the {@link #isTaskbarSupported} method to
+ * determine if the current taskbar is supported.
+ * @return the Taskbar instance
+ * @throws HeadlessException if {@link
+ * GraphicsEnvironment#isHeadless()} returns {@code true}
+ * @throws UnsupportedOperationException if this class is not
+ * supported on the current platform
+ * @see #isTaskbarSupported()
+ * @see java.awt.GraphicsEnvironment#isHeadless
+ */
+ public static synchronized Taskbar getTaskbar(){
+ if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();
+
+ if (!Taskbar.isTaskbarSupported()) {
+ throw new UnsupportedOperationException("Taskbar API is not " +
+ "supported on the current platform");
+ }
+
+ sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
+ Taskbar taskbar = (Taskbar)context.get(Taskbar.class);
+
+ if (taskbar == null) {
+ taskbar = new Taskbar();
+ context.put(Taskbar.class, taskbar);
+ }
+
+ return taskbar;
+ }
+
+ /**
+ * Tests whether this class is supported on the current platform.
+ * If it's supported, use {@link #getTaskbar()} to retrieve an
+ * instance.
+ *
+ * @return {@code true} if this class is supported on the
+ * current platform; {@code false} otherwise
+ * @see #getTaskbar()
+ */
+ public static boolean isTaskbarSupported(){
+ Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
+ if (defaultToolkit instanceof SunToolkit) {
+ return ((SunToolkit)defaultToolkit).isTaskbarSupported();
+ }
+ return false;
+ }
+
+ /**
+ * Requests user attention to this application.
+ *
+ * Depending on the platform, this may be visually indicated by a bouncing
+ * or flashing icon in the task area. It may have no effect on an already active
+ * application.
+ *
+ * On some platforms (e.g. Mac OS) this effect may disappear upon app activation
+ * and cannot be dismissed by setting {@code enabled} to false.
+ * Other platforms may require an additional call
+ * {@link #requestUserAttention} to dismiss this request
+ * with {@code enabled} parameter set to false.
+ *
+ * @param enabled disables this request if false
+ * @param critical if this is an important request
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#USER_ATTENTION} feature
+ */
+ public void requestUserAttention(final boolean enabled, final boolean critical) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.USER_ATTENTION);
+ peer.requestUserAttention(enabled, critical);
+ }
+
+ /**
+ * Requests user attention to the specified window until it is activated.
+ *
+ * On an already active window requesting attention does nothing.
+ *
+ * @param w window
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#USER_ATTENTION_WINDOW} feature
+ */
+ public void requestWindowUserAttention(Window w) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.USER_ATTENTION_WINDOW);
+ peer.requestWindowUserAttention(w);
+ }
+
+ /**
+ * Attaches the contents of the provided PopupMenu to the application icon
+ * in the task area.
+ *
+ * @param menu the PopupMenu to attach to this application
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#MENU} feature
+ */
+ public void setMenu(final PopupMenu menu) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.MENU);
+ peer.setMenu(menu);
+ }
+
+ /**
+ * Gets PopupMenu used to add items to this application's icon in system task area.
+ *
+ * @return the PopupMenu
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#MENU} feature
+ */
+ public PopupMenu getMenu() {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.MENU);
+ return peer.getMenu();
+ }
+
+ /**
+ * Changes this application's icon to the provided image.
+ *
+ * @param image to change
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature
+ */
+ public void setIconImage(final Image image) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.ICON_IMAGE);
+ peer.setIconImage(image);
+ }
+
+ /**
+ * Obtains an image of this application's icon.
+ *
+ * @return an image of this application's icon
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature
+ */
+ public Image getIconImage() {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.ICON_IMAGE);
+ return peer.getIconImage();
+ }
+
+ /**
+ * Affixes a small system-provided badge to this application's icon.
+ * Usually a number.
+ *
+ * Some platforms do not support string values and accept only integer
+ * values. In this case, pass an integer represented as a string as parameter.
+ * This can be tested by {@code Feature.ICON_BADGE_STRING} and
+ * {@code Feature.ICON_BADGE_NUMBER}.
+ *
+ * Passing {@code null} as parameter hides the badge.
+ * @param badge label to affix to the icon
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#ICON_BADGE_NUMBER} feature
+ */
+ public void setIconBadge(final String badge) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.ICON_BADGE_NUMBER);
+ peer.setIconBadge(badge);
+ }
+
+ /**
+ * Affixes a small badge to this application's icon in the task area
+ * for the specified window.
+ * It may be disabled by system settings.
+ *
+ * @param w window to update
+ * @param badge image to affix to the icon
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#ICON_BADGE_IMAGE_WINDOW} feature
+ */
+ public void setWindowIconBadge(Window w, final Image badge) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.ICON_BADGE_IMAGE_WINDOW);
+ if (w != null) {
+ peer.setWindowIconBadge(w, badge);
+ }
+ }
+
+
+ /**
+ * Affixes a small system-provided progress bar to this application's icon.
+ *
+ * @param value from 0 to 100, other to disable progress indication
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#PROGRESS_VALUE} feature
+ */
+ public void setProgressValue(int value) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.PROGRESS_VALUE);
+ peer.setProgressValue(value);
+ }
+
+ /**
+ * Displays progress for specified window.
+ *
+ * @param w window to update
+ * @param value from 0 to 100, other to disable progress indication
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#PROGRESS_VALUE_WINDOW} feature
+ */
+ public void setWindowProgressValue(Window w, int value) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.PROGRESS_VALUE_WINDOW);
+ if (w != null) {
+ peer.setWindowProgressValue(w, value);
+ }
+ }
+
+ /**
+ * Sets a progress state for a specified window.
+ *
+ * @param w window
+ * @param state to change to
+ * @see State#OFF
+ * @see State#NORMAL
+ * @see State#PAUSED
+ * @see State#INDETERMINATE
+ * @see State#ERROR
+ * @throws SecurityException if a security manager exists and it denies the
+ * {@code AWTPermission("showWindowWithoutWarningBanner")} permission.
+ * @throws UnsupportedOperationException if the current platform
+ * does not support the {@link Taskbar.Feature#PROGRESS_STATE_WINDOW} feature
+ */
+ public void setWindowProgressState(Window w, State state) {
+ checkAWTPermission();
+ checkFeatureSupport(Feature.PROGRESS_STATE_WINDOW);
+ if (w != null) {
+ peer.setWindowProgressState(w, state);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AboutEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+
+/**
+ * Event sent when the application is asked to open its about window.
+ *
+ * @see AboutHandler#handleAbout
+ *
+ * @since 9
+ */
+public final class AboutEvent extends AppEvent {
+ private static final long serialVersionUID = -5987180734802756477L;
+
+ /**
+ * Constructs an {@code AboutEvent}
+ */
+ public AboutEvent() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AboutHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * An implementer receives notification when the app is asked to show its about
+ * dialog.
+ *
+ * @see java.awt.Desktop#setAboutHandler(java.awt.desktop.AboutHandler)
+ *
+ * @since 9
+ */
+public interface AboutHandler {
+
+ /**
+ * Called when the application is asked to show its about dialog.
+ *
+ * @param e the request to show the about dialog.
+ */
+ public void handleAbout(final AboutEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+import java.awt.Desktop;
+import java.util.EventObject;
+
+/**
+ * AppEvents are sent to listeners and handlers installed on the
+ * {@link java.awt.Desktop}.
+ *
+ * @since 9
+ */
+public class AppEvent extends EventObject {
+
+ private static final long serialVersionUID = -5958503993556009432L;
+
+ AppEvent() {
+ super(Desktop.getDesktop());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppForegroundEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+
+/**
+ * Event sent when the application has become the foreground app, and when it is
+ * no longer the foreground app.
+ *
+ * @see AppForegroundListener#appRaisedToForeground(AppEvent.AppForegroundEvent)
+ * @see AppForegroundListener#appMovedToBackground(AppEvent.AppForegroundEvent)
+ *
+ * @since 9
+ */
+public final class AppForegroundEvent extends AppEvent {
+ private static final long serialVersionUID = -5513582555740533911L;
+
+ /**
+ * Constructs an {@code AppForegroundEvent}
+ */
+ public AppForegroundEvent() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppForegroundListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Implementors are notified when the app becomes the foreground app and when it
+ * is no longer the foreground app. This notification is useful for hiding and
+ * showing transient UI like palette windows which should be hidden when the app
+ * is in the background.
+ *
+ * @since 9
+ */
+public interface AppForegroundListener extends SystemEventListener {
+ /**
+ * Called when the app becomes the foreground app.
+ * @param e event
+ */
+ public void appRaisedToForeground(final AppForegroundEvent e);
+
+ /**
+ * Called when the app becomes the background app and another app becomes
+ * the foreground app.
+ *
+ * @param e event
+ */
+ public void appMovedToBackground(final AppForegroundEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppHiddenEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+
+/**
+ * Event sent when the application has been hidden or shown.
+ *
+ * @see AppHiddenListener#appHidden(AppEvent.AppHiddenEvent)
+ * @see AppHiddenListener#appUnhidden(AppEvent.AppHiddenEvent)
+ *
+ * @since 9
+ */
+public final class AppHiddenEvent extends AppEvent {
+ private static final long serialVersionUID = 2637465279476429224L;
+
+ /**
+ * Constructs an {@code AppHiddenEvent}
+ */
+ public AppHiddenEvent() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppHiddenListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Implementors are notified when the app is hidden or shown by the user. This
+ * notification is helpful for discontinuing a costly animation if it's not
+ * visible to the user.
+ *
+ * @since 9
+ */
+public interface AppHiddenListener extends SystemEventListener {
+
+ /**
+ * Called the app is hidden.
+ *
+ * @param e event
+ */
+ public void appHidden(final AppHiddenEvent e);
+
+ /**
+ * Called when the hidden app is shown again (but not necessarily brought to
+ * the foreground).
+ *
+ * @param e event
+ */
+ public void appUnhidden(final AppHiddenEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppReopenedEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+
+/**
+ * Event sent when the application is asked to re-open itself.
+ *
+ * @see AppReopenedListener#appReopened(AppEvent.AppReopenedEvent)
+ *
+ * @since 9
+ */
+public final class AppReopenedEvent extends AppEvent {
+ private static final long serialVersionUID = 1503238361530407990L;
+
+ /**
+ * Constructs an {@code AppReopenedEvent}
+ */
+ public AppReopenedEvent() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/AppReopenedListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Implementors receive notification when the app has been asked to open again.
+ *
+ * This notification is useful for showing a new document when your app has no open windows.
+ *
+ * @since 9
+ */
+public interface AppReopenedListener extends SystemEventListener {
+ /**
+ * Called when the app has been reopened
+ * @param e the request to reopen the app
+ */
+ public void appReopened(final AppReopenedEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Auxiliary event containing a list of files.
+ *
+ * @since 9
+ */
+public class FilesEvent extends AppEvent {
+ private static final long serialVersionUID = 5271763715462312871L;
+ final List<File> files;
+
+ /**
+ * Constructs a {@code FilesEvent}
+ * @param files files
+ * @param searchTerm searchTerm
+ */
+ FilesEvent(final List<File> files) {
+ this.files = files;
+ }
+
+ /**
+ * Gets the list of files
+ * @return the list of files
+ */
+ public List<File> getFiles() {
+ return files == null
+ ? null
+ : new ArrayList<>(files);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+import java.io.File;
+import java.util.List;
+
+
+/**
+ * Event sent when the app is asked to open a list of files.
+ *
+ * @see OpenFilesHandler#openFiles
+ *
+ * @since 9
+ */
+public final class OpenFilesEvent extends FilesEvent {
+ private static final long serialVersionUID = -3982871005867718956L;
+ final String searchTerm;
+
+ /**
+ * Constructs an {@code OpenFilesEvent}
+ * @param files files
+ * @param searchTerm searchTerm
+ */
+ public OpenFilesEvent(final List<File> files, final String searchTerm) {
+ super(files);
+ this.searchTerm = searchTerm == null
+ ? ""
+ : searchTerm;
+ }
+
+ /**
+ * Gets the search term. The platform may optionally provide the search
+ * term that was used to find the files. This is for example the case
+ * on Mac OS X, when the files were opened using the Spotlight search
+ * menu or a Finder search window.
+ *
+ * This is useful for highlighting the search term in the documents when
+ * they are opened.
+ *
+ * @return the search term used to find the files
+ */
+ public String getSearchTerm() {
+ return searchTerm;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenFilesHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+
+/**
+ * An implementor is notified when the application is asked to open a list of files.
+ *
+ * @see java.awt.Desktop#setOpenFileHandler(java.awt.desktop.OpenFilesHandler)
+ *
+ * @since 9
+ */
+public interface OpenFilesHandler {
+ /**
+ * Called when the application is asked to open a list of files.
+ * @param e the request to open a list of files, and the search term used to find them, if any.
+ */
+ public void openFiles(final OpenFilesEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+import java.net.URI;
+
+
+/**
+ * Event sent when the app is asked to open a {@code URI}.
+ *
+ * @see OpenURIHandler#openURI(AppEvent.OpenURIEvent)
+ *
+ * @since 9
+ */
+public final class OpenURIEvent extends AppEvent {
+ private static final long serialVersionUID = 221209100935933476L;
+ final URI uri;
+
+ /**
+ * Constructs an {@code OpenURIEvent}
+ * @param uri {@code URI}
+ */
+ public OpenURIEvent(final URI uri) {
+ this.uri = uri;
+ }
+
+ /**
+ * Get the {@code URI} the app was asked to open
+ * @return the {@code URI}
+ */
+ public URI getURI() {
+ return uri;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/OpenURIHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * An implementor is notified when the application is asked to open a URI.
+ *
+ * @see java.awt.Desktop#setOpenURIHandler(java.awt.desktop.OpenURIHandler)
+ *
+ * @since 9
+ */
+public interface OpenURIHandler {
+ /**
+ * Called when the application is asked to open a {@code URI}
+ * @param e the request to open a {@code URI}
+ */
+ public void openURI(final OpenURIEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/PreferencesEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+
+/**
+ * Event sent when the application is asked to open its preferences window.
+ *
+ * @see PreferencesHandler#handlePreferences
+ *
+ * @since 9
+ */
+public final class PreferencesEvent extends AppEvent {
+ private static final long serialVersionUID = -6398607097086476160L;
+
+ /**
+ * Constructs a {@code PreferencesEvent}
+ */
+ public PreferencesEvent() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/PreferencesHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * An implementor is notified when the app is asked to show its preferences UI.
+ *
+ * @see java.awt.Desktop#setPreferencesHandler(java.awt.desktop.PreferencesHandler)
+ *
+ * @since 9
+ */
+public interface PreferencesHandler {
+ /**
+ * Called when the app is asked to show its preferences UI.
+ * @param e the request to show preferences.
+ */
+ public void handlePreferences(final PreferencesEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/PrintFilesEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+import java.io.File;
+import java.util.List;
+
+
+/**
+ * Event sent when the app is asked to print a list of files.
+ *
+ * @see PrintFilesHandler#printFiles(AppEvent.PrintFilesEvent)
+ * @since 9
+ */
+public final class PrintFilesEvent extends FilesEvent {
+ private static final long serialVersionUID = -5752560876153618618L;
+
+ /**
+ * Constructs a {@code PrintFilesEvent}
+ * @param files files
+ */
+ public PrintFilesEvent(final List<File> files) {
+ super(files);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/PrintFilesHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * An implementor can respond to requests to print documents that the app has been registered to handle.
+ *
+ * @see java.awt.Desktop#setPrintFileHandler(java.awt.desktop.PrintFilesHandler)
+ *
+ * @since 9
+ */
+public interface PrintFilesHandler {
+ /**
+ * Called when the application is asked to print a list of files.
+ * @param e the request to print a list of files.
+ */
+ public void printFiles(final PrintFilesEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Event sent when the application is asked to quit.
+ *
+ * @see QuitHandler#handleQuitRequestWith(AppEvent.QuitEvent, QuitResponse)
+ *
+ * @since 9
+ */
+public final class QuitEvent extends AppEvent {
+
+ private static final long serialVersionUID = -256100795532403146L;
+
+ /**
+ * Constructs a {@code QuitEvent}
+ */
+ public QuitEvent() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * An implementor determines if requests to quit this application should proceed or cancel.
+ *
+ * @see java.awt.Desktop#setQuitHandler(java.awt.desktop.QuitHandler)
+ * @see java.awt.Desktop#setQuitStrategy(java.awt.desktop.QuitStrategy)
+ *
+ * @since 9
+ */
+public interface QuitHandler {
+ /**
+ * Invoked when the application is asked to quit.
+ *
+ * Implementors must call either {@link QuitResponse#cancelQuit()}, {@link QuitResponse#performQuit()}, or ensure the application terminates.
+ * The process (or log-out) requesting this app to quit will be blocked until the {@link QuitResponse} is handled.
+ * Apps that require complex UI to shutdown may call the {@link QuitResponse} from any thread.
+ * Your app may be asked to quit multiple times before you have responded to the initial request.
+ * This handler is called each time a quit is requested, and the same {@link QuitResponse} object is passed until it is handled.
+ * Once used, the {@link QuitResponse} cannot be used again to change the decision.
+ *
+ * @param e the request to quit this application.
+ * @param response the one-shot response object used to cancel or proceed with the quit action.
+ */
+ public void handleQuitRequestWith(final QuitEvent e, final QuitResponse response);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitResponse.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Used to respond to a request to quit the application.
+ *
+ * @see java.awt.Desktop#setQuitHandler(java.awt.desktop.QuitHandler)
+ * @see java.awt.desktop.QuitHandler
+ * @see java.awt.Desktop#setQuitStrategy(java.awt.desktop.QuitStrategy)
+ *
+ * @since 9
+ */
+public interface QuitResponse {
+
+ /**
+ * Notifies the external quit requester that the quit will proceed, and performs the default {@link java.awt.desktop.QuitStrategy}.
+ */
+ public void performQuit();
+
+ /**
+ * Notifies the external quit requester that the user has explicitly canceled the pending quit, and leaves the application running.
+ * <b>Note: this will cancel a pending log-out, restart, or shutdown.</b>
+ */
+ public void cancelQuit();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/QuitStrategy.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * The strategy used to shut down the application, if Sudden Termination is not enabled.
+ *
+ * @see java.awt.Desktop#setQuitHandler(java.awt.desktop.QuitHandler)
+ * @see java.awt.Desktop#setQuitStrategy(java.awt.desktop.QuitStrategy)
+ * @see java.awt.Desktop#enableSuddenTermination()
+ * @see java.awt.Desktop#disableSuddenTermination()
+ *
+ * @since 9
+ */
+public enum QuitStrategy {
+ /**
+ * Shuts down the application by calling {@code System.exit(0)}. This is the default strategy.
+ */
+ NORMAL_EXIT,
+
+ /**
+ * Shuts down the application by closing each window from back-to-front.
+ */
+ CLOSE_ALL_WINDOWS
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Event sent when the displays attached to the system enter and exit power save
+ * sleep.
+ *
+ * @see ScreenSleepListener#screenAboutToSleep(AppEvent.ScreenSleepEvent)
+ * @see ScreenSleepListener#screenAwoke(AppEvent.ScreenSleepEvent)
+ *
+ * @since 9
+ */
+public final class ScreenSleepEvent extends AppEvent {
+
+ private static final long serialVersionUID = 7521606180376544150L;
+
+ /**
+ * Constructs a ScreenSleepEvent
+ */
+ public ScreenSleepEvent() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/ScreenSleepListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Implementors receive notification when the displays attached to the system have entered power save sleep.
+ *
+ * This notification is useful for discontinuing a costly animation, or indicating that the user is no longer present on a network service.
+ *
+ * @since 9
+ */
+public interface ScreenSleepListener extends SystemEventListener {
+
+ /**
+ * Called when the system displays have entered power save sleep.
+ * @param e the screen sleep event
+ */
+ public void screenAboutToSleep(final ScreenSleepEvent e);
+
+ /**
+ * Called when the system displays have awoken from power save sleep.
+ * @param e the screen sleep event
+ */
+ public void screenAwoke(final ScreenSleepEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemEventListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+import java.util.EventListener;
+
+/**
+ * Common interface for all event listener sub-types.
+ *
+ * Implementors may implement multiple sub-types, but only need to call
+ * {@link java.awt.Desktop#addAppEventListener(SystemEventListener)} once to
+ * receive all notifications.
+ *
+ * @since 9
+ */
+public interface SystemEventListener extends EventListener {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemSleepEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Event sent when the system enters and exits power save sleep.
+ *
+ * @see SystemSleepListener#systemAboutToSleep(AppEvent.SystemSleepEvent)
+ * @see SystemSleepListener#systemAwoke(AppEvent.SystemSleepEvent)
+ *
+ * @since 9
+ */
+public final class SystemSleepEvent extends AppEvent {
+
+ private static final long serialVersionUID = 11372269824930549L;
+
+ /**
+ * Constructs a SystemSleepEvent
+ */
+ public SystemSleepEvent() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/SystemSleepListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Implementors receive notification as the system is entering sleep, and after
+ * the system wakes.
+ *
+ * This notification is useful for disconnecting from network services prior to
+ * sleep, or re-establishing a connection if the network configuration has
+ * changed during sleep.
+ *
+ * @since 9
+ */
+public interface SystemSleepListener extends SystemEventListener {
+
+ /**
+ * Called when the system is about to sleep. Note: This message may not be
+ * delivered prior to the actual system sleep, and may be processed after
+ * the corresponding wake has occurred.
+ *
+ * @param e the system sleep event
+ */
+ public void systemAboutToSleep(final SystemSleepEvent e);
+
+ /**
+ * Called after the system has awoken from sleeping.
+ *
+ * @param e the system sleep event
+ */
+ public void systemAwoke(final SystemSleepEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+/**
+ * Event sent when the user session has been changed.
+ *
+ * Some systems may provide a reason of a user session change.
+ *
+ * @see UserSessionListener#userSessionActivated(AppEvent.UserSessionEvent)
+ * @see UserSessionListener#userSessionDeactivated(AppEvent.UserSessionEvent)
+ *
+ * @since 9
+ */
+public final class UserSessionEvent extends AppEvent {
+
+ private static final long serialVersionUID = 6747138462796569055L;
+
+ private final Reason reason;
+
+ /**
+ * Kinds of available reasons of user session change.
+ */
+ public static enum Reason {
+ /**
+ * The system does not provide a reason for a session change.
+ */
+ UNSPECIFIED,
+
+ /**
+ * The session was connected/disconnected to the console terminal.
+ */
+ CONSOLE,
+
+ /**
+ * The session was connected/disconnected to the remote terminal.
+ */
+ REMOTE,
+
+ /**
+ * The session has been locked/unlocked.
+ */
+ LOCK
+ }
+
+ /**
+ * Constructs a {@code UserSessionEvent}
+ *
+ * @param reason of session change
+ */
+ public UserSessionEvent(Reason reason) {
+ this.reason = reason;
+ }
+
+ /**
+ * Gets a reason of the user session change.
+ *
+ * @return reason a reason
+ * @see Reason#UNSPECIFIED
+ * @see Reason#CONSOLE
+ * @see Reason#REMOTE
+ * @see Reason#LOCK
+ */
+ public Reason getReason() {
+ return reason;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/UserSessionListener.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016, 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.awt.desktop;
+
+
+/**
+ * Implementors receive notification when the user session changes.
+ *
+ * This notification is useful for discontinuing a costly animation,
+ * or indicating that the user is no longer present on a network service.
+ *
+ * Some systems may provide a reason of the user session change.
+ *
+ * @see UserSessionEvent.Reason#UNSPECIFIED
+ * @see UserSessionEvent.Reason#CONSOLE
+ * @see UserSessionEvent.Reason#REMOTE
+ * @see UserSessionEvent.Reason#LOCK
+ *
+ * @since 9
+ */
+public interface UserSessionListener extends SystemEventListener {
+ /**
+ * Called when the user session has been switched away.
+ * @param e the user session switch event
+ */
+ public void userSessionDeactivated(final UserSessionEvent e);
+
+ /**
+ * Called when the user session has been switched to.
+ * @param e the user session switch event
+ */
+ public void userSessionActivated(final UserSessionEvent e);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/desktop/package.html Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,36 @@
+<!--
+ Copyright (c) 2016, 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.
+-->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head><title></title></head>
+<body bgcolor="white">
+
+Provides interfaces and classes for interaction with various
+desktop capabilities.
+
+@since 9
+</body>
+</html>
--- a/jdk/src/java.desktop/share/classes/java/awt/image/SampleModel.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/image/SampleModel.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -126,7 +126,7 @@
throw new IllegalArgumentException("Width ("+w+") and height ("+
h+") must be > 0");
}
- if (size >= Integer.MAX_VALUE) {
+ if (size > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Dimensions (width="+w+
" height="+h+") are too large");
}
--- a/jdk/src/java.desktop/share/classes/java/awt/peer/DesktopPeer.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/java/awt/peer/DesktopPeer.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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,14 +22,21 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
-
package java.awt.peer;
-
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.awt.Desktop.Action;
+import java.awt.desktop.AboutHandler;
+import java.awt.desktop.SystemEventListener;
+import java.awt.desktop.OpenFilesHandler;
+import java.awt.desktop.OpenURIHandler;
+import java.awt.desktop.PreferencesHandler;
+import java.awt.desktop.PrintFilesHandler;
+import java.awt.desktop.QuitHandler;
+import java.awt.desktop.QuitStrategy;
+import javax.swing.JMenuBar;
/**
* The {@code DesktopPeer} interface provides methods for the operation
@@ -104,4 +111,168 @@
* or it fails to be launched.
*/
void browse(URI uri) throws IOException;
+
+ /**
+ * Adds sub-types of {@link SystemEventListener} to listen for notifications
+ * from the native system.
+ *
+ * @param listener listener
+ * @see java.awt.desktop.AppForegroundListener
+ * @see java.awt.desktop.AppHiddenListener
+ * @see java.awt.desktop.AppReopenedListener
+ * @see java.awt.desktop.ScreenSleepListener
+ * @see java.awt.desktop.SystemSleepListener
+ * @see java.awt.desktop.UserSessionListener
+ */
+ default void addAppEventListener(final SystemEventListener listener) {
+ }
+
+ /**
+ * Removes sub-types of {@link SystemEventListener} to listen for notifications
+ * from the native system.
+ *
+ * @param listener listener
+ * @see java.awt.desktop.AppForegroundListener
+ * @see java.awt.desktop.AppHiddenListener
+ * @see java.awt.desktop.AppReopenedListener
+ * @see java.awt.desktop.ScreenSleepListener
+ * @see java.awt.desktop.SystemSleepListener
+ * @see java.awt.desktop.UserSessionListener
+ */
+ default void removeAppEventListener(final SystemEventListener listener) {
+ }
+
+ /**
+ * Installs a handler to show a custom About window for your application.
+ * <p>
+ * Setting the {@link AboutHandler} to {@code null} reverts it to the
+ * default behavior.
+ *
+ * @param aboutHandler the handler to respond to the
+ * {@link AboutHandler#handleAbout} )} message
+ */
+ default void setAboutHandler(final AboutHandler aboutHandler) {
+ }
+
+ /**
+ * Installs a handler to show a custom Preferences window for your
+ * application.
+ * <p>
+ * Setting the {@link PreferencesHandler} to {@code null} reverts it to
+ * the default behavior
+ *
+ * @param preferencesHandler the handler to respond to the
+ * {@link java.awt.desktop.PreferencesHandler#handlePreferences(java.awt.PreferencesEvent) }
+ */
+ default void setPreferencesHandler(final PreferencesHandler preferencesHandler) {
+ }
+
+ /**
+ * Installs the handler which is notified when the application is asked to
+ * open a list of files.
+ *
+ * @param openFileHandler handler
+ *
+ */
+ default void setOpenFileHandler(final OpenFilesHandler openFileHandler) {
+ }
+
+ /**
+ * Installs the handler which is notified when the application is asked to
+ * print a list of files.
+ *
+ * @param printFileHandler handler
+ */
+ default void setPrintFileHandler(final PrintFilesHandler printFileHandler) {
+ }
+
+ /**
+ * Installs the handler which is notified when the application is asked to
+ * open a URL.
+ *
+ * Setting the handler to {@code null} causes all
+ * {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} requests to be
+ * enqueued until another handler is set.
+ *
+ * @param openURIHandler handler
+ */
+ default void setOpenURIHandler(final OpenURIHandler openURIHandler) {
+ }
+
+ /**
+ * Installs the handler which determines if the application should quit.
+ *
+ * @param quitHandler the handler that is called when the application is
+ * asked to quit
+ * @see java.awt.Desktop#setQuitHandler(java.awt.desktop.QuitHandler)
+ */
+ default void setQuitHandler(final QuitHandler quitHandler) {
+ }
+
+ /**
+ * Sets the default strategy used to quit this application. The default is
+ * calling SYSTEM_EXIT_0.
+ *
+ * @param strategy the way this application should be shutdown
+ */
+ default void setQuitStrategy(final QuitStrategy strategy) {
+ }
+
+ /**
+ * Enables this application to be suddenly terminated.
+ *
+ * @see java.awt.Desktop#disableSuddenTermination()
+ */
+ default void enableSuddenTermination() {
+ }
+
+ /**
+ * Prevents this application from being suddenly terminated.
+ *
+ * @see java.awt.Desktop#enableSuddenTermination()
+ */
+ default void disableSuddenTermination() {
+ }
+
+ /**
+ * Requests this application to move to the foreground.
+ *
+ * @param allWindows if all windows of this application should be moved to
+ * the foreground, or only the foremost one
+ */
+ default void requestForeground(final boolean allWindows) {
+ }
+
+ /**
+ * Opens the native help viewer application.
+ */
+ default void openHelpViewer() {
+ }
+
+ /**
+ * Sets the default menu bar to use when there are no active frames.
+ *
+ * @param menuBar to use when no other frames are active
+ */
+ default void setDefaultMenuBar(final JMenuBar menuBar) {
+ }
+
+ /**
+ * Opens a folder containing the {@code file} in a default system file manager.
+ * @param file the file
+ * @return returns true if successfully opened
+ */
+ default boolean browseFileDirectory(File file) {
+ return false;
+ }
+ /**
+ * Moves the specified file to the trash.
+ *
+ * @param file the file
+ * @return returns true if successfully moved the file to the trash.
+ */
+ default boolean moveToTrash(File file) {
+ return false;
+ }
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/peer/TaskbarPeer.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2016, 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.awt.peer;
+
+import java.awt.Image;
+import java.awt.PopupMenu;
+import java.awt.Taskbar;
+import java.awt.Taskbar.Feature;
+import java.awt.Taskbar.State;
+import java.awt.Window;
+
+
+/**
+ * The {@code TaskbarPeer} interface provides methods for interacting with
+ * system task area.
+ */
+public interface TaskbarPeer {
+
+ /**
+ * Requests user attention to this application.
+ *
+ * @param enabled disables this request if false
+ * @param critical if this is an important request
+ * @see Taskbar#requestUserAttention
+ */
+ default void requestUserAttention(boolean enabled, final boolean critical) {}
+
+ /**
+ * Requests user attention to the specified window until it is activated.
+ *
+ * On an already active window requesting attention does nothing.
+ *
+ * @param w window
+ */
+ default void requestWindowUserAttention(Window w) {}
+
+ /**
+ * Attaches the contents of the provided PopupMenu to the application icon
+ * in system task area.
+ *
+ * @param menu the PopupMenu to attach to this application
+ */
+ default void setMenu(final PopupMenu menu) {}
+
+ /**
+ * Gets PopupMenu used to add items to this application's icon in system task area.
+ *
+ * @return the PopupMenu
+ */
+ default PopupMenu getMenu() { return null; }
+
+ /**
+ * Changes this application's icon to the provided image.
+ *
+ * @param image to change
+ */
+ default void setIconImage(final Image image) {}
+
+ /**
+ * Obtains an image of this application's icon.
+ *
+ * @return an image of this application's icon
+ */
+ default Image getIconImage() { return null; }
+
+ /**
+ * Affixes a small system-provided badge to this application's icon.
+ * Usually a number.
+ *
+ * @param badge label to affix to the icon
+ */
+ default void setIconBadge(final String badge) {}
+
+ /**
+ * Affixes a small badge to this application's icon in task area
+ * for the specified window.
+ *
+ * @param w window to update
+ * @param badge image to affix to the icon
+ */
+ default void setWindowIconBadge(Window w, final Image badge) {}
+
+ /**
+ * Displays progress for specified window.
+ *
+ * @param w window to update
+ * @param value from 0 to 100, other to disable progress indication
+ */
+ default void setWindowProgressValue(Window w, int value) {}
+
+ /**
+ * Sets a progress state for a specified window.
+ *
+ * @param w window
+ * @param state to change to
+ * @see Taskbar#setWindowProgressState
+ */
+ default void setWindowProgressState(Window w, State state) {}
+
+ /**
+ * Affixes a small system-provided progress bar to this application's icon.
+ *
+ * @param value from 0 to 100, other to disable progress indication
+ */
+ default void setProgressValue(int value) {}
+
+ /**
+ * Tests support of {@code Feature} on current platform.
+ * @param f feature to test
+ * @return true if feature supported supported
+ */
+ default public boolean isSupported(Feature f) { return false; }
+}
--- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageTypeSpecifier.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageTypeSpecifier.java Thu Apr 07 11:03:59 2016 -0700
@@ -997,7 +997,7 @@
* negative or greater than the largest band index.
*/
public int getBitsPerBand(int band) {
- if (band < 0 | band >= getNumBands()) {
+ if (band < 0 || band >= getNumBands()) {
throw new IllegalArgumentException("band out of range!");
}
return sampleModel.getSampleSize(band);
--- a/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioInputStream.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/sound/sampled/AudioInputStream.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -249,10 +249,10 @@
*/
@Override
public int read(byte[] b, int off, int len) throws IOException {
-
// make sure we don't read fractions of a frame.
- if( (len%frameSize) != 0 ) {
- len -= (len%frameSize);
+ final int reminder = len % frameSize;
+ if (reminder != 0) {
+ len -= reminder;
if (len == 0) {
return 0;
}
@@ -312,6 +312,10 @@
/**
* Skips over and discards a specified number of bytes from this audio input
* stream.
+ * <p>
+ * This method will always skip an integral number of frames. If {@code n}
+ * does not specify an integral number of frames, a maximum of
+ * {@code n - (n % frameSize)} bytes will be skipped.
*
* @param n the requested number of bytes to be skipped
* @return the actual number of bytes skipped
@@ -321,15 +325,14 @@
*/
@Override
public long skip(long n) throws IOException {
- if (n <= 0) {
- return 0;
- }
-
// make sure not to skip fractional frames
final long reminder = n % frameSize;
if (reminder != 0) {
n -= reminder;
}
+ if (n <= 0) {
+ return 0;
+ }
if (frameLength != AudioSystem.NOT_SPECIFIED) {
// don't skip more than our set length in frames.
--- a/jdk/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/DefaultDesktopManager.java Thu Apr 07 11:03:59 2016 -0700
@@ -129,8 +129,12 @@
} catch (PropertyVetoException e2) {
}
} else {
+ Container c = f.getParent();
+ if (c == null) {
+ return;
+ }
f.setNormalBounds(f.getBounds());
- Rectangle desktopBounds = f.getParent().getBounds();
+ Rectangle desktopBounds = c.getBounds();
setBoundsForFrame(f, 0, 0,
desktopBounds.width, desktopBounds.height);
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -30,7 +30,6 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import javax.swing.SortOrder;
/**
* An implementation of <code>RowSorter</code> that provides sorting and
@@ -495,7 +494,7 @@
*/
public int convertRowIndexToView(int index) {
if (modelToView == null) {
- if (index < 0 || index >= getModelWrapper().getRowCount()) {
+ if (index < 0 || index >= modelRowCount) {
throw new IndexOutOfBoundsException("Invalid index");
}
return index;
@@ -510,7 +509,7 @@
*/
public int convertRowIndexToModel(int index) {
if (viewToModel == null) {
- if (index < 0 || index >= getModelWrapper().getRowCount()) {
+ if (index < 0 || index >= modelRowCount) {
throw new IndexOutOfBoundsException("Invalid index");
}
return index;
@@ -814,7 +813,7 @@
// When filtering this may differ from getModelWrapper().getRowCount()
return viewToModel.length;
}
- return getModelWrapper().getRowCount();
+ return Math.max(getModelWrapper().getRowCount(), modelRowCount);
}
/**
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -4401,13 +4401,8 @@
}
if (sortManager != null) {
- List<? extends RowSorter.SortKey> sortKeys =
- sortManager.sorter.getSortKeys();
- if (sortKeys.size() != 0 &&
- sortKeys.get(0).getSortOrder() != SortOrder.UNSORTED) {
- sortedTableChanged(null, e);
- return;
- }
+ sortedTableChanged(null, e);
+ return;
}
// The totalRowHeight calculated below will be incorrect if
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/AbstractButtonColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BorderColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/BoxMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JAppletMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JButtonMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMenuItemMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JCheckBoxMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JColorChooserMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComboBoxMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JComponentColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDesktopPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JDialogMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JEditorPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFileChooserMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFormattedTextFieldMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JFrameMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JInternalFrameMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLabelMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JLayeredPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JListMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuBarMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuItemMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JMenuMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JOptionPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPanelMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPasswordFieldMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JPopupMenuMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JProgressBarMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMenuItemMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRadioButtonMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JRootPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollBarMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JScrollPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSeparatorMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSliderMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSpinnerMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JSplitPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTabbedPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTableMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextAreaMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextFieldMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTextPaneMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToggleButtonMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JToolBarMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JTreeMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JViewportMono32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowColor16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowColor32.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowMono16.gif has changed
Binary file jdk/src/java.desktop/share/classes/javax/swing/beaninfo/images/JWindowMono32.gif has changed
--- a/jdk/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/border/TitledBorder.java Thu Apr 07 11:03:59 2016 -0700
@@ -34,6 +34,9 @@
import java.awt.Rectangle;
import java.awt.geom.Path2D;
import java.beans.ConstructorProperties;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.ref.WeakReference;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.UIManager;
@@ -246,6 +249,7 @@
this.label = new JLabel();
this.label.setOpaque(false);
this.label.putClientProperty(BasicHTML.propertyKey, null);
+ installPropertyChangeListeners();
}
/**
@@ -752,4 +756,25 @@
}
return insets;
}
+
+ private void installPropertyChangeListeners() {
+ final WeakReference<TitledBorder> weakReference = new WeakReference<TitledBorder>(this);
+ final PropertyChangeListener listener = new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (weakReference.get() == null) {
+ UIManager.removePropertyChangeListener(this);
+ UIManager.getDefaults().removePropertyChangeListener(this);
+ } else {
+ String prop = evt.getPropertyName();
+ if ("lookAndFeel".equals(prop) || "LabelUI".equals(prop)) {
+ label.updateUI();
+ }
+ }
+ }
+ };
+
+ UIManager.addPropertyChangeListener(listener);
+ UIManager.getDefaults().addPropertyChangeListener(listener);
+ }
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java Thu Apr 07 11:03:59 2016 -0700
@@ -1719,6 +1719,9 @@
if ((frame.getParent() != null) && !componentListenerAdded) {
f.getParent().addComponentListener(componentListener);
componentListenerAdded = true;
+ if (f.isMaximum()) {
+ maximizeFrame(f);
+ }
}
} else if (JInternalFrame.TITLE_PROPERTY == prop ||
prop == "closable" || prop == "iconable" ||
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthButtonUI.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -357,7 +357,7 @@
* This method will return the icon that should be used for a button. We
* only want to use the synth icon defined by the style if the specific
* icon has not been defined for the button state and the backup icon is a
- * UIResource (we set it, not the developer).
+ * UIResource (we set it, not the developer) or {@code null}.
*
* @param b button
* @param specificIcon icon returned from the button for the specific state
@@ -368,7 +368,7 @@
int state) {
Icon icon = specificIcon;
if (icon == null) {
- if (defaultIcon instanceof UIResource) {
+ if (defaultIcon == null || defaultIcon instanceof UIResource) {
icon = getSynthIcon(b, state);
if (icon == null) {
icon = defaultIcon;
@@ -398,11 +398,16 @@
private Icon getRolloverIcon(AbstractButton b, Icon defaultIcon) {
ButtonModel model = b.getModel();
- Icon icon;
+ Icon icon = null;
if (model.isSelected()) {
- icon = getIcon(b, b.getRolloverSelectedIcon(), defaultIcon,
+ icon = getIcon(b, b.getRolloverSelectedIcon(), null,
SynthConstants.MOUSE_OVER | SynthConstants.SELECTED);
- } else {
+ if (icon == null) {
+ icon = getIcon(b, b.getSelectedIcon(), null,
+ SynthConstants.SELECTED);
+ }
+ }
+ if (icon == null) {
icon = getIcon(b, b.getRolloverIcon(), defaultIcon,
SynthConstants.MOUSE_OVER);
}
@@ -416,11 +421,16 @@
private Icon getSynthDisabledIcon(AbstractButton b, Icon defaultIcon) {
ButtonModel model = b.getModel();
- Icon icon;
+ Icon icon = null;
if (model.isSelected()) {
- icon = getIcon(b, b.getDisabledSelectedIcon(), defaultIcon,
+ icon = getIcon(b, b.getDisabledSelectedIcon(), null,
SynthConstants.DISABLED | SynthConstants.SELECTED);
- } else {
+ if (icon == null) {
+ icon = getIcon(b, b.getSelectedIcon(), null,
+ SynthConstants.SELECTED);
+ }
+ }
+ if (icon == null) {
icon = getIcon(b, b.getDisabledIcon(), defaultIcon,
SynthConstants.DISABLED);
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractWriter.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/AbstractWriter.java Thu Apr 07 11:03:59 2016 -0700
@@ -441,7 +441,7 @@
--offsetIndent;
}
else {
- indentLevel = indentLevel > 0 ? indentLevel-- : 0;
+ indentLevel--;
}
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/CompositeView.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -24,7 +24,7 @@
*/
package javax.swing.text;
-import java.util.Vector;
+import java.util.*;
import java.awt.*;
import javax.swing.event.*;
import javax.swing.SwingConstants;
@@ -182,9 +182,11 @@
views = ZERO;
}
+ Set<View> set = new HashSet<>(Arrays.asList(views));
// update parent reference on removed views
for (int i = offset; i < offset + length; i++) {
- if (children[i].getParent() == this) {
+ View child = children[i];
+ if (child.getParent() == this && !set.contains(child)) {
// in FlowView.java view might be referenced
// from two super-views as a child. see logicalView
children[i].setParent(null);
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLWriter.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/html/HTMLWriter.java Thu Apr 07 11:03:59 2016 -0700
@@ -178,7 +178,8 @@
if (!synthesizedElement(top)) {
AttributeSet attrs = top.getAttributes();
if (!matchNameAttribute(attrs, HTML.Tag.PRE) &&
- !isFormElementWithContent(attrs)) {
+ !isFormElementWithContent(attrs) &&
+ !isPreTagWithParagraphTag(attrs)) {
decrIndent();
}
endTag(top);
@@ -223,7 +224,8 @@
if (!synthesizedElement(current)) {
AttributeSet attrs = current.getAttributes();
if (!matchNameAttribute(attrs, HTML.Tag.PRE) &&
- !isFormElementWithContent(attrs)) {
+ !isFormElementWithContent(attrs) &&
+ !isPreTagWithParagraphTag(attrs)) {
decrIndent();
}
endTag(current);
@@ -830,6 +832,14 @@
matchNameAttribute(attr, HTML.Tag.SELECT);
}
+ /**
+ * Determines if the element associated with the attributeset
+ * is a P tag and it is within Pre tag. If true, returns true else
+ * false
+ */
+ private boolean isPreTagWithParagraphTag(AttributeSet attr) {
+ return inPre && matchNameAttribute(attr, HTML.Tag.P);
+ }
/**
* Determines whether a the indentation needs to be
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/rtf/RTFGenerator.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/rtf/RTFGenerator.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -491,7 +491,10 @@
word.swingName(), MagicToken)) != null) {
if (parm == MagicToken)
parm = null;
- word.writeValue(parm, this, true);
+ if (!word.writeValue(parm, this, true) &&
+ word instanceof RTFAttributes.AssertiveAttribute ) {
+ currentAttributes.removeAttribute(word.swingName());
+ }
}
}
--- a/jdk/src/java.desktop/share/classes/module-info.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/module-info.java Thu Apr 07 11:03:59 2016 -0700
@@ -31,6 +31,7 @@
exports java.applet;
exports java.awt;
exports java.awt.color;
+ exports java.awt.desktop;
exports java.awt.dnd;
exports java.awt.event;
exports java.awt.font;
--- a/jdk/src/java.desktop/share/classes/sun/awt/ComponentFactory.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/ComponentFactory.java Thu Apr 07 11:03:59 2016 -0700
@@ -25,6 +25,7 @@
package sun.awt;
+import java.awt.peer.TaskbarPeer;
import java.awt.*;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.InvalidDnDOperationException;
@@ -75,6 +76,23 @@
}
/**
+ * Creates this toolkit's implementation of the {@code Taskbar} using the
+ * specified peer interface.
+ *
+ * @param target the taskbar to be implemented
+ * @return this toolkit's implementation of the {@code Taskbar}
+ * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns
+ * true
+ * @see java.awt.GraphicsEnvironment#isHeadless
+ * @see java.awt.Taskbar
+ * @see java.awt.peer.TaskbarPeer
+ * @since 9
+ */
+ default TaskbarPeer createTaskbarPeer(Taskbar target) {
+ throw new HeadlessException();
+ }
+
+ /**
* Creates this toolkit's implementation of {@code Button} using the
* specified peer interface.
*
--- a/jdk/src/java.desktop/share/classes/sun/awt/HToolkit.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/HToolkit.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -286,6 +286,11 @@
return false;
}
+ @Override
+ public boolean isTaskbarSupported() {
+ return false;
+ }
+
public boolean isWindowOpacityControlSupported() {
return false;
}
--- a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -1781,6 +1781,7 @@
public abstract boolean isDesktopSupported();
+ public abstract boolean isTaskbarSupported();
/*
* consumeNextKeyTyped() method is not currently used,
--- a/jdk/src/java.desktop/share/classes/sun/font/FileFont.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/font/FileFont.java Thu Apr 07 11:03:59 2016 -0700
@@ -36,6 +36,7 @@
import sun.java2d.DisposerRecord;
import java.io.IOException;
+import java.util.List;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
@@ -116,17 +117,17 @@
return true;
}
- void setFileToRemove(File file, CreatedFontTracker tracker) {
- Disposer.addObjectRecord(this,
- new CreatedFontFileDisposerRecord(file, tracker));
- }
+ static void setFileToRemove(List<Font2D> fonts,
+ File file, int cnt,
+ CreatedFontTracker tracker)
+ {
+ CreatedFontFileDisposerRecord dr =
+ new CreatedFontFileDisposerRecord(file, cnt, tracker);
- // MACOSX begin -- Make this static so that we can pass in CFont
- static void setFileToRemove(Object font, File file, CreatedFontTracker tracker) {
- Disposer.addObjectRecord(font,
- new CreatedFontFileDisposerRecord(file, tracker));
+ for (Font2D f : fonts) {
+ Disposer.addObjectRecord(f, dr);
+ }
}
- // MACOSX - end
/* This is called when a font scaler is determined to
* be unusable (ie bad).
@@ -251,11 +252,13 @@
implements DisposerRecord {
File fontFile = null;
+ int count = 0; // number of fonts referencing this file object.
CreatedFontTracker tracker;
- private CreatedFontFileDisposerRecord(File file,
+ private CreatedFontFileDisposerRecord(File file, int cnt,
CreatedFontTracker tracker) {
fontFile = file;
+ count = (cnt > 0) ? cnt : 1;
this.tracker = tracker;
}
@@ -263,6 +266,12 @@
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Object>() {
public Object run() {
+ synchronized (fontFile) {
+ count--;
+ if (count > 0) {
+ return null;
+ }
+ }
if (fontFile != null) {
try {
if (tracker != null) {
--- a/jdk/src/java.desktop/share/classes/sun/font/FontManager.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/font/FontManager.java Thu Apr 07 11:03:59 2016 -0700
@@ -81,13 +81,15 @@
*
* @param fontFile the file holding the font data
* @param fontFormat the expected font format
+ * @param all whether to retrieve all fonts in the resource or
+ * just the first one.
* @param isCopy {@code true} if the file is a copy and needs to be
* deleted, {@code false} otherwise
*
* @return the created Font2D instance
*/
- public Font2D createFont2D(File fontFile, int fontFormat,
- boolean isCopy, CreatedFontTracker tracker)
+ public Font2D[] createFont2D(File fontFile, int fontFormat, boolean all,
+ boolean isCopy, CreatedFontTracker tracker)
throws FontFormatException;
/**
--- a/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/font/SunFontManager.java Thu Apr 07 11:03:59 2016 -0700
@@ -40,6 +40,7 @@
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
@@ -2420,15 +2421,15 @@
protected abstract String getFontPath(boolean noType1Fonts);
- // MACOSX begin -- need to access this in subclass
- protected Thread fileCloser = null;
- // MACOSX end
+ Thread fileCloser = null;
Vector<File> tmpFontFiles = null;
- public Font2D createFont2D(File fontFile, int fontFormat,
- boolean isCopy, CreatedFontTracker tracker)
+ public Font2D[] createFont2D(File fontFile, int fontFormat, boolean all,
+ boolean isCopy, CreatedFontTracker tracker)
throws FontFormatException {
+ List<Font2D> fList = new ArrayList<Font2D>();
+ int cnt = 1;
String fontFilePath = fontFile.getPath();
FileFont font2D = null;
final File fFile = fontFile;
@@ -2437,9 +2438,19 @@
switch (fontFormat) {
case Font.TRUETYPE_FONT:
font2D = new TrueTypeFont(fontFilePath, null, 0, true);
+ fList.add(font2D);
+ if (!all) {
+ break;
+ }
+ cnt = ((TrueTypeFont)font2D).getFontCount();
+ int index = 1;
+ while (index < cnt) {
+ fList.add(new TrueTypeFont(fontFilePath, null, index++, true));
+ }
break;
case Font.TYPE1_FONT:
font2D = new Type1Font(fontFilePath, null, isCopy);
+ fList.add(font2D);
break;
default:
throw new FontFormatException("Unrecognised Font Format");
@@ -2460,7 +2471,7 @@
throw(e);
}
if (isCopy) {
- font2D.setFileToRemove(fontFile, tracker);
+ FileFont.setFileToRemove(fList, fontFile, cnt, tracker);
synchronized (FontManager.class) {
if (tmpFontFiles == null) {
@@ -2511,7 +2522,7 @@
}
}
}
- return font2D;
+ return fList.toArray(new Font2D[0]);
}
/* remind: used in X11GraphicsEnvironment and called often enough
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java Thu Apr 07 11:03:59 2016 -0700
@@ -2101,13 +2101,39 @@
if (w <= 0 || h <= 0) {
return;
}
+
+ if (transformState == SunGraphics2D.TRANSFORM_ISIDENT) {
+ // do nothing
+ } else if (transformState <= SunGraphics2D.TRANSFORM_ANY_TRANSLATE) {
+ x += transX;
+ y += transY;
+ } else if (transformState == SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
+ final double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
+ transform.transform(coords, 0, coords, 0, 3);
+ x = (int) Math.ceil(coords[0] - 0.5);
+ y = (int) Math.ceil(coords[1] - 0.5);
+ w = ((int) Math.ceil(coords[2] - 0.5)) - x;
+ h = ((int) Math.ceil(coords[3] - 0.5)) - y;
+ dx = ((int) Math.ceil(coords[4] - 0.5)) - x;
+ dy = ((int) Math.ceil(coords[5] - 0.5)) - y;
+ // In case of negative scale transform, reflect the rect coords.
+ if (w < 0) {
+ w = -w;
+ x -= w;
+ }
+ if (h < 0) {
+ h = -h;
+ y -= h;
+ }
+ } else {
+ throw new InternalError("transformed copyArea not implemented yet");
+ }
+
SurfaceData theData = surfaceData;
if (theData.copyArea(this, x, y, w, h, dx, dy)) {
return;
}
- if (transformState > TRANSFORM_TRANSLATESCALE) {
- throw new InternalError("transformed copyArea not implemented yet");
- }
+
// REMIND: This method does not deal with missing data from the
// source object (i.e. it does not send exposure events...)
@@ -2126,26 +2152,6 @@
lastCAcomp = comp;
}
- double[] coords = {x, y, x + w, y + h, x + dx, y + dy};
- transform.transform(coords, 0, coords, 0, 3);
-
- x = (int)Math.ceil(coords[0] - 0.5);
- y = (int)Math.ceil(coords[1] - 0.5);
- w = ((int)Math.ceil(coords[2] - 0.5)) - x;
- h = ((int)Math.ceil(coords[3] - 0.5)) - y;
- dx = ((int)Math.ceil(coords[4] - 0.5)) - x;
- dy = ((int)Math.ceil(coords[5] - 0.5)) - y;
-
- // In case of negative scale transform, reflect the rect coords.
- if (w < 0) {
- w *= -1;
- x -= w;
- }
- if (h < 0) {
- h *= -1;
- y -= h;
- }
-
Blit ob = lastCAblit;
if (dy == 0 && dx > 0 && dx < w) {
while (w > 0) {
@@ -2167,7 +2173,7 @@
}
return;
}
- ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h);
+ ob.Blit(theData, theData, comp, clip, x, y, x+dx, y+dy, w, h);
}
/*
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java Thu Apr 07 11:03:59 2016 -0700
@@ -208,9 +208,9 @@
* to use Mincho instead of Gothic for dialoginput in JA locales
* on windows. Not needed on other platforms.
*
- * DO NOT MOVE OR RENAME OR OTHERWISE ALTER THIS METHOD.
- * ITS USED BY SOME NON-JRE INTERNAL CODE.
+ * @deprecated as of JDK9. To be removed in a future release
*/
+ @Deprecated
public static void useAlternateFontforJALocales() {
getFontManagerForSGE().useAlternateFontforJALocales();
}
--- a/jdk/src/java.desktop/share/classes/sun/java2d/SurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/SurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -1039,6 +1039,11 @@
* Performs a copyarea within this surface. Returns
* false if there is no algorithm to perform the copyarea
* given the current settings of the SunGraphics2D.
+ *
+ * @param x the x coordinate of the area in device space
+ * @param y the y coordinate of the area in device space
+ * @param w the width of the area in device space
+ * @param h the height of the area in device space
*/
public boolean copyArea(SunGraphics2D sg2d,
int x, int y, int w, int h, int dx, int dy)
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java Thu Apr 07 11:03:59 2016 -0700
@@ -51,6 +51,9 @@
private static final float MIN_PEN_SIZE = 1f / NORM_SUBPIXELS;
+ static final float UPPER_BND = Float.MAX_VALUE / 2.0f;
+ static final float LOWER_BND = -UPPER_BND;
+
/**
* Public constructor
*/
@@ -279,7 +282,7 @@
float dashphase,
PathConsumer2D pc2d)
{
- // We use strokerat and outat so that in Stroker and Dasher we can work only
+ // We use strokerat so that in Stroker and Dasher we can work only
// with the pre-transformation coordinates. This will repeat a lot of
// computations done in the path iterator, but the alternative is to
// work with transformed paths and compute untransformed coordinates
@@ -289,15 +292,11 @@
// However, if a path's width is constant after a transformation,
// we can skip all this untransforming.
- // If normalization is off we save some transformations by not
- // transforming the input to pisces. Instead, we apply the
- // transformation after the path processing has been done.
- // We can't do this if normalization is on, because it isn't a good
- // idea to normalize before the transformation is applied.
+ // As pathTo() will check transformed coordinates for invalid values
+ // (NaN / Infinity) to ignore such points, it is necessary to apply the
+ // transformation before the path processing.
AffineTransform strokerat = null;
- AffineTransform outat = null;
- PathIterator pi;
int dashLen = -1;
boolean recycleDashes = false;
@@ -333,6 +332,7 @@
// leave a bit of room for error.
if (nearZero(a*b + c*d) && nearZero(a*a + c*c - (b*b + d*d))) {
final float scale = (float) Math.sqrt(a*a + c*c);
+
if (dashes != null) {
recycleDashes = true;
dashLen = dashes.length;
@@ -349,48 +349,35 @@
System.arraycopy(dashes, 0, newDashes, 0, dashLen);
dashes = newDashes;
for (int i = 0; i < dashLen; i++) {
- dashes[i] = scale * dashes[i];
+ dashes[i] *= scale;
}
- dashphase = scale * dashphase;
+ dashphase *= scale;
}
- width = scale * width;
- pi = getNormalizingPathIterator(rdrCtx, normalize,
- src.getPathIterator(at));
+ width *= scale;
- // by now strokerat == null && outat == null. Input paths to
+ // by now strokerat == null. Input paths to
// stroker (and maybe dasher) will have the full transform at
// applied to them and nothing will happen to the output paths.
} else {
- if (normalize != NormMode.OFF) {
- strokerat = at;
- pi = getNormalizingPathIterator(rdrCtx, normalize,
- src.getPathIterator(at));
+ strokerat = at;
- // by now strokerat == at && outat == null. Input paths to
- // stroker (and maybe dasher) will have the full transform at
- // applied to them, then they will be normalized, and then
- // the inverse of *only the non translation part of at* will
- // be applied to the normalized paths. This won't cause problems
- // in stroker, because, suppose at = T*A, where T is just the
- // translation part of at, and A is the rest. T*A has already
- // been applied to Stroker/Dasher's input. Then Ainv will be
- // applied. Ainv*T*A is not equal to T, but it is a translation,
- // which means that none of stroker's assumptions about its
- // input will be violated. After all this, A will be applied
- // to stroker's output.
- } else {
- outat = at;
- pi = src.getPathIterator(null);
- // outat == at && strokerat == null. This is because if no
- // normalization is done, we can just apply all our
- // transformations to stroker's output.
- }
+ // by now strokerat == at. Input paths to
+ // stroker (and maybe dasher) will have the full transform at
+ // applied to them, then they will be normalized, and then
+ // the inverse of *only the non translation part of at* will
+ // be applied to the normalized paths. This won't cause problems
+ // in stroker, because, suppose at = T*A, where T is just the
+ // translation part of at, and A is the rest. T*A has already
+ // been applied to Stroker/Dasher's input. Then Ainv will be
+ // applied. Ainv*T*A is not equal to T, but it is a translation,
+ // which means that none of stroker's assumptions about its
+ // input will be violated. After all this, A will be applied
+ // to stroker's output.
}
} else {
// either at is null or it's the identity. In either case
// we don't transform the path.
- pi = getNormalizingPathIterator(rdrCtx, normalize,
- src.getPathIterator(null));
+ at = null;
}
if (useSimplifier) {
@@ -399,12 +386,7 @@
pc2d = rdrCtx.simplifier.init(pc2d);
}
- // by now, at least one of outat and strokerat will be null. Unless at is not
- // a constant multiple of an orthogonal transformation, they will both be
- // null. In other cases, outat == at if normalization is off, and if
- // normalization is on, strokerat == at.
final TransformingPathConsumer2D transformerPC2D = rdrCtx.transformerPC2D;
- pc2d = transformerPC2D.transformConsumer(pc2d, outat);
pc2d = transformerPC2D.deltaTransformConsumer(pc2d, strokerat);
pc2d = rdrCtx.stroker.init(pc2d, width, caps, join, miterlimit);
@@ -417,18 +399,22 @@
recycleDashes);
}
pc2d = transformerPC2D.inverseDeltaTransformConsumer(pc2d, strokerat);
+
+ final PathIterator pi = getNormalizingPathIterator(rdrCtx, normalize,
+ src.getPathIterator(at));
+
pathTo(rdrCtx, pi, pc2d);
/*
* Pipeline seems to be:
- * shape.getPathIterator
- * -> NormalizingPathIterator
- * -> inverseDeltaTransformConsumer
- * -> Dasher
+ * shape.getPathIterator(at)
+ * -> (NormalizingPathIterator)
+ * -> (inverseDeltaTransformConsumer)
+ * -> (Dasher)
* -> Stroker
- * -> deltaTransformConsumer OR transformConsumer
+ * -> (deltaTransformConsumer)
*
- * -> CollinearSimplifier to remove redundant segments
+ * -> (CollinearSimplifier) to remove redundant segments
*
* -> pc2d = Renderer (bounding box)
*/
@@ -642,27 +628,109 @@
private static void pathToLoop(final float[] coords, final PathIterator pi,
final PathConsumer2D pc2d)
{
+ // ported from DuctusRenderingEngine.feedConsumer() but simplified:
+ // - removed skip flag = !subpathStarted
+ // - removed pathClosed (ie subpathStarted not set to false)
+ boolean subpathStarted = false;
+
for (; !pi.isDone(); pi.next()) {
switch (pi.currentSegment(coords)) {
- case PathIterator.SEG_MOVETO:
+ case PathIterator.SEG_MOVETO:
+ /* Checking SEG_MOVETO coordinates if they are out of the
+ * [LOWER_BND, UPPER_BND] range. This check also handles NaN
+ * and Infinity values. Skipping next path segment in case of
+ * invalid data.
+ */
+ if (coords[0] < UPPER_BND && coords[0] > LOWER_BND &&
+ coords[1] < UPPER_BND && coords[1] > LOWER_BND)
+ {
pc2d.moveTo(coords[0], coords[1]);
- continue;
- case PathIterator.SEG_LINETO:
- pc2d.lineTo(coords[0], coords[1]);
- continue;
- case PathIterator.SEG_QUADTO:
- pc2d.quadTo(coords[0], coords[1],
- coords[2], coords[3]);
- continue;
- case PathIterator.SEG_CUBICTO:
- pc2d.curveTo(coords[0], coords[1],
- coords[2], coords[3],
- coords[4], coords[5]);
- continue;
- case PathIterator.SEG_CLOSE:
+ subpathStarted = true;
+ }
+ break;
+ case PathIterator.SEG_LINETO:
+ /* Checking SEG_LINETO coordinates if they are out of the
+ * [LOWER_BND, UPPER_BND] range. This check also handles NaN
+ * and Infinity values. Ignoring current path segment in case
+ * of invalid data. If segment is skipped its endpoint
+ * (if valid) is used to begin new subpath.
+ */
+ if (coords[0] < UPPER_BND && coords[0] > LOWER_BND &&
+ coords[1] < UPPER_BND && coords[1] > LOWER_BND)
+ {
+ if (subpathStarted) {
+ pc2d.lineTo(coords[0], coords[1]);
+ } else {
+ pc2d.moveTo(coords[0], coords[1]);
+ subpathStarted = true;
+ }
+ }
+ break;
+ case PathIterator.SEG_QUADTO:
+ // Quadratic curves take two points
+ /* Checking SEG_QUADTO coordinates if they are out of the
+ * [LOWER_BND, UPPER_BND] range. This check also handles NaN
+ * and Infinity values. Ignoring current path segment in case
+ * of invalid endpoints's data. Equivalent to the SEG_LINETO
+ * if endpoint coordinates are valid but there are invalid data
+ * among other coordinates
+ */
+ if (coords[2] < UPPER_BND && coords[2] > LOWER_BND &&
+ coords[3] < UPPER_BND && coords[3] > LOWER_BND)
+ {
+ if (subpathStarted) {
+ if (coords[0] < UPPER_BND && coords[0] > LOWER_BND &&
+ coords[1] < UPPER_BND && coords[1] > LOWER_BND)
+ {
+ pc2d.quadTo(coords[0], coords[1],
+ coords[2], coords[3]);
+ } else {
+ pc2d.lineTo(coords[2], coords[3]);
+ }
+ } else {
+ pc2d.moveTo(coords[2], coords[3]);
+ subpathStarted = true;
+ }
+ }
+ break;
+ case PathIterator.SEG_CUBICTO:
+ // Cubic curves take three points
+ /* Checking SEG_CUBICTO coordinates if they are out of the
+ * [LOWER_BND, UPPER_BND] range. This check also handles NaN
+ * and Infinity values. Ignoring current path segment in case
+ * of invalid endpoints's data. Equivalent to the SEG_LINETO
+ * if endpoint coordinates are valid but there are invalid data
+ * among other coordinates
+ */
+ if (coords[4] < UPPER_BND && coords[4] > LOWER_BND &&
+ coords[5] < UPPER_BND && coords[5] > LOWER_BND)
+ {
+ if (subpathStarted) {
+ if (coords[0] < UPPER_BND && coords[0] > LOWER_BND &&
+ coords[1] < UPPER_BND && coords[1] > LOWER_BND &&
+ coords[2] < UPPER_BND && coords[2] > LOWER_BND &&
+ coords[3] < UPPER_BND && coords[3] > LOWER_BND)
+ {
+ pc2d.curveTo(coords[0], coords[1],
+ coords[2], coords[3],
+ coords[4], coords[5]);
+ } else {
+ pc2d.lineTo(coords[4], coords[5]);
+ }
+ } else {
+ pc2d.moveTo(coords[4], coords[5]);
+ subpathStarted = true;
+ }
+ }
+ break;
+ case PathIterator.SEG_CLOSE:
+ if (subpathStarted) {
pc2d.closePath();
- continue;
- default:
+ // do not set subpathStarted to false
+ // in case of missing moveTo() after close()
+ }
+ break;
+ default:
}
}
pc2d.pathDone();
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Stroker.java Thu Apr 07 11:03:59 2016 -0700
@@ -338,11 +338,6 @@
}
private void drawRoundCap(float cx, float cy, float mx, float my) {
- // the first and second arguments of the following two calls
- // are really will be ignored by emitCurveTo (because of the false),
- // but we put them in anyway, as opposed to just giving it 4 zeroes,
- // because it's just 4 additions and it's not good to rely on this
- // sort of assumption (right now it's true, but that may change).
emitCurveTo(cx+mx-C*my, cy+my+C*mx,
cx-my+C*mx, cy+mx+C*my,
cx-my, cy+mx);
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/TransformingPathConsumer2D.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/TransformingPathConsumer2D.java Thu Apr 07 11:03:59 2016 -0700
@@ -35,7 +35,7 @@
// used by RendererContext
}
- // recycled PathConsumer2D instance from transformConsumer()
+ // recycled PathConsumer2D instance from wrapPath2d()
private final Path2DWrapper wp_Path2DWrapper = new Path2DWrapper();
PathConsumer2D wrapPath2d(Path2D.Float p2d)
@@ -43,46 +43,6 @@
return wp_Path2DWrapper.init(p2d);
}
- // recycled PathConsumer2D instances from transformConsumer()
- private final TranslateFilter tx_TranslateFilter = new TranslateFilter();
- private final DeltaScaleFilter tx_DeltaScaleFilter = new DeltaScaleFilter();
- private final ScaleFilter tx_ScaleFilter = new ScaleFilter();
- private final DeltaTransformFilter tx_DeltaTransformFilter = new DeltaTransformFilter();
- private final TransformFilter tx_TransformFilter = new TransformFilter();
-
- PathConsumer2D transformConsumer(PathConsumer2D out,
- AffineTransform at)
- {
- if (at == null) {
- return out;
- }
- float mxx = (float) at.getScaleX();
- float mxy = (float) at.getShearX();
- float mxt = (float) at.getTranslateX();
- float myx = (float) at.getShearY();
- float myy = (float) at.getScaleY();
- float myt = (float) at.getTranslateY();
- if (mxy == 0f && myx == 0f) {
- if (mxx == 1f && myy == 1f) {
- if (mxt == 0f && myt == 0f) {
- return out;
- } else {
- return tx_TranslateFilter.init(out, mxt, myt);
- }
- } else {
- if (mxt == 0f && myt == 0f) {
- return tx_DeltaScaleFilter.init(out, mxx, myy);
- } else {
- return tx_ScaleFilter.init(out, mxx, myy, mxt, myt);
- }
- }
- } else if (mxt == 0f && myt == 0f) {
- return tx_DeltaTransformFilter.init(out, mxx, mxy, myx, myy);
- } else {
- return tx_TransformFilter.init(out, mxx, mxy, mxt, myx, myy, myt);
- }
- }
-
// recycled PathConsumer2D instances from deltaTransformConsumer()
private final DeltaScaleFilter dt_DeltaScaleFilter = new DeltaScaleFilter();
private final DeltaTransformFilter dt_DeltaTransformFilter = new DeltaTransformFilter();
@@ -97,6 +57,7 @@
float mxy = (float) at.getShearX();
float myx = (float) at.getShearY();
float myy = (float) at.getScaleY();
+
if (mxy == 0f && myx == 0f) {
if (mxx == 1f && myy == 1f) {
return out;
@@ -122,6 +83,7 @@
float mxy = (float) at.getShearX();
float myx = (float) at.getShearY();
float myy = (float) at.getScaleY();
+
if (mxy == 0f && myx == 0f) {
if (mxx == 1f && myy == 1f) {
return out;
@@ -138,197 +100,6 @@
}
}
- static final class TranslateFilter implements PathConsumer2D {
- private PathConsumer2D out;
- private float tx, ty;
-
- TranslateFilter() {}
-
- TranslateFilter init(PathConsumer2D out,
- float tx, float ty)
- {
- this.out = out;
- this.tx = tx;
- this.ty = ty;
- return this; // fluent API
- }
-
- @Override
- public void moveTo(float x0, float y0) {
- out.moveTo(x0 + tx, y0 + ty);
- }
-
- @Override
- public void lineTo(float x1, float y1) {
- out.lineTo(x1 + tx, y1 + ty);
- }
-
- @Override
- public void quadTo(float x1, float y1,
- float x2, float y2)
- {
- out.quadTo(x1 + tx, y1 + ty,
- x2 + tx, y2 + ty);
- }
-
- @Override
- public void curveTo(float x1, float y1,
- float x2, float y2,
- float x3, float y3)
- {
- out.curveTo(x1 + tx, y1 + ty,
- x2 + tx, y2 + ty,
- x3 + tx, y3 + ty);
- }
-
- @Override
- public void closePath() {
- out.closePath();
- }
-
- @Override
- public void pathDone() {
- out.pathDone();
- }
-
- @Override
- public long getNativeConsumer() {
- return 0;
- }
- }
-
- static final class ScaleFilter implements PathConsumer2D {
- private PathConsumer2D out;
- private float sx, sy, tx, ty;
-
- ScaleFilter() {}
-
- ScaleFilter init(PathConsumer2D out,
- float sx, float sy,
- float tx, float ty)
- {
- this.out = out;
- this.sx = sx;
- this.sy = sy;
- this.tx = tx;
- this.ty = ty;
- return this; // fluent API
- }
-
- @Override
- public void moveTo(float x0, float y0) {
- out.moveTo(x0 * sx + tx, y0 * sy + ty);
- }
-
- @Override
- public void lineTo(float x1, float y1) {
- out.lineTo(x1 * sx + tx, y1 * sy + ty);
- }
-
- @Override
- public void quadTo(float x1, float y1,
- float x2, float y2)
- {
- out.quadTo(x1 * sx + tx, y1 * sy + ty,
- x2 * sx + tx, y2 * sy + ty);
- }
-
- @Override
- public void curveTo(float x1, float y1,
- float x2, float y2,
- float x3, float y3)
- {
- out.curveTo(x1 * sx + tx, y1 * sy + ty,
- x2 * sx + tx, y2 * sy + ty,
- x3 * sx + tx, y3 * sy + ty);
- }
-
- @Override
- public void closePath() {
- out.closePath();
- }
-
- @Override
- public void pathDone() {
- out.pathDone();
- }
-
- @Override
- public long getNativeConsumer() {
- return 0;
- }
- }
-
- static final class TransformFilter implements PathConsumer2D {
- private PathConsumer2D out;
- private float mxx, mxy, mxt, myx, myy, myt;
-
- TransformFilter() {}
-
- TransformFilter init(PathConsumer2D out,
- float mxx, float mxy, float mxt,
- float myx, float myy, float myt)
- {
- this.out = out;
- this.mxx = mxx;
- this.mxy = mxy;
- this.mxt = mxt;
- this.myx = myx;
- this.myy = myy;
- this.myt = myt;
- return this; // fluent API
- }
-
- @Override
- public void moveTo(float x0, float y0) {
- out.moveTo(x0 * mxx + y0 * mxy + mxt,
- x0 * myx + y0 * myy + myt);
- }
-
- @Override
- public void lineTo(float x1, float y1) {
- out.lineTo(x1 * mxx + y1 * mxy + mxt,
- x1 * myx + y1 * myy + myt);
- }
-
- @Override
- public void quadTo(float x1, float y1,
- float x2, float y2)
- {
- out.quadTo(x1 * mxx + y1 * mxy + mxt,
- x1 * myx + y1 * myy + myt,
- x2 * mxx + y2 * mxy + mxt,
- x2 * myx + y2 * myy + myt);
- }
-
- @Override
- public void curveTo(float x1, float y1,
- float x2, float y2,
- float x3, float y3)
- {
- out.curveTo(x1 * mxx + y1 * mxy + mxt,
- x1 * myx + y1 * myy + myt,
- x2 * mxx + y2 * mxy + mxt,
- x2 * myx + y2 * myy + myt,
- x3 * mxx + y3 * mxy + mxt,
- x3 * myx + y3 * myy + myt);
- }
-
- @Override
- public void closePath() {
- out.closePath();
- }
-
- @Override
- public void pathDone() {
- out.pathDone();
- }
-
- @Override
- public long getNativeConsumer() {
- return 0;
- }
- }
static final class DeltaScaleFilter implements PathConsumer2D {
private PathConsumer2D out;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java Thu Apr 07 11:03:59 2016 -0700
@@ -27,7 +27,7 @@
public final class Version {
- private static final String version = "marlin-0.7.3.2-Unsafe-OpenJDK";
+ private static final String version = "marlin-0.7.3.3-Unsafe-OpenJDK";
public static String getVersion() {
return version;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -542,20 +542,14 @@
return super.getMaskFill(sg2d);
}
- public boolean copyArea(SunGraphics2D sg2d,
- int x, int y, int w, int h, int dx, int dy)
- {
- if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
- sg2d.compositeState < SunGraphics2D.COMP_XOR)
- {
- x += sg2d.transX;
- y += sg2d.transY;
-
- oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
-
- return true;
+ @Override
+ public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
+ int dx, int dy) {
+ if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
+ return false;
}
- return false;
+ oglRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
+ return true;
}
public void flush() {
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/AAShapePipe.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/AAShapePipe.java Thu Apr 07 11:03:59 2016 -0700
@@ -28,7 +28,6 @@
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
-import java.util.concurrent.ConcurrentLinkedQueue;
import sun.awt.SunHints;
import sun.java2d.ReentrantContext;
import sun.java2d.ReentrantContextProvider;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java Thu Apr 07 11:03:59 2016 -0700
@@ -340,8 +340,8 @@
* <li> Image will be used only once and acceleration caching wouldn't help
* </ul>
*/
- BufferedImage makeBufferedImage(Image img, Color bgColor, int type,
- int sx1, int sy1, int sx2, int sy2)
+ private BufferedImage makeBufferedImage(Image img, Color bgColor, int type,
+ int sx1, int sy1, int sx2, int sy2)
{
final int width = sx2 - sx1;
final int height = sy2 - sy1;
@@ -430,10 +430,16 @@
if (isBgOperation(srcData, bgColor)) {
// We cannot perform bg operations during transform so make
- // an opaque temp image with the appropriate background
- // and work from there.
- img = makeBufferedImage(img, bgColor, BufferedImage.TYPE_INT_RGB,
- sx1, sy1, sx2, sy2);
+ // a temp image with the appropriate background based on
+ // background alpha value and work from there. If background
+ // alpha is opaque use INT_RGB else use INT_ARGB so that we
+ // will not lose translucency of background.
+
+ int bgAlpha = bgColor.getAlpha();
+ int type = ((bgAlpha == 255)
+ ? BufferedImage.TYPE_INT_RGB
+ : BufferedImage.TYPE_INT_ARGB);
+ img = makeBufferedImage(img, bgColor, type, sx1, sy1, sx2, sy2);
// Temp image has appropriate subimage at 0,0 now.
sx2 -= sx1;
sy2 -= sy1;
--- a/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/print/PrintJob2D.java Thu Apr 07 11:03:59 2016 -0700
@@ -995,6 +995,7 @@
public void run() {
try {
+ attributes.remove(PageRanges.class);
printerJob.print(attributes);
} catch (PrinterException e) {
//REMIND: need to store this away and not rethrow it.
--- a/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java Thu Apr 07 11:03:59 2016 -0700
@@ -1212,6 +1212,7 @@
pageRangesAttr = (PageRanges)attributes.get(PageRanges.class);
if (!isSupportedValue(pageRangesAttr, attributes)) {
pageRangesAttr = null;
+ setPageRange(-1, -1);
} else {
if ((SunPageSelection)attributes.get(SunPageSelection.class)
== SunPageSelection.RANGE) {
--- a/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -913,7 +913,15 @@
private class DetailsTableRowSorter extends TableRowSorter<TableModel> {
public DetailsTableRowSorter() {
- setModelWrapper(new SorterModelWrapper());
+ SorterModelWrapper modelWrapper = new SorterModelWrapper();
+ setModelWrapper(modelWrapper);
+ modelWrapper.getModel().addTableModelListener(
+ new TableModelListener() {
+ @Override
+ public void tableChanged(TableModelEvent e) {
+ modelStructureChanged();
+ }
+ });
}
public void updateComparators(ShellFolderColumnInfo [] columns) {
--- a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc Thu Apr 07 11:03:59 2016 -0700
@@ -293,7 +293,7 @@
return NULL;
}
length = env->GetArrayLength(tableBytes);
- buffer = new jbyte[length];
+ buffer = (jbyte *)calloc(length, sizeof(jbyte));
env->GetByteArrayRegion(tableBytes, 0, length, buffer);
return hb_blob_create((const char *)buffer, length,
--- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.c Thu Apr 07 11:03:59 2016 -0700
@@ -389,3 +389,8 @@
pStream->close = closeMem;
return 1;
}
+
+SPLASHEXPORT int
+SplashGetScaledImgNameMaxPstfixLen(const char *fileName){
+ return strlen(fileName) + strlen(".java-scale-200") + 1;
+}
--- a/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/splashscreen_impl.h Thu Apr 07 11:03:59 2016 -0700
@@ -28,6 +28,7 @@
#include "splashscreen_config.h"
#include "splashscreen_gfx.h"
+#include "jni.h"
SPLASHEXPORT int SplashLoadMemory(void *pdata, int size); /* requires preloading the file */
SPLASHEXPORT int SplashLoadFile(const char *filename); // FIXME: range checking for SplashLoadMemory
@@ -36,11 +37,14 @@
SPLASHEXPORT void SplashClose(void);
SPLASHEXPORT void SplashSetScaleFactor(float);
-SPLASHEXPORT char* SplashGetScaledImageName(const char*, const char*, float*);
+SPLASHEXPORT jboolean SplashGetScaledImageName(const char*, const char*,
+ float*, char*, const size_t scaledImageNameLength);
SPLASHEXPORT void
SplashSetFileJarName(const char* fileName, const char* jarName);
+SPLASHEXPORT int
+SplashGetScaledImgNameMaxPstfixLen(const char*);
typedef struct SplashImage
{
rgbquad_t *bitmapBits;
@@ -119,9 +123,9 @@
unsigned SplashTime();
char* SplashConvertStringAlloc(const char* in, int *size);
-char* SplashGetScaledImageName(const char* jarName,
- const char* fileName, float *scaleFactor);
-
+jboolean SplashGetScaledImageName(const char* jarName,
+ const char* fileName, float *scaleFactor,
+ char *scaleImageName, const size_t scaledImageNameLength);
void SplashLock(Splash * splash);
void SplashUnlock(Splash * splash);
@@ -145,7 +149,7 @@
void SplashCleanup(Splash * splash);
void SplashSetScaleFactor(float scaleFactor);
-
+int SplashGetScaledImgNameMaxPstfixLen(const char *fileName);
typedef struct SplashStream {
int (*read)(void* pStream, void* pData, int nBytes);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2016, 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 sun.awt.X11;
+
+import java.awt.MenuItem;
+import java.awt.PopupMenu;
+import java.awt.Taskbar.Feature;
+import java.awt.peer.TaskbarPeer;
+import java.awt.event.ActionEvent;
+import sun.misc.ManagedLocalsThread;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+
+final class XTaskbarPeer implements TaskbarPeer {
+
+ private static boolean nativeLibraryLoaded = false;
+ private static boolean initExecuted = false;
+
+ private PopupMenu menu = null;
+
+ private static void initWithLock() {
+ XToolkit.awtLock();
+ try {
+ if (!initExecuted) {
+ String dname = AccessController.doPrivileged(
+ new GetPropertyAction("java.desktop.appName", ""));
+ nativeLibraryLoaded = init(dname);
+ if (nativeLibraryLoaded) {
+ ManagedLocalsThread t
+ = new ManagedLocalsThread(() -> {
+ runloop();
+ });
+ t.setDaemon(true);
+ t.start();
+ }
+ }
+ } finally {
+ initExecuted = true;
+ XToolkit.awtUnlock();
+ }
+ }
+
+ XTaskbarPeer() {
+ initWithLock();
+ }
+
+ static boolean isTaskbarSupported() {
+ initWithLock();
+ return nativeLibraryLoaded;
+ }
+
+ @Override
+ public boolean isSupported(Feature feature) {
+ switch (feature) {
+ case ICON_BADGE_NUMBER:
+ case MENU:
+ case PROGRESS_VALUE:
+ case USER_ATTENTION:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public void setProgressValue(int value) {
+ boolean visible
+ = value >= 0
+ && value <= 100;
+
+ double v = visible
+ ? (double) value / 100
+ : 0d;
+
+ updateProgress(v, visible);
+ }
+
+ @Override
+ public void setIconBadge(String badge) {
+ boolean visible = false;
+ long val = 0;
+ if (badge != null) {
+ try {
+ val = Long.parseLong(badge);
+ visible = true;
+ } catch (NumberFormatException e) {
+ }
+ }
+ setBadge(val, visible);
+ }
+
+ @Override
+ public PopupMenu getMenu() {
+ return menu;
+ }
+
+ @Override
+ public synchronized void setMenu(PopupMenu m) {
+ this.menu = m;
+
+ if (menu != null && menu.getItemCount() > 0) {
+ int msize = menu.getItemCount();
+ MenuItem[] items = new MenuItem[msize];
+ for (int i = 0; i < msize; i++) {
+ items[i] = menu.getItem(i);
+ }
+ setNativeMenu(items);
+ } else {
+ setNativeMenu(null);
+ }
+ }
+
+ @Override
+ public void requestUserAttention(boolean enabled, boolean critical) {
+ setUrgent(enabled);
+ }
+
+ private static void menuItemCallback(MenuItem mi) {
+ if (mi != null) {
+ ActionEvent ae = new ActionEvent(mi, ActionEvent.ACTION_PERFORMED,
+ mi.getActionCommand());
+ try {
+ XToolkit.awtLock();
+ XToolkit.postEvent(XToolkit.targetToAppContext(ae.getSource()), ae);
+ } finally {
+ XToolkit.awtUnlock();
+ }
+ }
+ }
+
+ private static native boolean init(String name);
+
+ private static native void runloop();
+
+ private native void setBadge(long value, boolean visible);
+
+ private native void updateProgress(double value, boolean visible);
+
+ private native void setUrgent(boolean urgent);
+
+ private native void setNativeMenu(MenuItem[] items);
+}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -24,6 +24,7 @@
*/
package sun.awt.X11;
+import java.awt.peer.TaskbarPeer;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
@@ -769,17 +770,20 @@
GraphicsEnvironment.getLocalGraphicsEnvironment();
if (!x11ge.runningXinerama())
{
- Rectangle workArea = XToolkit.getWorkArea(root, scale);
- if (workArea != null)
- {
- return new Insets(workArea.y,
- workArea.x,
- rootBounds.height - workArea.height - workArea.y,
- rootBounds.width - workArea.width - workArea.x);
- }
+ Insets screenInsets = getInsets(root, rootBounds, scale);
+ if (screenInsets != null) return screenInsets;
}
- return getScreenInsetsManually(root, rootBounds, gc.getBounds(), scale);
+ Insets insets = getScreenInsetsManually(root, rootBounds,
+ gc.getBounds(), scale);
+ if ((insets.left | insets.top | insets.bottom | insets.right) == 0
+ && rootBounds != null ) {
+ root = XlibWrapper.RootWindow(XToolkit.getDisplay(),
+ x11gd.getScreen());
+ Insets screenInsets = getInsets(root, rootBounds, scale);
+ if (screenInsets != null) return screenInsets;
+ }
+ return insets;
}
finally
{
@@ -787,6 +791,16 @@
}
}
+ private Insets getInsets(long root, Rectangle rootBounds, int scale) {
+ Rectangle workArea = XToolkit.getWorkArea(root, scale);
+ if (workArea == null) {
+ return null;
+ }
+ return new Insets(workArea.y, workArea.x,
+ rootBounds.height - workArea.height - workArea.y,
+ rootBounds.width - workArea.width - workArea.x);
+ }
+
/*
* Manual calculation of screen insets: get all the windows with
* _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
@@ -2568,6 +2582,16 @@
}
@Override
+ public boolean isTaskbarSupported(){
+ return XTaskbarPeer.isTaskbarSupported();
+ }
+
+ @Override
+ public TaskbarPeer createTaskbarPeer(Taskbar target){
+ return new XTaskbarPeer();
+ }
+
+ @Override
public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
return areExtraMouseButtonsEnabled;
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java Thu Apr 07 11:03:59 2016 -0700
@@ -1008,13 +1008,10 @@
// if ( Check if it's a resize, a move, or a stacking order change )
// {
Rectangle bounds = getBounds();
- final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
if (!bounds.getSize().equals(oldBounds.getSize())) {
- acc.setSize(target, bounds.width, bounds.height);
postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED));
}
if (!bounds.getLocation().equals(oldBounds.getLocation())) {
- acc.setLocation(target, bounds.x, bounds.y);
postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_MOVED));
}
// }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, 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
@@ -87,7 +87,7 @@
// used for modal blocking to keep existing z-order
protected XWindowPeer prevTransientFor, nextTransientFor;
// value of WM_TRANSIENT_FOR hint set on this window
- private XWindowPeer curRealTransientFor;
+ private XBaseWindow curRealTransientFor;
private boolean grab = false; // Whether to do a grab during showing
@@ -803,23 +803,31 @@
*/
@Override
public void handleConfigureNotifyEvent(XEvent xev) {
+ assert (SunToolkit.isAWTLockHeldByCurrentThread());
XConfigureEvent xe = xev.get_xconfigure();
- /*
- * Correct window location which could be wrong in some cases.
- * See getNewLocation() for the details.
- */
- Point newLocation = getNewLocation(xe, 0, 0);
- xe.set_x(scaleUp(newLocation.x));
- xe.set_y(scaleUp(newLocation.y));
- checkIfOnNewScreen(new Rectangle(newLocation.x,
- newLocation.y,
- scaleDown(xe.get_width()),
- scaleDown(xe.get_height())));
+ if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
+ insLog.fine(xe.toString());
+ }
+ checkIfOnNewScreen(toGlobal(new Rectangle(scaleDown(xe.get_x()),
+ scaleDown(xe.get_y()),
+ scaleDown(xe.get_width()),
+ scaleDown(xe.get_height()))));
+
+ Rectangle oldBounds = getBounds();
- // Don't call super until we've handled a screen change. Otherwise
- // there could be a race condition in which a ComponentListener could
- // see the old screen.
- super.handleConfigureNotifyEvent(xev);
+ x = scaleDown(xe.get_x());
+ y = scaleDown(xe.get_y());
+ width = scaleDown(xe.get_width());
+ height = scaleDown(xe.get_height());
+
+ if (!getBounds().getSize().equals(oldBounds.getSize())) {
+ AWTAccessor.getComponentAccessor().setSize(target, width, height);
+ postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_RESIZED));
+ }
+ if (!getBounds().getLocation().equals(oldBounds.getLocation())) {
+ AWTAccessor.getComponentAccessor().setLocation(target, x, y);
+ postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
+ }
repositionSecurityWarning();
}
@@ -1057,13 +1065,23 @@
log.fine("Promoting always-on-top state {0}", Boolean.valueOf(alwaysOnTop));
}
XWM.getWM().setLayer(this,
- alwaysOnTop ?
- XLayerProtocol.LAYER_ALWAYS_ON_TOP :
- XLayerProtocol.LAYER_NORMAL);
+ alwaysOnTop ?
+ XLayerProtocol.LAYER_ALWAYS_ON_TOP :
+ XLayerProtocol.LAYER_NORMAL);
}
public void updateAlwaysOnTopState() {
this.alwaysOnTop = ((Window) this.target).isAlwaysOnTop();
+ if (ownerPeer != null) {
+ XToolkit.awtLock();
+ try {
+ restoreTransientFor(this);
+ applyWindowType();
+ }
+ finally {
+ XToolkit.awtUnlock();
+ }
+ }
updateAlwaysOnTop();
}
@@ -1107,7 +1125,27 @@
if (!vis && warningWindow != null) {
warningWindow.setSecurityWarningVisible(false, false);
}
+ boolean refreshChildsTransientFor = isVisible() != vis;
super.setVisible(vis);
+ if (refreshChildsTransientFor) {
+ for (Window child : ((Window) target).getOwnedWindows()) {
+ XToolkit.awtLock();
+ try {
+ if(!child.isLightweight() && child.isVisible()) {
+ ComponentPeer childPeer = AWTAccessor.
+ getComponentAccessor().getPeer(child);
+ if(childPeer instanceof XWindowPeer) {
+ XWindowPeer windowPeer = (XWindowPeer) childPeer;
+ restoreTransientFor(windowPeer);
+ windowPeer.applyWindowType();
+ }
+ }
+ }
+ finally {
+ XToolkit.awtUnlock();
+ }
+ }
+ }
if (!vis && !isWithdrawn()) {
// ICCCM, 4.1.4. Changing Window State:
// "Iconic -> Withdrawn - The client should unmap the window and follow it
@@ -1636,9 +1674,6 @@
window.prevTransientFor = transientForWindow;
transientForWindow.nextTransientFor = window;
}
- if (window.curRealTransientFor == transientForWindow) {
- return;
- }
if (!allStates && (window.getWMState() != transientForWindow.getWMState())) {
return;
}
@@ -1650,11 +1685,14 @@
bpw = XlibUtil.getParentWindow(bpw);
}
long tpw = transientForWindow.getWindow();
- while (!XlibUtil.isToplevelWindow(tpw) && !XlibUtil.isXAWTToplevelWindow(tpw)) {
+ XBaseWindow parent = transientForWindow;
+ while (tpw != 0 && ((!XlibUtil.isToplevelWindow(tpw) &&
+ !XlibUtil.isXAWTToplevelWindow(tpw)) || !parent.isVisible())) {
tpw = XlibUtil.getParentWindow(tpw);
+ parent = XToolkit.windowToXWindow(tpw);
}
XlibWrapper.XSetTransientFor(XToolkit.getDisplay(), bpw, tpw);
- window.curRealTransientFor = transientForWindow;
+ window.curRealTransientFor = parent;
}
/*
@@ -1948,7 +1986,7 @@
switch (getWindowType())
{
case NORMAL:
- typeAtom = (ownerPeer == null) ?
+ typeAtom = curRealTransientFor == null ?
protocol.XA_NET_WM_WINDOW_TYPE_NORMAL :
protocol.XA_NET_WM_WINDOW_TYPE_DIALOG;
break;
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -487,12 +487,9 @@
makePipes();
}
CompositeType comptype = sg2d.imageComp;
- if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
- (CompositeType.SrcOverNoEa.equals(comptype) ||
+ if ((CompositeType.SrcOverNoEa.equals(comptype) ||
CompositeType.SrcNoEa.equals(comptype)))
{
- x += sg2d.transX;
- y += sg2d.transY;
SunToolkit.awtLock();
try {
boolean needExposures = canSourceSendExposures(x, y, w, h);
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -365,12 +365,9 @@
makePipes();
}
CompositeType comptype = sg2d.imageComp;
- if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
- (CompositeType.SrcOverNoEa.equals(comptype) ||
- CompositeType.SrcNoEa.equals(comptype)))
+ if (CompositeType.SrcOverNoEa.equals(comptype) ||
+ CompositeType.SrcNoEa.equals(comptype))
{
- x += sg2d.transX;
- y += sg2d.transY;
try {
SunToolkit.awtLock();
boolean needExposures = canSourceSendExposures(x, y, w, h);
--- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Thu Apr 07 11:03:59 2016 -0700
@@ -929,6 +929,7 @@
DocFlavor[] flavor = new DocFlavor[2];
flavor[0] = DocFlavor.SERVICE_FORMATTED.PAGEABLE;
flavor[1] = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
+ supportedDocFlavors = flavor;
return flavor;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.c Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,52 @@
+/*
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+
+#include "systemScale.h"
+#include <stdlib.h>
+
+int getNativeScaleFactor() {
+
+ static int scale = -2.0;
+
+ if (scale == -2) {
+ scale = getScale("J2D_UISCALE");
+ }
+
+ if (scale >= 1) {
+ return (int) scale;
+ }
+ return getScale("GDK_SCALE");
+}
+
+int getScale(const char *name) {
+ char *uiScale = getenv(name);
+ if (uiScale != NULL) {
+ double scale = strtod(uiScale, NULL);
+ if (scale < 1) {
+ return -1;
+ }
+ return (int) scale;
+ }
+ return -1;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/native/common/awt/systemscale/systemScale.h Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+#ifndef _AWT_SYSTEMSCALE_H
+#define _AWT_SYSTEMSCALE_H
+
+#include <signal.h>
+#include <stdlib.h>
+
+int getNativeScaleFactor();
+int getScale(const char *uiScale);
+
+#endif
+
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c Thu Apr 07 11:03:59 2016 -0700
@@ -43,7 +43,7 @@
#include <jvm.h>
#include <jvm_md.h>
#include <jlong.h>
-
+#include "systemScale.h"
#include <stdlib.h>
#include "awt_GraphicsEnv.h"
@@ -2083,17 +2083,6 @@
* End DisplayMode/FullScreen support
*/
-int getScale(const char *name) {
- char *uiScale = getenv(name);
- if (uiScale != NULL) {
- double scale = strtod(uiScale, NULL);
- if (errno == ERANGE || scale < 1) {
- return -1;
- }
- return (int) scale;
- }
- return -1;
-}
/*
* Class: sun_awt_X11GraphicsDevice
@@ -2104,16 +2093,5 @@
Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor
(JNIEnv *env, jobject this, jint screen) {
- // for debug purposes
- static int scale = -2.0;
-
- if (scale == -2) {
- scale = getScale("J2D_UISCALE");
- }
-
- if (scale >= 1) {
- return scale;
- }
-
- return getScale("GDK_SCALE");
+ return getNativeScaleFactor();
}
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.c Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -831,6 +831,10 @@
fp_gtk_separator_tool_item_new =
dl_symbol("gtk_vseparator_new");
}
+
+ fp_g_list_append = dl_symbol("g_list_append");
+ fp_g_list_free = dl_symbol("g_list_free");
+ fp_g_list_free_full = dl_symbol("g_list_free_full");
}
/* Now we have only one kind of exceptions: NO_SYMBOL_EXCEPTION
* Otherwise we can check the return value of setjmp method.
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -289,6 +289,15 @@
GSList *next;
};
+typedef struct _GList GList;
+
+struct _GList
+{
+ gpointer data;
+ GList *next;
+ GList *prev;
+};
+
typedef void GdkColormap;
typedef void GdkDrawable;
typedef void GdkGC;
@@ -841,6 +850,11 @@
gchar* (*fp_g_path_get_dirname) (const gchar *file_name);
XID (*fp_gdk_x11_drawable_get_xid) (GdkWindow *drawable);
+
+GList* (*fp_g_list_append) (GList *list, gpointer data);
+void (*fp_g_list_free) (GList *list);
+void (*fp_g_list_free_full) (GList *list, GDestroyNotify free_func);
+
/**
* This function is available for GLIB > 2.20, so it MUST be
* called within GLIB_CHECK_VERSION(2, 20, 0) check.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.c Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+#include <dlfcn.h>
+#include "jvm_md.h"
+#include <setjmp.h>
+#include <string.h>
+
+#include "jni_util.h"
+#include "awt_Taskbar.h"
+
+
+extern JavaVM *jvm;
+
+#define NO_SYMBOL_EXCEPTION 1
+
+#define UNITY_LIB_VERSIONED VERSIONED_JNI_LIB_NAME("unity", "9")
+#define UNITY_LIB JNI_LIB_NAME("unity")
+
+static jmp_buf j;
+
+static void *unity_libhandle = NULL;
+
+static DbusmenuMenuitem* menu = NULL;
+UnityLauncherEntry* entry = NULL;
+
+static jclass jTaskbarCls = NULL;
+static jmethodID jTaskbarCallback = NULL;
+static jmethodID jMenuItemGetLabel = NULL;
+
+GList* globalRefs = NULL;
+
+static void* dl_symbol(const char* name) {
+ void* result = dlsym(unity_libhandle, name);
+ if (!result)
+ longjmp(j, NO_SYMBOL_EXCEPTION);
+
+ return result;
+}
+
+static gboolean unity_load() {
+ unity_libhandle = dlopen(UNITY_LIB_VERSIONED, RTLD_LAZY | RTLD_LOCAL);
+ if (unity_libhandle == NULL) {
+ unity_libhandle = dlopen(UNITY_LIB, RTLD_LAZY | RTLD_LOCAL);
+ if (unity_libhandle == NULL) {
+ return FALSE;
+ }
+ }
+ if (setjmp(j) == 0) {
+ fp_unity_launcher_entry_get_for_desktop_file = dl_symbol("unity_launcher_entry_get_for_desktop_file");
+ fp_unity_launcher_entry_set_count = dl_symbol("unity_launcher_entry_set_count");
+ fp_unity_launcher_entry_set_count_visible = dl_symbol("unity_launcher_entry_set_count_visible");
+ fp_unity_launcher_entry_set_urgent = dl_symbol("unity_launcher_entry_set_urgent");
+ fp_unity_launcher_entry_set_progress = dl_symbol("unity_launcher_entry_set_progress");
+ fp_unity_launcher_entry_set_progress_visible = dl_symbol("unity_launcher_entry_set_progress_visible");
+
+ fp_dbusmenu_menuitem_new = dl_symbol("dbusmenu_menuitem_new");
+ fp_dbusmenu_menuitem_property_set = dl_symbol("dbusmenu_menuitem_property_set");
+ fp_dbusmenu_menuitem_property_set_int = dl_symbol("dbusmenu_menuitem_property_set_int");
+ fp_dbusmenu_menuitem_property_get_int = dl_symbol("dbusmenu_menuitem_property_get_int");
+ fp_dbusmenu_menuitem_property_set = dl_symbol("dbusmenu_menuitem_property_set");
+ fp_dbusmenu_menuitem_child_append = dl_symbol("dbusmenu_menuitem_child_append");
+ fp_dbusmenu_menuitem_child_delete = dl_symbol("dbusmenu_menuitem_child_delete");
+ fp_dbusmenu_menuitem_take_children = dl_symbol("dbusmenu_menuitem_take_children");
+ fp_dbusmenu_menuitem_foreach = dl_symbol("dbusmenu_menuitem_foreach");
+ fp_unity_launcher_entry_set_quicklist = dl_symbol("unity_launcher_entry_set_quicklist");
+ fp_unity_launcher_entry_get_quicklist = dl_symbol("unity_launcher_entry_get_quicklist");
+ } else {
+ dlclose(unity_libhandle);
+ unity_libhandle = NULL;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void callback(DbusmenuMenuitem* mi, guint ts, jobject data) {
+ JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ (*env)->CallStaticVoidMethod(env, jTaskbarCls, jTaskbarCallback, data,
+ fp_dbusmenu_menuitem_property_get_int(mi, "toggle-state")
+ ? JNI_FALSE
+ : JNI_TRUE);
+}
+
+/*
+ * Class: sun_awt_X11_XTaskbarPeer
+ * Method: init
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_awt_X11_XTaskbarPeer_init
+(JNIEnv *env, jclass cls, jstring jname) {
+ jclass clazz;
+
+ jTaskbarCls = (*env)->NewGlobalRef(env, cls);
+
+ CHECK_NULL_RETURN(jTaskbarCallback =
+ (*env)->GetStaticMethodID(env, cls, "menuItemCallback", "(Ljava/awt/MenuItem;)V"), JNI_FALSE);
+ CHECK_NULL_RETURN(
+ clazz = (*env)->FindClass(env, "java/awt/MenuItem"), JNI_FALSE);
+ CHECK_NULL_RETURN(
+ jMenuItemGetLabel = (*env)->GetMethodID(env, clazz, "getLabel", "()Ljava/lang/String;"), JNI_FALSE);
+
+ if (gtk2_load(env) && unity_load()) {
+ const gchar* name = (*env)->GetStringUTFChars(env, jname, NULL);
+ if (name) {
+ entry = fp_unity_launcher_entry_get_for_desktop_file(name);
+ (*env)->ReleaseStringUTFChars(env, jname, name);
+ return JNI_TRUE;
+ }
+ }
+ return JNI_FALSE;
+}
+
+/*
+ * Class: sun_awt_X11_XTaskbarPeer
+ * Method: runloop
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_runloop
+(JNIEnv *env, jclass cls) {
+ fp_gdk_threads_enter();
+ fp_gtk_main();
+ fp_gdk_threads_leave();
+}
+
+/*
+ * Class: sun_awt_X11_XTaskbarPeer
+ * Method: setBadge
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setBadge
+(JNIEnv *env, jobject obj, jlong value, jboolean visible) {
+ fp_gdk_threads_enter();
+ fp_unity_launcher_entry_set_count(entry, value);
+ fp_unity_launcher_entry_set_count_visible(entry, visible);
+ DbusmenuMenuitem* m;
+ if (m = fp_unity_launcher_entry_get_quicklist(entry)) {
+ fp_unity_launcher_entry_set_quicklist(entry, m);
+ }
+ fp_gdk_threads_leave();
+}
+
+/*
+ * Class: sun_awt_X11_XTaskbarPeer
+ * Method: setUrgent
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setUrgent
+(JNIEnv *env, jobject obj, jboolean urgent) {
+ fp_gdk_threads_enter();
+ fp_unity_launcher_entry_set_urgent(entry, urgent);
+ DbusmenuMenuitem* m;
+ if (m = fp_unity_launcher_entry_get_quicklist(entry)) {
+ fp_unity_launcher_entry_set_quicklist(entry, m);
+ }
+ fp_gdk_threads_leave();
+}
+
+/*
+ * Class: sun_awt_X11_XTaskbarPeer
+ * Method: updateProgress
+ * Signature: (DZ)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_updateProgress
+(JNIEnv *env, jobject obj, jdouble value, jboolean visible) {
+ fp_gdk_threads_enter();
+ fp_unity_launcher_entry_set_progress(entry, value);
+ fp_unity_launcher_entry_set_progress_visible(entry, visible);
+ DbusmenuMenuitem* m;
+ if (m = fp_unity_launcher_entry_get_quicklist(entry)) {
+ fp_unity_launcher_entry_set_quicklist(entry, m);
+ }
+ fp_gdk_threads_leave();
+}
+
+void deleteGlobalRef(gpointer data) {
+ JNIEnv* env = (JNIEnv*) JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ (*env)->DeleteGlobalRef(env, data);
+}
+
+void fill_menu(JNIEnv *env, jobjectArray items) {
+ int index;
+ jsize length = (*env)->GetArrayLength(env, items);
+ for (index = 0; index < length; index++) {
+ jobject elem = (*env)->GetObjectArrayElement(env, items, index);
+ if ((*env)->ExceptionCheck(env)) {
+ break;
+ }
+ elem = (*env)->NewGlobalRef(env, elem);
+
+ globalRefs = fp_g_list_append(globalRefs, elem);
+
+ jstring jlabel = (jstring) (*env)->CallObjectMethod(env, elem, jMenuItemGetLabel);
+ if (!(*env)->ExceptionCheck(env) && jlabel) {
+ const gchar* label = (*env)->GetStringUTFChars(env, jlabel, NULL);
+ if (label) {
+ DbusmenuMenuitem* mi = fp_dbusmenu_menuitem_new();
+ if (!strcmp(label, "-")) {
+ fp_dbusmenu_menuitem_property_set(mi, "type", "separator");
+ } else {
+ fp_dbusmenu_menuitem_property_set(mi, "label", label);
+ }
+
+ (*env)->ReleaseStringUTFChars(env, jlabel, label);
+ fp_dbusmenu_menuitem_child_append(menu, mi);
+ fp_g_signal_connect(mi, "item_activated", G_CALLBACK(callback), elem);
+ }
+ }
+ }
+}
+
+/*
+ * Class: sun_awt_X11_XTaskbarPeer
+ * Method: setNativeMenu
+ * Signature: ([Ljava/awt/MenuItem;)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_X11_XTaskbarPeer_setNativeMenu
+(JNIEnv *env, jobject obj, jobjectArray items) {
+
+ fp_gdk_threads_enter();
+
+ if (!menu) {
+ menu = fp_dbusmenu_menuitem_new();
+ }
+
+ fp_unity_launcher_entry_set_quicklist(entry, menu);
+
+ GList* list = fp_dbusmenu_menuitem_take_children(menu);
+ fp_g_list_free_full(list, fp_g_object_unref);
+
+ fp_g_list_free_full(globalRefs, deleteGlobalRef);
+ globalRefs = NULL;
+
+ if (items) {
+ fill_menu(env, items);
+ }
+
+ fp_gdk_threads_leave();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/awt_Taskbar.h Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, 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 thats
+ * 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.
+ */
+
+#ifndef AWT_TASKBAR_H
+#define AWT_TASKBAR_H
+
+#include "gtk2_interface.h"
+
+typedef void UnityLauncherEntry;
+typedef void DbusmenuMenuitem;
+
+static UnityLauncherEntry* (*fp_unity_launcher_entry_get_for_desktop_file) (const gchar* desktop_file);
+
+static void (*fp_unity_launcher_entry_set_count) (UnityLauncherEntry* self, gint64 value);
+static void (*fp_unity_launcher_entry_set_count_visible) (UnityLauncherEntry* self, gboolean value);
+
+static void (*fp_unity_launcher_entry_set_urgent) (UnityLauncherEntry* self, gboolean value);
+
+static void (*fp_unity_launcher_entry_set_progress) (UnityLauncherEntry* self, gdouble value);
+static void (*fp_unity_launcher_entry_set_progress_visible) (UnityLauncherEntry* self, gboolean value);
+
+
+static DbusmenuMenuitem* (*fp_dbusmenu_menuitem_new) (void);
+static gboolean (*fp_dbusmenu_menuitem_property_set) (DbusmenuMenuitem* mi, const gchar* property, const gchar* value);
+static gboolean (*fp_dbusmenu_menuitem_property_set_int) (DbusmenuMenuitem * mi, const gchar * property, const gint value);
+static gint (*fp_dbusmenu_menuitem_property_get_int) (const DbusmenuMenuitem * mi, const gchar * property);
+static gboolean (*fp_dbusmenu_menuitem_child_append) (DbusmenuMenuitem* mi, DbusmenuMenuitem* child);
+static gboolean (*fp_dbusmenu_menuitem_child_delete) (DbusmenuMenuitem * mi, DbusmenuMenuitem * child);
+static GList * (*fp_dbusmenu_menuitem_take_children) (DbusmenuMenuitem * mi);
+static void (*fp_dbusmenu_menuitem_foreach) (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem * mi, gpointer data), gpointer data);
+static void (*fp_unity_launcher_entry_set_quicklist) (UnityLauncherEntry* self, DbusmenuMenuitem* value);
+static DbusmenuMenuitem* (*fp_unity_launcher_entry_get_quicklist) (UnityLauncherEntry* self);
+
+
+#endif /* AWT_TASKBAR_H */
+
--- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_config.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_config.h Thu Apr 07 11:03:59 2016 -0700
@@ -39,6 +39,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include "systemScale.h"
typedef uint32_t rgbquad_t;
typedef uint16_t word_t;
@@ -57,5 +58,4 @@
#define INLINE static
#define SPLASHEXPORT
-
#endif
--- a/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/unix/native/libsplashscreen/splashscreen_sys.c Thu Apr 07 11:03:59 2016 -0700
@@ -797,10 +797,60 @@
sendctl(splash, SPLASHCTL_RECONFIGURE);
}
-SPLASHEXPORT char*
+SPLASHEXPORT jboolean
SplashGetScaledImageName(const char* jarName, const char* fileName,
- float *scaleFactor)
+ float *scaleFactor, char *scaledImgName,
+ const size_t scaledImageNameLength)
{
*scaleFactor = 1;
- return NULL;
+#ifndef __linux__
+ return JNI_FALSE;
+#endif
+ *scaleFactor = getNativeScaleFactor();
+ if (*scaleFactor == 2.0) {
+ size_t length = 0;
+ char *stringToAppend = ".java-scale2x";
+ char *dupFileName = strdup(fileName);
+ char *fileExtension = strrchr(dupFileName, '.');
+ if (fileExtension == NULL) {
+ length = strlen(dupFileName) + strlen(stringToAppend) + 1;
+ if (length > scaledImageNameLength) {
+ *scaleFactor = 1;
+ free(dupFileName);
+ return JNI_FALSE;
+ }
+ int retVal = snprintf(scaledImgName, length, "%s%s",
+ dupFileName, stringToAppend);
+ if (retVal < 0 || (retVal != length - 1)) {
+ free(dupFileName);
+ *scaleFactor = 1;
+ return JNI_FALSE;
+ }
+ } else {
+ int length_without_ext = fileExtension - dupFileName;
+ length = length_without_ext +
+ strlen(stringToAppend) + strlen(fileExtension) + 1;
+ if (length > scaledImageNameLength) {
+ *scaleFactor = 1;
+ free(dupFileName);
+ return JNI_FALSE;
+ }
+ int retVal = snprintf(scaledImgName, length, "%.*s%s%s",
+ length_without_ext, dupFileName, stringToAppend, fileExtension);
+ if (retVal < 0 || retVal != length - 1) {
+ free(dupFileName);
+ *scaleFactor = 1;
+ return JNI_FALSE;
+ }
+ }
+ free(dupFileName);
+ FILE *fp;
+ if (!(fp = fopen(scaledImgName, "r"))) {
+ *scaleFactor = 1;
+ return JNI_FALSE;
+ }
+ fclose(fp);
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WDesktopPeer.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WDesktopPeer.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,10 +27,19 @@
import java.awt.Desktop.Action;
+import java.awt.EventQueue;
+import java.awt.desktop.SystemEventListener;
+import java.awt.desktop.SystemSleepEvent;
+import java.awt.desktop.SystemSleepListener;
+import java.awt.desktop.UserSessionEvent;
+import java.awt.desktop.UserSessionEvent.Reason;
+import java.awt.desktop.UserSessionListener;
import java.awt.peer.DesktopPeer;
import java.io.File;
import java.io.IOException;
import java.net.URI;
+import javax.swing.event.EventListenerList;
+import sun.awt.OSInfo;
/**
@@ -45,10 +54,33 @@
private static String ACTION_EDIT_VERB = "edit";
private static String ACTION_PRINT_VERB = "print";
+ private static boolean isEventUserSessionSupported = false;
+
+ private static native void init();
+
+ WDesktopPeer() {
+ init();
+ isEventUserSessionSupported = OSInfo.getWindowsVersion()
+ .compareTo(OSInfo.WINDOWS_VISTA) >= 0;
+ }
+
@Override
public boolean isSupported(Action action) {
- // OPEN, EDIT, PRINT, MAIL, BROWSE all supported on windows.
- return true;
+ switch(action) {
+ case OPEN:
+ case EDIT:
+ case PRINT:
+ case MAIL:
+ case BROWSE:
+ case MOVE_TO_TRASH:
+ case APP_SUDDEN_TERMINATION:
+ case APP_EVENT_SYSTEM_SLEEP:
+ return true;
+ case APP_EVENT_USER_SESSION:
+ return isEventUserSessionSupported;
+ default:
+ return false;
+ }
}
@Override
@@ -94,4 +126,70 @@
private static native String ShellExecute(String fileOrUri, String verb);
+ private static final EventListenerList listenerList = new EventListenerList();
+
+ @Override
+ public void disableSuddenTermination() {
+ setSuddenTerminationEnabled(false);
+ }
+
+ @Override
+ public void enableSuddenTermination() {
+ setSuddenTerminationEnabled(true);
+ }
+
+ private static native void setSuddenTerminationEnabled(boolean enable);
+
+ @Override
+ public void addAppEventListener(final SystemEventListener listener) {
+ if (listener instanceof UserSessionListener) {
+ listenerList.add(UserSessionListener.class, (UserSessionListener) listener);
+ }
+ if (listener instanceof SystemSleepListener) {
+ listenerList.add(SystemSleepListener.class, (SystemSleepListener) listener);
+ }
+ }
+
+ @Override
+ public void removeAppEventListener(final SystemEventListener listener) {
+ if (listener instanceof UserSessionListener) {
+ listenerList.remove(UserSessionListener.class, (UserSessionListener) listener);
+ }
+ if (listener instanceof SystemSleepListener) {
+ listenerList.remove(SystemSleepListener.class, (SystemSleepListener) listener);
+ }
+ }
+
+ private static void userSessionCallback(boolean activated, Reason reason) {
+ UserSessionListener[] listeners = listenerList.getListeners(UserSessionListener.class);
+ for (UserSessionListener use : listeners) {
+ EventQueue.invokeLater(() -> {
+ if (activated) {
+ use.userSessionActivated(new UserSessionEvent(reason));
+ } else {
+ use.userSessionDeactivated(new UserSessionEvent(reason));
+ }
+ });
+ }
+ }
+
+ private static void systemSleepCallback(boolean resumed) {
+ SystemSleepListener[] listeners = listenerList.getListeners(SystemSleepListener.class);
+ for (SystemSleepListener ssl : listeners) {
+ EventQueue.invokeLater(() -> {
+ if (resumed) {
+ ssl.systemAwoke(new SystemSleepEvent());
+ } else {
+ ssl.systemAboutToSleep(new SystemSleepEvent());
+ }
+ });
+ }
+ }
+
+ @Override
+ public boolean moveToTrash(File file) {
+ return moveToTrash(file.getAbsolutePath());
+ }
+ private static native boolean moveToTrash(String file);
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTaskbarPeer.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016, 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 sun.awt.windows;
+
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Taskbar.Feature;
+import java.awt.Taskbar.State;
+import java.awt.peer.TaskbarPeer;
+import java.awt.Window;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import sun.awt.AWTAccessor;
+import sun.awt.OSInfo;
+import sun.awt.shell.ShellFolder;
+
+final class WTaskbarPeer implements TaskbarPeer {
+
+ private static boolean supported = false;
+ private static boolean initExecuted = false;
+
+ private static synchronized void init() {
+ if (!initExecuted) {
+ supported = OSInfo.getWindowsVersion()
+ .compareTo(OSInfo.WINDOWS_7) >= 0
+ && ShellFolder.invoke(() -> nativeInit());
+ }
+ initExecuted = true;
+ }
+
+ static boolean isTaskbarSupported() {
+ init();
+ return supported;
+ }
+
+ WTaskbarPeer() {
+ init();
+ }
+
+ @Override
+ public boolean isSupported(Feature feature) {
+ switch(feature) {
+ case ICON_BADGE_IMAGE_WINDOW:
+ case PROGRESS_STATE_WINDOW:
+ case PROGRESS_VALUE_WINDOW:
+ return supported;
+ case USER_ATTENTION_WINDOW:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private static int[] imageToArray(Image image) {
+ if (image == null) {
+ return null;
+ }
+
+ int w = image.getWidth(null);
+ int h = image.getHeight(null);
+
+ if (w < 0 || h < 0) {
+ return null;
+ }
+
+ BufferedImage bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
+ Graphics2D g2 = bimg.createGraphics();
+ g2.setComposite(AlphaComposite.Src);
+ g2.drawImage(image, 0, 0, null);
+ g2.dispose();
+
+ return ((DataBufferInt) bimg.getRaster().getDataBuffer()).getData();
+ }
+
+ @Override
+ public void setWindowIconBadge(Window window, final Image image) {
+ WWindowPeer wp = AWTAccessor.getComponentAccessor().getPeer(window);
+ if (wp != null) {
+ int[] buffer = imageToArray(image);
+ ShellFolder.invoke(() -> {
+ setOverlayIcon(wp.getHWnd(), buffer,
+ buffer != null ? image.getWidth(null) : 0,
+ buffer != null ? image.getHeight(null) : 0);
+ return null;
+ });
+ }
+ }
+
+ @Override
+ public void requestWindowUserAttention(Window window) {
+ WWindowPeer wp = AWTAccessor.getComponentAccessor().getPeer(window);
+ if (wp != null) {
+ flashWindow(wp.getHWnd());
+ }
+ }
+
+ @Override
+ public void setWindowProgressValue(Window window, int value) {
+ WWindowPeer wp = AWTAccessor.getComponentAccessor().getPeer(window);
+ if (wp != null) {
+ ShellFolder.invoke(() -> {
+ setProgressValue(wp.getHWnd(), value);
+ return null;
+ });
+ }
+ }
+
+ @Override
+ public void setWindowProgressState(Window window, State state) {
+ WWindowPeer wp = AWTAccessor.getComponentAccessor().getPeer(window);
+ if (wp != null) {
+ ShellFolder.invoke(() -> {
+ setProgressState(wp.getHWnd(), state);
+ return null;
+ });
+ }
+ }
+
+ private static native boolean nativeInit();
+
+ private native void setProgressValue(long hwnd, int value);
+
+ private native void setProgressState(long hwnd, State state);
+
+ private native void setOverlayIcon(long hwnd, int[] badge, int width, int height);
+
+ private native void flashWindow(long hWnd);
+
+}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -25,6 +25,7 @@
package sun.awt.windows;
+import java.awt.peer.TaskbarPeer;
import java.awt.*;
import java.awt.im.InputMethodHighlight;
import java.awt.im.spi.InputMethodDescriptor;
@@ -1131,6 +1132,7 @@
@Override
public native boolean syncNativeQueue(final long timeout);
+
@Override
public boolean isDesktopSupported() {
return true;
@@ -1141,6 +1143,16 @@
return new WDesktopPeer();
}
+ @Override
+ public boolean isTaskbarSupported() {
+ return WTaskbarPeer.isTaskbarSupported();
+ }
+
+ @Override
+ public TaskbarPeer createTaskbarPeer(Taskbar target) {
+ return new WTaskbarPeer();
+ }
+
private static native void setExtraMouseButtonsEnabledNative(boolean enable);
@Override
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DSurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -703,20 +703,13 @@
}
@Override
- public boolean copyArea(SunGraphics2D sg2d,
- int x, int y, int w, int h, int dx, int dy)
- {
- if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
- sg2d.compositeState < SunGraphics2D.COMP_XOR)
- {
- x += sg2d.transX;
- y += sg2d.transY;
-
- d3dRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
-
- return true;
+ public boolean copyArea(SunGraphics2D sg2d, int x, int y, int w, int h,
+ int dx, int dy) {
+ if (sg2d.compositeState >= SunGraphics2D.COMP_XOR) {
+ return false;
}
- return false;
+ d3dRenderPipe.copyArea(sg2d, x, y, w, h, dx, dy);
+ return true;
}
@Override
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java Thu Apr 07 11:03:59 2016 -0700
@@ -311,13 +311,10 @@
int x, int y, int w, int h, int dx, int dy)
{
CompositeType comptype = sg2d.imageComp;
- if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE &&
- sg2d.clipState != SunGraphics2D.CLIP_SHAPE &&
+ if (sg2d.clipState != SunGraphics2D.CLIP_SHAPE &&
(CompositeType.SrcOverNoEa.equals(comptype) ||
CompositeType.SrcNoEa.equals(comptype)))
{
- x += sg2d.transX;
- y += sg2d.transY;
int dstx1 = x + dx;
int dsty1 = y + dy;
int dstx2 = dstx1 + w;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+#include "systemScale.h"
+#include <d2d1.h>
+#pragma comment(lib, "d2d1")
+#include <jdk_util.h>
+#ifndef MDT_EFFECTIVE_DPI
+#define MDT_EFFECTIVE_DPI 0
+#endif
+
+void GetScreenDpi(HMONITOR hmon, float *dpiX, float *dpiY)
+{
+ unsigned x = 0;
+ unsigned y = 0;
+
+ // for debug purposes
+ static float scale = -2.0f;
+ if (scale == -2) {
+ scale = -1;
+ char *uiScale = getenv("J2D_UISCALE");
+ if (uiScale != NULL) {
+ scale = (float)strtod(uiScale, NULL);
+ if (errno == ERANGE || scale <= 0) {
+ scale = -1;
+ }
+ }
+ }
+
+ if (scale > 0) {
+ *dpiX = *dpiY = scale;
+ return;
+ }
+
+ typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*);
+ static HMODULE hLibSHCoreDll = NULL;
+ static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL;
+
+ if (hLibSHCoreDll == NULL) {
+ hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll");
+ if (hLibSHCoreDll != NULL) {
+ lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress(
+ hLibSHCoreDll, "GetDpiForMonitor");
+ }
+ }
+
+ if (lpGetDpiForMonitor != NULL) {
+ HRESULT hResult = lpGetDpiForMonitor(hmon,
+ MDT_EFFECTIVE_DPI, &x, &y);
+ if (hResult == S_OK) {
+ *dpiX = static_cast<float>(x);
+ *dpiY = static_cast<float>(y);
+ }
+ } else {
+ ID2D1Factory* m_pDirect2dFactory;
+ HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
+ &m_pDirect2dFactory);
+ if (res == S_OK) {
+ m_pDirect2dFactory->GetDesktopDpi(dpiX, dpiY);
+ m_pDirect2dFactory->Release();
+ }
+ }
+ return;
+}
+
+HMONITOR WINAPI getPrimaryMonitor()
+{
+ const POINT point = { 0, 0 };
+ return MonitorFromPoint(point, MONITOR_DEFAULTTOPRIMARY);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/native/common/awt/systemscale/systemScale.h Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*/
+#ifndef _AWT_SYSTEM_SCALE_H
+#define _AWT_SYSTEM_SCALE_H
+#include <windows.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void GetScreenDpi(HMONITOR mon, float *dpiX, float *dpiY);
+ HMONITOR WINAPI getPrimaryMonitor();
+#ifdef __cplusplus
+}
+#endif
+#endif
--- a/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -31,6 +31,8 @@
#include "awt_Object.h"
#include "awt_Component.h"
+#include "math.h"
+
// Important note about VC6 and VC7 (or XP Platform SDK) !
//
// These type definitions have been imported from UxTheme.h
@@ -68,6 +70,11 @@
#define TMT_TRANSPARENT 2201
#endif // _UXTHEME_H_
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+# define ROUND_TO_INT(num) ((int) round(num))
+#else
+# define ROUND_TO_INT(num) ((int) floor((num) + 0.5))
+#endif
#define ALPHA_MASK 0xff000000
#define RED_MASK 0xff0000
@@ -745,6 +752,23 @@
return NULL;
}
+void rescale(SIZE *size) {
+ HWND hWnd = ::GetDesktopWindow();
+ HDC hDC = ::GetDC(hWnd);
+ int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
+ int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
+
+ if (dpiX !=0 && dpiX != 96) {
+ float invScaleX = 96.0f / dpiX;
+ size->cx = ROUND_TO_INT(size->cx * invScaleX);
+ }
+ if (dpiY != 0 && dpiY != 96) {
+ float invScaleY = 96.0f / dpiY;
+ size->cy = ROUND_TO_INT(size->cy * invScaleY);
+ }
+ ::ReleaseDC(hWnd, hDC);
+}
+
/*
* Class: sun_awt_windows_ThemeReader
* Method: getPartSize
@@ -770,6 +794,8 @@
dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
CHECK_NULL_RETURN(dimMID, NULL);
}
+
+ rescale(&size);
jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
if (safe_ExceptionOccurred(env)) {
env->ExceptionDescribe();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Desktop.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -28,6 +28,18 @@
#include <jni.h>
#include <shellapi.h>
#include <float.h>
+#include <shlobj.h>
+#include "awt_Toolkit.h"
+
+#define BUFFER_LIMIT MAX_PATH+1
+
+#define NOTIFY_FOR_ALL_SESSIONS 1
+#define NOTIFY_FOR_THIS_SESSION 0
+
+typedef BOOL (WINAPI *WTSRegisterSessionNotification)(HWND,DWORD);
+static WTSRegisterSessionNotification fn_WTSRegisterSessionNotification;
+
+BOOL isSuddenTerminationEnabled = TRUE;
#ifdef __cplusplus
extern "C" {
@@ -35,6 +47,28 @@
/*
* Class: sun_awt_windows_WDesktopPeer
+ * Method: init
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WDesktopPeer_init
+ (JNIEnv *, jclass) {
+ static HMODULE libWtsapi32 = NULL;
+ if (libWtsapi32 == NULL) {
+ libWtsapi32 = JDK_LoadSystemLibrary("Wtsapi32.dll");
+ if (libWtsapi32) {
+ fn_WTSRegisterSessionNotification = (WTSRegisterSessionNotification)
+ GetProcAddress(libWtsapi32, "WTSRegisterSessionNotification");
+ if (fn_WTSRegisterSessionNotification) {
+ HWND hwnd = AwtToolkit::GetInstance().GetHWnd();
+ //used for UserSessionListener
+ fn_WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION);
+ }
+ }
+ }
+}
+
+/*
+ * Class: sun_awt_windows_WDesktopPeer
* Method: ShellExecute
* Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
@@ -82,6 +116,53 @@
return NULL;
}
+/*
+ * Class: sun_awt_windows_WDesktopPeer
+ * Method: moveToTrash
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WDesktopPeer_moveToTrash
+ (JNIEnv *env, jclass, jstring jpath)
+{
+ LPCTSTR pathStr = JNU_GetStringPlatformChars(env, jpath, (jboolean *)NULL);
+ if (pathStr) {
+ try {
+ LPTSTR fileBuffer = new TCHAR[BUFFER_LIMIT];
+ memset(fileBuffer, 0, BUFFER_LIMIT * sizeof(TCHAR));
+ // the fileBuffer is double null terminated string
+ _tcsncpy(fileBuffer, pathStr, BUFFER_LIMIT - 2);
+
+ SHFILEOPSTRUCT fop;
+ memset(&fop, 0, sizeof(SHFILEOPSTRUCT));
+ fop.hwnd = NULL;
+ fop.wFunc = FO_DELETE;
+ fop.pFrom = fileBuffer;
+ fop.fFlags = FOF_ALLOWUNDO;
+
+ int res = SHFileOperation(&fop);
+
+ delete[] fileBuffer;
+ JNU_ReleaseStringPlatformChars(env, jpath, pathStr);
+
+ return !res ? JNI_TRUE : JNI_FALSE;
+ } catch (std::bad_alloc&) {
+ JNU_ReleaseStringPlatformChars(env, jpath, pathStr);
+ }
+ }
+ return JNI_FALSE;
+}
+
+/*
+ * Class: sun_awt_windows_WDesktopPeer
+ * Method: setSuddenTerminationEnabled
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WDesktopPeer_setSuddenTerminationEnabled
+ (JNIEnv *, jclass, jboolean enabled)
+{
+ isSuddenTerminationEnabled = enabled;
+}
+
#ifdef __cplusplus
}
#endif
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -35,6 +35,14 @@
#include <shellapi.h>
#include <shlobj.h>
+#include "math.h"
+
+#if defined(_MSC_VER) && _MSC_VER >= 1800
+# define ROUND_TO_INT(num) ((int) round(num))
+#else
+# define ROUND_TO_INT(num) ((int) floor((num) + 0.5))
+#endif
+
// WDesktopProperties fields
jfieldID AwtDesktopProperties::pDataID = 0;
jmethodID AwtDesktopProperties::setBooleanPropertyID = 0;
@@ -79,18 +87,35 @@
}
}
+void getInvScale(float &invScaleX, float &invScaleY) {
+ HWND hWnd = ::GetDesktopWindow();
+ HDC hDC = ::GetDC(hWnd);
+ int dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
+ int dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
+ ::ReleaseDC(hWnd, hDC);
+ invScaleX = (dpiX == 0.0f) ? 1.0f : 96.0f / dpiX;
+ invScaleY = (dpiY == 0.0f) ? 1.0f : 96.0f / dpiY;
+}
+
+int rescale(int value, float invScale){
+ return invScale == 1.0f ? value : ROUND_TO_INT(value * invScale);
+}
+
void AwtDesktopProperties::GetSystemProperties() {
HDC dc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
if (dc != NULL) {
try {
- SetFontProperty(dc, ANSI_FIXED_FONT, TEXT("win.ansiFixed.font"));
- SetFontProperty(dc, ANSI_VAR_FONT, TEXT("win.ansiVar.font"));
- SetFontProperty(dc, DEVICE_DEFAULT_FONT, TEXT("win.deviceDefault.font"));
- SetFontProperty(dc, DEFAULT_GUI_FONT, TEXT("win.defaultGUI.font"));
- SetFontProperty(dc, OEM_FIXED_FONT, TEXT("win.oemFixed.font"));
- SetFontProperty(dc, SYSTEM_FONT, TEXT("win.system.font"));
- SetFontProperty(dc, SYSTEM_FIXED_FONT, TEXT("win.systemFixed.font"));
+ float invScaleX;
+ float invScaleY;
+ getInvScale(invScaleX, invScaleY);
+ SetFontProperty(dc, ANSI_FIXED_FONT, TEXT("win.ansiFixed.font"), 1.0f);
+ SetFontProperty(dc, ANSI_VAR_FONT, TEXT("win.ansiVar.font"), 1.0f);
+ SetFontProperty(dc, DEVICE_DEFAULT_FONT, TEXT("win.deviceDefault.font"), 1.0f);
+ SetFontProperty(dc, DEFAULT_GUI_FONT, TEXT("win.defaultGUI.font"), invScaleY);
+ SetFontProperty(dc, OEM_FIXED_FONT, TEXT("win.oemFixed.font"), 1.0f);
+ SetFontProperty(dc, SYSTEM_FONT, TEXT("win.system.font"), 1.0f);
+ SetFontProperty(dc, SYSTEM_FIXED_FONT, TEXT("win.systemFixed.font"), 1.0f);
}
catch (std::bad_alloc&) {
DeleteDC(dc);
@@ -266,31 +291,35 @@
}
VERIFY( SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncmetrics.cbSize, &ncmetrics, FALSE) );
- SetFontProperty( TEXT("win.frame.captionFont"), ncmetrics.lfCaptionFont );
- SetIntegerProperty( TEXT("win.frame.captionHeight"), ncmetrics.iCaptionHeight );
- SetIntegerProperty( TEXT("win.frame.captionButtonWidth"), ncmetrics.iCaptionWidth );
- SetIntegerProperty( TEXT("win.frame.captionButtonHeight"), ncmetrics.iCaptionHeight );
- SetFontProperty( TEXT("win.frame.smallCaptionFont"), ncmetrics.lfSmCaptionFont );
- SetIntegerProperty( TEXT("win.frame.smallCaptionHeight"), ncmetrics.iSmCaptionHeight );
- SetIntegerProperty( TEXT("win.frame.smallCaptionButtonWidth"), ncmetrics.iSmCaptionWidth );
- SetIntegerProperty( TEXT("win.frame.smallCaptionButtonHeight"), ncmetrics.iSmCaptionHeight );
- SetIntegerProperty( TEXT("win.frame.sizingBorderWidth"), ncmetrics.iBorderWidth );
+ float invScaleX;
+ float invScaleY;
+ getInvScale(invScaleX, invScaleY);
+
+ SetFontProperty(TEXT("win.frame.captionFont"), ncmetrics.lfCaptionFont, invScaleY);
+ SetIntegerProperty(TEXT("win.frame.captionHeight"), rescale(ncmetrics.iCaptionHeight, invScaleY));
+ SetIntegerProperty(TEXT("win.frame.captionButtonWidth"), rescale(ncmetrics.iCaptionWidth, invScaleX));
+ SetIntegerProperty(TEXT("win.frame.captionButtonHeight"), rescale(ncmetrics.iCaptionHeight, invScaleY));
+ SetFontProperty(TEXT("win.frame.smallCaptionFont"), ncmetrics.lfSmCaptionFont, invScaleY);
+ SetIntegerProperty(TEXT("win.frame.smallCaptionHeight"), rescale(ncmetrics.iSmCaptionHeight, invScaleY));
+ SetIntegerProperty(TEXT("win.frame.smallCaptionButtonWidth"), rescale(ncmetrics.iSmCaptionWidth, invScaleX));
+ SetIntegerProperty(TEXT("win.frame.smallCaptionButtonHeight"), rescale(ncmetrics.iSmCaptionHeight, invScaleY));
+ SetIntegerProperty(TEXT("win.frame.sizingBorderWidth"), rescale(ncmetrics.iBorderWidth, invScaleX));
// menu properties
- SetFontProperty( TEXT("win.menu.font"), ncmetrics.lfMenuFont );
- SetIntegerProperty( TEXT("win.menu.height"), ncmetrics.iMenuHeight );
- SetIntegerProperty( TEXT("win.menu.buttonWidth"), ncmetrics.iMenuWidth );
+ SetFontProperty(TEXT("win.menu.font"), ncmetrics.lfMenuFont, invScaleY);
+ SetIntegerProperty(TEXT("win.menu.height"), rescale(ncmetrics.iMenuHeight, invScaleY));
+ SetIntegerProperty(TEXT("win.menu.buttonWidth"), rescale(ncmetrics.iMenuWidth, invScaleX));
// scrollbar properties
- SetIntegerProperty( TEXT("win.scrollbar.width"), ncmetrics.iScrollWidth );
- SetIntegerProperty( TEXT("win.scrollbar.height"), ncmetrics.iScrollHeight );
+ SetIntegerProperty(TEXT("win.scrollbar.width"), rescale(ncmetrics.iScrollWidth, invScaleX));
+ SetIntegerProperty(TEXT("win.scrollbar.height"), rescale(ncmetrics.iScrollHeight, invScaleY));
// status bar and tooltip properties
- SetFontProperty( TEXT("win.status.font"), ncmetrics.lfStatusFont );
- SetFontProperty( TEXT("win.tooltip.font"), ncmetrics.lfStatusFont );
+ SetFontProperty(TEXT("win.status.font"), ncmetrics.lfStatusFont, invScaleY);
+ SetFontProperty(TEXT("win.tooltip.font"), ncmetrics.lfStatusFont, invScaleY);
// message box properties
- SetFontProperty( TEXT("win.messagebox.font"), ncmetrics.lfMessageFont );
+ SetFontProperty(TEXT("win.messagebox.font"), ncmetrics.lfMessageFont, invScaleY);
}
void AwtDesktopProperties::GetIconParameters() {
@@ -302,10 +331,13 @@
iconmetrics.cbSize = sizeof(iconmetrics);
VERIFY( SystemParametersInfo(SPI_GETICONMETRICS, iconmetrics.cbSize, &iconmetrics, FALSE) );
- SetIntegerProperty(TEXT("win.icon.hspacing"), iconmetrics.iHorzSpacing);
- SetIntegerProperty(TEXT("win.icon.vspacing"), iconmetrics.iVertSpacing);
+ float invScaleX;
+ float invScaleY;
+ getInvScale(invScaleX, invScaleY);
+ SetIntegerProperty(TEXT("win.icon.hspacing"), rescale(iconmetrics.iHorzSpacing, invScaleX));
+ SetIntegerProperty(TEXT("win.icon.vspacing"), rescale(iconmetrics.iVertSpacing, invScaleY));
SetBooleanProperty(TEXT("win.icon.titleWrappingOn"), iconmetrics.iTitleWrap != 0);
- SetFontProperty(TEXT("win.icon.font"), iconmetrics.lfFont);
+ SetFontProperty(TEXT("win.icon.font"), iconmetrics.lfFont, invScaleY);
}
/*
Windows settings for these are also in the registry
@@ -718,6 +750,7 @@
}
void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
+
jstring key = JNU_NewStringPlatform(GetEnv(), propName);
if (key == NULL) {
throw std::bad_alloc();
@@ -752,8 +785,8 @@
}
void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
- LPCTSTR propName) {
- HGDIOBJ font = GetStockObject(fontID);
+ LPCTSTR propName, float invScale) {
+ HGDIOBJ font = GetStockObject(fontID);
if (font != NULL && SelectObject(dc, font) != NULL) {
int length = GetTextFace(dc, 0, NULL);
@@ -789,8 +822,8 @@
throw std::bad_alloc();
}
- jint pointSize = metrics.tmHeight -
- metrics.tmInternalLeading;
+ jint pointSize = rescale(metrics.tmHeight -
+ metrics.tmInternalLeading, invScale);
jint style = java_awt_Font_PLAIN;
if (metrics.tmWeight >= FW_BOLD) {
@@ -818,7 +851,8 @@
}
}
-void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font) {
+void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font,
+ float invScale) {
jstring fontName;
jint pointSize;
jint style;
@@ -836,7 +870,7 @@
ReleaseDC(NULL, hdc);
#endif
// Java uses point sizes, but assumes 1 pixel = 1 point
- pointSize = -font.lfHeight;
+ pointSize = rescale(-font.lfHeight, invScale);
// convert Windows font style to Java style
style = java_awt_Font_PLAIN;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DesktopProperties.h Thu Apr 07 11:03:59 2016 -0700
@@ -73,8 +73,8 @@
void SetIntegerProperty(LPCTSTR, int);
void SetStringProperty(LPCTSTR, LPTSTR);
void SetColorProperty(LPCTSTR, DWORD);
- void SetFontProperty(HDC, int, LPCTSTR);
- void SetFontProperty(LPCTSTR, const LOGFONT &);
+ void SetFontProperty(HDC, int, LPCTSTR, float invScale);
+ void SetFontProperty(LPCTSTR, const LOGFONT &, float invScale);
void SetSoundProperty(LPCTSTR, LPCTSTR);
JNIEnv * GetEnv() {
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDT.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -127,6 +127,16 @@
return (ULONG)refs;
}
+void ScaleDown(POINT &cp, HWND m_window) {
+ int screen = AwtWin32GraphicsDevice::DeviceIndexForWindow(m_window);
+ Devices::InstanceAccess devices;
+ AwtWin32GraphicsDevice* device = devices->GetDevice(screen);
+ if (device) {
+ cp.x = device->ScaleDownX(cp.x);
+ cp.y = device->ScaleDownY(cp.y);
+ }
+}
+
/**
* DragEnter
*/
@@ -176,6 +186,7 @@
cp.x = pt.x - wr.left;
cp.y = pt.y - wr.top;
+ ScaleDown(cp, m_window);
jint actions = call_dTCenter(env, m_dtcp, m_target,
(jint)cp.x, (jint)cp.y,
@@ -237,6 +248,7 @@
cp.x = pt.x - wr.left;
cp.y = pt.y - wr.top;
+ ScaleDown(cp, m_window);
actions = call_dTCmotion(env, m_dtcp, m_target,(jint)cp.x, (jint)cp.y,
::convertDROPEFFECTToActions(mapModsToDROPEFFECT(*pdwEffect, grfKeyState)),
@@ -336,6 +348,7 @@
cp.x = pt.x - wr.left;
cp.y = pt.y - wr.top;
+ ScaleDown(cp, m_window);
m_dropActions = java_awt_dnd_DnDConstants_ACTION_NONE;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -770,6 +770,10 @@
AwtPrintControl::getMinPageID);
jint maxPage = env->CallIntMethod(printCtrl,
AwtPrintControl::getMaxPageID);
+
+ jint selectType = env->CallIntMethod(printCtrl,
+ AwtPrintControl::getSelectID);
+
pd.nMaxPage = (maxPage <= (jint)((WORD)-1)) ? (WORD)maxPage : (WORD)-1;
// In the event that the application displays the dialog before
// installing a Printable, but sets a page range, then max page will be 1
@@ -779,8 +783,12 @@
// So if we detect this fix up such a problem here.
if (pd.nMinPage > pd.nFromPage) pd.nMinPage = pd.nFromPage;
if (pd.nMaxPage < pd.nToPage) pd.nMaxPage = pd.nToPage;
- if (pd.nFromPage > pd.nMinPage || pd.nToPage < pd.nMaxPage) {
- pd.Flags |= PD_PAGENUMS;
+ if (selectType != 0 && (pd.nFromPage > pd.nMinPage || pd.nToPage < pd.nMaxPage)) {
+ if (selectType == PD_SELECTION) {
+ pd.Flags |= PD_SELECTION;
+ } else {
+ pd.Flags |= PD_PAGENUMS;
+ }
}
if (env->CallBooleanMethod(printCtrl,
@@ -788,9 +796,6 @@
pd.Flags |= PD_PRINTTOFILE;
}
- jint selectType = env->CallIntMethod(printCtrl,
- AwtPrintControl::getSelectID);
-
// selectType identifies whether No selection (2D) or
// SunPageSelection (AWT)
if (selectType != 0) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+#include "jni_util.h"
+#include "awt.h"
+#include <jni.h>
+#include "awt_Taskbar.h"
+#include "awt_Window.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Class: sun_awt_windows_WTaskbarPeer
+ * Method: nativeInit
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WTaskbarPeer_nativeInit
+ (JNIEnv *env, jclass)
+{
+ if (SUCCEEDED(::CoCreateInstance(CLSID_TaskbarList, NULL,
+ CLSCTX_INPROC_SERVER, IID_ITaskbarList, (LPVOID *)&m_Taskbar))) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+/*
+ * Class: sun_awt_windows_WTaskbarPeer
+ * Method: setProgressValue
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_setProgressValue
+ (JNIEnv *, jobject, jlong window, jint value)
+{
+ m_Taskbar->SetProgressValue((HWND)window, value, 100);
+}
+
+
+
+/*
+ * Class: sun_awt_windows_WTaskbarPeer
+ * Method: setProgressState
+ * Signature: (JI)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_setProgressState
+ (JNIEnv *env, jobject, jlong window, jobject state)
+{
+ TBPFLAG flag = TBPF_NOPROGRESS;
+
+ static jmethodID nameMID = NULL;
+ if (!nameMID) {
+ jclass stateCls = env->FindClass("java/awt/Taskbar$State");
+ CHECK_NULL(stateCls);
+ nameMID = env->GetMethodID(stateCls, "name", "()Ljava/lang/String;");
+ CHECK_NULL(nameMID);
+ }
+ jstring value = (jstring) env->CallObjectMethod(state, nameMID);
+ CHECK_NULL(value);
+ const char* valueNative = env->GetStringUTFChars(value, 0);
+ if (valueNative) {
+ if (strcmp(valueNative, "OFF") == 0) {
+ flag = TBPF_NOPROGRESS;
+ } else if (strcmp(valueNative, "NORMAL") == 0) {
+ flag = TBPF_NORMAL;
+ } else if (strcmp(valueNative, "PAUSED") == 0) {
+ flag = TBPF_PAUSED;
+ } else if (strcmp(valueNative, "INDETERMINATE") == 0) {
+ flag = TBPF_INDETERMINATE;
+ } else if (strcmp(valueNative, "ERROR") == 0) {
+ flag = TBPF_ERROR;
+ }
+ env->ReleaseStringUTFChars(value, valueNative);
+ m_Taskbar->SetProgressState((HWND)window, flag);
+ }
+}
+
+/*
+ * Class: sun_awt_windows_WTaskbarPeer
+ * Method: flashWindow
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_flashWindow
+ (JNIEnv *, jobject, jlong window)
+{
+ AwtWindow::FlashWindowEx((HWND) window, 3, 0, FLASHW_TIMERNOFG);
+}
+
+/*
+ * Class: sun_awt_windows_WTaskbarPeer
+ * Method: setOverlayIcon
+ * Signature: (J[III)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WTaskbarPeer_setOverlayIcon
+ (JNIEnv *env, jobject, jlong window, jintArray buf, jint w, jint h)
+{
+ HICON icon = CreateIconFromRaster(env, buf, w, h);
+ m_Taskbar->SetOverlayIcon((HWND)window, icon, NULL);
+ ::DestroyIcon(icon);
+}
+#ifdef __cplusplus
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Taskbar.h Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+#ifndef AWT_TASKBAR_H
+#define AWT_TASKBAR_H
+
+#include <windows.h>
+#include <shlobj.h>
+
+
+#ifndef __ITaskbarList_INTERFACE_DEFINED__
+#define __ITaskbarList_INTERFACE_DEFINED__
+extern "C" {
+ const GUID CLSID_TaskbarList = {0x56FDF344, 0xFD6D, 0x11D0,
+ {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}};
+ const GUID IID_ITaskbarList = {0x56FDF342, 0xFD6D, 0x11D0,
+ {0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90}};
+}
+
+class ITaskbarList : public IUnknown {
+public:
+ virtual HRESULT STDMETHODCALLTYPE HrInit(void) = 0;
+ virtual HRESULT STDMETHODCALLTYPE AddTab(HWND hwnd) = 0;
+ virtual HRESULT STDMETHODCALLTYPE DeleteTab(HWND hwnd) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ActivateTab(HWND hwnd) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetActiveAlt(HWND hwnd) = 0;
+};
+#endif /* ITaskbarList */
+
+#ifndef __ITaskbarList2_INTERFACE_DEFINED__
+#define __ITaskbarList2_INTERFACE_DEFINED__
+
+class ITaskbarList2 : public ITaskbarList {
+public:
+ virtual HRESULT STDMETHODCALLTYPE MarkFullscreenWindow(HWND hwnd, BOOL fFullscreen) = 0;
+};
+#endif /* ITaskbarList2 */
+
+#ifndef __ITaskbarList3_INTERFACE_DEFINED__
+#define __ITaskbarList3_INTERFACE_DEFINED__
+
+typedef enum THUMBBUTTONFLAGS {
+ THBF_ENABLED = 0, THBF_DISABLED = 0x1, THBF_DISMISSONCLICK = 0x2, THBF_NOBACKGROUND = 0x4, THBF_HIDDEN = 0x8, THBF_NONINTERACTIVE = 0x10
+} THUMBBUTTONFLAGS;
+
+typedef enum THUMBBUTTONMASK {
+ THB_BITMAP = 0x1, THB_ICON = 0x2, THB_TOOLTIP = 0x4, THB_FLAGS = 0x8
+} THUMBBUTTONMASK;
+
+typedef struct THUMBBUTTON {
+ THUMBBUTTONMASK dwMask;
+ UINT iId;
+ UINT iBitmap;
+ HICON hIcon;
+ WCHAR szTip[260];
+ THUMBBUTTONFLAGS dwFlags;
+} THUMBBUTTON;
+
+typedef enum TBPFLAG {
+ TBPF_NOPROGRESS = 0, TBPF_INDETERMINATE = 0x1, TBPF_NORMAL = 0x2, TBPF_ERROR = 0x4, TBPF_PAUSED = 0x8
+} TBPFLAG;
+#define THBN_CLICKED 0x1800
+
+class ITaskbarList3 : public ITaskbarList2 {
+public:
+ virtual HRESULT STDMETHODCALLTYPE SetProgressValue(HWND hwnd, ULONGLONG ullCompleted, ULONGLONG ullTotal) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetProgressState(HWND hwnd, TBPFLAG tbpFlags) = 0;
+ virtual HRESULT STDMETHODCALLTYPE RegisterTab(HWND hwndTab, HWND hwndMDI) = 0;
+ virtual HRESULT STDMETHODCALLTYPE UnregisterTab(HWND hwndTab) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetTabOrder(HWND hwndTab, HWND hwndInsertBefore) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetTabActive(HWND hwndTab, HWND hwndMDI, DWORD dwReserved) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ThumbBarAddButtons(HWND hwnd, UINT cButtons, THUMBBUTTON * pButton) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ThumbBarUpdateButtons(HWND hwnd, UINT cButtons, THUMBBUTTON * pButton) = 0;
+ virtual HRESULT STDMETHODCALLTYPE ThumbBarSetImageList(HWND hwnd, HIMAGELIST himl) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetOverlayIcon(HWND hwnd, HICON hIcon, LPCWSTR pszDescription) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetThumbnailTooltip(HWND hwnd, LPCWSTR pszTip) = 0;
+ virtual HRESULT STDMETHODCALLTYPE SetThumbnailClip(HWND hwnd, RECT *prcClip) = 0;
+};
+#endif /* ITaskbarList3 */
+
+
+ITaskbarList3 * m_Taskbar;
+
+
+#endif /* AWT_TASKBAR_H */
+
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -225,31 +225,18 @@
/*
* We consume WM_MOUSEMOVE while the left mouse button is pressed,
- * so we have to simulate autoscrolling when mouse is moved outside
- * of the client area.
+ * so we have to simulate selection autoscrolling when mouse is moved
+ * outside of the client area.
*/
POINT p;
RECT r;
- BOOL bScrollLeft = FALSE;
- BOOL bScrollRight = FALSE;
- BOOL bScrollUp = FALSE;
BOOL bScrollDown = FALSE;
p.x = msg->pt.x;
p.y = msg->pt.y;
VERIFY(::GetClientRect(GetHWnd(), &r));
- if (p.x < 0) {
- bScrollLeft = TRUE;
- p.x = 0;
- } else if (p.x > r.right) {
- bScrollRight = TRUE;
- p.x = r.right - 1;
- }
- if (p.y < 0) {
- bScrollUp = TRUE;
- p.y = 0;
- } else if (p.y > r.bottom) {
+ if (p.y > r.bottom) {
bScrollDown = TRUE;
p.y = r.bottom - 1;
}
@@ -269,32 +256,7 @@
EditSetSel(cr);
}
-
- if (bScrollLeft == TRUE || bScrollRight == TRUE) {
- SCROLLINFO si;
- memset(&si, 0, sizeof(si));
- si.cbSize = sizeof(si);
- si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
-
- VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si));
- if (bScrollLeft == TRUE) {
- si.nPos = si.nPos - si.nPage / 2;
- si.nPos = max(si.nMin, si.nPos);
- } else if (bScrollRight == TRUE) {
- si.nPos = si.nPos + si.nPage / 2;
- si.nPos = min(si.nPos, si.nMax);
- }
- /*
- * Okay to use 16-bit position since RichEdit control adjusts
- * its scrollbars so that their range is always 16-bit.
- */
- DASSERT(abs(si.nPos) < 0x8000);
- SendMessage(WM_HSCROLL,
- MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos)));
- }
- if (bScrollUp == TRUE) {
- SendMessage(EM_LINESCROLL, 0, -1);
- } else if (bScrollDown == TRUE) {
+ if (bScrollDown == TRUE) {
SendMessage(EM_LINESCROLL, 0, 1);
}
delete msg;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -157,27 +157,12 @@
/*
* We consume WM_MOUSEMOVE while the left mouse button is pressed,
- * so we have to simulate autoscrolling when mouse is moved outside
- * of the client area.
+ * so we have to simulate selection autoscrolling when mouse is moved
+ * outside of the client area.
*/
POINT p;
- RECT r;
- BOOL bScrollLeft = FALSE;
- BOOL bScrollRight = FALSE;
- BOOL bScrollUp = FALSE;
- BOOL bScrollDown = FALSE;
-
p.x = msg->pt.x;
p.y = msg->pt.y;
- VERIFY(::GetClientRect(GetHWnd(), &r));
-
- if (p.x < 0) {
- bScrollLeft = TRUE;
- p.x = 0;
- } else if (p.x > r.right) {
- bScrollRight = TRUE;
- p.x = r.right - 1;
- }
LONG lCurPos = EditGetCharFromPos(p);
if (GetStartSelectionPos() != -1 &&
@@ -193,32 +178,6 @@
EditSetSel(cr);
}
-
- if (bScrollLeft == TRUE || bScrollRight == TRUE) {
- SCROLLINFO si;
- memset(&si, 0, sizeof(si));
- si.cbSize = sizeof(si);
- si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
-
- SendMessage(EM_SHOWSCROLLBAR, SB_HORZ, TRUE);
- VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si));
- SendMessage(EM_SHOWSCROLLBAR, SB_HORZ, FALSE);
-
- if (bScrollLeft == TRUE) {
- si.nPos = si.nPos - si.nPage / 2;
- si.nPos = max(si.nMin, si.nPos);
- } else if (bScrollRight == TRUE) {
- si.nPos = si.nPos + si.nPage / 2;
- si.nPos = min(si.nPos, si.nMax);
- }
- /*
- * Okay to use 16-bit position since RichEdit control adjusts
- * its scrollbars so that their range is always 16-bit.
- */
- DASSERT(abs(si.nPos) < 0x8000);
- SendMessage(WM_HSCROLL,
- MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos)));
- }
delete msg;
return mrConsume;
} else if (msg->message == WM_KEYDOWN) {
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -80,6 +80,16 @@
extern jfieldID jawtSDataID;
extern jfieldID jawtSMgrID;
+jobject reasonUnspecified;
+jobject reasonConsole;
+jobject reasonRemote;
+jobject reasonLock;
+
+extern jobject GetStaticObject(JNIEnv *env, jclass wfClass, const char *fieldName,
+ const char *signature);
+
+extern BOOL isSuddenTerminationEnabled;
+
extern void DWMResetCompositionEnabled();
/************************************************************************
@@ -269,6 +279,9 @@
/* ids for WToolkit fields accessed from native code */
jmethodID AwtToolkit::windowsSettingChangeMID;
jmethodID AwtToolkit::displayChangeMID;
+
+jmethodID AwtToolkit::userSessionMID;
+jmethodID AwtToolkit::systemSleepMID;
/* ids for Toolkit methods */
jmethodID AwtToolkit::getDefaultToolkitMID;
jmethodID AwtToolkit::getFontMetricsMID;
@@ -1046,6 +1059,9 @@
/* Session management */
case WM_QUERYENDSESSION: {
/* Shut down cleanly */
+ if (!isSuddenTerminationEnabled) {
+ return FALSE;
+ }
if (JVM_RaiseSignal(SIGTERM)) {
AwtToolkit::GetInstance().m_vmSignalled = TRUE;
}
@@ -1075,6 +1091,69 @@
DASSERT(FALSE);
break;
}
+#ifndef WM_WTSSESSION_CHANGE
+#define WM_WTSSESSION_CHANGE 0x02B1
+#define WTS_CONSOLE_CONNECT 0x1
+#define WTS_CONSOLE_DISCONNECT 0x2
+#define WTS_REMOTE_CONNECT 0x3
+#define WTS_REMOTE_DISCONNECT 0x4
+#define WTS_SESSION_LOGON 0x5
+#define WTS_SESSION_LOGOFF 0x6
+#define WTS_SESSION_LOCK 0x7
+#define WTS_SESSION_UNLOCK 0x8
+#define WTS_SESSION_REMOTE_CONTROL 0x9
+#endif // WM_WTSSESSION_CHANGE
+ case WM_WTSSESSION_CHANGE: {
+ jclass clzz = env->FindClass("sun/awt/windows/WDesktopPeer");
+ DASSERT(clzz != NULL);
+ if (!clzz) throw std::bad_alloc();
+
+ if (wParam == WTS_CONSOLE_CONNECT
+ || wParam == WTS_CONSOLE_DISCONNECT
+ || wParam == WTS_REMOTE_CONNECT
+ || wParam == WTS_REMOTE_DISCONNECT
+ || wParam == WTS_SESSION_UNLOCK
+ || wParam == WTS_SESSION_LOCK) {
+
+ BOOL activate = wParam == WTS_CONSOLE_CONNECT
+ || wParam == WTS_REMOTE_CONNECT
+ || wParam == WTS_SESSION_UNLOCK;
+ jobject reason = reasonUnspecified;
+
+ switch (wParam) {
+ case WTS_CONSOLE_CONNECT:
+ case WTS_CONSOLE_DISCONNECT:
+ reason = reasonConsole;
+ break;
+ case WTS_REMOTE_CONNECT:
+ case WTS_REMOTE_DISCONNECT:
+ reason = reasonRemote;
+ break;
+ case WTS_SESSION_UNLOCK:
+ case WTS_SESSION_LOCK:
+ reason = reasonLock;
+ }
+
+ env->CallStaticVoidMethod(clzz, AwtToolkit::userSessionMID,
+ activate
+ ? JNI_TRUE
+ : JNI_FALSE, reason);
+ }
+ break;
+ }
+ case WM_POWERBROADCAST: {
+ jclass clzz = env->FindClass("sun/awt/windows/WDesktopPeer");
+ DASSERT(clzz != NULL);
+ if (!clzz) throw std::bad_alloc();
+
+ if (wParam == PBT_APMSUSPEND || wParam == PBT_APMRESUMEAUTOMATIC) {
+ env->CallStaticVoidMethod(clzz, AwtToolkit::systemSleepMID,
+ wParam == PBT_APMRESUMEAUTOMATIC
+ ? JNI_TRUE
+ : JNI_FALSE);
+ }
+ break;
+ }
case WM_SYNC_WAIT:
SetEvent(AwtToolkit::GetInstance().m_waitEvent);
break;
@@ -2133,6 +2212,45 @@
CHECK_NULL(jawtVImgClass);
jawtComponentClass = (jclass)env->NewGlobalRef(componentClassLocal);
+ jclass dPeerClassLocal = env->FindClass("sun/awt/windows/WDesktopPeer");
+ DASSERT(dPeerClassLocal != 0);
+ CHECK_NULL(dPeerClassLocal);
+
+ jclass reasonClassLocal = env->FindClass("java/awt/desktop/UserSessionEvent$Reason");
+ CHECK_NULL(reasonClassLocal);
+
+ reasonUnspecified = GetStaticObject(env, reasonClassLocal, "UNSPECIFIED",
+ "Ljava/awt/desktop/UserSessionEvent$Reason;");
+ CHECK_NULL (reasonUnspecified);
+ reasonUnspecified = env->NewGlobalRef(reasonUnspecified);
+
+ reasonConsole = GetStaticObject(env, reasonClassLocal, "CONSOLE",
+ "Ljava/awt/desktop/UserSessionEvent$Reason;");
+ CHECK_NULL (reasonConsole);
+ reasonConsole = env->NewGlobalRef(reasonConsole);
+
+ reasonRemote = GetStaticObject(env, reasonClassLocal, "REMOTE",
+ "Ljava/awt/desktop/UserSessionEvent$Reason;");
+ CHECK_NULL (reasonRemote);
+ reasonRemote = env->NewGlobalRef(reasonRemote);
+
+ reasonLock = GetStaticObject(env, reasonClassLocal, "LOCK",
+ "Ljava/awt/desktop/UserSessionEvent$Reason;");
+ CHECK_NULL (reasonLock);
+ reasonLock = env->NewGlobalRef(reasonLock);
+
+
+ AwtToolkit::userSessionMID =
+ env->GetStaticMethodID(dPeerClassLocal, "userSessionCallback",
+ "(ZLjava/awt/desktop/UserSessionEvent$Reason;)V");
+ DASSERT(AwtToolkit::userSessionMID != 0);
+ CHECK_NULL(AwtToolkit::userSessionMID);
+
+ AwtToolkit::systemSleepMID =
+ env->GetStaticMethodID(dPeerClassLocal, "systemSleepCallback", "(Z)V");
+ DASSERT(AwtToolkit::systemSleepMID != 0);
+ CHECK_NULL(AwtToolkit::systemSleepMID);
+
CATCH_BAD_ALLOC;
}
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -171,12 +171,15 @@
/* java.awt.Toolkit method ids */
static jmethodID getDefaultToolkitMID;
static jmethodID getFontMetricsMID;
- static jmethodID insetsMID;
+ static jmethodID insetsMID;
/* sun.awt.windows.WToolkit ids */
static jmethodID windowsSettingChangeMID;
static jmethodID displayChangeMID;
+ static jmethodID userSessionMID;
+ static jmethodID systemSleepMID;
+
BOOL m_isDynamicLayoutSet;
AwtToolkit();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -51,10 +51,7 @@
#include "Devices.h"
#include <d2d1.h>
#pragma comment(lib, "d2d1")
-
-#ifndef MDT_Effective_DPI
-#define MDT_Effective_DPI 0
-#endif
+#include "systemScale.h"
uns_ordered_dither_array img_oda_alpha;
@@ -655,58 +652,9 @@
void AwtWin32GraphicsDevice::InitDesktopScales()
{
- unsigned x = 0;
- unsigned y = 0;
float dpiX = -1.0f;
float dpiY = -1.0f;
-
- // for debug purposes
- static float scale = -2.0f;
- if (scale == -2) {
- scale = -1;
- char *uiScale = getenv("J2D_UISCALE");
- if (uiScale != NULL) {
- scale = (float)strtod(uiScale, NULL);
- if (errno == ERANGE || scale <= 0) {
- scale = -1;
- }
- }
- }
-
- if (scale > 0) {
- SetScale(scale, scale);
- return;
- }
-
- typedef HRESULT(WINAPI GetDpiForMonitorFunc)(HMONITOR, int, UINT*, UINT*);
- static HMODULE hLibSHCoreDll = NULL;
- static GetDpiForMonitorFunc *lpGetDpiForMonitor = NULL;
-
- if (hLibSHCoreDll == NULL) {
- hLibSHCoreDll = JDK_LoadSystemLibrary("shcore.dll");
- if (hLibSHCoreDll != NULL) {
- lpGetDpiForMonitor = (GetDpiForMonitorFunc*)GetProcAddress(
- hLibSHCoreDll, "GetDpiForMonitor");
- }
- }
-
- if (lpGetDpiForMonitor != NULL) {
- HRESULT hResult = lpGetDpiForMonitor(GetMonitor(),
- MDT_Effective_DPI, &x, &y);
- if (hResult == S_OK) {
- dpiX = static_cast<float>(x);
- dpiY = static_cast<float>(y);
- }
- } else {
- ID2D1Factory* m_pDirect2dFactory;
- HRESULT res = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
- &m_pDirect2dFactory);
- if (res == S_OK) {
- m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
- m_pDirect2dFactory->Release();
- }
- }
-
+ GetScreenDpi(GetMonitor(), &dpiX, &dpiY);
if (dpiX > 0 && dpiY > 0) {
SetScale(dpiX / 96, dpiY / 96);
}
@@ -1471,4 +1419,5 @@
if (device != NULL) {
device->InitDesktopScales();
}
-}
\ No newline at end of file
+}
+
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, 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
@@ -1154,6 +1154,7 @@
void AwtWindow::InitOwner(AwtWindow *owner)
{
DASSERT(owner != NULL);
+ AwtWindow *initialOwner = owner;
while (owner != NULL && owner->IsSimpleWindow()) {
HWND ownerOwnerHWND = ::GetWindow(owner->GetHWnd(), GW_OWNER);
@@ -1163,6 +1164,9 @@
}
owner = (AwtWindow *)AwtComponent::GetComponent(ownerOwnerHWND);
}
+ if (!owner) {
+ owner = initialOwner->GetOwningFrameOrDialog();
+ }
m_owningFrameDialog = (AwtFrame *)owner;
}
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Window.h Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -398,4 +398,6 @@
inline bool IsAlwaysOnTop() { return m_alwaysOnTop; }
};
+HICON CreateIconFromRaster(JNIEnv* env, jintArray iconRaster, jint w, jint h);
+
#endif /* AWT_WINDOW_H */
--- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_config.h Thu Apr 07 11:03:59 2016 -0700
@@ -41,6 +41,7 @@
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
+#include "systemScale.h"
typedef DWORD rgbquad_t;
typedef WORD word_t;
@@ -56,5 +57,4 @@
#define SPLASHEXPORT __declspec(dllexport)
-
#endif
--- a/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.desktop/windows/native/libsplashscreen/splashscreen_sys.c Thu Apr 07 11:03:59 2016 -0700
@@ -58,6 +58,8 @@
#define WM_SPLASHUPDATE WM_USER+1
#define WM_SPLASHRECONFIGURE WM_USER+2
+#define BUFF_SIZE 1024
+
/* Could use npt but decided to cut down on linked code size */
char* SplashConvertStringAlloc(const char* in, int *size) {
int len, outChars, rc;
@@ -569,10 +571,66 @@
PostMessage(splash->hWnd, WM_SPLASHRECONFIGURE, 0, 0);
}
-SPLASHEXPORT char*
+jboolean
SplashGetScaledImageName(const char* jarName, const char* fileName,
- float *scaleFactor)
+ float *scaleFactor, char *scaleImageName,
+ const size_t scaledImageLength)
{
- *scaleFactor = 1;
- return NULL;
+ float dpiScaleX = -1.0f;
+ float dpiScaleY = -1.0f;
+ FILE *fp = NULL;
+ *scaleFactor = 1.0;
+ GetScreenDpi(getPrimaryMonitor(), &dpiScaleX, &dpiScaleY);
+ *scaleFactor = dpiScaleX > 0 ? dpiScaleX / 96 : *scaleFactor;
+ if (*scaleFactor > 1.0) {
+ char strDpi[BUFF_SIZE];
+ char *dupFileName = strdup(fileName);
+ char *fileExtension = strrchr(dupFileName, '.');
+ char *nameToAppend = ".scale-";
+ size_t length = 0;
+ int retVal = 0;
+ _snprintf(strDpi, BUFF_SIZE, "%d", (int)dpiScaleX);
+ /*File is missing extension */
+ if (fileExtension == NULL) {
+ length = strlen(dupFileName) + strlen(nameToAppend) +
+ strlen(strDpi) + 1;
+ if (length > scaledImageLength) {
+ *scaleFactor = 1;
+ free(dupFileName);
+ return JNI_FALSE;
+ }
+ retVal = _snprintf(scaleImageName, length, "%s%s%s", dupFileName,
+ nameToAppend, strDpi);
+ if (retVal < 0 || (retVal != length - 1)) {
+ *scaleFactor = 1;
+ free(dupFileName);
+ return JNI_FALSE;
+ }
+ }
+ else {
+ size_t length_Without_Ext = fileExtension - dupFileName;
+ length = length_Without_Ext + strlen(nameToAppend) + strlen(strDpi) +
+ strlen(fileExtension) + 1;
+ if (length > scaledImageLength) {
+ *scaleFactor = 1;
+ free(dupFileName);
+ return JNI_FALSE;
+ }
+ retVal = _snprintf(scaleImageName, length, "%.*s%s%s%s",
+ length_Without_Ext, dupFileName, nameToAppend, strDpi, fileExtension);
+ if (retVal < 0 || (retVal != length - 1)) {
+ *scaleFactor = 1;
+ free(dupFileName);
+ return JNI_FALSE;
+ }
+ }
+ free(dupFileName);
+ if (!(fp = fopen(scaleImageName, "r"))) {
+ *scaleFactor = 1;
+ return JNI_FALSE;
+ }
+ fclose(fp);
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
}
--- a/jdk/src/java.management/share/classes/sun/management/Agent.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.management/share/classes/sun/management/Agent.java Thu Apr 07 11:03:59 2016 -0700
@@ -52,7 +52,7 @@
import sun.management.jmxremote.ConnectorBootstrap;
import sun.management.jdp.JdpController;
import sun.management.jdp.JdpException;
-import sun.misc.VMSupport;
+import jdk.internal.vm.VMSupport;
/**
* This Agent is started by the VM when -Dcom.sun.management.snmp or
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java Thu Apr 07 11:03:59 2016 -0700
@@ -41,7 +41,6 @@
import java.rmi.dgc.Lease;
import java.rmi.dgc.VMID;
import java.rmi.server.ObjID;
-import sun.misc.GC;
import sun.rmi.runtime.NewThreadAction;
import sun.rmi.server.UnicastRef;
import sun.rmi.server.Util;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/GC.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 1998, 2008, 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 sun.rmi.transport;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+
+/**
+ * Support for garbage-collection latency requests.
+ *
+ * @author Mark Reinhold
+ * @since 1.2
+ */
+
+class GC {
+
+ private GC() { } /* To prevent instantiation */
+
+
+ /* Latency-target value indicating that there's no active target
+ */
+ private static final long NO_TARGET = Long.MAX_VALUE;
+
+ /* The current latency target, or NO_TARGET if there is no target
+ */
+ private static long latencyTarget = NO_TARGET;
+
+ /* The daemon thread that implements the latency-target mechanism,
+ * or null if there is presently no daemon thread
+ */
+ private static Thread daemon = null;
+
+ /* The lock object for the latencyTarget and daemon fields. The daemon
+ * thread, if it exists, waits on this lock for notification that the
+ * latency target has changed.
+ */
+ private static class LatencyLock extends Object { };
+ private static Object lock = new LatencyLock();
+
+
+ /**
+ * Returns the maximum <em>object-inspection age</em>, which is the number
+ * of real-time milliseconds that have elapsed since the
+ * least-recently-inspected heap object was last inspected by the garbage
+ * collector.
+ *
+ * <p> For simple stop-the-world collectors this value is just the time
+ * since the most recent collection. For generational collectors it is the
+ * time since the oldest generation was most recently collected. Other
+ * collectors are free to return a pessimistic estimate of the elapsed
+ * time, or simply the time since the last full collection was performed.
+ *
+ * <p> Note that in the presence of reference objects, a given object that
+ * is no longer strongly reachable may have to be inspected multiple times
+ * before it can be reclaimed.
+ */
+ public static native long maxObjectInspectionAge();
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("rmi");
+ return null;
+ }});
+ }
+
+ private static class Daemon extends Thread {
+
+ public void run() {
+ for (;;) {
+ long l;
+ synchronized (lock) {
+
+ l = latencyTarget;
+ if (l == NO_TARGET) {
+ /* No latency target, so exit */
+ GC.daemon = null;
+ return;
+ }
+
+ long d = maxObjectInspectionAge();
+ if (d >= l) {
+ /* Do a full collection. There is a remote possibility
+ * that a full collection will occurr between the time
+ * we sample the inspection age and the time the GC
+ * actually starts, but this is sufficiently unlikely
+ * that it doesn't seem worth the more expensive JVM
+ * interface that would be required.
+ */
+ System.gc();
+ d = 0;
+ }
+
+ /* Wait for the latency period to expire,
+ * or for notification that the period has changed
+ */
+ try {
+ lock.wait(l - d);
+ } catch (InterruptedException x) {
+ continue;
+ }
+ }
+ }
+ }
+
+ private Daemon(ThreadGroup tg) {
+ super(tg, null, "GC Daemon", 0L, false);
+ }
+
+ /* Create a new daemon thread in the root thread group */
+ public static void create() {
+ PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
+ public Void run() {
+ ThreadGroup tg = Thread.currentThread().getThreadGroup();
+ for (ThreadGroup tgn = tg;
+ tgn != null;
+ tg = tgn, tgn = tg.getParent());
+ Daemon d = new Daemon(tg);
+ d.setDaemon(true);
+ d.setPriority(Thread.MIN_PRIORITY + 1);
+ d.start();
+ GC.daemon = d;
+ return null;
+ }};
+ AccessController.doPrivileged(pa);
+ }
+
+ }
+
+
+ /* Sets the latency target to the given value.
+ * Must be invoked while holding the lock.
+ */
+ private static void setLatencyTarget(long ms) {
+ latencyTarget = ms;
+ if (daemon == null) {
+ /* Create a new daemon thread */
+ Daemon.create();
+ } else {
+ /* Notify the existing daemon thread
+ * that the lateency target has changed
+ */
+ lock.notify();
+ }
+ }
+
+
+ /**
+ * Represents an active garbage-collection latency request. Instances of
+ * this class are created by the <code>{@link #requestLatency}</code>
+ * method. Given a request, the only interesting operation is that of
+ * cancellation.
+ */
+ public static class LatencyRequest
+ implements Comparable<LatencyRequest> {
+
+ /* Instance counter, used to generate unique identifers */
+ private static long counter = 0;
+
+ /* Sorted set of active latency requests */
+ private static SortedSet<LatencyRequest> requests = null;
+
+ /* Examine the request set and reset the latency target if necessary.
+ * Must be invoked while holding the lock.
+ */
+ private static void adjustLatencyIfNeeded() {
+ if ((requests == null) || requests.isEmpty()) {
+ if (latencyTarget != NO_TARGET) {
+ setLatencyTarget(NO_TARGET);
+ }
+ } else {
+ LatencyRequest r = requests.first();
+ if (r.latency != latencyTarget) {
+ setLatencyTarget(r.latency);
+ }
+ }
+ }
+
+ /* The requested latency, or NO_TARGET
+ * if this request has been cancelled
+ */
+ private long latency;
+
+ /* Unique identifier for this request */
+ private long id;
+
+ private LatencyRequest(long ms) {
+ if (ms <= 0) {
+ throw new IllegalArgumentException("Non-positive latency: "
+ + ms);
+ }
+ this.latency = ms;
+ synchronized (lock) {
+ this.id = ++counter;
+ if (requests == null) {
+ requests = new TreeSet<LatencyRequest>();
+ }
+ requests.add(this);
+ adjustLatencyIfNeeded();
+ }
+ }
+
+ /**
+ * Cancels this latency request.
+ *
+ * @throws IllegalStateException
+ * If this request has already been cancelled
+ */
+ public void cancel() {
+ synchronized (lock) {
+ if (this.latency == NO_TARGET) {
+ throw new IllegalStateException("Request already"
+ + " cancelled");
+ }
+ if (!requests.remove(this)) {
+ throw new InternalError("Latency request "
+ + this + " not found");
+ }
+ if (requests.isEmpty()) requests = null;
+ this.latency = NO_TARGET;
+ adjustLatencyIfNeeded();
+ }
+ }
+
+ public int compareTo(LatencyRequest r) {
+ long d = this.latency - r.latency;
+ if (d == 0) d = this.id - r.id;
+ return (d < 0) ? -1 : ((d > 0) ? +1 : 0);
+ }
+
+ public String toString() {
+ return (LatencyRequest.class.getName()
+ + "[" + latency + "," + id + "]");
+ }
+
+ }
+
+
+ /**
+ * Makes a new request for a garbage-collection latency of the given
+ * number of real-time milliseconds. A low-priority daemon thread makes a
+ * best effort to ensure that the maximum object-inspection age never
+ * exceeds the smallest of the currently active requests.
+ *
+ * @param latency
+ * The requested latency
+ *
+ * @throws IllegalArgumentException
+ * If the given <code>latency</code> is non-positive
+ */
+ public static LatencyRequest requestLatency(long latency) {
+ return new LatencyRequest(latency);
+ }
+
+
+ /**
+ * Returns the current smallest garbage-collection latency request, or zero
+ * if there are no active requests.
+ */
+ public static long currentLatencyTarget() {
+ long t = latencyTarget;
+ return (t == NO_TARGET) ? 0 : t;
+ }
+
+}
--- a/jdk/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java Thu Apr 07 11:03:59 2016 -0700
@@ -34,7 +34,6 @@
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
-import sun.misc.GC;
import sun.rmi.runtime.Log;
import sun.rmi.runtime.NewThreadAction;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.rmi/share/native/librmi/GC.c Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 1998, 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.
+ */
+
+#include <jni.h>
+#include <jvm.h>
+#include "sun_rmi_transport_GC.h"
+
+
+JNIEXPORT jlong JNICALL
+Java_sun_rmi_transport_GC_maxObjectInspectionAge(JNIEnv *env, jclass cls)
+{
+ return JVM_MaxObjectInspectionAge();
+}
--- a/jdk/src/java.se/share/classes/module-info.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/java.se/share/classes/module-info.java Thu Apr 07 11:03:59 2016 -0700
@@ -27,4 +27,5 @@
requires public java.compact3;
requires public java.datatransfer;
requires public java.desktop;
+ requires public java.httpclient;
}
--- a/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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
@@ -1408,7 +1408,9 @@
s.indexOf(AccessibleState.MANAGES_DESCENDANTS.toDisplayString(Locale.US)) == -1) {
// Indicate whether this component manages its own
// children
- AccessibleRole role = ac.getAccessibleRole();
+ AccessibleRole role = InvocationUtils.invokeAndWait(() -> {
+ return ac.getAccessibleRole();
+ }, ac);
if (role == AccessibleRole.LIST ||
role == AccessibleRole.TABLE ||
role == AccessibleRole.TREE) {
@@ -1666,7 +1668,9 @@
*/
private AccessibleComponent getAccessibleComponentFromContext(AccessibleContext ac) {
if (ac != null) {
- AccessibleComponent acmp = ac.getAccessibleComponent();
+ AccessibleComponent acmp = InvocationUtils.invokeAndWait(() -> {
+ return ac.getAccessibleComponent();
+ }, ac);
if (acmp != null) {
debugString("Returning AccessibleComponent Context");
return acmp;
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Key.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -45,6 +45,7 @@
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+import sun.security.util.Debug;
import sun.security.util.DerValue;
import sun.security.util.Length;
import sun.security.util.ECUtil;
@@ -1110,11 +1111,41 @@
}
private static void drainRefQueueBounded() {
+ Session sess = null;
+ Token tkn = null;
while (true) {
SessionKeyRef next = (SessionKeyRef) refQueue.poll();
- if (next == null) break;
+ if (next == null) {
+ break;
+ }
+
+ // If the token is still valid, try to remove the object
+ if (next.session.token.isValid()) {
+ // If this key's token is the same as the previous key, the
+ // same session can be used for C_DestroyObject.
+ try {
+ if (next.session.token != tkn || sess == null) {
+ // Release session if not using previous token
+ if (tkn != null && sess != null) {
+ tkn.releaseSession(sess);
+ sess = null;
+ }
+
+ tkn = next.session.token;
+ sess = tkn.getOpSession();
+ }
+ next.disposeNative(sess);
+ } catch (PKCS11Exception e) {
+ // ignore
+ }
+ }
+ // Regardless of native results, dispose of java references
next.dispose();
}
+
+ if (tkn != null && sess != null) {
+ tkn.releaseSession(sess);
+ }
}
// handle to the native key
@@ -1127,25 +1158,17 @@
this.session = session;
this.session.addObject();
refList.add(this);
- // TBD: run at some interval and not every time?
drainRefQueueBounded();
}
+ private void disposeNative(Session s) throws PKCS11Exception {
+ session.token.p11.C_DestroyObject(s.id(), keyID);
+ }
+
private void dispose() {
refList.remove(this);
- if (session.token.isValid()) {
- Session newSession = null;
- try {
- newSession = session.token.getOpSession();
- session.token.p11.C_DestroyObject(newSession.id(), keyID);
- } catch (PKCS11Exception e) {
- // ignore
- } finally {
- this.clear();
- session.token.releaseSession(newSession);
- session.removeObject();
- }
- }
+ this.clear();
+ session.removeObject();
}
public int compareTo(SessionKeyRef other) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SessionManager.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/SessionManager.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -34,7 +34,7 @@
import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -112,8 +112,8 @@
}
maxSessions = (int)Math.min(n, Integer.MAX_VALUE);
this.token = token;
- this.objSessions = new Pool(this);
- this.opSessions = new Pool(this);
+ this.objSessions = new Pool(this, true);
+ this.opSessions = new Pool(this, false);
if (debug != null) {
maxActiveSessionsLock = new Object();
}
@@ -236,12 +236,18 @@
public static final class Pool {
private final SessionManager mgr;
-
- private final ConcurrentLinkedDeque<Session> pool;
+ private final AbstractQueue<Session> pool;
+ private final int SESSION_MAX = 5;
- Pool(SessionManager mgr) {
- this.mgr = mgr;
- pool = new ConcurrentLinkedDeque<Session>();
+ // Object session pools can contain unlimited sessions.
+ // Operation session pools are limited and enforced by the queue.
+ Pool(SessionManager mgr, boolean obj) {
+ this.mgr = mgr;
+ if (obj) {
+ pool = new LinkedBlockingQueue<Session>();
+ } else {
+ pool = new LinkedBlockingQueue<Session>(SESSION_MAX);
+ }
}
boolean remove(Session session) {
@@ -249,24 +255,24 @@
}
Session poll() {
- return pool.pollLast();
+ return pool.poll();
}
void release(Session session) {
- pool.offer(session);
- if (session.hasObjects()) {
- return;
+ // Object session pools never return false, only Operation ones
+ if (!pool.offer(session)) {
+ mgr.closeSession(session);
+ free();
}
+ }
- int n = pool.size();
- if (n < 5) {
- return;
- }
-
+ // Free any old operation session if this queue is full
+ void free() {
+ int n = SESSION_MAX;
+ int i = 0;
Session oldestSession;
long time = System.currentTimeMillis();
- int i = 0;
- // Check if the session head is too old and continue through queue
+ // Check if the session head is too old and continue through pool
// until only one is left.
do {
oldestSession = pool.peek();
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.c Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.c Thu Apr 07 11:03:59 2016 -0700
@@ -257,9 +257,9 @@
gdata->property_user_dir
= getPropertyUTF8(env, "user.dir");
- /* Get agent properties: invoke sun.misc.VMSupport.getAgentProperties */
+ /* Get agent properties: invoke VMSupport.getAgentProperties */
localVMSupportClass = JNI_FUNC_PTR(env,FindClass)
- (env, "sun/misc/VMSupport");
+ (env, "jdk/internal/vm/VMSupport");
if (localVMSupportClass == NULL) {
gdata->agent_properties = NULL;
if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
@@ -276,7 +276,7 @@
if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
JNI_FUNC_PTR(env,ExceptionClear)(env);
EXIT_ERROR(AGENT_ERROR_INTERNAL,
- "Exception occurred calling sun.misc.VMSupport.getAgentProperties");
+ "Exception occurred calling VMSupport.getAgentProperties");
}
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java Thu Apr 07 11:03:59 2016 -0700
@@ -41,12 +41,13 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
import jdk.internal.org.objectweb.asm.ClassReader;
-import jdk.tools.jlink.plugin.TransformerPlugin;
-import jdk.tools.jlink.plugin.Pool;
-import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
import jdk.tools.jlink.internal.Utils;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.Pool;
+import jdk.tools.jlink.plugin.Pool.ModuleDataType;
+import jdk.tools.jlink.plugin.TransformerPlugin;
/**
* Plugin to explicitly specify the locale data included in jdk.localedata
@@ -84,8 +85,8 @@
private static final String METAINFONAME = "LocaleDataMetaInfo";
private static final String META_FILES =
"*module-info.class," +
- "*LocaleDataProvider*," +
- "*" + METAINFONAME + "*,";
+ "*LocaleDataProvider.class," +
+ "*" + METAINFONAME + ".class,";
private static final String INCLUDE_LOCALE_FILES =
"*sun/text/resources/ext/[^\\/]+_%%.class," +
"*sun/util/resources/ext/[^\\/]+_%%.class," +
@@ -116,7 +117,8 @@
if (resource.getModule().equals(MODULENAME)) {
String path = resource.getPath();
resource = predicate.test(path) ? resource: null;
- if (resource != null) {
+ if (resource != null &&
+ resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) {
byte[] bytes = resource.getBytes();
ClassReader cr = new ClassReader(bytes);
if (Arrays.stream(cr.getInterfaces())
@@ -249,10 +251,10 @@
files += INCLUDE_LOCALE_FILES.replaceAll("%%", isoSpecial + "_[0-9]{3}");
}
- // Add Thai BreakIterator related files
+ // Add Thai BreakIterator related data files
if (lang.equals("th")) {
files += "*sun/text/resources/thai_dict," +
- "*sun/text/resources/[^\\/]+_th,";
+ "*sun/text/resources/[^\\/]+BreakIteratorData_th,";
}
// Add Taiwan resource bundles for Hong Kong
--- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/protocol/local/PerfDataFile.java Thu Apr 07 11:03:59 2016 -0700
@@ -27,6 +27,7 @@
import java.io.File;
import java.io.FilenameFilter;
+import jdk.internal.vm.VMSupport;
/**
* Class to provide translations from the local Vm Identifier
@@ -291,7 +292,7 @@
* the same directory. Instead of guessing which directory the
* VM is using, we will ask.
*/
- String tmpdir = sun.misc.VMSupport.getVMTemporaryDirectory();
+ String tmpdir = VMSupport.getVMTemporaryDirectory();
/*
* Assure that the string returned has a trailing File.separator
--- a/jdk/test/ProblemList.txt Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/ProblemList.txt Thu Apr 07 11:03:59 2016 -0700
@@ -238,7 +238,7 @@
sun/security/pkcs11/MessageDigest/ReinitDigest.java 8077138,8023434 windows-all
sun/security/pkcs11/MessageDigest/TestCloning.java 8077138,8023434 windows-all
sun/security/pkcs11/Provider/ConfigQuotedString.sh 8077138,8023434 windows-all
-sun/security/pkcs11/Provider/Login.sh 8077138,8023434 windows-all
+sun/security/pkcs11/Provider/Login.sh 8077138,8023434,8153545 windows-all,linux-all
sun/security/pkcs11/SampleTest.java 8077138,8023434 windows-all
sun/security/pkcs11/Secmod/AddPrivateKey.java 8077138,8023434 windows-all
sun/security/pkcs11/Secmod/AddTrustedCert.java 8077138,8023434 windows-all
@@ -282,6 +282,8 @@
sun/security/tools/keytool/autotest.sh 8130302 generic-all
+sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java 8137255 generic-all
+
############################################################################
# jdk_sound
@@ -315,8 +317,6 @@
tools/pack200/Pack200Test.java 8059906,8151901 generic-all
-tools/pack200/Pack200Props.java 8152622 macosx-all
-
tools/launcher/FXLauncherTest.java 8068049 linux-all,macosx-all
############################################################################
--- a/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.html Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-<!--
- Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-
-<html>
-<!--
- @test
- @bug 5028014
- @summary Focus request & mouse click being performed nearly synchronously shouldn't break the focus subsystem
- @author anton.tarasov@sun.com: area=awt-focus
- @run applet MouseClickRequestFocusRaceTest.html
- -->
-<head>
-<title>MouseClickRequestFocusRaceTest</title>
-</head>
-<body>
-
-<h1>MouseClickRequestFocusRaceTest<br>Bug ID: 5028014</h1>
-
-<p>See the dialog box (usually in upper left corner) for instructions</p>
-
-<APPLET CODE=MouseClickRequestFocusRaceTest.class WIDTH=200 HEIGHT=200></APPLET>
-</body>
-</html>
--- a/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -21,57 +21,59 @@
* questions.
*/
-/*
- test
- @bug 5028014
- @summary Focus request & mouse click performed nearly synchronously shouldn't lead to a focus race.
- @author anton.tarasov@sun.com: area=awt-focus
- @run applet MouseClickRequestFocusRaceTest.html
-*/
+import java.awt.AWTException;
+import java.awt.FlowLayout;
+import java.awt.KeyboardFocusManager;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
-import java.awt.*;
-import javax.swing.*;
-import java.awt.event.*;
-import java.applet.Applet;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.WindowConstants;
+
+import jdk.testlibrary.OSInfo;
-public class MouseClickRequestFocusRaceTest extends Applet {
- Robot robot;
- JFrame frame1 = new JFrame("Frame-1") {
+/**
+ * @test
+ * @bug 5028014
+ * @summary Focus request & mouse click being performed nearly synchronously
+ * shouldn't break the focus subsystem
+ * @author anton.tarasov@sun.com: area=awt-focus
+ * @library ../../../../lib/testlibrary
+ * @build jdk.testlibrary.OSInfo
+ * @run main MouseClickRequestFocusRaceTest
+ */
+public class MouseClickRequestFocusRaceTest {
+ static Robot robot;
+ static JFrame frame1 = new JFrame("Frame-1") {
public String toString() { return "Frame-1";}
};
- JFrame frame2 = new JFrame("Frame-2") {
+ static JFrame frame2 = new JFrame("Frame-2") {
public String toString() { return "Frame-2";}
};
- JButton button1 = new JButton("button-1") {
+ static JButton button1 = new JButton("button-1") {
public String toString() { return "button-1";}
};
- JButton button2 = new JButton("button-2") {
+ static JButton button2 = new JButton("button-2") {
public String toString() { return "button-2";}
};
- JPopupMenu popup = new JPopupMenu();
+ static JPopupMenu popup = new JPopupMenu();
public static void main(String[] args) {
- MouseClickRequestFocusRaceTest app = new MouseClickRequestFocusRaceTest();
- app.init();
- app.start();
- }
-
- public void init() {
try {
robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+ robot.setAutoDelay(100);
} catch (AWTException e) {
throw new RuntimeException("Error: unable to create robot", e);
}
- // Create instructions for the user here, as well as set up
- // the environment -- set the layout manager, add buttons,
- // etc.
- this.setLayout (new BorderLayout ());
- Sysout.createDialogWithInstructions(new String[]
- {"Automatic test. Simply wait until it is done."
- });
- }
-
- public void start() {
frame1.add(button1);
frame2.add(button2);
frame1.setBounds(0, 0, 200, 300);
@@ -110,198 +112,64 @@
frame1.setVisible(true);
frame2.setVisible(true);
-// ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
+
robot.delay(1000);
-
- test();
+ try {
+ test();
+ } finally {
+ frame1.dispose();
+ frame2.dispose();
+ }
}
- public void test() {
+ public static void test() {
// Right click Frame-1
robot.mouseMove(frame1.getLocation().x + 100, frame1.getLocation().y + 200);
robot.mousePress(InputEvent.BUTTON3_MASK);
- robot.delay(100);
robot.mouseRelease(InputEvent.BUTTON3_MASK);
-// ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
robot.delay(1000);
// Left click Frame-2
robot.mouseMove(frame2.getLocation().x + 100, frame1.getLocation().y + 200);
robot.mousePress(InputEvent.BUTTON1_MASK);
- robot.delay(100);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
-// ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
robot.delay(1000);
JComponent focusOwner = (JComponent)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
JFrame focusedWindow = (JFrame)KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
- Sysout.println("focus owner: " + focusOwner);
- Sysout.println("focused window: " + focusedWindow);
+ System.out.println("focus owner: " + focusOwner);
+ System.out.println("focused window: " + focusedWindow);
// Verify that the focused window is the ancestor of the focus owner
if (!focusedWindow.isAncestorOf(focusOwner)) {
- throw new TestFailedException("The focus owner is not in the focused window!");
+ throw new RuntimeException("The focus owner is not in the focused window!");
}
- // Try to close native focused window
- robot.keyPress(KeyEvent.VK_ALT);
- robot.keyPress(KeyEvent.VK_F4);
- robot.keyRelease(KeyEvent.VK_F4);
- robot.keyRelease(KeyEvent.VK_ALT);
-
-// ((SunToolkit)Toolkit.getDefaultToolkit()).realSync();
- robot.delay(1000);
-
- // Verify that the Java focused window really mapped the native focused window.
- if (focusedWindow.isVisible()) {
- throw new TestFailedException("The focused window is different on Java and on the native level.");
- }
- }
-
- class TestFailedException extends RuntimeException {
- public TestFailedException(String cause) {
- super("Test failed.");
- Sysout.println(cause);
+ if (!OSInfo.getOSType().equals(OSInfo.OSType.MACOSX)) {
+ // Try to close native focused window
+ robot.keyPress(KeyEvent.VK_ALT);
+ robot.keyPress(KeyEvent.VK_F4);
+ robot.keyRelease(KeyEvent.VK_F4);
+ robot.keyRelease(KeyEvent.VK_ALT);
+ robot.delay(1000);
+ // Verify that the Java focused window really mapped the native focused window.
+ if (focusedWindow.isVisible()) {
+ throw new RuntimeException("The focused window is different on Java and on the native level.");
+ }
+ } else {
+ // Try to move native focus to previous window
+ robot.keyPress(KeyEvent.VK_CONTROL);
+ robot.keyPress(KeyEvent.VK_F4);
+ robot.keyRelease(KeyEvent.VK_F4);
+ robot.keyRelease(KeyEvent.VK_CONTROL);
+ robot.delay(1000);
+ // Verify that the Java focused window really mapped the native focused window.
+ if (focusedWindow.isFocused()) {
+ throw new RuntimeException("The focused window is different on Java and on the native level.");
+ }
}
}
}
-
-/****************************************************
- Standard Test Machinery
- DO NOT modify anything below -- it's a standard
- chunk of code whose purpose is to make user
- interaction uniform, and thereby make it simpler
- to read and understand someone else's test.
- ****************************************************/
-
-/**
- This is part of the standard test machinery.
- It creates a dialog (with the instructions), and is the interface
- for sending text messages to the user.
- To print the instructions, send an array of strings to Sysout.createDialog
- WithInstructions method. Put one line of instructions per array entry.
- To display a message for the tester to see, simply call Sysout.println
- with the string to be displayed.
- This mimics System.out.println but works within the test harness as well
- as standalone.
- */
-
-class Sysout
-{
- static TestDialog dialog;
-
- public static void createDialogWithInstructions( String[] instructions )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- dialog.printInstructions( instructions );
-// dialog.setVisible(true);
- println( "Any messages for the tester will display here." );
- }
-
- public static void createDialog( )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- String[] defInstr = { "Instructions will appear here. ", "" } ;
- dialog.printInstructions( defInstr );
-// dialog.setVisible(true);
- println( "Any messages for the tester will display here." );
- }
-
-
- public static void printInstructions( String[] instructions )
- {
- dialog.printInstructions( instructions );
- }
-
-
- public static void println( String messageIn )
- {
- dialog.displayMessage( messageIn );
- }
-
-}// Sysout class
-
-/**
- This is part of the standard test machinery. It provides a place for the
- test instructions to be displayed, and a place for interactive messages
- to the user to be displayed.
- To have the test instructions displayed, see Sysout.
- To have a message to the user be displayed, see Sysout.
- Do not call anything in this dialog directly.
- */
-class TestDialog extends Dialog
-{
-
- TextArea instructionsText;
- TextArea messageText;
- int maxStringLength = 80;
-
- //DO NOT call this directly, go through Sysout
- public TestDialog( Frame frame, String name )
- {
- super( frame, name );
- int scrollBoth = TextArea.SCROLLBARS_BOTH;
- instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
- add( "North", instructionsText );
-
- messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
- add("Center", messageText);
-
- pack();
-
-// setVisible(true);
- }// TestDialog()
-
- //DO NOT call this directly, go through Sysout
- public void printInstructions( String[] instructions )
- {
- //Clear out any current instructions
- instructionsText.setText( "" );
-
- //Go down array of instruction strings
-
- String printStr, remainingStr;
- for( int i=0; i < instructions.length; i++ )
- {
- //chop up each into pieces maxSringLength long
- remainingStr = instructions[ i ];
- while( remainingStr.length() > 0 )
- {
- //if longer than max then chop off first max chars to print
- if( remainingStr.length() >= maxStringLength )
- {
- //Try to chop on a word boundary
- int posOfSpace = remainingStr.
- lastIndexOf( ' ', maxStringLength - 1 );
-
- if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
-
- printStr = remainingStr.substring( 0, posOfSpace + 1 );
- remainingStr = remainingStr.substring( posOfSpace + 1 );
- }
- //else just print
- else
- {
- printStr = remainingStr;
- remainingStr = "";
- }
-
- instructionsText.append( printStr + "\n" );
-
- }// while
-
- }// for
-
- }//printInstructions()
-
- //DO NOT call this directly, go through Sysout
- public void displayMessage( String messageIn )
- {
- messageText.append( messageIn + "\n" );
- System.out.println(messageIn);
- }
-
-}// TestDialog class
--- a/jdk/test/java/awt/FontClass/CreateFont/BigFont.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/FontClass/CreateFont/BigFont.java Thu Apr 07 11:03:59 2016 -0700
@@ -60,12 +60,16 @@
System.out.println("Applet " + id + " "+
Thread.currentThread().getThreadGroup());
+ if (System.getSecurityManager() == null) {
+ System.setSecurityManager(new SecurityManager());
+ }
// Larger than size for a single font.
int fontSize = 64 * 1000 * 1000;
SizedInputStream sis = new SizedInputStream(fontSize);
try {
Font font = Font.createFont(Font.TRUETYPE_FONT, sis);
} catch (Throwable t) {
+ t.printStackTrace();
if (t instanceof FontFormatException ||
fontSize <= sis.getCurrentSize())
{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/FontClass/CreateFont/CreateFontArrayTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8055463
+ * @summary Test createFont APIs
+ * @run CreateFontArrayTest
+ */
+
+import java.awt.Font;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+/*
+ * This test pokes around in platform folders/directories to try
+ * to find some fonts with which to test. It will do different things
+ * on different platforms and may not do anything at all if the platform
+ * directories aren't where it expects. For example if /usr/share/fonts
+ * is not used on a particular Linux distro or on Windows the fonts are
+ * not in c:\windows\fonts (which would be the right place on 99.99% of
+ * systems you will find today.
+ * It ought to be very reliable but it is not 100% guaranteed.
+ * Failure to find fonts to test is 'not a product bug'.
+ * Fonts on a system having different content than we expect based on
+ * file extension is also 'not a product bug'.
+ * The former will cause silent success, the latter may cause 'noisy' failure
+ * and the test would then need to be dialled back to be more cautious.
+ */
+
+public class CreateFontArrayTest {
+
+ public static void main(String[] args) throws Exception {
+ test(".ttc", 2, -1, true);
+ test(".ttf", 1, 1, true);
+ test(".otf", 1, 1, true);
+ test(".pfa", 0, 0, false);
+ test(".pfb", 0, 0, false);
+ }
+
+ static File getPlatformFontFolder(String ext) throws Exception {
+ boolean recurse = false;
+ String folder = null;
+ String os = System.getProperty("os.name");
+ if (os.startsWith("Win")) {
+ folder = "c:\\windows\\fonts";
+ } else if (os.startsWith("Linux")) {
+ folder = "/usr/share/fonts";
+ recurse = true; // need to dig to find fonts.
+ } else if (os.startsWith("Mac")) {
+ // Disabled until createFont can handle mac font names.
+ //folder = "/Library/Fonts";
+ }
+ if (folder == null) {
+ return null;
+ }
+ File dir = new File(folder);
+ if (!dir.exists() || !dir.isDirectory()) {
+ return null;
+ }
+ // Have a root.
+ if (!recurse) {
+ return dir;
+ }
+
+ // If "recurse" is set, try to find a sub-folder which contains
+ // fonts with the specified extension
+ return findSubFolder(dir, ext);
+ }
+
+ static File findSubFolder(File folder, String ext) {
+ File[] files =
+ folder.listFiles(f -> f.getName().toLowerCase().endsWith(ext));
+ if (files != null && files.length > 0) {
+ return folder;
+ }
+ File[] subdirs = folder.listFiles(f -> f.isDirectory());
+ for (File f : subdirs) {
+ File subfolder = findSubFolder(f, ext);
+ if (subfolder != null) {
+ return subfolder;
+ }
+ }
+ return null;
+ }
+
+ static void test(String ext, int min, int max,
+ boolean expectSuccess ) throws Exception {
+
+ File dir = getPlatformFontFolder(ext);
+ if (dir == null) {
+ System.out.println("No folder to test for " + ext);
+ return;
+ }
+ File[] files =
+ dir.listFiles(f -> f.getName().toLowerCase().endsWith(ext));
+ if (files == null || files.length == 0) {
+ System.out.println("No files to test for " + ext);
+ return;
+ }
+ System.out.println("Create from file " + files[0]);
+ Font[] fonts = null;
+ try {
+ fonts = Font.createFonts(files[0]);
+ System.out.println("createFont from file returned " + fonts);
+ } catch (Exception e) {
+ if (expectSuccess) {
+ throw new RuntimeException("Unexpected exception", e);
+ } else {
+ System.out.println("Got expected exception " + e);
+ return;
+ }
+ }
+ for (Font f : fonts) {
+ System.out.println(ext + " component : " + f);
+ }
+ if (fonts.length < min) {
+ throw new RuntimeException("Expected at least " + min +
+ " but got " + fonts.length);
+ }
+ if (max > 0 && fonts.length > max) {
+ throw new RuntimeException("Expected no more than " + max +
+ " but got " + fonts.length);
+ }
+ FileInputStream fis = null;
+ try {
+ System.out.println("Create from stream " + files[0]);
+ fis = new FileInputStream(files[0]);
+ InputStream s = new BufferedInputStream(fis);
+ fonts = null;
+ try {
+ fonts = Font.createFonts(s);
+ System.out.println("createFont from stream returned " + fonts);
+ } catch (Exception e) {
+ if (expectSuccess) {
+ throw new RuntimeException("Unexpected exception", e);
+ } else {
+ System.out.println("Got expected exception " + e);
+ return;
+ }
+ }
+ for (Font f : fonts) {
+ System.out.println(ext + " component : " + f);
+ }
+ if (fonts.length < min) {
+ throw new RuntimeException("Expected at least " + min +
+ " but got " + fonts.length);
+ }
+ if (max > 0 && fonts.length > max) {
+ throw new RuntimeException("Expected no more than " + max +
+ " but got " + fonts.length);
+ }
+ } finally {
+ if (fis != null) {
+ fis.close();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Graphics/CopyScaledArea/CopyScaledAreaTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.awt.image.VolatileImage;
+import static sun.awt.OSInfo.*;
+
+/**
+ * @test
+ * @bug 8069348
+ * @summary SunGraphics2D.copyArea() does not properly work for scaled graphics
+ * @modules java.desktop/sun.awt
+ * @run main/othervm -Dsun.java2d.uiScale=2 CopyScaledAreaTest
+ * @run main/othervm -Dsun.java2d.opengl=true -Dsun.java2d.uiScale=2 CopyScaledAreaTest
+ * @run main/othervm -Dsun.java2d.d3d=true -Dsun.java2d.uiScale=2 CopyScaledAreaTest
+ * @run main/othervm -Dsun.java2d.d3d=false -Dsun.java2d.opengl=false
+ * -Dsun.java2d.uiScale=2 CopyScaledAreaTest
+ */
+public class CopyScaledAreaTest {
+
+ private static final int IMAGE_WIDTH = 800;
+ private static final int IMAGE_HEIGHT = 800;
+ private static final int X = 50;
+ private static final int Y = 50;
+ private static final int W = 100;
+ private static final int H = 75;
+ private static final int DX = 15;
+ private static final int DY = 10;
+ private static final int N = 3;
+ private static final Color BACKGROUND_COLOR = Color.YELLOW;
+ private static final Color FILL_COLOR = Color.ORANGE;
+ private static final double[][] SCALES = {{1.3, 1.4}, {0.3, 2.3}, {2.7, 0.1}};
+
+ private static boolean isSupported() {
+ String d3d = System.getProperty("sun.java2d.d3d");
+ return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS;
+ }
+
+ private static int scale(int x, double scale) {
+ return (int) Math.floor(x * scale);
+ }
+
+ private static VolatileImage createVolatileImage(GraphicsConfiguration conf) {
+ return conf.createCompatibleVolatileImage(IMAGE_WIDTH, IMAGE_HEIGHT);
+ }
+
+ // rendering to the image
+ private static void renderOffscreen(VolatileImage vImg,
+ GraphicsConfiguration conf,
+ double scaleX,
+ double scaleY)
+ {
+ int attempts = 0;
+ do {
+
+ if (attempts > 10) {
+ throw new RuntimeException("Too many attempts!");
+ }
+
+ if (vImg.validate(conf) == VolatileImage.IMAGE_INCOMPATIBLE) {
+ // old vImg doesn't work with new GraphicsConfig; re-create it
+ vImg = createVolatileImage(conf);
+ }
+ Graphics2D g = vImg.createGraphics();
+ //
+ // miscellaneous rendering commands...
+ //
+ g.setColor(BACKGROUND_COLOR);
+ g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+ g.scale(scaleX, scaleY);
+
+ g.setColor(FILL_COLOR);
+ g.fillRect(X, Y, W, H);
+
+ for (int i = 0; i < N; i++) {
+ g.copyArea(X + i * DX, Y + i * DY, W, H, DX, DY);
+ }
+ g.dispose();
+ attempts++;
+ } while (vImg.contentsLost());
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ if (!isSupported()) {
+ return;
+ }
+
+ GraphicsConfiguration graphicsConfiguration =
+ GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration();
+
+ for(double[] scales: SCALES){
+ testScale(scales[0], scales[1], graphicsConfiguration);
+ }
+ }
+
+ private static void testScale(double scaleX, double scaleY,
+ GraphicsConfiguration gc) throws Exception
+ {
+
+ BufferedImage buffImage = new BufferedImage(IMAGE_WIDTH, IMAGE_HEIGHT,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics g = buffImage.createGraphics();
+
+ VolatileImage vImg = createVolatileImage(gc);
+
+ int attempts = 0;
+ do {
+
+ if (attempts > 10) {
+ throw new RuntimeException("Too many attempts!");
+ }
+
+ int returnCode = vImg.validate(gc);
+ if (returnCode == VolatileImage.IMAGE_RESTORED) {
+ // Contents need to be restored
+ renderOffscreen(vImg, gc, scaleX, scaleY); // restore contents
+ } else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
+ // old vImg doesn't work with new GraphicsConfig; re-create it
+ vImg = createVolatileImage(gc);
+ renderOffscreen(vImg, gc, scaleX, scaleY);
+ }
+ g.drawImage(vImg, 0, 0, null);
+ attempts++;
+ } while (vImg.contentsLost());
+
+ g.dispose();
+
+ int x = scale(X + N * DX, scaleX) + 1;
+ int y = scale(Y + N * DY, scaleY) + 1;
+ int w = scale(W, scaleX) - 2;
+ int h = scale(H, scaleY) - 2;
+
+ for (int i = x; i < x + w; i++) {
+ for (int j = y; j < y + h; j++) {
+ if (buffImage.getRGB(i, j) != FILL_COLOR.getRGB()) {
+ throw new RuntimeException("Wrong rectangle color!");
+ }
+ }
+ }
+ }
+}
--- a/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java Thu Apr 07 11:03:59 2016 -0700
@@ -50,9 +50,10 @@
@bug 6778882
@summary Viewport overlapping test for each AWT component
@author sergey.grinev@oracle.com: area=awt.mixing
-@library ../../regtesthelpers
+@library /java/awt/patchlib ../../regtesthelpers
@modules java.desktop/sun.awt
java.desktop/java.awt.peer
+@build java.desktop/java.awt.Helper
@build Util
@run main ViewportOverlapping
*/
--- a/jdk/test/java/awt/MouseInfo/PointerInfoCrashTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/MouseInfo/PointerInfoCrashTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -32,7 +32,7 @@
* @test
* @bug 8143316
* @modules java.desktop/java.awt.peer
- * java.desktop/sun.awt.peer
+ * java.desktop/sun.awt
* @summary Crash Trend in 1.9.0-ea-b93 (sun.awt.DefaultMouseInfoPeer.fillPointWithCoords)
*/
public class PointerInfoCrashTest {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/PrintJob/HighResTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ @test
+ @bug 4227128 8066139
+ @summary Test printing at resolutions > 72dpi
+ @author dpm: area=awt.print
+ @run main/manual HighResTest
+ */
+import java.awt.Button;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.JobAttributes;
+import java.awt.PageAttributes;
+import java.awt.PrintJob;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.JobAttributes.DialogType;
+import java.awt.JobAttributes.SidesType;
+import java.awt.PageAttributes.OrientationRequestedType;
+import java.awt.PageAttributes.OriginType;
+import java.awt.Dialog;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+public class HighResTest {
+ static Frame f = new Frame();
+
+ private static void init() {
+ String[] instructions = {
+ "To be able to run this test it is required to have a default",
+ "printer configured in your user environment.",
+ "If no default printer exists, then test passes.",
+ " ",
+ "There will be 2 print dialogs. The first dialog should show",
+ "portrait as the selected orientation. The 2nd dialog should show",
+ "landscape as the selected orientation.",
+ " ",
+ "Visual inspection of the printed pages is needed. A passing",
+ "test will print 2 pages in portrait and 2 pages in landscape.",
+ "The pages have on the center of the page the text \"Center\"",
+ "2 rectangles will appear above and below it, the one below is",
+ "filled."
+ };
+ Sysout.createDialog();
+ Sysout.printInstructions(instructions);
+
+ PrintJob job = null;
+ Dimension dim = null;
+ JobAttributes jobAttributes = new JobAttributes();
+ PageAttributes pageAttributes = new PageAttributes();
+ String center = "Center";
+ Font font = new Font("SansSerif", Font.PLAIN, 200);
+ FontMetrics metrics = null;
+ int width = 0;
+ Graphics g = null;
+
+ jobAttributes.setDialog(DialogType.NATIVE);
+ pageAttributes.setOrigin(OriginType.PRINTABLE);
+ pageAttributes.setPrinterResolution(new int[]{1200, 1200, 3});
+ pageAttributes.setOrientationRequested(
+ OrientationRequestedType.PORTRAIT);
+ jobAttributes.setSides(SidesType.TWO_SIDED_LONG_EDGE);
+
+ job = f.getToolkit().getPrintJob(f, "Portrait Test", jobAttributes,
+ pageAttributes);
+ if (job != null) {
+ dim = job.getPageDimension();
+ for (int i = 0; i < 2; i++) {
+ g = job.getGraphics();
+
+ g.drawLine(0, 0, dim.width, 0);
+ g.drawLine(dim.width, 0, dim.width, dim.height);
+ g.drawLine(dim.width, dim.height, 0, dim.height);
+ g.drawLine(0, dim.height, 0, 0);
+
+ g.drawRect(dim.width / 2 - 200, dim.height / 3 - 300, 400, 600);
+ g.fillRect(dim.width / 2 - 200, 2 * dim.height / 3 - 300, 400, 600);
+
+ g.setFont(font);
+ metrics = g.getFontMetrics();
+ width = metrics.stringWidth(center);
+ g.setColor(Color.black);
+ g.drawString(center, (dim.width / 2) - (width / 2), dim.height / 2);
+
+ g.dispose();
+ }
+ job.end();
+ job = null;
+ }
+
+ pageAttributes.setOrientationRequested(
+ OrientationRequestedType.LANDSCAPE);
+
+ job = f.getToolkit().getPrintJob(f, "Landscape Test", jobAttributes,
+ pageAttributes);
+ if (job != null) {
+ dim = job.getPageDimension();
+ for (int i = 0; i < 2; i++) {
+ g = job.getGraphics();
+ g.drawLine(0, 0, dim.width, 0);
+ g.drawLine(dim.width, 0, dim.width, dim.height);
+ g.drawLine(dim.width, dim.height, 0, dim.height);
+ g.drawLine(0, dim.height, 0, 0);
+
+ g.drawRect(dim.width / 2 - 200, dim.height / 3 - 300, 400, 600);
+ g.fillRect(dim.width / 2 - 200, 2 * dim.height / 3 - 300, 400, 600);
+
+ g.setFont(font);
+ metrics = g.getFontMetrics();
+ width = metrics.stringWidth(center);
+ g.setColor(Color.black);
+ g.drawString(center, (dim.width / 2) - (width / 2), dim.height / 2);
+
+ g.dispose();
+ }
+ job.end();
+ job = null;
+ }
+ System.out.println("done");
+ }
+
+
+
+ /**
+ * ***************************************************
+ * Standard Test Machinery Section DO NOT modify anything in this section -- it's a
+ standard chunk of code which has all of the
+ synchronisation necessary for the test harness.
+ By keeping it the same in all tests, it is easier
+ to read and understand someone else's test, as
+ well as insuring that all tests behave correctly
+ with the test harness.
+ There is a section following this for test-defined
+ classes
+ *****************************************************
+ */
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+
+ private static Thread mainThread = null;
+
+ private static int sleepTime = 300000;
+
+ public static void main(String args[]) throws InterruptedException {
+ mainThread = Thread.currentThread();
+ try {
+ init();
+ } catch (TestPassedException e) {
+ //The test passed, so just return from main and harness will
+ // interepret this return as a pass
+ return;
+ }
+ //At this point, neither test passed nor test failed has been
+ // called -- either would have thrown an exception and ended the
+ // test, so we know we have multiple threads.
+
+ //Test involves other threads, so sleep and wait for them to
+ // called pass() or fail()
+ try {
+ Thread.sleep(sleepTime);
+ //Timed out, so fail the test
+ throw new RuntimeException("Timed out after " + sleepTime / 1000 + " seconds");
+ } catch (InterruptedException e) {
+ if (!testGeneratedInterrupt) {
+ throw e;
+ }
+
+ //reset flag in case hit this code more than once for some reason (just safety)
+ testGeneratedInterrupt = false;
+ if (theTestPassed == false) {
+ throw new RuntimeException(failureMessage);
+ }
+ }
+
+ }//main
+
+ public static synchronized void setTimeoutTo(int seconds) {
+ sleepTime = seconds * 1000;
+ }
+
+ public static synchronized void pass() {
+ Sysout.println("The test passed.");
+ //first check if this is executing in main thread
+ if (mainThread == Thread.currentThread()) {
+ //Still in the main thread, so set the flag just for kicks,
+ // and throw a test passed exception which will be caught
+ // and end the test.
+ theTestPassed = true;
+ throw new TestPassedException();
+ }
+ //pass was called from a different thread, so set the flag and interrupt
+ // the main thead.
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ Sysout.dispose();
+ }//pass()
+
+ public static synchronized void fail() {
+ //test writer didn't specify why test failed, so give generic
+ fail("it just plain failed! :-)");
+ }
+
+ public static synchronized void fail(String whyFailed) {
+ Sysout.println("The test failed: " + whyFailed);
+ //check if this called from main thread
+ if (mainThread == Thread.currentThread()) {
+ //If main thread, fail now 'cause not sleeping
+ throw new RuntimeException(whyFailed);
+ }
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ Sysout.dispose();
+ }//fail()
+
+ }// class HighResTest
+
+//This exception is used to exit from any level of call nesting
+// when it's determined that the test has passed, and immediately
+// end the test.
+class TestPassedException extends RuntimeException
+ {
+ }
+
+//*********** End Standard Test Machinery Section **********
+
+//************** End classes defined for the test *******************
+
+
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+ chunk of code whose purpose is to make user
+ interaction uniform, and thereby make it simpler
+ to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+ for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+ WithInstructions method. Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+ with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+ as standalone.
+ */
+
+class Sysout {
+ private static TestDialog dialog;
+
+ public static void createDialogWithInstructions(String[] instructions) {
+ dialog = new TestDialog(new Frame(), "Instructions");
+ dialog.printInstructions(instructions);
+ println("Any messages for the tester will display here.");
+ }
+
+ public static void createDialog() {
+ dialog = new TestDialog(new Frame(), "Instructions");
+ String[] defInstr = {"Instructions will appear here. ", ""};
+ dialog.printInstructions(defInstr);
+ println("Any messages for the tester will display here.");
+ }
+
+
+ public static void printInstructions(String[] instructions) {
+ dialog.printInstructions(instructions);
+ }
+
+
+ public static void println(String messageIn) {
+ dialog.displayMessage(messageIn);
+ }
+
+ public static void dispose() {
+ Sysout.println("Shutting down the Java process..");
+ HighResTest.f.dispose();
+ dialog.dispose();
+ }
+ }// Sysout class
+
+/**
+ This is part of the standard test machinery. It provides a place for the
+ test instructions to be displayed, and a place for interactive messages
+ to the user to be displayed.
+ To have the test instructions displayed, see Sysout.
+ To have a message to the user be displayed, see Sysout.
+ Do not call anything in this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener
+{
+
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP = new Panel();
+ Button passB = new Button("pass");
+ Button failB = new Button("fail");
+
+ //DO NOT call this directly, go through Sysout
+ public TestDialog(Frame frame, String name) {
+ super(frame, name);
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
+ add("North", instructionsText);
+
+ messageText = new TextArea("", 5, maxStringLength, scrollBoth);
+ add("Center", messageText);
+
+ passB = new Button("pass");
+ passB.setActionCommand("pass");
+ passB.addActionListener(this);
+ buttonP.add("East", passB);
+
+ failB = new Button("fail");
+ failB.setActionCommand("fail");
+ failB.addActionListener(this);
+ buttonP.add("West", failB);
+
+ add("South", buttonP);
+ pack();
+
+ show();
+ }// TestDialog()
+
+ //DO NOT call this directly, go through Sysout
+ public void printInstructions(String[] instructions) {
+ //Clear out any current instructions
+ instructionsText.setText("");
+
+ //Go down array of instruction strings
+
+ String printStr, remainingStr;
+ for (int i = 0; i < instructions.length; i++) {
+ //chop up each into pieces maxSringLength long
+ remainingStr = instructions[i];
+ while (remainingStr.length() > 0) {
+ //if longer than max then chop off first max chars to print
+ if (remainingStr.length() >= maxStringLength) {
+ //Try to chop on a word boundary
+ int posOfSpace = remainingStr.
+ lastIndexOf(' ', maxStringLength - 1);
+
+ if (posOfSpace <= 0) {
+ posOfSpace = maxStringLength - 1;
+ }
+
+ printStr = remainingStr.substring(0, posOfSpace + 1);
+ remainingStr = remainingStr.substring(posOfSpace + 1);
+ } //else just print
+ else {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+
+ instructionsText.append(printStr + "\n");
+
+ }// while
+
+ }// for
+
+ }//printInstructions()
+
+ //DO NOT call this directly, go through Sysout
+ public void displayMessage(String messageIn) {
+ messageText.append(messageIn + "\n");
+ }
+
+ //catch presses of the passed and failed buttons.
+ //simply call the standard pass() or fail() static methods of
+ //HighResTest
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand() == "pass") {
+ HighResTest.pass();
+ } else {
+ HighResTest.fail();
+ }
+ }
+}// TestDialog class
--- a/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -26,6 +26,7 @@
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.Robot;
@@ -38,12 +39,11 @@
import javax.imageio.ImageIO;
import sun.java2d.SunGraphics2D;
+
/**
* @test
- * @bug 8043869 8075244 8078082
- * @author Alexander Scherbatiy
- * @summary [macosx] java -splash does not honor 2x hi dpi notation for retina
- * support
+ * @bug 8043869 8075244 8078082 8145173
+ * @summary Tests the HiDPI splash screen support for windows and MAC
* @modules java.desktop/sun.java2d
* @run main MultiResolutionSplashTest GENERATE_IMAGES
* @run main/othervm -splash:splash1.png MultiResolutionSplashTest TEST_SPLASH 0
@@ -56,16 +56,26 @@
private static final int IMAGE_WIDTH = 300;
private static final int IMAGE_HEIGHT = 200;
- private static final ImageInfo[] tests = {
+ private static final ImageInfo[] macTests = {
new ImageInfo("splash1.png", "splash1@2x.png", Color.BLUE, Color.GREEN),
new ImageInfo("splash2", "splash2@2x", Color.WHITE, Color.BLACK),
new ImageInfo("splash3.", "splash3@2x.", Color.YELLOW, Color.RED)
};
+ private static final ImageInfo[] windowsTests = {
+ new ImageInfo("splash1.png", "splash1.scale-120.png", Color.BLUE, Color.GREEN),
+ new ImageInfo("splash2", "splash2.scale-120", Color.WHITE, Color.BLACK),
+ new ImageInfo("splash3.", "splash3.scale-120.", Color.YELLOW, Color.RED)
+ };
+ private static ImageInfo[] tests;
public static void main(String[] args) throws Exception {
String test = args[0];
-
+ tests = windowsTests;
+ String osName = System.getProperty("os.name");
+ if (osName.contains("OS X")) {
+ tests = macTests;
+ }
switch (test) {
case "GENERATE_IMAGES":
generateImages();
@@ -156,7 +166,10 @@
public void paint(Graphics g) {
float scaleFactor = 1;
if (g instanceof SunGraphics2D) {
- scaleFactor = ((SunGraphics2D) g).surfaceData.getDefaultScale();
+ scaleFactor = (float)GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().getDefaultConfiguration().
+ getDefaultTransform().getScaleX();
}
scaleFactors[0] = scaleFactor;
dialog.setVisible(false);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/SplashScreen/MultiResolutionSplash/unix/UnixMultiResolutionSplashTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Panel;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.SplashScreen;
+import java.awt.TextField;
+import java.awt.Window;
+import java.awt.event.KeyEvent;
+import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.imageio.ImageIO;
+
+/**
+ * @test @bug 8145174
+ * @summary HiDPI splash screen support on Linux
+ * @modules java.desktop/sun.java2d
+ * @run main UnixMultiResolutionSplashTest
+ */
+public class UnixMultiResolutionSplashTest {
+
+ private static final int IMAGE_WIDTH = 300;
+ private static final int IMAGE_HEIGHT = 200;
+ private static int inx = 0;
+ private static final ImageInfo[] tests = {
+ new ImageInfo("splash1.png", "splash1.java-scale2x.png", Color.BLUE, Color.GREEN),
+ new ImageInfo("splash2", "splash2.java-scale2x", Color.WHITE, Color.BLACK),
+ new ImageInfo("splash3.", "splash3.java-scale2x.", Color.YELLOW, Color.RED)
+ };
+
+ public static void main(String[] args) throws Exception {
+
+ if (args.length == 0) {
+ generateImages();
+ for (ImageInfo test : tests) {
+ createChildProcess(test);
+ }
+ } else {
+ int index = Integer.parseInt(args[0]);
+ testSplash(tests[index]);
+ }
+ }
+
+ static void createChildProcess(ImageInfo test) {
+ String javaPath = System.getProperty("java.home");
+ File file = new File(test.name1x);
+ String classPathDir = System.getProperty("java.class.path");
+ Map<String, String> env = new HashMap<String, String>();
+ env.put("GDK_SCALE", "2");
+ int exitValue = doExec(env, javaPath + File.separator + "bin" + File.separator
+ + "java", "-splash:" + file.getAbsolutePath(), "-cp",
+ classPathDir, "UnixMultiResolutionSplashTest", String.valueOf(inx++));
+ if (exitValue != 0) {
+ throw new RuntimeException("Test Failed");
+ }
+ }
+
+ static void testSplash(ImageInfo test) throws Exception {
+ SplashScreen splashScreen = SplashScreen.getSplashScreen();
+ if (splashScreen == null) {
+ throw new RuntimeException("Splash screen is not shown!");
+ }
+ Graphics2D g = splashScreen.createGraphics();
+ Rectangle splashBounds = splashScreen.getBounds();
+ int screenX = (int) splashBounds.getCenterX();
+ int screenY = (int) splashBounds.getCenterY();
+ System.out.println(screenX);
+ System.out.println(screenY);
+ Robot robot = new Robot();
+ Color splashScreenColor = robot.getPixelColor(screenX, screenY);
+
+ float scaleFactor = getScaleFactor();
+ Color testColor = (1 < scaleFactor) ? test.color2x : test.color1x;
+ if (!compare(testColor, splashScreenColor)) {
+ throw new RuntimeException(
+ "Image with wrong resolution is used for splash screen!");
+ }
+ }
+
+ static int doExec(Map<String, String> envToSet, String... cmds) {
+ Process p = null;
+ ProcessBuilder pb = new ProcessBuilder(cmds);
+ Map<String, String> env = pb.environment();
+ for (String cmd : cmds) {
+ System.out.print(cmd + " ");
+ }
+ System.out.println();
+ if (envToSet != null) {
+ env.putAll(envToSet);
+ }
+ BufferedReader rdr = null;
+ try {
+ List<String> outputList = new ArrayList<>();
+ pb.redirectErrorStream(true);
+ p = pb.start();
+ rdr = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String in = rdr.readLine();
+ while (in != null) {
+ outputList.add(in);
+ in = rdr.readLine();
+ System.out.println(in);
+ }
+ p.waitFor();
+ p.destroy();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return p.exitValue();
+ }
+
+ static void testFocus() throws Exception {
+
+ System.out.println("Focus Test!");
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+ Frame frame = new Frame();
+ frame.setSize(100, 100);
+ String test = "123";
+ TextField textField = new TextField(test);
+ textField.selectAll();
+ frame.add(textField);
+ frame.setVisible(true);
+ robot.waitForIdle();
+
+ robot.keyPress(KeyEvent.VK_A);
+ robot.keyRelease(KeyEvent.VK_A);
+ robot.keyPress(KeyEvent.VK_B);
+ robot.keyRelease(KeyEvent.VK_B);
+ robot.waitForIdle();
+
+ frame.dispose();
+ if (!textField.getText().equals("ab")) {
+ throw new RuntimeException("Focus is lost!");
+ }
+ }
+
+ static boolean compare(Color c1, Color c2) {
+ return compare(c1.getRed(), c2.getRed())
+ && compare(c1.getGreen(), c2.getGreen())
+ && compare(c1.getBlue(), c2.getBlue());
+ }
+
+ static boolean compare(int n, int m) {
+ return Math.abs(n - m) <= 50;
+ }
+
+ static float getScaleFactor() {
+
+ final Dialog dialog = new Dialog((Window) null);
+ dialog.setSize(100, 100);
+ dialog.setModal(true);
+ float[] scaleFactors = new float[1];
+ Panel panel = new Panel() {
+
+ @Override
+ public void paint(Graphics g) {
+ String scaleStr = System.getenv("GDK_SCALE");
+ if (scaleStr != null && !scaleStr.equals("")) {
+ try {
+ scaleFactors[0] = Float.valueOf(scaleStr);
+ } catch (NumberFormatException ex) {
+ scaleFactors[0] = 1.0f;
+ }
+ }
+ dialog.setVisible(false);
+ }
+ };
+ dialog.add(panel);
+ dialog.setVisible(true);
+ dialog.dispose();
+ return scaleFactors[0];
+ }
+
+ static void generateImages() throws Exception {
+ for (ImageInfo test : tests) {
+ generateImage(test.name1x, test.color1x, 1);
+ generateImage(test.name2x, test.color2x, 2);
+ }
+ }
+
+ static void generateImage(String name, Color color, int scale) throws Exception {
+ File file = new File(name);
+ if (file.exists()) {
+ return;
+ }
+ BufferedImage image = new BufferedImage(scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT,
+ BufferedImage.TYPE_INT_RGB);
+ Graphics g = image.getGraphics();
+ g.setColor(color);
+ g.fillRect(0, 0, scale * IMAGE_WIDTH, scale * IMAGE_HEIGHT);
+ ImageIO.write(image, "png", file);
+ }
+
+ static class ImageInfo {
+
+ final String name1x;
+ final String name2x;
+ final Color color1x;
+ final Color color2x;
+
+ public ImageInfo(String name1x, String name2x, Color color1x, Color color2x) {
+ this.name1x = name1x;
+ this.name2x = name2x;
+ this.color1x = color1x;
+ this.color2x = color2x;
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/TextArea/OverScrollTest/OverScrollTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 8149636
+ @summary TextArea over scrolls to right when selecting text towards right.
+ @requires os.family == "windows"
+ @run main OverScrollTest
+ */
+
+import java.awt.Frame;
+import java.awt.FlowLayout;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.TextArea;
+import java.awt.event.InputEvent;
+
+public class OverScrollTest {
+ Frame mainFrame;
+ TextArea textArea;
+ Robot robot;
+
+ OverScrollTest() {
+ try {
+ robot = new Robot();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex.getMessage());
+ }
+
+ mainFrame = new Frame();
+ mainFrame.setSize(400, 200);
+ mainFrame.setLocation(200, 200);
+ mainFrame.setLayout(new FlowLayout());
+
+ textArea = new TextArea(2, 10);
+ textArea.setSize(300, 100);
+ textArea.setText("123456 789123");
+ mainFrame.add(textArea);
+ mainFrame.setVisible(true);
+ textArea.requestFocusInWindow();
+ }
+
+ public void dispose() {
+ if (mainFrame != null) {
+ mainFrame.dispose();
+ }
+ }
+
+ public void performTest() {
+ Point loc = textArea.getLocationOnScreen();
+ Rectangle textAreaBounds = new Rectangle();
+ textArea.getBounds(textAreaBounds);
+
+ // Move mouse at center in first row of TextArea.
+ robot.mouseMove(loc.x + textAreaBounds.width / 2, loc.y + 5);
+
+ // Perform selection by scrolling to right from end of char sequence.
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ for (int i = 0; i < textAreaBounds.width; i += 15) {
+ robot.mouseMove(i + loc.x + textAreaBounds.width / 2, loc.y + 5);
+ robot.delay(10);
+ }
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+
+ // Perform double click on beginning word of TextArea
+ robot.mouseMove(loc.x + 5, loc.y + 5);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.delay(100);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+
+ dispose();
+ if (!textArea.getSelectedText().contains("123456")) {
+ throw new RuntimeException ("TextArea over scrolled towards right. "
+ + "Selected text should contain: '123456' "
+ + "Actual selected test: '" + textArea.getSelectedText() + "'");
+ }
+ }
+
+ public static void main(String argv[]) throws RuntimeException {
+ OverScrollTest test = new OverScrollTest();
+ test.performTest();
+ }
+}
--- a/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.html Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-<!--
- Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-
-<html>
-<!--
- @test
- @bug 6497109
- @summary TextArea must have selection expanding, and also be autoscrolled, if mouse is dragged from inside.
- @author Konstantin Voloshin: area=TextArea
- @library ../../regtesthelpers
- @build Util
- @run applet SelectionAutoscrollTest.html
- -->
-<head>
-<title> </title>
-</head>
-<body>
-
-<h1>SelectionAutoscrollTest<br>Bug ID: 6497109</h1>
-
-<p> This is an AUTOMATIC test, simply wait for completion </p>
-
-<APPLET CODE="SelectionAutoscrollTest.class" WIDTH=200 HEIGHT=200></APPLET>
-</body>
-</html>
--- a/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, 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,11 +22,13 @@
*/
/*
- test
- @bug 6497109
+ @test
+ @bug 6497109 6734341
@summary TextArea must have selection expanding, and also be autoscrolled, if mouse is dragged from inside.
+ @library ../../regtesthelpers
+ @build Util
@author Konstantin Voloshin: area=TextArea
- @run applet SelectionAutoscrollTest.html
+ @run main SelectionAutoscrollTest
*/
/**
@@ -38,12 +40,10 @@
*/
-import java.applet.Applet;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.GridLayout;
import java.awt.TextArea;
-
import java.awt.Point;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
@@ -52,16 +52,18 @@
import test.java.awt.regtesthelpers.Util;
-public class SelectionAutoscrollTest extends Applet {
+public class SelectionAutoscrollTest {
TextArea textArea;
Robot robot;
final int desiredSelectionEnd = ('z'-'a'+1)*2; // 52
final static int SCROLL_DELAY = 10; // ms
- public void start () {
- createObjects();
- manipulateMouse();
- checkResults();
+ public static void main(String[] args) {
+ SelectionAutoscrollTest selectionAutoscrollTest
+ = new SelectionAutoscrollTest();
+ selectionAutoscrollTest.createObjects();
+ selectionAutoscrollTest.manipulateMouse();
+ selectionAutoscrollTest.checkResults();
}
void createObjects() {
@@ -102,7 +104,7 @@
robot.mousePress( MouseEvent.BUTTON1_MASK );
Util.waitForIdle( robot );
- for( int tremble=0; tremble < desiredSelectionEnd; ++tremble ) {
+ for( int tremble=0; tremble < 10; ++tremble ) {
// Mouse is moved repeatedly here (with conservatively chosen
// ammount of times), to give some time/chance for TextArea to
// autoscroll and for text-selection to expand to the end.
@@ -125,7 +127,7 @@
// and this is probably a bug). But, starting with 2nd iteration,
// all events received will be mouse-dragged events.
- moveMouseBelowTextArea( tremble%2!=0 );
+ moveMouseBelowTextArea( tremble );
Util.waitForIdle( robot );
// it is needed to add some small delay on Gnome
waitUntilScrollIsPerformed(robot);
@@ -138,16 +140,28 @@
void moveMouseToCenterOfTextArea() {
Dimension d = textArea.getSize();
Point l = textArea.getLocationOnScreen();
- robot.mouseMove( (int)(l.x+d.width*.5), (int)(l.y+d.height*.5) );
+ Util.mouseMove(robot, l, new Point((int) (l.x + d.width * .5),
+ (int) (l.y + d.height * .5)));
}
- void moveMouseBelowTextArea( boolean shift ) {
+ void moveMouseBelowTextArea(int tremble) {
Dimension d = textArea.getSize();
Point l = textArea.getLocationOnScreen();
- int x = (int)(l.x+d.width*.5);
- int y = (int)(l.y+d.height*1.5);
- if( shift ) y+=15;
- robot.mouseMove( x, y );
+ Point p1;
+ if (tremble == 0) {
+ p1 = new Point((int) (l.x + d.width * .5),
+ (int) (l.y + d.height * 0.5));
+ } else {
+ p1 = new Point((int) (l.x + d.width * .5),
+ (int) (l.y + d.height * 1.5));
+ }
+ Point p2 = new Point((int) (l.x + d.width * .5),
+ (int) (l.y + d.height * 1.5) + 15);
+ if (tremble % 2 == 0) {
+ Util.mouseMove(robot, p1, p2);
+ } else {
+ Util.mouseMove(robot, p2, p1);
+ }
}
void waitUntilScrollIsPerformed(Robot robot) {
@@ -160,15 +174,11 @@
}
void checkResults() {
- //try { Thread.sleep( 30*1000 ); }
- //catch( Exception e ) { throw new RuntimeException( e ); }
-
final int currentSelectionEnd = textArea.getSelectionEnd();
-
System.out.println(
- "TEST: Selection range after test is: ( "
- + textArea.getSelectionStart() + ", "
- + currentSelectionEnd + " )"
+ "TEST: Selection range after test is: ( "
+ + textArea.getSelectionStart() + ", "
+ + currentSelectionEnd + " )"
);
boolean resultOk = ( currentSelectionEnd == desiredSelectionEnd );
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/TextField/OverScrollTest/OverScrollTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 8149636
+ @summary TextField over scrolls to right when selecting text towards right.
+ @requires os.family == "windows"
+ @run main OverScrollTest
+ */
+
+import java.awt.Frame;
+import java.awt.FlowLayout;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.TextField;
+import java.awt.event.InputEvent;
+
+public class OverScrollTest {
+ Frame mainFrame;
+ TextField textField;
+ Robot robot;
+
+ OverScrollTest() {
+ try {
+ robot = new Robot();
+ } catch (Exception ex) {
+ throw new RuntimeException(ex.getMessage());
+ }
+
+ mainFrame = new Frame();
+ mainFrame.setSize(400, 200);
+ mainFrame.setLocation(200, 200);
+ mainFrame.setLayout(new FlowLayout());
+
+ textField = new TextField(10);
+ textField.setSize(300, 100);
+ textField.setText("123456 789123");
+ mainFrame.add(textField);
+ mainFrame.setVisible(true);
+ textField.requestFocusInWindow();
+ }
+
+ public void dispose() {
+ if (mainFrame != null) {
+ mainFrame.dispose();
+ }
+ }
+
+ public void performTest() {
+ Point loc = textField.getLocationOnScreen();
+ Rectangle textFieldBounds = new Rectangle();
+ textField.getBounds(textFieldBounds);
+
+ // Move mouse at center in first row of TextField.
+ robot.mouseMove(loc.x + textFieldBounds.width / 2, loc.y + 5);
+
+ // Perform selection by scrolling to right from end of char sequence.
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ for (int i = 0; i < textFieldBounds.width; i += 15) {
+ robot.mouseMove(i + loc.x + textFieldBounds.width / 2, loc.y + 5);
+ robot.delay(10);
+ }
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+
+ // Perform double click on beginning word of TextField
+ robot.mouseMove(loc.x + 5, loc.y + 5);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.delay(100);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+
+ dispose();
+ if (!textField.getSelectedText().contains("123456")) {
+ throw new RuntimeException ("TextField over scrolled towards right. "
+ + "Selected text should contain: '123456' "
+ + "Actual selected test: '" + textField.getSelectedText() + "'");
+ }
+ }
+
+ public static void main(String argv[]) throws RuntimeException {
+ OverScrollTest test = new OverScrollTest();
+ test.performTest();
+ }
+}
--- a/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.html Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-<!--
- 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
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
--->
-
-<html>
-<!--
- @test
- @bug 4118621
- @summary tests that selected text isn't scrolled if there is enough room.
- @author prs: area=TextField
- @run applet/manual=yesno ScrollSelectionTest.html
- -->
-<head>
-<title> ScrollSelectionTest </title>
-</head>
-<body>
-
-<h1>ScrollSelectionTest<br>4118621: </h1>
-
-<p> See the dialog box (usually in upper left corner) for instructions</p>
-
-<APPLET CODE="ScrollSelectionTest.class" WIDTH=300 HEIGHT=300></APPLET>
-</body>
-</html>
--- a/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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,193 +22,240 @@
*/
/*
- test
- @bug 4118621
- @summary tests that selected text isn't scrolled when there is enough room.
- @author prs: area=TextField
- @run applet/manual=yesno ScrollSelectionTest.html
-*/
+ @test
+ @bug 4118621 8149636
+ @summary Test the selection scrolling in TextField.
+ @run main/manual ScrollSelectionTest
+ */
+import java.awt.Button;
+import java.awt.Dialog;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.TextField;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
-/**
- * ScrollSelectionTest.java
- *
- * summary: tests that selected text isn't scrolled when there is enough room.
- */
+public class ScrollSelectionTest {
-import java.applet.Applet;
-import java.awt.Dialog;
-import java.awt.Frame;
-import java.awt.TextField;
-import java.awt.TextArea;
+ static Frame mainFrame;
+ static TextField textField;
-public class ScrollSelectionTest extends Applet
- {
-
- Frame frame = new Frame("ScrollSelectionTest frame");
- TextField tf = new TextField(40);
-
- public void init()
- {
- tf.setText("abcdefghijklmnopqrstuvwxyz");
- frame.add(tf);
- tf.select(0, 20);
+ private static void init() throws Exception {
+ String[] instructions
+ = {
+ "INSTRUCTIONS: There are 2 Tests",
+ "Test1: Text visibility with Scroll",
+ "This is a test for a win32 specific problem",
+ "If you see all the letters from 'a' to 'z' and",
+ "letters from 'a' to 't' are selected then test passes.",
+ "You may have to activate the frame to see the selection",
+ "highlighted (e.g. by clicking on frame's title).",
+ ".",
+ "Test2: Flicker with selection scroll",
+ "Mouse press on the TextField text.",
+ "Move mouse towards left or right with selecting text.",
+ "Move mouse away outside the bounds of TextField.",
+ "No flicker should be observed.",
+ };
- String[] instructions = {
- "INSTRUCTIONS:",
- "This is a test for a win32 specific problem",
- "If you see all the letters from 'a' to 'z' and",
- "letters from 'a' to 't' are selected then test passes.",
- "You may have to activate the frame to see the selection"
- + " highlighted (e.g. by clicking on frame's title)."
- };
- Sysout.createDialogWithInstructions( instructions );
+ Sysout.createDialog();
+ Sysout.printInstructions(instructions);
+ }
- }// init()
+ public static void initTestWindow() {
+ mainFrame = new Frame("ScrollSelectionTest frame");
+ mainFrame.setBounds(500, 0, 400, 200);
- public void start ()
- {
- setSize (300,300);
- setVisible(true);
-
- frame.setVisible(true);
- frame.setBounds (400, 0, 300, 300);
-
- }// start()
+ textField = new TextField(40);
+ textField.setText("abcdefghijklmnopqrstuvwxyz");
+ mainFrame.add(textField);
+ mainFrame.setLayout(new FlowLayout());
+ textField.select(0, 20);
+ mainFrame.setVisible(true);
+ }
- }// class ScrollSelectionTest
-
-/****************************************************
- Standard Test Machinery
- DO NOT modify anything below -- it's a standard
- chunk of code whose purpose is to make user
- interaction uniform, and thereby make it simpler
- to read and understand someone else's test.
- ****************************************************/
+ public static void dispose() {
+ Sysout.dispose();
+ mainFrame.dispose();
+ }
-/**
- This is part of the standard test machinery.
- It creates a dialog (with the instructions), and is the interface
- for sending text messages to the user.
- To print the instructions, send an array of strings to Sysout.createDialog
- WithInstructions method. Put one line of instructions per array entry.
- To display a message for the tester to see, simply call Sysout.println
- with the string to be displayed.
- This mimics System.out.println but works within the test harness as well
- as standalone.
- */
+ /**
+ * ***************************************************
+ * Standard Test Machinery Section DO NOT modify anything in this section --
+ * it's a standard chunk of code which has all of the synchronization
+ * necessary for the test harness. By keeping it the same in all tests, it
+ * is easier to read and understand someone else's test, as well as insuring
+ * that all tests behave correctly with the test harness. There is a section
+ * following this for test-defined classes
+ * ****************************************************
+ */
+ private static boolean theTestPassed = false;
+ private static boolean testGeneratedInterrupt = false;
+ private static String failureMessage = "";
+ private static Thread mainThread = null;
+ final private static int sleepTime = 300000;
-class Sysout
- {
- private static TestDialog dialog;
+ public static void main(String args[]) throws Exception {
+ mainThread = Thread.currentThread();
+ try {
+ init();
+ initTestWindow();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ try {
+ mainThread.sleep(sleepTime);
+ } catch (InterruptedException e) {
+ dispose();
+ if (testGeneratedInterrupt && !theTestPassed) {
+ throw new Exception(failureMessage);
+ }
+ }
+ if (!testGeneratedInterrupt) {
+ dispose();
+ throw new RuntimeException("Timed out after " + sleepTime / 1000
+ + " seconds");
+ }
+ }
- public static void createDialogWithInstructions( String[] instructions )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- dialog.printInstructions( instructions );
- dialog.show();
- println( "Any messages for the tester will display here." );
+ public static synchronized void pass() {
+ theTestPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
}
- public static void createDialog( )
- {
- dialog = new TestDialog( new Frame(), "Instructions" );
- String[] defInstr = { "Instructions will appear here. ", "" } ;
- dialog.printInstructions( defInstr );
- dialog.show();
- println( "Any messages for the tester will display here." );
+ public static synchronized void fail(String whyFailed) {
+ theTestPassed = false;
+ testGeneratedInterrupt = true;
+ failureMessage = whyFailed;
+ mainThread.interrupt();
+ }
+}
+
+// *********** End Standard Test Machinery Section **********
+/**
+ * **************************************************
+ * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk
+ * of code whose purpose is to make user interaction uniform, and thereby make
+ * it simpler to read and understand someone else's test.
+ * **************************************************
+ */
+/**
+ * This is part of the standard test machinery. It creates a dialog (with the
+ * instructions), and is the interface for sending text messages to the user. To
+ * print the instructions, send an array of strings to Sysout.createDialog
+ * WithInstructions method. Put one line of instructions per array entry. To
+ * display a message for the tester to see, simply call Sysout.println with the
+ * string to be displayed. This mimics System.out.println but works within the
+ * test harness as well as standalone.
+ */
+class Sysout {
+ private static TestDialog dialog;
+ private static Frame frame;
+
+ public static void createDialog() {
+ frame = new Frame();
+ dialog = new TestDialog(frame, "Instructions");
+ String[] defInstr = {"Instructions will appear here. ", ""};
+ dialog.printInstructions(defInstr);
+ dialog.setVisible(true);
+ println("Any messages for the tester will display here.");
}
-
- public static void printInstructions( String[] instructions )
- {
- dialog.printInstructions( instructions );
+ public static void printInstructions(String[] instructions) {
+ dialog.printInstructions(instructions);
}
-
- public static void println( String messageIn )
- {
- dialog.displayMessage( messageIn );
+ public static void println(String messageIn) {
+ dialog.displayMessage(messageIn);
}
- }// Sysout class
+ public static void dispose() {
+ dialog.dispose();
+ frame.dispose();
+ }
+}
/**
- This is part of the standard test machinery. It provides a place for the
- test instructions to be displayed, and a place for interactive messages
- to the user to be displayed.
- To have the test instructions displayed, see Sysout.
- To have a message to the user be displayed, see Sysout.
- Do not call anything in this dialog directly.
- */
-class TestDialog extends Dialog
- {
-
- TextArea instructionsText;
- TextArea messageText;
- int maxStringLength = 80;
-
- //DO NOT call this directly, go through Sysout
- public TestDialog( Frame frame, String name )
- {
- super( frame, name );
- int scrollBoth = TextArea.SCROLLBARS_BOTH;
- instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
- add( "North", instructionsText );
-
- messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
- add("South", messageText);
-
- pack();
-
- show();
- }// TestDialog()
-
- //DO NOT call this directly, go through Sysout
- public void printInstructions( String[] instructions )
- {
- //Clear out any current instructions
- instructionsText.setText( "" );
-
- //Go down array of instruction strings
+ * This is part of the standard test machinery. It provides a place for the test
+ * instructions to be displayed, and a place for interactive messages to the
+ * user to be displayed. To have the test instructions displayed, see Sysout. To
+ * have a message to the user be displayed, see Sysout. Do not call anything in
+ * this dialog directly.
+ */
+class TestDialog extends Dialog implements ActionListener {
+ TextArea instructionsText;
+ TextArea messageText;
+ int maxStringLength = 80;
+ Panel buttonP;
+ Button failB;
+ Button passB;
- String printStr, remainingStr;
- for( int i=0; i < instructions.length; i++ )
- {
- //chop up each into pieces maxSringLength long
- remainingStr = instructions[ i ];
- while( remainingStr.length() > 0 )
- {
- //if longer than max then chop off first max chars to print
- if( remainingStr.length() >= maxStringLength )
- {
- //Try to chop on a word boundary
- int posOfSpace = remainingStr.
- lastIndexOf( ' ', maxStringLength - 1 );
+ // DO NOT call this directly, go through Sysout
+ public TestDialog(Frame frame, String name) {
+ super(frame, name);
+ int scrollBoth = TextArea.SCROLLBARS_BOTH;
+ instructionsText = new TextArea("", 15, maxStringLength, scrollBoth);
+ add("North", instructionsText);
- if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+ messageText = new TextArea("", 5, maxStringLength, scrollBoth);
+ add("Center", messageText);
- printStr = remainingStr.substring( 0, posOfSpace + 1 );
- remainingStr = remainingStr.substring( posOfSpace + 1 );
- }
- //else just print
- else
- {
- printStr = remainingStr;
- remainingStr = "";
- }
+ buttonP = new Panel();
+ passB = new Button("pass");
+ passB.setActionCommand("pass");
+ passB.addActionListener(this);
+ buttonP.add("East", passB);
- instructionsText.append( printStr + "\n" );
-
- }// while
-
- }// for
+ failB = new Button("Fail");
+ failB.setActionCommand("fail");
+ failB.addActionListener(this);
+ buttonP.add("West", failB);
- }//printInstructions()
-
- //DO NOT call this directly, go through Sysout
- public void displayMessage( String messageIn )
- {
- messageText.append( messageIn + "\n" );
+ add("South", buttonP);
+ pack();
+ setVisible(true);
}
- }// TestDialog class
+ // DO NOT call this directly, go through Sysout
+ public void printInstructions(String[] instructions) {
+ instructionsText.setText("");
+ String printStr, remainingStr;
+ for (int i = 0; i < instructions.length; i++) {
+ remainingStr = instructions[i];
+ while (remainingStr.length() > 0) {
+ if (remainingStr.length() >= maxStringLength) {
+ int posOfSpace = remainingStr.
+ lastIndexOf(' ', maxStringLength - 1);
+
+ if (posOfSpace <= 0) {
+ posOfSpace = maxStringLength - 1;
+ }
+
+ printStr = remainingStr.substring(0, posOfSpace + 1);
+ remainingStr = remainingStr.substring(posOfSpace + 1);
+ }
+ else {
+ printStr = remainingStr;
+ remainingStr = "";
+ }
+ instructionsText.append(printStr + "\n");
+ }
+ }
+ }
+
+ public void displayMessage(String messageIn) {
+ messageText.append(messageIn + "\n");
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().equals("pass")) {
+ ScrollSelectionTest.pass();
+ } else {
+ ScrollSelectionTest.fail("User Clicked Fail");
+ }
+ }
+}
--- a/jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/Toolkit/Headless/WrappedToolkitTest/WrappedToolkitTest.sh Thu Apr 07 11:03:59 2016 -0700
@@ -105,17 +105,6 @@
fi
echo "JDK under test is: $TESTJAVA"
-##Deal with .class files:
-#if [ -n "${STANDALONE}" ] ; then
-# # then compile all .java files (if there are any) into .class files
-# if [ -a *.java ]; then
-# ${TESTJAVA}/bin/javac$ ./*.java ;
-# fi
-# # else in harness so copy all the class files from where jtreg put them
-# # over to the scratch directory this test is running in.
-# else cp ${TESTCLASSES}/*.class . ;
-#fi
-#
#if in test harness, then copy the entire directory that the test is in over
# to the scratch directory. This catches any support files needed by the test.
if [ -z "${STANDALONE}" ] ;
@@ -124,7 +113,8 @@
case "$OS" in
Windows* | CYGWIN* )
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
@@ -134,7 +124,8 @@
SunOS | Linux )
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
@@ -144,7 +135,8 @@
Darwin)
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
*.java
status=$?
if [ ! $status -eq "0" ]; then
@@ -162,14 +154,16 @@
case "$OS" in
Windows* | CYGWIN* )
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
TestWrapped sun.awt.windows.WToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.windows.WToolkit";
fi
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.awt.windows=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.awt.windows.WToolkit \
TestWrapped sun.awt.windows.WToolkit
status=$?
@@ -180,7 +174,8 @@
SunOS | Linux )
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.awt.X11.XToolkit \
TestWrapped sun.awt.X11.XToolkit
status=$?
@@ -188,7 +183,8 @@
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.awt.xawt.XToolkit";
fi
AWT_TOOLKIT=XToolkit ${TESTJAVA}/bin/java ${TESTVMOPTS} \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED ${CP} \
-Djava.awt.headless=true \
TestWrapped sun.awt.X11.XToolkit
status=$?
@@ -199,14 +195,16 @@
Darwin)
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
TestWrapped sun.lwawt.macosx.LWCToolkit
status=$?
if [ ! $status -eq "0" ]; then
fail "Test FAILED: toolkit wrapped into HeadlessToolkit is not an instance of sun.lwawt.macosx.LWCToolkit";
fi
${TESTJAVA}/bin/java ${TESTVMOPTS} -Djava.awt.headless=true \
- -XaddExports:java.desktop/sun.awt=ALL-UNNAMED,java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
+ -XaddExports:java.desktop/sun.awt=ALL-UNNAMED \
+ -XaddExports:java.desktop/sun.lwawt.macosx=ALL-UNNAMED ${CP} \
-Dawt.toolkit=sun.lwawt.macosx.LWCToolkit \
TestWrapped sun.lwawt.macosx.LWCToolkit
status=$?
--- a/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/TrayIcon/MouseMovedTest/MouseMovedTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -30,7 +30,7 @@
* @bug 7153700
* @summary Check for mouseMoved event for java.awt.TrayIcon
* @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
- * @library ../../../../lib/testlibrary
+ * @library ../../../../lib/testlibrary ../
* @build ExtendedRobot SystemTrayIconHelper
* @run main MouseMovedTest
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Window/FindOwner/FindOwnerTest.html Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,43 @@
+<!--
+ Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+
+
+ @test
+ @bug 8139227
+ @summary Text fields in JPopupMenu structure do not receive focus in hosted
+ Applets
+ @author Semyon Sadetsky
+ @run applet FindOwnerTest.html
+-->
+
+<html>
+<head>
+ <title>Testing Menus</title>
+</head>
+<body>
+<applet id="ownerTester"
+ name="Testing Owner"
+ code="FindOwnerTest.class"
+ width="250" height="150">
+</applet>
+</body>
+</html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Window/FindOwner/FindOwnerTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @bug 8139227
+ @summary Text fields in JPopupMenu structure do not receive focus in hosted
+ Applets
+ @author Semyon Sadetsky
+*/
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class FindOwnerTest extends Applet
+{
+
+ private boolean gained;
+
+ public void init() {
+ super.init();
+ }
+
+ @Override
+ public void start() {
+ Window owner = SwingUtilities.windowForComponent(this);
+
+ Window window1 = new Window(owner);
+ window1.setVisible(true);
+
+ Window window2 = new Window(window1);
+ window2.setFocusable(true);
+ JTextField field = new JTextField("JTextField");
+ field.addFocusListener(new FocusListener() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ gained = true;
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ }
+ });
+ window2.setBounds(100, 100, 200, 200);
+ window2.add(field);
+ window2.setVisible(true);
+
+ try {
+ gained = false;
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+ robot.waitForIdle();
+ robot.delay(200);
+
+ Point p = field.getLocationOnScreen();
+ System.out.println(p);
+ robot.mouseMove(p.x + 1, p.y + 1);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+ robot.delay(200);
+
+ if (!gained) {
+ throw new Exception("Focus is not gained upon mouse click");
+ }
+ System.out.println("ok");
+ } catch (SecurityException e) {
+
+ JOptionPane optionPane = new JOptionPane(
+ "You are in the browser so test is manual. Try to " +
+ "click \"JTextField\" in the opened window then press OK " +
+ "below",
+ JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
+ JDialog dialog =
+ optionPane.createDialog(null,"FindOwnerTest instruction");
+ dialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
+ dialog.setVisible(true);
+ if (!gained) {
+ throw new RuntimeException(
+ "Focus is not gained upon mouse click");
+ }
+ System.out.println("ok");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ window1.dispose();
+ stop();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Window/MultiWindowApp/ChildAlwaysOnTopTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test @summary setAlwaysOnTop doesn't behave correctly in Linux/Solaris under
+ * certain scenarios
+ * @bug 8021961
+ * @author Semyon Sadetsky
+ * @run main ChildAlwaysOnTopTest
+ */
+
+import javax.swing.*;
+import java.awt.*;
+
+public class ChildAlwaysOnTopTest {
+
+ private static Window win1;
+ private static Window win2;
+ private static Point point;
+
+ public static void main(String[] args) throws Exception {
+ if( Toolkit.getDefaultToolkit().isAlwaysOnTopSupported() ) {
+
+
+ test(null);
+
+ Window f = new Frame();
+ f.setBackground(Color.darkGray);
+ f.setSize(500, 500);
+ try {
+ test(f);
+ } finally {
+ f.dispose();
+ }
+
+ f = new Frame();
+ f.setBackground(Color.darkGray);
+ f.setSize(500, 500);
+ f.setVisible(true);
+ f = new Dialog((Frame)f);
+ try {
+ test(f);
+ } finally {
+ ((Frame)f.getParent()).dispose();
+ }
+ }
+ System.out.println("ok");
+ }
+
+ public static void test(Window parent) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ win1 = parent == null ? new JDialog() : new JDialog(parent);
+ win1.setName("top");
+ win2 = parent == null ? new JDialog() : new JDialog(parent);
+ win2.setName("behind");
+ win1.setSize(200, 200);
+ Panel panel = new Panel();
+ panel.setBackground(Color.GREEN);
+ win1.add(panel);
+ panel = new Panel();
+ panel.setBackground(Color.RED);
+ win2.add(panel);
+ win1.setAlwaysOnTop(true);
+ win2.setAlwaysOnTop(false);
+ win1.setVisible(true);
+ }
+ });
+
+ Robot robot = new Robot();
+ robot.delay(200);
+ robot.waitForIdle();
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ point = win1.getLocationOnScreen();
+ win2.setBounds(win1.getBounds());
+ win2.setVisible(true);
+ }
+ });
+
+ robot.delay(200);
+ robot.waitForIdle();
+
+ Color color = robot.getPixelColor(point.x + 100, point.y + 100);
+ if(!color.equals(Color.GREEN)) {
+ win1.dispose();
+ win2.dispose();
+ throw new RuntimeException("alawaysOnTop window is sent back by " +
+ "another child window setVisible(). " + color);
+ }
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ win2.toFront();
+ if (parent != null) {
+ parent.setLocation(win1.getLocation());
+ parent.toFront();
+ }
+ }
+ });
+
+ robot.delay(200);
+ robot.waitForIdle();
+
+ color = robot.getPixelColor(point.x + 100, point.y + 100);
+ if(!color.equals(Color.GREEN)) {
+ win1.dispose();
+ win2.dispose();
+ throw new RuntimeException("alawaysOnTop window is sent back by " +
+ "another child window toFront(). " + color);
+ }
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ win1.setAlwaysOnTop(false);
+ if (parent != null) {
+ parent.setVisible(false);
+ parent.setVisible(true);
+ }
+ win2.toFront();
+ }
+ });
+
+ robot.delay(200);
+ robot.waitForIdle();
+
+ color = robot.getPixelColor(point.x + 100, point.y + 100);
+ if(!color.equals(Color.RED)) {
+ throw new RuntimeException("Failed to unset alawaysOnTop " + color);
+ }
+
+ win1.dispose();
+ win2.dispose();
+ }
+}
--- a/jdk/test/java/awt/font/FontNames/GetLCIDFromLocale.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/font/FontNames/GetLCIDFromLocale.java Thu Apr 07 11:03:59 2016 -0700
@@ -4,9 +4,7 @@
*
* 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.
+ * published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/font/FontScaling/FontScalingTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import javax.swing.JButton;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+
+/*
+ * @test
+ * @bug 8076545
+ * @summary Text size is twice bigger under Windows L&F on Win 8.1 with
+ * HiDPI display
+ */
+public class FontScalingTest {
+
+ public static void main(String[] args) throws Exception {
+ int metalFontSize = getFontSize(MetalLookAndFeel.class.getName());
+ int systemFontSize = getFontSize(UIManager.getSystemLookAndFeelClassName());
+
+ if (Math.abs(systemFontSize - metalFontSize) > 8) {
+ throw new RuntimeException("System L&F is too big!");
+ }
+ }
+
+ private static int getFontSize(String laf) throws Exception {
+
+ UIManager.setLookAndFeel(laf);
+ final int[] sizes = new int[1];
+
+ SwingUtilities.invokeAndWait(() -> {
+ JButton button = new JButton("Test");
+ sizes[0] = button.getFont().getSize();
+ });
+
+ return sizes[0];
+ }
+}
\ No newline at end of file
--- a/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesLinuxTest.java Thu Apr 07 10:07:02 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.awt.Dialog;
-import java.awt.Frame;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.geom.AffineTransform;
-import javax.swing.UIManager;
-
-/* @test
- * @bug 8137571
- * @summary Linux HiDPI Graphics support
- * @author Alexander Scherbatiy
- * @requires (os.family == "linux")
- * @run main/othervm -Dsun.java2d.uiScale.enabled=false
- * -Dsun.java2d.uiScale=2
- * HiDPIPropertiesLinuxTest UISCALE_DISABLED
- * HiDPIPropertiesTest UISCALE_DISABLED
- * @run main/othervm -Dsun.java2d.uiScale.enabled=true
- * -Dsun.java2d.uiScale=3
- * HiDPIPropertiesLinuxTest UISCALE_3
- * @run main/othervm -Dsun.java2d.uiScale=4
- * HiDPIPropertiesLinuxTest UISCALE_4
- */
-public class HiDPIPropertiesLinuxTest {
-
- public static void main(String[] args) throws Exception {
-
- try {
- UIManager.setLookAndFeel(
- "com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
- } catch (Exception e) {
- return;
- }
-
- String testCase = args[0];
- switch (testCase) {
- case "UISCALE_DISABLED":
- testScale(1.0, 1.0);
- break;
- case "UISCALE_3":
- testScale(3.0, 3.0);
- break;
- case "UISCALE_4":
- testScale(4.0, 4.0);
- break;
- default:
- throw new RuntimeException("Unknown test case: " + testCase);
- }
- }
-
- private static void testScale(double scaleX, double scaleY) {
-
- Dialog dialog = new Dialog((Frame) null, true) {
-
- @Override
- public void paint(Graphics g) {
- super.paint(g);
- AffineTransform tx = ((Graphics2D) g).getTransform();
- dispose();
- if (scaleX != tx.getScaleX() || scaleY != tx.getScaleY()) {
- throw new RuntimeException(String.format("Wrong scale:"
- + "[%f, %f] instead of [%f, %f].",
- tx.getScaleX(), tx.getScaleY(), scaleX, scaleY));
- }
- }
- };
- dialog.setSize(200, 300);
- dialog.setVisible(true);
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/hidpi/properties/HiDPIPropertiesUnixTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import javax.swing.UIManager;
+
+/* @test
+ * @bug 8137571
+ * @summary Linux HiDPI Graphics support
+ * @author Alexander Scherbatiy
+ * @requires (os.family == "linux" | os.family == "mac")
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=false
+ * -Dsun.java2d.uiScale=2
+ * HiDPIPropertiesUnixTest UISCALE_DISABLED
+ * @run main/othervm -Dsun.java2d.uiScale.enabled=true
+ * -Dsun.java2d.uiScale=3
+ * HiDPIPropertiesUnixTest UISCALE_3
+ * @run main/othervm -Dsun.java2d.uiScale=4
+ * HiDPIPropertiesUnixTest UISCALE_4
+ */
+public class HiDPIPropertiesUnixTest {
+
+ public static void main(String[] args) throws Exception {
+
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+
+ String testCase = args[0];
+ switch (testCase) {
+ case "UISCALE_DISABLED":
+ testScale(1.0, 1.0);
+ break;
+ case "UISCALE_3":
+ testScale(3.0, 3.0);
+ break;
+ case "UISCALE_4":
+ testScale(4.0, 4.0);
+ break;
+ default:
+ throw new RuntimeException("Unknown test case: " + testCase);
+ }
+ }
+
+ private static void testScale(double scaleX, double scaleY) {
+
+ Dialog dialog = new Dialog((Frame) null, true) {
+
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+ AffineTransform tx = ((Graphics2D) g).getTransform();
+ dispose();
+ if (scaleX != tx.getScaleX() || scaleY != tx.getScaleY()) {
+ throw new RuntimeException(String.format("Wrong scale:"
+ + "[%f, %f] instead of [%f, %f].",
+ tx.getScaleX(), tx.getScaleY(), scaleX, scaleY));
+ }
+ }
+ };
+ dialog.setSize(200, 300);
+ dialog.setVisible(true);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/DrawImage/ScaledImageAlphaTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8139183
+ * @summary Test verifies whether alpha channel of a translucent
+ * image is proper or not after scaling through drawImage.
+ * @run main ScaledImageAlphaTest
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Transparency;
+import java.awt.image.BufferedImage;
+import java.awt.image.VolatileImage;
+
+public class ScaledImageAlphaTest {
+
+ static final int translucentAlpha = 128, opaqueAlpha = 255;
+ static final int[] translucentVariants = new int[] {
+ BufferedImage.TYPE_INT_ARGB,
+ BufferedImage.TYPE_INT_ARGB_PRE,
+ BufferedImage.TYPE_4BYTE_ABGR,
+ BufferedImage.TYPE_4BYTE_ABGR_PRE
+ };
+ static final int[] alphaValues = new int[] {
+ translucentAlpha,
+ opaqueAlpha
+ };
+ static int width = 50, height = 50;
+ static int scaleX = 5, scaleY = 5, scaleWidth = 40, scaleHeight = 40;
+
+ private static void verifyAlpha(Color color, int alpha) {
+
+ /* if extracted alpha value is equal alpha that we set
+ * for background color, alpha channel is not lost
+ * while scaling otherwise we have lost alpha channel.
+ */
+ int extractedAlpha = color.getAlpha();
+
+ if (extractedAlpha != alpha) {
+ throw new RuntimeException("Alpha channel for background"
+ + " is lost while scaling");
+ }
+ }
+
+ private static void validateBufferedImageAlpha() {
+
+ Color backgroundColor, extractedColor;
+ // verify for all translucent buffered image types
+ for (int type : translucentVariants) {
+ // verify for both opaque and translucent background color
+ for (int alpha : alphaValues) {
+ // create BufferedImage of dimension (50,50)
+ BufferedImage img = new
+ BufferedImage(width, height, type);
+ Graphics2D imgGraphics = (Graphics2D)img.getGraphics();
+ /* scale image to smaller dimension and set any
+ * background color with alpha.
+ */
+ backgroundColor = new Color(0, 255, 0, alpha);
+ imgGraphics.
+ drawImage(img, scaleX, scaleY, scaleWidth, scaleHeight,
+ backgroundColor, null);
+ imgGraphics.dispose();
+
+ /* get pixel information for background color with
+ * scaled coordinates.
+ */
+ extractedColor = new Color(img.getRGB(scaleX, scaleY), true);
+ verifyAlpha(extractedColor, alpha);
+ }
+ }
+ }
+
+ private static void validateVolatileImageAlpha() {
+
+ Color backgroundColor, extractedColor;
+ VolatileImage img;
+ BufferedImage bufImg = new
+ BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ for (int alpha : alphaValues) {
+ backgroundColor = new Color(0, 255, 0, alpha);
+ do {
+ img = createVolatileImage(width, height,
+ Transparency.TRANSLUCENT);
+ Graphics2D imgGraphics = (Graphics2D)img.getGraphics();
+ // clear VolatileImage as by default it has white opaque image
+ imgGraphics.setComposite(AlphaComposite.Clear);
+ imgGraphics.fillRect(0,0, width, height);
+
+ imgGraphics.setComposite(AlphaComposite.SrcOver);
+ /* scale image to smaller dimension and set background color
+ * to green with translucent alpha.
+ */
+ imgGraphics.
+ drawImage(img, scaleX, scaleY, scaleWidth, scaleHeight,
+ backgroundColor, null);
+ //get BufferedImage out of VolatileImage
+ bufImg = img.getSnapshot();
+ imgGraphics.dispose();
+ } while (img.contentsLost());
+
+ /* get pixel information for background color with
+ * scaled coordinates.
+ */
+ extractedColor = new Color(bufImg.getRGB(scaleX, scaleY), true);
+ verifyAlpha(extractedColor, alpha);
+ }
+ }
+
+ private static VolatileImage createVolatileImage(int width, int height,
+ int transparency) {
+ GraphicsEnvironment ge = GraphicsEnvironment.
+ getLocalGraphicsEnvironment();
+ GraphicsConfiguration gc = ge.getDefaultScreenDevice().
+ getDefaultConfiguration();
+
+ VolatileImage image = gc.createCompatibleVolatileImage(width, height,
+ transparency);
+ return image;
+ }
+
+ public static void main(String[] args) {
+ // test alpha channel with different types of BufferedImage
+ validateBufferedImageAlpha();
+ // test alpha channel with VolatileImage
+ validateVolatileImageAlpha();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/SampleModelConstructorTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6185114
+ * @summary test SampleModel constructor for different combinations of
+ * width and height
+ */
+
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+
+
+public class SampleModelConstructorTest {
+
+ public static void main(String[] a) throws RuntimeException {
+
+ SampleModel model = Raster.createBandedRaster(DataBuffer.TYPE_INT,
+ 10, 5, 4, null).getSampleModel();
+
+ final int inputWidths[]
+ = {Integer.MIN_VALUE, -1000, -1, 0, 1, 1000, Integer.MAX_VALUE};
+
+ final int inputHeights[]
+ = {Integer.MIN_VALUE, -1000, -1, 0, 1, 1000, Integer.MAX_VALUE};
+
+ // There are 49 combinations of (width, height) possible using above two
+ // arrays
+
+ // Only 6 valid combinations of (width, height) that do not throw
+ // exception are :
+ // (1, 1)
+ // (1, 1000)
+ // (1, Integer.MAX_VALUE)
+ // (1000, 1)
+ // (1000, 1000)
+ // (Integer.MAX_VALUE, 1)
+ final int expectedCount = 43;
+ int count = 0;
+
+ for (int i : inputWidths) {
+ for (int j : inputHeights) {
+ try {
+ SampleModel model2 = model.createCompatibleSampleModel(i, j);
+ } catch (IllegalArgumentException e) {
+ count++;
+ }
+ }
+ }
+
+ if (count != expectedCount) {
+ throw new RuntimeException(
+ "Test Failed. Expected IllegalArgumentException Count = " +
+ expectedCount + " Got Count = " + count);
+ }
+ }
+}
+
--- a/jdk/test/java/awt/image/multiresolution/BaseMultiResolutionImageTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/image/multiresolution/BaseMultiResolutionImageTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -191,6 +191,17 @@
if (!passed) {
throw new RuntimeException("Resolution variants list is modifiable!");
}
+
+ passed = false;
+ try {
+ mrImage.getGraphics();
+ } catch (UnsupportedOperationException e) {
+ passed = true;
+ }
+
+ if (!passed) {
+ throw new RuntimeException("getGraphics() method shouldn't be supported!");
+ }
}
private static int getSize(int i) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/multiresolution/Corrupted2XImageTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8142406
+ * @author a.stepanov
+ * @summary [HiDPI] [macosx] check that for a pair of images
+ * (image.ext, image@2x.ext) the 1st one is loaded
+ * in case if the 2nd is corrupted
+ *
+ * @requires (os.family == "mac")
+ *
+ * @library ../../../../lib/testlibrary/
+ * @build ExtendedRobot
+ * @run main Corrupted2XImageTest
+ */
+
+import java.awt.*;
+import java.awt.image.*;
+import java.io.*;
+
+import javax.imageio.ImageIO;
+
+public class Corrupted2XImageTest extends Frame {
+
+ private static final int SZ = 200;
+ private static final Color C = Color.BLUE;
+
+ private final String format, name1x, name2x;
+
+ public Corrupted2XImageTest(String format) throws IOException {
+
+ this.format = format;
+ name1x = "test." + format;
+ name2x = "test@2x." + format;
+ createFiles();
+ }
+
+ private void UI() {
+
+ setTitle(format);
+ setSize(SZ, SZ);
+ setResizable(false);
+ setLocation(50, 50);
+ setVisible(true);
+ }
+
+ @Override
+ public void paint(Graphics g) {
+
+ Image img = Toolkit.getDefaultToolkit().getImage(
+ new File(name1x).getAbsolutePath());
+ g.drawImage(img, 0, 0, this);
+ }
+
+ private void createFiles() throws IOException {
+
+ BufferedImage img =
+ new BufferedImage(SZ, SZ, BufferedImage.TYPE_INT_RGB);
+ Graphics g = img.getGraphics();
+ g.setColor(C);
+ g.fillRect(0, 0, SZ, SZ);
+ ImageIO.write(img, format, new File(name1x));
+
+ // corrupted @2x "image" - just a text file
+ Writer writer = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(new File(name2x)), "utf-8"));
+ writer.write("corrupted \"image\"");
+ writer.close();
+ }
+
+ // need this for jpg
+ private static boolean cmpColors(Color c1, Color c2) {
+
+ int tol = 10;
+ return (
+ Math.abs(c2.getRed() - c1.getRed() ) < tol &&
+ Math.abs(c2.getGreen() - c1.getGreen()) < tol &&
+ Math.abs(c2.getBlue() - c1.getBlue() ) < tol);
+ }
+
+ private void doTest() throws Exception {
+
+ ExtendedRobot r = new ExtendedRobot();
+ System.out.println("format: " + format);
+ r.waitForIdle(1000);
+ EventQueue.invokeAndWait(this::UI);
+ r.waitForIdle(1000);
+ Point loc = getLocationOnScreen();
+ Color c = r.getPixelColor(loc.x + SZ / 2, loc.y + SZ / 2);
+ if (!cmpColors(c, C)) {
+ throw new RuntimeException("test failed, color = " + c); }
+ System.out.println("ok");
+ dispose();
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ // formats supported by Toolkit.getImage()
+ for (String format : new String[]{"gif", "jpg", "png"}) {
+ (new Corrupted2XImageTest(format)).doTest();
+ }
+ }
+}
--- a/jdk/test/java/awt/image/multiresolution/MenuMultiresolutionIconTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/image/multiresolution/MenuMultiresolutionIconTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -115,13 +115,6 @@
}
}
- private static boolean is2x() {
-
- return GraphicsEnvironment.getLocalGraphicsEnvironment().
- getDefaultScreenDevice().getDefaultConfiguration().
- getDefaultTransform().getScaleX() > 1.001;
- }
-
private boolean eqColors(Color c1, Color c2) {
int tol = 15;
@@ -133,7 +126,8 @@
private void checkIconColor(Point p, String what) {
- Color expected = is2x() ? C2X : C1X;
+ String scale = System.getProperty(SCALE);
+ Color expected = "2".equals(scale) ? C2X : C1X;
Color c = r.getPixelColor(p.x + SZ / 2, p.y + SZ / 2);
if (!eqColors(c, expected)) {
frame.dispose();
@@ -177,9 +171,6 @@
public static void main(String s[]) throws Exception {
- // TODO: remove is2x() after JDK-8150844 fix
- if (is2x() == "2".equals(System.getProperty(SCALE))) {
- (new MenuMultiresolutionIconTest()).doTest();
- }
+ (new MenuMultiresolutionIconTest()).doTest();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionJOptionPaneIconTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 8150176 8150844
+ @author a.stepanov
+ @summary Check if correct resolution variant is used
+ for JOptionPane dialog / internal frame icons.
+ @library ../../../../lib/testlibrary/
+ @build ExtendedRobot
+ @run main/othervm/timeout=300 -Dsun.java2d.uiScale=1 MultiResolutionJOptionPaneIconTest
+ @run main/othervm/timeout=300 -Dsun.java2d.uiScale=2 MultiResolutionJOptionPaneIconTest
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+import javax.swing.*;
+
+public class MultiResolutionJOptionPaneIconTest implements ActionListener {
+
+ private final static Color C1X = Color.ORANGE, C2X = Color.CYAN;
+
+ private final boolean isInternal;
+
+ private volatile JFrame test;
+ private volatile JDialog dialog;
+ private volatile JInternalFrame frame;
+ private final JDesktopPane parentPane = new JDesktopPane();
+ private final JButton run = new JButton("run");
+
+ private final ExtendedRobot robot = new ExtendedRobot();
+
+ private static BufferedImage getSquare(int sz, Color c) {
+
+ BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB);
+ Graphics g = img.getGraphics();
+ g.setColor(c);
+ g.fillRect(0, 0, sz, sz);
+ return img;
+ }
+
+ private static Icon getIcon() {
+
+ BaseMultiResolutionImage mri = new BaseMultiResolutionImage(
+ new BufferedImage[]{getSquare(16, C1X), getSquare(32, C2X)});
+ return new ImageIcon(mri);
+ }
+
+ public MultiResolutionJOptionPaneIconTest(boolean internal,
+ UIManager.LookAndFeelInfo lf) throws Exception {
+
+ UIManager.setLookAndFeel(lf.getClassName());
+
+ isInternal = internal;
+ robot.setAutoDelay(50);
+ SwingUtilities.invokeAndWait(this::UI);
+ }
+
+ private void UI() {
+
+ test = new JFrame();
+ test.setLayout(new BorderLayout());
+ test.add(parentPane, BorderLayout.CENTER);
+ run.addActionListener(this);
+ test.add(run, BorderLayout.SOUTH);
+ test.setUndecorated(true);
+ test.setSize(400, 300);
+ test.setLocation(50, 50);
+ test.setVisible(true);
+ }
+
+ private void disposeAll() {
+
+ if (dialog != null) { dialog.dispose(); }
+ if (frame != null) { frame.dispose(); }
+ if (test != null) { test.dispose(); }
+ }
+
+ public void doTest() throws Exception {
+
+ robot.waitForIdle(1000);
+ clickButton(robot);
+ robot.waitForIdle(2000);
+
+ Component c = isInternal ?
+ frame.getContentPane() : dialog.getContentPane();
+
+ System.out.println("\ncheck " + (isInternal ? "internal frame" :
+ "dialog") + " icon:");
+
+ Point pt = c.getLocationOnScreen();
+ checkColors(pt.x, c.getWidth(), pt.y, c.getHeight());
+ System.out.println("ok");
+ robot.waitForIdle();
+ SwingUtilities.invokeAndWait(this::disposeAll);
+ robot.waitForIdle();
+ }
+
+ private void checkColors(int x0, int w, int y0, int h) {
+
+ boolean is2x = "2".equals(System.getProperty("sun.java2d.uiScale"));
+ Color
+ expected = is2x ? C2X : C1X,
+ unexpected = is2x ? C1X : C2X;
+
+ for (int y = y0; y < y0 + h; y += 5) {
+ for (int x = x0; x < x0 + w; x += 5) {
+
+ Color c = robot.getPixelColor(x, y);
+ if (c.equals(unexpected)) {
+ throw new RuntimeException(
+ "invalid color was found, test failed");
+ } else if (c.equals(expected)) { return; }
+ }
+ }
+
+ // no icon found at all
+ throw new RuntimeException("the icon wasn't found");
+ }
+
+ private void showDialogOrFrame() {
+
+ JOptionPane pane = new JOptionPane("",
+ JOptionPane.DEFAULT_OPTION,
+ JOptionPane.INFORMATION_MESSAGE,
+ getIcon());
+ pane.setOptions(new Object[]{}); // no buttons
+
+ if (isInternal) {
+ frame = pane.createInternalFrame(parentPane, "");
+ frame.setLocation(0, 0);
+ frame.setVisible(true);
+ } else {
+ dialog = pane.createDialog(parentPane, "");
+ dialog.setVisible(true);
+ }
+ }
+
+ public void clickButton(ExtendedRobot robot) {
+
+ Point pt = run.getLocationOnScreen();
+ robot.mouseMove(pt.x + run.getWidth() / 2, pt.y + run.getHeight() / 2);
+ robot.waitForIdle();
+ robot.click();
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent event) { showDialogOrFrame(); }
+
+
+ public static void main(String[] args) throws Exception {
+
+ for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) {
+ System.out.println("\nL&F: " + LF.getName());
+ (new MultiResolutionJOptionPaneIconTest(false, LF)).doTest();
+ (new MultiResolutionJOptionPaneIconTest(true , LF)).doTest();
+ }
+ }
+}
--- a/jdk/test/java/awt/image/multiresolution/MultiResolutionRenderingHintsTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionRenderingHintsTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -47,6 +47,7 @@
* @author Alexander Scherbatiy
* @summary Custom MultiResolution image support on HiDPI displays
* @modules java.desktop/sun.java2d
+ * @modules java.desktop/sun.java2d.loops
* @run main MultiResolutionRenderingHintsTest
*/
public class MultiResolutionRenderingHintsTest {
--- a/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/image/multiresolution/MultiResolutionTrayIconTest/MultiResolutionTrayIconTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -90,8 +90,10 @@
BufferedImage nok = generateImage(w / 2 + 2, h / 2 + 2, Color.RED);
BaseMultiResolutionImage mri =
new BaseMultiResolutionImage(new BufferedImage[] {nok, img});
- icon = new TrayIcon(img);
+ icon = new TrayIcon(img);
+ icon.setImageAutoSize(true); // just in case
iconMRI = new TrayIcon(mri);
+ iconMRI.setImageAutoSize(true);
}
private void doTest() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/multiresolution/MultiresolutionIconTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8150724 8151303
+ * @author a.stepanov
+ * @summary Check that correct resolution variants are chosen for icons
+ * when multiresolution image is used for their construction.
+ *
+ * @library ../../../../lib/testlibrary/
+ * @build ExtendedRobot
+ * @run main/othervm/timeout=240 -Dsun.java2d.uiScale=1 MultiresolutionIconTest
+ * @run main/othervm/timeout=240 -Dsun.java2d.uiScale=2 MultiresolutionIconTest
+ */
+
+
+// TODO: please remove the "@requires" tag after 8151303 fix
+
+
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.image.BaseMultiResolutionImage;
+import java.awt.image.BufferedImage;
+import javax.swing.*;
+
+public class MultiresolutionIconTest extends JFrame {
+
+ private final static int SZ = 100;
+ private final static int N = 5; // number of components
+
+ private final static String SCALE = "sun.java2d.uiScale";
+ private final static Color C1X = Color.RED;
+ private final static Color C2X = Color.BLUE;
+
+ private JLabel lbl;
+ private JTabbedPane tabbedPane;
+
+ private final ExtendedRobot r;
+
+ private static BufferedImage generateImage(int sz, Color c) {
+
+ BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB);
+ Graphics g = img.getGraphics();
+ g.setColor(c);
+ g.fillRect(0, 0, sz, sz);
+ return img;
+ }
+
+ public MultiresolutionIconTest(UIManager.LookAndFeelInfo lf) throws Exception {
+
+ UIManager.setLookAndFeel(lf.getClassName());
+ r = new ExtendedRobot();
+ SwingUtilities.invokeAndWait(this::UI);
+ }
+
+ private void UI() {
+
+ setUndecorated(true);
+
+ BufferedImage img1x = generateImage(SZ / 2, C1X);
+ BufferedImage img2x = generateImage(SZ, C2X);
+ BaseMultiResolutionImage mri = new BaseMultiResolutionImage(
+ new BufferedImage[]{img1x, img2x});
+ Icon icon = new ImageIcon(mri);
+
+ // hardcoded icon size for OS X (Mac OS X L&F) - see JDK-8151060
+ BufferedImage tab1x = generateImage(16, C1X);
+ BufferedImage tab2x = generateImage(32, C2X);
+ BaseMultiResolutionImage tabMRI = new BaseMultiResolutionImage(
+ new BufferedImage[]{tab1x, tab2x});
+ Icon tabIcon = new ImageIcon(tabMRI);
+
+ setSize((N + 1) * SZ, SZ);
+ setLocation(50, 50);
+
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ getContentPane().setLayout(new GridLayout(1, 1));
+
+ JPanel p = new JPanel();
+ p.setLayout(new GridLayout(1, N));
+
+ JButton btn = new JButton(icon);
+ p.add(btn);
+
+ JToggleButton tbn = new JToggleButton(icon);
+ p.add(tbn);
+
+ JRadioButton rbn = new JRadioButton(icon);
+ rbn.setHorizontalAlignment(SwingConstants.CENTER);
+ p.add(rbn);
+
+ JCheckBox cbx = new JCheckBox(icon);
+ cbx.setHorizontalAlignment(SwingConstants.CENTER);
+ p.add(cbx);
+
+ lbl = new JLabel(icon);
+ p.add(lbl);
+
+ tabbedPane = new JTabbedPane(JTabbedPane.LEFT);
+ tabbedPane.addTab("", tabIcon, p);
+ getContentPane().add(tabbedPane);
+
+ setResizable(false);
+ setVisible(true);
+ }
+
+ private boolean checkPressedColor(int x, int y, Color ok) {
+
+ r.mouseMove(x, y);
+ r.waitForIdle();
+ r.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ r.waitForIdle(100);
+ Color c = r.getPixelColor(x, y);
+ r.waitForIdle(100);
+ r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ r.waitForIdle(100);
+ if (!c.equals(ok)) { return false; }
+ // check the icon's color hasn't changed
+ // after the mouse was released
+ c = r.getPixelColor(x, y);
+ return c.equals(ok);
+ }
+
+ private boolean checkTabIcon(
+ int xStart, int xEnd, int yStart, int yEnd, Color ok, Color nok) {
+
+ for (int y = yStart; y < yEnd; y += 2) {
+ for (int x = xStart; x < xEnd; x += 2) {
+ Color c = r.getPixelColor(x, y);
+ if (c.equals(nok)) { return false; }
+ else if (c.equals(ok)) {
+ // shift a bit to avoid the selection effects
+ return checkPressedColor(x + 5, y + 5, ok);
+ }
+ }
+ }
+
+ return false; // didn't find the icon
+ }
+
+
+ private void doTest() {
+
+ r.waitForIdle(2000);
+ String scale = System.getProperty(SCALE);
+ boolean is2x = "2".equals(scale);
+ Color expected = is2x ? C2X : C1X;
+ Color unexpected = is2x ? C1X : C2X;
+
+ Point p = lbl.getLocationOnScreen();
+ int x = p.x + lbl.getWidth() / 2;
+ int y = p.y + lbl.getHeight() / 2;
+ int w = lbl.getWidth();
+
+ boolean ok = true, curr;
+ Color c;
+ String components[] = new String[]{
+ "JLabel", "JCheckBox", "JRadioButton", "JToggleButton", "JButton"};
+ for (int i = 0; i < N; i++) {
+
+ curr = true;
+ int t = x - i * w;
+
+ // check icon color
+ c = r.getPixelColor(t, y);
+ System.out.print(components[i] + " icon: ");
+ if (!c.equals(expected)) {
+ curr = false;
+ } else {
+ // check icon color when mouse button pressed - see JDK-8151303
+ curr = checkPressedColor(t, y, expected);
+ }
+
+ System.out.println(curr ? "ok" : "nok");
+ ok = ok && curr;
+
+ r.waitForIdle();
+ }
+
+ int x0 = tabbedPane.getLocationOnScreen().x;
+ int x1 = x - ((N - 1) * w + w / 2);
+ int y0 = getLocationOnScreen().y;
+ int y1 = y0 + getHeight();
+ curr = checkTabIcon(x0, x1, y0, y1, expected, unexpected);
+
+ System.out.println("JTabbedPane icon: " + (curr ? "ok" : "nok"));
+ ok = ok && curr;
+
+ if (!ok) { throw new RuntimeException("test failed"); }
+
+ r.waitForIdle();
+ dispose();
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) {
+ System.out.println("\nL&F: " + LF.getName());
+ (new MultiresolutionIconTest(LF)).doTest();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/multiresolution/MultiresolutionSourceTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8151269
+ * @author a.stepanov
+ * @summary Multiresolution image: check that the base resolution variant
+ * source is passed to the corresponding ImageConsumer
+ * @run main MultiresolutionSourceTest
+ */
+
+import java.awt.*;
+import java.awt.image.*;
+
+public class MultiresolutionSourceTest {
+
+ private static class Checker implements ImageConsumer {
+
+ private final int refW, refH, refType;
+ private final boolean refHasAlpha;
+ private final Color refColor;
+
+ public Checker(int w,
+ int h,
+ Color c,
+ boolean hasAlpha,
+ int transferType) {
+ refW = w;
+ refH = h;
+ refColor = c;
+ refHasAlpha = hasAlpha;
+ refType = transferType;
+ }
+
+ @Override
+ public void imageComplete(int status) {}
+
+ @Override
+ public void setColorModel(ColorModel model) {
+
+ boolean a = model.hasAlpha();
+ if (a != refHasAlpha) {
+ throw new RuntimeException("invalid hasAlpha: " + a);
+ }
+
+ int tt = model.getTransferType();
+ if (tt != refType) {
+ throw new RuntimeException("invalid transfer type: " + tt);
+ }
+ }
+
+ @Override
+ public void setDimensions(int w, int h) {
+
+ if (w != refW) { throw new RuntimeException("invalid width: " + w +
+ ", expected: " + refW); }
+
+ if (h != refH) { throw new RuntimeException("invalid height: " + h +
+ ", expected: " + refH); }
+ }
+
+ @Override
+ public void setHints(int flags) {}
+
+ @Override
+ public void setPixels(int x, int y, int w, int h, ColorModel model,
+ byte pixels[], int offset, int scansize) {
+
+ for (int i = 0; i < pixels.length; i++) {
+ int p = pixels[i];
+ // just in case...
+ Color c = model.hasAlpha() ?
+ new Color(model.getRed (p),
+ model.getGreen(p),
+ model.getBlue (p),
+ model.getAlpha(p)) :
+ new Color(model.getRGB(p));
+
+ if (!c.equals(refColor)) {
+ throw new RuntimeException("invalid color: " + c +
+ ", expected: " + refColor);
+ }
+ }
+ }
+
+ @Override
+ public void setPixels(int x, int y, int w, int h, ColorModel model,
+ int pixels[], int offset, int scansize) {
+
+ for (int i = 0; i < pixels.length; i++) {
+ int p = pixels[i];
+ Color c = model.hasAlpha() ?
+ new Color(model.getRed (p),
+ model.getGreen(p),
+ model.getBlue (p),
+ model.getAlpha(p)) :
+ new Color(model.getRGB(p));
+
+ if (!c.equals(refColor)) {
+ throw new RuntimeException("invalid color: " + c +
+ ", expected: " + refColor);
+ }
+ }
+ }
+
+ @Override
+ public void setProperties(java.util.Hashtable props) {}
+ }
+
+ private static BufferedImage generateImage(int w, int h, Color c, int type) {
+
+ BufferedImage img = new BufferedImage(w, h, type);
+ Graphics g = img.getGraphics();
+ g.setColor(c);
+ g.fillRect(0, 0, w, h);
+ return img;
+ }
+
+ public static void main(String[] args) {
+
+ final int w1 = 20, w2 = 100, h1 = 30, h2 = 50;
+ final Color
+ c1 = new Color(255, 0, 0, 100), c2 = Color.BLACK, gray = Color.GRAY;
+
+ BufferedImage img1 =
+ generateImage(w1, h1, c1, BufferedImage.TYPE_INT_ARGB);
+
+ BufferedImage dummy =
+ generateImage(w1 + 5, h1 + 5, gray, BufferedImage.TYPE_BYTE_GRAY);
+
+ BufferedImage img2 =
+ generateImage(w2, h2, c2, BufferedImage.TYPE_BYTE_BINARY);
+
+ BufferedImage vars[] = new BufferedImage[] {img1, dummy, img2};
+
+ // default base image index (zero)
+ BaseMultiResolutionImage mri1 = new BaseMultiResolutionImage(vars);
+ // base image index = 2
+ BaseMultiResolutionImage mri2 = new BaseMultiResolutionImage(2, vars);
+
+ // do checks
+ mri1.getSource().startProduction(
+ new Checker(w1, h1, c1, true, DataBuffer.TYPE_INT));
+
+ mri2.getSource().startProduction(
+ new Checker(w2, h2, c2, false, DataBuffer.TYPE_BYTE));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/keyboard/AllKeyCode/AllKeyCode.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ @test
+ @bug 8149456 8147834 8150230
+ @requires os.family == "mac"
+ @summary KeyEvents for all keys
+ @run main AllKeyCode
+*/
+
+import java.awt.AWTException;
+import java.awt.GridBagLayout;
+import java.awt.Robot;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.Frame;
+import java.awt.TextArea;
+
+public class AllKeyCode extends Frame {
+
+ private static Frame frame;
+ private static TextArea textArea;
+ private static KeyListener keyListener;
+ private static int allKeyArr[];
+ private static int keyPressedIndex;
+
+ AllKeyCode() {
+ AllKeyCode.allKeyArr = new int[] {
+ KeyEvent.VK_BACK_SPACE,
+ KeyEvent.VK_TAB,
+ KeyEvent.VK_ENTER,
+ KeyEvent.VK_CLEAR,
+ KeyEvent.VK_SHIFT,
+ KeyEvent.VK_CONTROL,
+ KeyEvent.VK_ALT,
+ KeyEvent.VK_CAPS_LOCK,
+ KeyEvent.VK_ESCAPE,
+ KeyEvent.VK_SPACE,
+ KeyEvent.VK_PAGE_UP,
+ KeyEvent.VK_PAGE_DOWN,
+ KeyEvent.VK_END,
+ KeyEvent.VK_HOME,
+ KeyEvent.VK_LEFT,
+ KeyEvent.VK_UP,
+ KeyEvent.VK_RIGHT,
+ KeyEvent.VK_DOWN,
+ KeyEvent.VK_COMMA,
+ KeyEvent.VK_MINUS,
+ KeyEvent.VK_PERIOD,
+ KeyEvent.VK_SLASH,
+ KeyEvent.VK_0,
+ KeyEvent.VK_1,
+ KeyEvent.VK_2,
+ KeyEvent.VK_3,
+ KeyEvent.VK_4,
+ KeyEvent.VK_5,
+ KeyEvent.VK_6,
+ KeyEvent.VK_7,
+ KeyEvent.VK_8,
+ KeyEvent.VK_9,
+ KeyEvent.VK_SEMICOLON,
+ KeyEvent.VK_EQUALS,
+ KeyEvent.VK_A,
+ KeyEvent.VK_B,
+ KeyEvent.VK_C,
+ KeyEvent.VK_D,
+ KeyEvent.VK_E,
+ KeyEvent.VK_F,
+ KeyEvent.VK_G,
+ KeyEvent.VK_H,
+ KeyEvent.VK_I,
+ KeyEvent.VK_J,
+ KeyEvent.VK_K,
+ KeyEvent.VK_L,
+ KeyEvent.VK_M,
+ KeyEvent.VK_N,
+ KeyEvent.VK_O,
+ KeyEvent.VK_P,
+ KeyEvent.VK_Q,
+ KeyEvent.VK_R,
+ KeyEvent.VK_S,
+ KeyEvent.VK_T,
+ KeyEvent.VK_U,
+ KeyEvent.VK_V,
+ KeyEvent.VK_W,
+ KeyEvent.VK_X,
+ KeyEvent.VK_Y,
+ KeyEvent.VK_Z,
+ KeyEvent.VK_OPEN_BRACKET,
+ KeyEvent.VK_BACK_SLASH,
+ KeyEvent.VK_CLOSE_BRACKET,
+ KeyEvent.VK_NUMPAD0,
+ KeyEvent.VK_NUMPAD1,
+ KeyEvent.VK_NUMPAD2,
+ KeyEvent.VK_NUMPAD3,
+ KeyEvent.VK_NUMPAD4,
+ KeyEvent.VK_NUMPAD5,
+ KeyEvent.VK_NUMPAD6,
+ KeyEvent.VK_NUMPAD7,
+ KeyEvent.VK_NUMPAD8,
+ KeyEvent.VK_NUMPAD9,
+ KeyEvent.VK_MULTIPLY,
+ KeyEvent.VK_ADD,
+ KeyEvent.VK_SUBTRACT,
+ KeyEvent.VK_DECIMAL,
+ KeyEvent.VK_DIVIDE,
+ KeyEvent.VK_F1,
+ KeyEvent.VK_F2,
+ KeyEvent.VK_F3,
+ KeyEvent.VK_F4,
+ KeyEvent.VK_F5,
+ KeyEvent.VK_F6,
+ KeyEvent.VK_F7,
+ KeyEvent.VK_F8,
+ KeyEvent.VK_F9,
+ KeyEvent.VK_F10,
+ KeyEvent.VK_F11,
+ KeyEvent.VK_F12,
+ KeyEvent.VK_DELETE,
+ KeyEvent.VK_HELP,
+ KeyEvent.VK_META,
+ KeyEvent.VK_BACK_QUOTE,
+ KeyEvent.VK_QUOTE,
+ KeyEvent.VK_F13,
+ KeyEvent.VK_F14,
+ KeyEvent.VK_F15,
+ KeyEvent.VK_F16,
+ KeyEvent.VK_F17,
+ KeyEvent.VK_F18,
+ KeyEvent.VK_F19,
+ KeyEvent.VK_F20
+ };
+
+ keyPressedIndex = -1;
+ }
+
+ private void createAndShowGUI() {
+ frame = new Frame("Function Key Keycodes");
+ textArea = new TextArea();
+ textArea.setFocusable(true);
+ frame.add(textArea);
+ frame.pack();
+ frame.setSize(200, 200);
+
+ textArea.addKeyListener(keyListener = new KeyListener() {
+
+ @Override
+ public void keyTyped(KeyEvent ke) {
+ }
+
+ @Override
+ public void keyPressed(KeyEvent ke) {
+ if (allKeyArr[keyPressedIndex] != ke.getKeyCode()) {
+ throw new RuntimeException("Wrong keycode received");
+ }
+ }
+
+ @Override
+ public void keyReleased(KeyEvent ke) {
+ }
+ });
+ frame.setVisible(true);
+ }
+
+ private void removeListener() {
+ if (keyListener != null) {
+ textArea.removeKeyListener(keyListener);
+ keyListener = null;
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (null != frame) {
+ frame.dispose();
+ frame = null;
+ }
+ }
+
+ public void generateFunctionKeyPress() {
+ try {
+ Robot robot = new Robot();
+ robot.waitForIdle();
+
+ for (int i = 0; i < allKeyArr.length; i++) {
+ keyPressedIndex = i;
+ robot.keyPress(allKeyArr[i]);
+ robot.keyRelease(allKeyArr[i]);
+ robot.waitForIdle();
+ }
+ removeListener();
+
+ } catch (AWTException e) {
+ throw new RuntimeException("Robot creation failed");
+ }
+ }
+
+ public static void main(String args[]) {
+ AllKeyCode allKeyObj = new AllKeyCode();
+ allKeyObj.createAndShowGUI();
+ allKeyObj.generateFunctionKeyPress();
+ allKeyObj.dispose();
+
+ System.out.println("Test Passed");
+ }
+}
--- a/jdk/test/java/awt/print/PageFormat/PageFormatFromAttributes.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/print/PageFormat/PageFormatFromAttributes.java Thu Apr 07 11:03:59 2016 -0700
@@ -84,12 +84,13 @@
throw new RuntimeException("expected a media size");
}
double units = Size2DSyntax.INCH/72.0;
- int w = (int)(mediaSize.getX(1)/units);
- int h = (int)(mediaSize.getY(1)/units);
+ double w = mediaSize.getX(1) / units;
+ double h = mediaSize.getY(1) / units;
Paper paper = pf.getPaper();
- int pw = (int)paper.getWidth();
- int ph = (int)paper.getHeight();
- if (pw != w || ph != h) {
+ double pw = paper.getWidth();
+ double ph = paper.getHeight();
+ if (Math.round(pw) != Math.round(w) ||
+ Math.round(ph) != Math.round(h)) {
throw new RuntimeException("size not as specified");
}
}
--- a/jdk/test/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/print/PrinterJob/MultiMonPrintDlgTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -43,16 +43,18 @@
*/
public class MultiMonPrintDlgTest implements ActionListener {
- Frame primaryFrame = null;
- Frame secFrame = null;
- GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment().
+ private static boolean testPassed;
+ private static Thread mainThread;
+ private static boolean testGeneratedInterrupt;
+ private static int sleepTime = 30000;
+ private static String message = "User has not executed the test";
+
+ static Frame primaryFrame = null;
+ static Frame secFrame = null;
+ static GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment().
getScreenDevices();
- public MultiMonPrintDlgTest() throws Exception {
- if (gd.length <= 1) {
- System.out.println("This test should be run only on dual-monitor systems. Aborted!!");
- return;
- }
+ private static void init() throws Exception {
String[] instructions =
{
@@ -70,6 +72,10 @@
instructions,
"information", JOptionPane.INFORMATION_MESSAGE);
});
+ }
+
+ private void executeTest() {
+
GraphicsDevice defDev = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int x = 0;
Frame f = null;
@@ -95,31 +101,67 @@
}
public void actionPerformed (ActionEvent ae) {
- try {
- javax.print.attribute.PrintRequestAttributeSet prSet =
- new javax.print.attribute.HashPrintRequestAttributeSet();
- java.awt.print.PrinterJob.getPrinterJob().pageDialog(prSet);
- Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
- int dialogButton = JOptionPane.showConfirmDialog (w,
- "Did the pageDialog shown in non-default monitor?",
- null, JOptionPane.YES_NO_OPTION);
- if(dialogButton == JOptionPane.NO_OPTION) {
- throw new RuntimeException("PageDialog is shown in wrong monitor");
- }
+ javax.print.attribute.PrintRequestAttributeSet prSet =
+ new javax.print.attribute.HashPrintRequestAttributeSet();
+ java.awt.print.PrinterJob.getPrinterJob().pageDialog(prSet);
+ Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ int dialogButton = JOptionPane.showConfirmDialog (w,
+ "Did the pageDialog shown in non-default monitor?",
+ null, JOptionPane.YES_NO_OPTION);
+ if(dialogButton == JOptionPane.NO_OPTION) {
+ fail("PageDialog is shown in wrong monitor");
+ } else {
java.awt.print.PrinterJob.getPrinterJob().printDialog(prSet);
dialogButton = JOptionPane.showConfirmDialog (w,
- "Did the printDialog shown in non-default monitor?",
- null, JOptionPane.YES_NO_OPTION);
+ "Did the printDialog shown in non-default monitor?",
+ null, JOptionPane.YES_NO_OPTION);
if(dialogButton == JOptionPane.NO_OPTION) {
- throw new RuntimeException("PrintDialog is shown in wrong monitor");
+ fail("PrintDialog is shown in wrong monitor");
+ } else {
+ pass();
}
- } finally {
- primaryFrame.dispose();
- secFrame.dispose();
}
}
+ private static void dispose() {
+ primaryFrame.dispose();
+ secFrame.dispose();
+ }
+
+ public static synchronized void pass() {
+ testPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ public static synchronized void fail(String msg) {
+ testPassed = false;
+ message = msg;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
public static void main (String args[]) throws Exception {
+ if (gd.length <= 1) {
+ System.out.println("This test should be run only on dual-monitor systems. Aborted!!");
+ return;
+ }
+ init();
MultiMonPrintDlgTest test = new MultiMonPrintDlgTest();
+ test.executeTest();
+ mainThread = Thread.currentThread();
+
+ try {
+ mainThread.sleep(sleepTime);
+ } catch (InterruptedException ex) {
+ dispose();
+ if (!testPassed && testGeneratedInterrupt) {
+ throw new RuntimeException(message);
+ }
+ }
+ if (!testGeneratedInterrupt) {
+ dispose();
+ throw new RuntimeException(message);
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/PrintTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ * @test
+ * @bug 8151590
+ * @summary All radio button should be selected when we call
+ * setDefaultSelection(JobAttributes.DefaultSelectionType.ALL);
+ * @run main/manual PrintTest
+ */
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.JobAttributes;
+import java.awt.PageAttributes;
+import java.awt.PrintJob;
+import java.awt.Toolkit;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+public class PrintTest {
+
+ private static Thread mainThread;
+ private static boolean testPassed;
+ private static boolean testGeneratedInterrupt;
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ doTest(PrintTest::printTest);
+ }
+ });
+ mainThread = Thread.currentThread();
+ try {
+ mainThread.sleep(30000);
+ } catch (InterruptedException e) {
+ if (!testPassed && testGeneratedInterrupt) {
+ throw new RuntimeException("All radio button is not selected");
+ }
+ }
+ if (!testGeneratedInterrupt) {
+ throw new RuntimeException("user has not executed the test");
+ }
+ }
+
+ private static void printTest() {
+ JobAttributes job = new JobAttributes();
+ PageAttributes page = new PageAttributes();
+ job.setDialog(JobAttributes.DialogType.NATIVE);
+ job.setDefaultSelection(JobAttributes.DefaultSelectionType.ALL);
+ job.setFromPage(2);
+ job.setToPage(5);
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ // setting this dialog to native printdialog
+ if (tk != null) {
+ PrintJob pj = tk.getPrintJob(new JFrame(),
+ "testing the attribute setting ", job, page);
+ }
+ }
+
+ public static synchronized void pass() {
+ testPassed = true;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ public static synchronized void fail() {
+ testPassed = false;
+ testGeneratedInterrupt = true;
+ mainThread.interrupt();
+ }
+
+ private static void doTest(Runnable action) {
+ String description
+ = " Visual inspection of print dialog is required.\n"
+ + " A print dialog will be shown.\n "
+ + " Please verify ALL radio button is selected.\n"
+ + " If ALL radio button is selected,press PASS else press FAIL";
+
+ final JDialog dialog = new JDialog();
+ dialog.setTitle("printSelectionTest");
+ JTextArea textArea = new JTextArea(description);
+ textArea.setEditable(false);
+ final JButton testButton = new JButton("Start Test");
+ final JButton passButton = new JButton("PASS");
+ passButton.setEnabled(false);
+ passButton.addActionListener((e) -> {
+ dialog.dispose();
+ pass();
+ });
+ final JButton failButton = new JButton("FAIL");
+ failButton.setEnabled(false);
+ failButton.addActionListener((e) -> {
+ dialog.dispose();
+ fail();
+ });
+ testButton.addActionListener((e) -> {
+ testButton.setEnabled(false);
+ action.run();
+ passButton.setEnabled(true);
+ failButton.setEnabled(true);
+ });
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ mainPanel.add(textArea, BorderLayout.CENTER);
+ JPanel buttonPanel = new JPanel(new FlowLayout());
+ buttonPanel.add(testButton);
+ buttonPanel.add(passButton);
+ buttonPanel.add(failButton);
+ mainPanel.add(buttonPanel, BorderLayout.SOUTH);
+ dialog.add(mainPanel);
+ dialog.pack();
+ dialog.setVisible(true);
+ }
+}
--- a/jdk/test/java/awt/xembed/server/RunTestXEmbed.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/xembed/server/RunTestXEmbed.java Thu Apr 07 11:03:59 2016 -0700
@@ -28,8 +28,8 @@
* @author Denis Mikhalkin: area=awt.xembed
* @requires (!(os.family=="mac") & !(os.family=="windows"))
* @library /lib/testlibrary
+ * @modules java.desktop/sun.awt
* @build jdk.testlibrary.Platform
- * @modules java.desktop/sun.awt
* @compile JavaClient.java TesterClient.java TestXEmbedServer.java
* @run main/timeout=6000 RunTestXEmbed
*/
@@ -39,6 +39,7 @@
import java.util.logging.*;
import java.util.*;
import java.io.*;
+import jdk.testlibrary.Platform;
public class RunTestXEmbed extends TestXEmbedServer {
private static final Logger log = Logger.getLogger("test.xembed");
@@ -72,7 +73,7 @@
}
}
Process proc = Runtime.getRuntime().exec(java_home +
- "/bin/java -Dawt.toolkit=sun.awt.X11.XToolkit TesterClient "
+ "/bin/java -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED -Dawt.toolkit=sun.awt.X11.XToolkit TesterClient "
+ test.getName() + " " + window + buf,
enva);
System.err.println("Test for " + test.getName() + " has started.");
--- a/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/xembed/server/TestXEmbedServerJava.java Thu Apr 07 11:03:59 2016 -0700
@@ -26,6 +26,7 @@
* @bug 4931668
* @summary Tests XEmbed server/client functionality
* @author denis mikhalkin: area=awt.xembed
+ * @requires (!(os.family=="mac") & !(os.family=="windows"))
* @modules java.desktop/sun.awt
* @compile JavaClient.java TesterClient.java TestXEmbedServer.java
* @run main/manual TestXEmbedServerJava
@@ -38,9 +39,6 @@
public class TestXEmbedServerJava extends TestXEmbedServer {
public static void main(String[] args) {
- if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
- return;
- }
// Enabled XEmbed
System.setProperty("sun.awt.xembedserver", "true");
@@ -78,7 +76,7 @@
public Process startClient(Rectangle[] bounds, long window) {
try {
String java_home = System.getProperty("java.home");
- return Runtime.getRuntime().exec(java_home + "/bin/java JavaClient " + window);
+ return Runtime.getRuntime().exec(java_home + "/bin/java -XaddExports:java.desktop/sun.awt.X11=ALL-UNNAMED JavaClient " + window);
} catch (IOException ex1) {
ex1.printStackTrace();
}
--- a/jdk/test/java/awt/xembed/server/TesterClient.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/awt/xembed/server/TesterClient.java Thu Apr 07 11:03:59 2016 -0700
@@ -32,7 +32,6 @@
public static void main(String[] args) throws Throwable {
// First parameter is the name of the test, second is the window, the rest are rectangles
Class cl = Class.forName("sun.awt.X11.XEmbedServerTester");
- cl.getModule().addExports("sun.awt.X11",TesterClient.class.getModule());
test = cl.getMethod(args[0], new Class[0]);
long window = Long.parseLong(args[1]);
--- a/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -61,8 +61,8 @@
* loads all the classes in the BCL, get their declared fields,
* and call setAccessible(false) followed by setAccessible(true);
* @modules java.base/jdk.internal.module
- * @run main/othervm FieldSetAccessibleTest UNSECURE
- * @run main/othervm FieldSetAccessibleTest SECURE
+ * @run main/othervm -Djdk.launcher.addmods=ALL-SYSTEM FieldSetAccessibleTest UNSECURE
+ * @run main/othervm -Djdk.launcher.addmods=ALL-SYSTEM FieldSetAccessibleTest SECURE
*
* @author danielfuchs
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseByteArrayTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.function.Function;
+
+public abstract class VarHandleBaseByteArrayTest extends VarHandleBaseTest {
+
+ enum MemoryMode {
+ ALIGNED(0, false), UNALIGNED(0, true),
+ BIG_ENDIAN(1, false), LITTLE_ENDIAN(1, true),
+ READ_WRITE(2, false), READ_ONLY(2, true),;
+
+ final int bit;
+ final int value;
+
+ MemoryMode(int bit, boolean value) {
+ this.bit = bit;
+ this.value = value ? 1 << bit : 0;
+ }
+
+ boolean isSet(int bitSet) {
+ return (bitSet & (1 << bit)) == value;
+ }
+
+ static int bitSet(MemoryMode... modes) {
+ if (modes == null) return 0;
+
+ int set = 0;
+ for (MemoryMode m : modes) {
+ set = (set & ~(1 << m.bit)) | m.value;
+ }
+ return set;
+ }
+
+ static EnumSet<MemoryMode> enumSet(int bitSet) {
+ EnumSet<MemoryMode> es = EnumSet.noneOf(MemoryMode.class);
+ for (MemoryMode m : values()) {
+ if (m.isSet(bitSet)) {
+ es.add(m);
+ }
+ }
+ return es;
+ }
+ }
+
+ static class Source<T> {
+ final T s;
+ final int memoryModes;
+
+ public Source(T s, MemoryMode... modes) {
+ this.s = s;
+ memoryModes = MemoryMode.bitSet(modes);
+ }
+
+ @Override
+ public String toString() {
+ return s.getClass().getCanonicalName() + " " + MemoryMode.enumSet(memoryModes);
+ }
+ }
+
+ static abstract class ByteArrayViewSource<T> extends Source<T> {
+ public ByteArrayViewSource(T t, MemoryMode... modes) {
+ super(t, modes);
+ }
+
+ abstract void fill(byte value);
+
+ abstract void fill(byte[] values);
+ }
+
+ static class ByteArraySource extends ByteArrayViewSource<byte[]> {
+ public ByteArraySource(byte[] bytes, MemoryMode... modes) {
+ super(bytes, modes);
+ }
+
+ void fill(byte value) {
+ Arrays.fill(s, value);
+ }
+
+ void fill(byte[] values) {
+ for (int i = 0; i < s.length; i++) {
+ s[i] = values[i % values.length];
+ }
+ }
+ }
+
+ static class ByteBufferSource extends ByteArrayViewSource<ByteBuffer> {
+ public ByteBufferSource(ByteBuffer buffer, MemoryMode... modes) {
+ super(buffer, modes);
+ }
+
+ void fill(byte value) {
+ for (int i = 0; i < s.limit(); i++) {
+ s.put(i, value);
+ }
+ }
+
+ void fill(byte[] values) {
+ for (int i = 0; i < s.limit(); i++) {
+ s.put(i, values[i % values.length]);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return s + " " + MemoryMode.enumSet(memoryModes);
+ }
+ }
+
+ static class ByteBufferReadOnlySource extends ByteBufferSource {
+ final ByteBuffer rwSource;
+
+ public ByteBufferReadOnlySource(ByteBuffer roBuffer, ByteBuffer rwSource, MemoryMode... modes) {
+ super(roBuffer, modes);
+ this.rwSource = rwSource;
+ }
+
+ void fill(byte value) {
+ for (int i = 0; i < rwSource.limit(); i++) {
+ rwSource.put(i, value);
+ }
+ }
+
+ void fill(byte[] values) {
+ for (int i = 0; i < rwSource.limit(); i++) {
+ rwSource.put(i, values[i % values.length]);
+ }
+ }
+ }
+
+ static class VarHandleSource extends Source<VarHandle> {
+ VarHandleSource(VarHandle vh, MemoryMode... modes) {
+ super(vh, modes);
+ }
+
+ boolean matches(ByteArrayViewSource<?> bav) {
+ return s.coordinateTypes().get(0).isAssignableFrom(bav.s.getClass());
+ }
+
+ @Override
+ public String toString() {
+ return " VarHandle " + MemoryMode.enumSet(memoryModes);
+ }
+ }
+
+ static class VarHandleSourceAccessTestCase extends AccessTestCase<VarHandleSource> {
+ final ByteArrayViewSource<?> bs;
+ final VarHandleSource vhs;
+
+ VarHandleSourceAccessTestCase(String desc, ByteArrayViewSource<?> bs, VarHandleSource vhs, AccessTestAction<VarHandleSource> ata) {
+ this(desc, bs, vhs, ata, true);
+ }
+
+ VarHandleSourceAccessTestCase(String desc, ByteArrayViewSource<?> bs, VarHandleSource vhs, AccessTestAction<VarHandleSource> ata, boolean loop) {
+ super(vhs + " -> " + bs + " " + desc, ata, loop);
+ this.bs = bs;
+ this.vhs = vhs;
+ }
+
+ @Override
+ VarHandleSource get() {
+ return vhs;
+ }
+ }
+
+
+ static double rotateLeft(double i, int distance) {
+ return Double.longBitsToDouble(
+ Long.rotateLeft(Double.doubleToRawLongBits(i), distance));
+ }
+
+ static double rotateRight(double i, int distance) {
+ return Double.longBitsToDouble(
+ Long.rotateRight(Double.doubleToRawLongBits(i), distance));
+ }
+
+ static float rotateLeft(float i, int distance) {
+ return Float.intBitsToFloat(
+ Integer.rotateLeft(Float.floatToRawIntBits(i), distance));
+ }
+
+ static float rotateRight(float i, int distance) {
+ return Float.intBitsToFloat(
+ Integer.rotateRight(Float.floatToRawIntBits(i), distance));
+ }
+
+ static long rotateLeft(long i, int distance) {
+ return Long.rotateLeft(i, distance);
+ }
+
+ static long rotateRight(long i, int distance) {
+ return Long.rotateRight(i, distance);
+ }
+
+ static int rotateLeft(int i, int distance) {
+ return Integer.rotateLeft(i, distance);
+ }
+
+ static int rotateRight(int i, int distance) {
+ return Integer.rotateRight(i, distance);
+ }
+
+ static short rotateLeft(short i, int distance) {
+ int v = (i << 16) | i;
+ v = Integer.rotateLeft(v, distance);
+ return (short) v;
+ }
+
+ static short rotateRight(short i, int distance) {
+ int v = (i << 16) | i;
+ v = Integer.rotateRight(v, distance);
+ return (short) v;
+ }
+
+ static char rotateLeft(char i, int distance) {
+ int v = (i << 16) | i;
+ v = Integer.rotateLeft(v, distance);
+ return (char) v;
+ }
+
+ static char rotateRight(char i, int distance) {
+ int v = (i << 16) | i;
+ v = Integer.rotateRight(v, distance);
+ return (char) v;
+ }
+
+ static final int LENGTH_BYTES = 32;
+
+ byte[] array;
+
+ List<ByteArrayViewSource<?>> bavss;
+
+ List<VarHandleSource> vhss;
+
+ public void setupByteSources() {
+ array = new byte[LENGTH_BYTES];
+
+ // Native endianess
+ MemoryMode ne = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN
+ ? MemoryMode.BIG_ENDIAN : MemoryMode.LITTLE_ENDIAN;
+
+ bavss = new ArrayList<>();
+
+ // byte[] source
+ ByteArraySource a =
+ new ByteArraySource(array,
+ ne, MemoryMode.READ_WRITE);
+ bavss.add(a);
+
+
+ // Combinations of ByteBuffer sources
+ ByteBufferSource hbb =
+ new ByteBufferSource(ByteBuffer.wrap(array),
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(hbb);
+ ByteBufferReadOnlySource hbb_ro =
+ new ByteBufferReadOnlySource(hbb.s.asReadOnlyBuffer(), hbb.s,
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(hbb_ro);
+
+ ByteBufferSource hbb_offset_aligned =
+ new ByteBufferSource(ByteBuffer.wrap(array, array.length / 4, array.length / 2).slice(),
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(hbb_offset_aligned);
+ ByteBufferReadOnlySource hbb_offset_aligned_ro =
+ new ByteBufferReadOnlySource(hbb_offset_aligned.s.asReadOnlyBuffer(), hbb_offset_aligned.s,
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(hbb_offset_aligned_ro);
+
+ ByteBufferSource hbb_offset_unaligned =
+ new ByteBufferSource(ByteBuffer.wrap(array, array.length / 4 - 1, array.length / 2).slice(),
+ MemoryMode.UNALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(hbb_offset_unaligned);
+ ByteBufferReadOnlySource hbb_offset_unaligned_ro =
+ new ByteBufferReadOnlySource(hbb_offset_unaligned.s.asReadOnlyBuffer(), hbb_offset_unaligned.s,
+ MemoryMode.UNALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(hbb_offset_unaligned_ro);
+
+
+ ByteBufferSource dbb =
+ new ByteBufferSource(ByteBuffer.allocateDirect(array.length),
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(dbb);
+ ByteBufferReadOnlySource dbb_ro =
+ new ByteBufferReadOnlySource(dbb.s.asReadOnlyBuffer(), dbb.s,
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(dbb_ro);
+
+ ByteBufferSource dbb_offset_aligned =
+ new ByteBufferSource(dbb.s.slice().position(array.length / 4).limit(array.length / 4 + array.length / 2).slice(),
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(dbb_offset_aligned);
+ ByteBufferReadOnlySource dbb_offset_aligned_ro =
+ new ByteBufferReadOnlySource(dbb_offset_aligned.s.asReadOnlyBuffer(), dbb_offset_aligned.s,
+ MemoryMode.ALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(dbb_offset_aligned_ro);
+
+ ByteBufferSource dbb_offset_unaligned =
+ new ByteBufferSource(dbb.s.slice().position(array.length / 4 - 1).limit(array.length / 4 - 1 + array.length / 2).slice(),
+ MemoryMode.UNALIGNED, ne, MemoryMode.READ_WRITE);
+ bavss.add(dbb_offset_unaligned);
+ ByteBufferReadOnlySource dbb_offset_unaligned_ro =
+ new ByteBufferReadOnlySource(dbb_offset_unaligned.s.asReadOnlyBuffer(), dbb_offset_unaligned.s,
+ MemoryMode.UNALIGNED, ne, MemoryMode.READ_ONLY);
+ bavss.add(dbb_offset_unaligned_ro);
+ }
+
+ @BeforeClass
+ public void setup() {
+ setupByteSources();
+ setupVarHandleSources();
+ }
+
+ abstract void setupVarHandleSources();
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ return vhss.stream().map(cvh -> new Object[]{cvh}).toArray(Object[][]::new);
+ }
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<java.lang.Class<?>> aepts = Arrays.asList(byte[].class, int.class);
+ List<java.lang.Class<?>> bbpts = Arrays.asList(ByteBuffer.class, int.class);
+
+ Function<VarHandle, List<Class<?>>> vhToPts = vh ->
+ vh.coordinateTypes().get(0) == byte[].class ? aepts : bbpts;
+
+ return vhss.stream().map(vh -> new Object[]{vh.s, vhToPts.apply(vh.s)}).toArray(Object[][]::new);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle;
+import java.lang.invoke.WrongMethodTypeException;
+import java.lang.reflect.Method;
+import java.nio.ReadOnlyBufferException;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.toList;
+import static org.testng.Assert.*;
+
+abstract class VarHandleBaseTest {
+ static final int ITERS = Integer.getInteger("iters", 1);
+
+ interface ThrowingRunnable {
+ void run() throws Throwable;
+ }
+
+ static void checkUOE(ThrowingRunnable r) {
+ checkWithThrowable(UnsupportedOperationException.class, null, r);
+ }
+
+ static void checkUOE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(UnsupportedOperationException.class, message, r);
+ }
+
+ static void checkROBE(ThrowingRunnable r) {
+ checkWithThrowable(ReadOnlyBufferException.class, null, r);
+ }
+
+ static void checkROBE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(ReadOnlyBufferException.class, message, r);
+ }
+
+ static void checkIOOBE(ThrowingRunnable r) {
+ checkWithThrowable(IndexOutOfBoundsException.class, null, r);
+ }
+
+ static void checkIOOBE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(IndexOutOfBoundsException.class, message, r);
+ }
+
+ static void checkISE(ThrowingRunnable r) {
+ checkWithThrowable(IllegalStateException.class, null, r);
+ }
+
+ static void checkISE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(IllegalStateException.class, message, r);
+ }
+
+ static void checkIAE(ThrowingRunnable r) {
+ checkWithThrowable(IllegalAccessException.class, null, r);
+ }
+
+ static void checkIAE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(IllegalAccessException.class, message, r);
+ }
+
+ static void checkWMTE(ThrowingRunnable r) {
+ checkWithThrowable(WrongMethodTypeException.class, null, r);
+ }
+
+ static void checkWMTE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(WrongMethodTypeException.class, message, r);
+ }
+
+ static void checkCCE(ThrowingRunnable r) {
+ checkWithThrowable(ClassCastException.class, null, r);
+ }
+
+ static void checkCCE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(ClassCastException.class, message, r);
+ }
+
+ static void checkNPE(ThrowingRunnable r) {
+ checkWithThrowable(NullPointerException.class, null, r);
+ }
+
+ static void checkNPE(Object message, ThrowingRunnable r) {
+ checkWithThrowable(NullPointerException.class, message, r);
+ }
+
+ static void checkWithThrowable(Class<? extends Throwable> re,
+ Object message,
+ ThrowingRunnable r) {
+ Throwable _e = null;
+ try {
+ r.run();
+ }
+ catch (Throwable e) {
+ _e = e;
+ }
+ message = message == null ? "" : message + ". ";
+ assertNotNull(_e, String.format("%sNo throwable thrown. Expected %s", message, re));
+ assertTrue(re.isInstance(_e), String.format("%sIncorrect throwable thrown, %s. Expected %s", message, _e, re));
+ }
+
+
+ enum TestAccessType {
+ get,
+ set,
+ compareAndSet,
+ compareAndExchange,
+ getAndSet,
+ getAndAdd;
+ }
+
+ enum TestAccessMode {
+ get(TestAccessType.get),
+ set(TestAccessType.set),
+ getVolatile(TestAccessType.get),
+ setVolatile(TestAccessType.set),
+ getAcquire(TestAccessType.get),
+ setRelease(TestAccessType.set),
+ getOpaque(TestAccessType.get),
+ setOpaque(TestAccessType.set),
+ compareAndSet(TestAccessType.compareAndSet),
+ compareAndExchangeVolatile(TestAccessType.compareAndExchange),
+ compareAndExchangeAcquire(TestAccessType.compareAndExchange),
+ compareAndExchangeRelease(TestAccessType.compareAndExchange),
+ weakCompareAndSet(TestAccessType.compareAndSet),
+ weakCompareAndSetAcquire(TestAccessType.compareAndSet),
+ weakCompareAndSetRelease(TestAccessType.compareAndSet),
+ getAndSet(TestAccessType.getAndSet),
+ getAndAdd(TestAccessType.getAndAdd),
+ addAndGet(TestAccessType.getAndAdd),;
+
+ final TestAccessType at;
+ final boolean isPolyMorphicInReturnType;
+ final Class<?> returnType;
+
+ TestAccessMode(TestAccessType at) {
+ this.at = at;
+
+ try {
+ Method m = VarHandle.class.getMethod(name(), Object[].class);
+ this.returnType = m.getReturnType();
+ isPolyMorphicInReturnType = returnType != Object.class;
+ }
+ catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ boolean isOfType(TestAccessType at) {
+ return this.at == at;
+ }
+
+ VarHandle.AccessMode toAccessMode() {
+ return VarHandle.AccessMode.valueOf(name());
+ }
+ }
+
+ static List<TestAccessMode> testAccessModes() {
+ return Stream.of(TestAccessMode.values()).collect(toList());
+ }
+
+ static List<TestAccessMode> testAccessModesOfType(TestAccessType... ats) {
+ Stream<TestAccessMode> s = Stream.of(TestAccessMode.values());
+ for (TestAccessType at : ats) {
+ s = s.filter(e -> e.isOfType(at));
+ }
+ return s.collect(toList());
+ }
+
+ static List<VarHandle.AccessMode> accessModes() {
+ return Stream.of(VarHandle.AccessMode.values()).collect(toList());
+ }
+
+ static List<VarHandle.AccessMode> accessModesOfType(TestAccessType... ats) {
+ Stream<TestAccessMode> s = Stream.of(TestAccessMode.values());
+ for (TestAccessType at : ats) {
+ s = s.filter(e -> e.isOfType(at));
+ }
+ return s.map(TestAccessMode::toAccessMode).collect(toList());
+ }
+
+ static MethodHandle toMethodHandle(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ return vh.toMethodHandle(tam.toAccessMode());
+ }
+
+ static MethodHandle findVirtual(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ mt = vh.accessModeType(tam.toAccessMode());
+ MethodHandle mh;
+ try {
+ mh = MethodHandles.publicLookup().
+ findVirtual(VarHandle.class,
+ tam.name(),
+ mt);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return bind(vh, tam, mh, mt);
+ }
+
+ static MethodHandle varHandleInvokerWithAccessModeType(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ mt = vh.accessModeType(tam.toAccessMode());
+ MethodHandle mh = MethodHandles.varHandleInvoker(
+ tam.toAccessMode(),
+ mt);
+
+ return bind(vh, tam, mh, mt);
+ }
+
+ static MethodHandle varHandleInvokerWithSymbolicTypeDescriptor(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ MethodHandle mh = MethodHandles.varHandleInvoker(
+ tam.toAccessMode(),
+ mt);
+
+ return bind(vh, tam, mh, mt);
+ }
+
+ static MethodHandle varHandleExactInvokerWithAccessModeType(VarHandle vh, TestAccessMode tam, MethodType mt) {
+ mt = vh.accessModeType(tam.toAccessMode());
+ MethodHandle mh = MethodHandles.varHandleExactInvoker(
+ tam.toAccessMode(),
+ mt);
+
+ return bind(vh, tam, mh, mt);
+ }
+
+ private static MethodHandle bind(VarHandle vh, TestAccessMode testAccessMode, MethodHandle mh, MethodType emt) {
+ assertEquals(mh.type(), emt.insertParameterTypes(0, VarHandle.class),
+ "MethodHandle type differs from access mode type");
+
+ MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh);
+ assertEquals(info.getMethodType(), emt,
+ "MethodHandleInfo method type differs from access mode type");
+
+ return mh.bindTo(vh);
+ }
+
+ private interface TriFunction<T, U, V, R> {
+ R apply(T t, U u, V v);
+ }
+
+ enum VarHandleToMethodHandle {
+ VAR_HANDLE_TO_METHOD_HANDLE(
+ "VarHandle.toMethodHandle",
+ VarHandleBaseTest::toMethodHandle),
+ METHOD_HANDLES_LOOKUP_FIND_VIRTUAL(
+ "Lookup.findVirtual",
+ VarHandleBaseTest::findVirtual),
+ METHOD_HANDLES_VAR_HANDLE_INVOKER_WITH_ACCESS_MODE_TYPE(
+ "MethodHandles.varHandleInvoker(accessModeType)",
+ VarHandleBaseTest::varHandleInvokerWithAccessModeType),
+ METHOD_HANDLES_VAR_HANDLE_INVOKER_WITH_SYMBOLIC_TYPE_DESCRIPTOR(
+ "MethodHandles.varHandleInvoker(symbolicTypeDescriptor)",
+ VarHandleBaseTest::varHandleInvokerWithSymbolicTypeDescriptor),
+ METHOD_HANDLES_VAR_HANDLE_EXACT_INVOKER_WITH_ACCESS_MODE_TYPE(
+ "MethodHandles.varHandleExactInvoker(accessModeType)",
+ VarHandleBaseTest::varHandleExactInvokerWithAccessModeType);
+
+ final String desc;
+ final TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f;
+ final boolean exact;
+
+ VarHandleToMethodHandle(String desc, TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f) {
+ this(desc, f, false);
+ }
+
+ VarHandleToMethodHandle(String desc, TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f,
+ boolean exact) {
+ this.desc = desc;
+ this.f = f;
+ this.exact = exact;
+ }
+
+ MethodHandle apply(VarHandle vh, TestAccessMode am, MethodType mt) {
+ return f.apply(vh, am, mt);
+ }
+
+ @Override
+ public String toString() {
+ return desc;
+ }
+ }
+
+ static class Handles {
+ static class AccessModeAndType {
+ final TestAccessMode tam;
+ final MethodType t;
+
+ public AccessModeAndType(TestAccessMode tam, MethodType t) {
+ this.tam = tam;
+ this.t = t;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ AccessModeAndType x = (AccessModeAndType) o;
+
+ if (tam != x.tam) return false;
+ if (t != null ? !t.equals(x.t) : x.t != null) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = tam != null ? tam.hashCode() : 0;
+ result = 31 * result + (t != null ? t.hashCode() : 0);
+ return result;
+ }
+ }
+
+ final VarHandle vh;
+ final VarHandleToMethodHandle f;
+ final EnumMap<TestAccessMode, MethodType> amToType;
+ final Map<AccessModeAndType, MethodHandle> amToHandle;
+
+ Handles(VarHandle vh, VarHandleToMethodHandle f) throws Exception {
+ this.vh = vh;
+ this.f = f;
+ this.amToHandle = new HashMap<>();
+
+ amToType = new EnumMap<>(TestAccessMode.class);
+ for (TestAccessMode am : testAccessModes()) {
+ amToType.put(am, vh.accessModeType(am.toAccessMode()));
+ }
+ }
+
+ MethodHandle get(TestAccessMode am) {
+ return get(am, amToType.get(am));
+ }
+
+ MethodHandle get(TestAccessMode am, MethodType mt) {
+ AccessModeAndType amt = new AccessModeAndType(am, mt);
+ return amToHandle.computeIfAbsent(
+ amt, k -> f.apply(vh, am, mt));
+ }
+ }
+
+ interface AccessTestAction<T> {
+ void action(T t) throws Throwable;
+ }
+
+ static abstract class AccessTestCase<T> {
+ final String desc;
+ final AccessTestAction<T> ata;
+ final boolean loop;
+
+ AccessTestCase(String desc, AccessTestAction<T> ata, boolean loop) {
+ this.desc = desc;
+ this.ata = ata;
+ this.loop = loop;
+ }
+
+ boolean requiresLoop() {
+ return loop;
+ }
+
+ abstract T get() throws Exception;
+
+ void testAccess(T t) throws Throwable {
+ ata.action(t);
+ }
+
+ @Override
+ public String toString() {
+ return desc;
+ }
+ }
+
+ static class VarHandleAccessTestCase extends AccessTestCase<VarHandle> {
+ final VarHandle vh;
+
+ VarHandleAccessTestCase(String desc, VarHandle vh, AccessTestAction<VarHandle> ata) {
+ this(desc, vh, ata, true);
+ }
+
+ VarHandleAccessTestCase(String desc, VarHandle vh, AccessTestAction<VarHandle> ata, boolean loop) {
+ super("VarHandle -> " + desc, ata, loop);
+ this.vh = vh;
+ }
+
+ @Override
+ VarHandle get() {
+ return vh;
+ }
+ }
+
+ static class MethodHandleAccessTestCase extends AccessTestCase<Handles> {
+ final VarHandle vh;
+ final VarHandleToMethodHandle f;
+
+ MethodHandleAccessTestCase(String desc, VarHandle vh, VarHandleToMethodHandle f, AccessTestAction<Handles> ata) {
+ this(desc, vh, f, ata, true);
+ }
+
+ MethodHandleAccessTestCase(String desc, VarHandle vh, VarHandleToMethodHandle f, AccessTestAction<Handles> ata, boolean loop) {
+ super("VarHandle -> " + f.toString() + " -> " + desc, ata, loop);
+ this.vh = vh;
+ this.f = f;
+ }
+
+ @Override
+ Handles get() throws Exception {
+ return new Handles(vh, f);
+ }
+ }
+
+ static void testTypes(VarHandle vh) {
+ List<Class<?>> pts = vh.coordinateTypes();
+
+ for (TestAccessMode accessMode : testAccessModes()) {
+ MethodType amt = vh.accessModeType(accessMode.toAccessMode());
+
+ assertEquals(amt.parameterList().subList(0, pts.size()), pts);
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.get)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), vh.varType());
+ assertEquals(mt.parameterList(), pts);
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.set)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), void.class);
+ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), boolean.class);
+ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
+ assertEquals(mt.parameterType(mt.parameterCount() - 2), vh.varType());
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), vh.varType());
+ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
+ assertEquals(mt.parameterType(mt.parameterCount() - 2), vh.varType());
+ }
+
+ for (TestAccessMode testAccessMode : testAccessModesOfType(TestAccessType.getAndSet, TestAccessType.getAndAdd)) {
+ MethodType mt = vh.accessModeType(testAccessMode.toAccessMode());
+ assertEquals(mt.returnType(), vh.varType());
+ assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType());
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessBoolean
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessBoolean
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessBoolean
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessBoolean
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessBoolean extends VarHandleBaseTest {
+ static final boolean static_final_v = true;
+
+ static boolean static_v;
+
+ final boolean final_v = true;
+
+ boolean v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessBoolean.class, "final_v", boolean.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessBoolean.class, "v", boolean.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessBoolean.class, "static_final_v", boolean.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessBoolean.class, "static_v", boolean.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(boolean[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessBoolean.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(boolean[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), boolean.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessBoolean.class, "final_v", boolean.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessBoolean.class, "v", boolean.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessBoolean.class, "static_final_v", boolean.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessBoolean.class, "static_v", boolean.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessBoolean::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessBoolean::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessBoolean::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessBoolean::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessBoolean::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessBoolean::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessBoolean::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessBoolean recv, VarHandle vh) {
+ // Plain
+ {
+ boolean x = (boolean) vh.get(recv);
+ assertEquals(x, true, "get boolean value");
+ }
+
+
+ // Volatile
+ {
+ boolean x = (boolean) vh.getVolatile(recv);
+ assertEquals(x, true, "getVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ boolean x = (boolean) vh.getAcquire(recv);
+ assertEquals(x, true, "getRelease boolean value");
+ }
+
+ // Opaque
+ {
+ boolean x = (boolean) vh.getOpaque(recv);
+ assertEquals(x, true, "getOpaque boolean value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessBoolean recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, false);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, false);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, false);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(recv, true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(recv, true);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ boolean x = (boolean) vh.get();
+ assertEquals(x, true, "get boolean value");
+ }
+
+
+ // Volatile
+ {
+ boolean x = (boolean) vh.getVolatile();
+ assertEquals(x, true, "getVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ boolean x = (boolean) vh.getAcquire();
+ assertEquals(x, true, "getRelease boolean value");
+ }
+
+ // Opaque
+ {
+ boolean x = (boolean) vh.getOpaque();
+ assertEquals(x, true, "getOpaque boolean value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(false);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(false);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(false);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(true);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessBoolean recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, true);
+ boolean x = (boolean) vh.get(recv);
+ assertEquals(x, true, "set boolean value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, false);
+ boolean x = (boolean) vh.getVolatile(recv);
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, true);
+ boolean x = (boolean) vh.getAcquire(recv);
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, false);
+ boolean x = (boolean) vh.getOpaque(recv);
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessBoolean recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(recv, true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(recv, true);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(true);
+ boolean x = (boolean) vh.get();
+ assertEquals(x, true, "set boolean value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(false);
+ boolean x = (boolean) vh.getVolatile();
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(true);
+ boolean x = (boolean) vh.getAcquire();
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(false);
+ boolean x = (boolean) vh.getOpaque();
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(true);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ boolean[] array = new boolean[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, true);
+ boolean x = (boolean) vh.get(array, i);
+ assertEquals(x, true, "get boolean value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, false);
+ boolean x = (boolean) vh.getVolatile(array, i);
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, true);
+ boolean x = (boolean) vh.getAcquire(array, i);
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, false);
+ boolean x = (boolean) vh.getOpaque(array, i);
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ boolean[] array = new boolean[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeVolatile(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeAcquire(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = (boolean) vh.compareAndExchangeRelease(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, true, false);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.getAndAdd(array, i, true);
+ });
+
+ checkUOE(() -> {
+ boolean o = (boolean) vh.addAndGet(array, i, true);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ boolean[] array = new boolean[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ boolean x = (boolean) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, true);
+ });
+
+ checkIOOBE(() -> {
+ boolean x = (boolean) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, true);
+ });
+
+ checkIOOBE(() -> {
+ boolean x = (boolean) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, true);
+ });
+
+ checkIOOBE(() -> {
+ boolean x = (boolean) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, true);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessByte
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessByte
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessByte
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessByte extends VarHandleBaseTest {
+ static final byte static_final_v = (byte)1;
+
+ static byte static_v;
+
+ final byte final_v = (byte)1;
+
+ byte v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessByte.class, "final_v", byte.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessByte.class, "v", byte.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessByte.class, "static_final_v", byte.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessByte.class, "static_v", byte.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(byte[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessByte.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(byte[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), byte.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessByte.class, "final_v", byte.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessByte.class, "v", byte.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessByte.class, "static_final_v", byte.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessByte.class, "static_v", byte.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessByte::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessByte::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessByte::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessByte::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessByte::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessByte::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessByte recv, VarHandle vh) {
+ // Plain
+ {
+ byte x = (byte) vh.get(recv);
+ assertEquals(x, (byte)1, "get byte value");
+ }
+
+
+ // Volatile
+ {
+ byte x = (byte) vh.getVolatile(recv);
+ assertEquals(x, (byte)1, "getVolatile byte value");
+ }
+
+ // Lazy
+ {
+ byte x = (byte) vh.getAcquire(recv);
+ assertEquals(x, (byte)1, "getRelease byte value");
+ }
+
+ // Opaque
+ {
+ byte x = (byte) vh.getOpaque(recv);
+ assertEquals(x, (byte)1, "getOpaque byte value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, (byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, (byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, (byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd(recv, (byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet(recv, (byte)1);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ byte x = (byte) vh.get();
+ assertEquals(x, (byte)1, "get byte value");
+ }
+
+
+ // Volatile
+ {
+ byte x = (byte) vh.getVolatile();
+ assertEquals(x, (byte)1, "getVolatile byte value");
+ }
+
+ // Lazy
+ {
+ byte x = (byte) vh.getAcquire();
+ assertEquals(x, (byte)1, "getRelease byte value");
+ }
+
+ // Opaque
+ {
+ byte x = (byte) vh.getOpaque();
+ assertEquals(x, (byte)1, "getOpaque byte value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set((byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile((byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease((byte)2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque((byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd((byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet((byte)1);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessByte recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, (byte)1);
+ byte x = (byte) vh.get(recv);
+ assertEquals(x, (byte)1, "set byte value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, (byte)2);
+ byte x = (byte) vh.getVolatile(recv);
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, (byte)1);
+ byte x = (byte) vh.getAcquire(recv);
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, (byte)2);
+ byte x = (byte) vh.getOpaque(recv);
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessByte recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd(recv, (byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet(recv, (byte)1);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set((byte)1);
+ byte x = (byte) vh.get();
+ assertEquals(x, (byte)1, "set byte value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile((byte)2);
+ byte x = (byte) vh.getVolatile();
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease((byte)1);
+ byte x = (byte) vh.getAcquire();
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque((byte)2);
+ byte x = (byte) vh.getOpaque();
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd((byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet((byte)1);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ byte[] array = new byte[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, (byte)1);
+ byte x = (byte) vh.get(array, i);
+ assertEquals(x, (byte)1, "get byte value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, (byte)2);
+ byte x = (byte) vh.getVolatile(array, i);
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, (byte)1);
+ byte x = (byte) vh.getAcquire(array, i);
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, (byte)2);
+ byte x = (byte) vh.getOpaque(array, i);
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ byte[] array = new byte[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeVolatile(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeAcquire(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte r = (byte) vh.compareAndExchangeRelease(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, (byte)1, (byte)2);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.getAndAdd(array, i, (byte)1);
+ });
+
+ checkUOE(() -> {
+ byte o = (byte) vh.addAndGet(array, i, (byte)1);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ byte[] array = new byte[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ byte x = (byte) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, (byte)1);
+ });
+
+ checkIOOBE(() -> {
+ byte x = (byte) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, (byte)1);
+ });
+
+ checkIOOBE(() -> {
+ byte x = (byte) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, (byte)1);
+ });
+
+ checkIOOBE(() -> {
+ byte x = (byte) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, (byte)1);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessChar
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessChar
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessChar
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessChar
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessChar extends VarHandleBaseTest {
+ static final char static_final_v = 'a';
+
+ static char static_v;
+
+ final char final_v = 'a';
+
+ char v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessChar.class, "final_v", char.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessChar.class, "v", char.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessChar.class, "static_final_v", char.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessChar.class, "static_v", char.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(char[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessChar.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(char[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), char.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessChar.class, "final_v", char.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessChar.class, "v", char.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessChar.class, "static_final_v", char.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessChar.class, "static_v", char.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessChar::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessChar::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessChar::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessChar::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessChar::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessChar::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessChar::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessChar recv, VarHandle vh) {
+ // Plain
+ {
+ char x = (char) vh.get(recv);
+ assertEquals(x, 'a', "get char value");
+ }
+
+
+ // Volatile
+ {
+ char x = (char) vh.getVolatile(recv);
+ assertEquals(x, 'a', "getVolatile char value");
+ }
+
+ // Lazy
+ {
+ char x = (char) vh.getAcquire(recv);
+ assertEquals(x, 'a', "getRelease char value");
+ }
+
+ // Opaque
+ {
+ char x = (char) vh.getOpaque(recv);
+ assertEquals(x, 'a', "getOpaque char value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessChar recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 'b');
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 'b');
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 'b');
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(recv, 'a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(recv, 'a');
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ char x = (char) vh.get();
+ assertEquals(x, 'a', "get char value");
+ }
+
+
+ // Volatile
+ {
+ char x = (char) vh.getVolatile();
+ assertEquals(x, 'a', "getVolatile char value");
+ }
+
+ // Lazy
+ {
+ char x = (char) vh.getAcquire();
+ assertEquals(x, 'a', "getRelease char value");
+ }
+
+ // Opaque
+ {
+ char x = (char) vh.getOpaque();
+ assertEquals(x, 'a', "getOpaque char value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set('b');
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile('b');
+ });
+
+ checkUOE(() -> {
+ vh.setRelease('b');
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque('b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd('a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet('a');
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessChar recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 'a');
+ char x = (char) vh.get(recv);
+ assertEquals(x, 'a', "set char value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 'b');
+ char x = (char) vh.getVolatile(recv);
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 'a');
+ char x = (char) vh.getAcquire(recv);
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 'b');
+ char x = (char) vh.getOpaque(recv);
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessChar recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(recv, 'a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(recv, 'a');
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set('a');
+ char x = (char) vh.get();
+ assertEquals(x, 'a', "set char value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile('b');
+ char x = (char) vh.getVolatile();
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease('a');
+ char x = (char) vh.getAcquire();
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque('b');
+ char x = (char) vh.getOpaque();
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire('a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease('a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd('a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet('a');
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ char[] array = new char[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 'a');
+ char x = (char) vh.get(array, i);
+ assertEquals(x, 'a', "get char value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 'b');
+ char x = (char) vh.getVolatile(array, i);
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 'a');
+ char x = (char) vh.getAcquire(array, i);
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 'b');
+ char x = (char) vh.getOpaque(array, i);
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ char[] array = new char[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 'a', 'b');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(array, i, 'a');
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(array, i, 'a');
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ char[] array = new char[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ char x = (char) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 'a');
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 'a');
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 'a');
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 'a');
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessDouble
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessDouble
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessDouble
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessDouble
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessDouble extends VarHandleBaseTest {
+ static final double static_final_v = 1.0d;
+
+ static double static_v;
+
+ final double final_v = 1.0d;
+
+ double v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessDouble.class, "final_v", double.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessDouble.class, "v", double.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessDouble.class, "static_final_v", double.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessDouble.class, "static_v", double.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(double[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessDouble.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(double[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), double.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessDouble.class, "final_v", double.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessDouble.class, "v", double.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessDouble.class, "static_final_v", double.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessDouble.class, "static_v", double.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessDouble::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessDouble::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessDouble::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessDouble::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessDouble::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessDouble::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessDouble::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessDouble recv, VarHandle vh) {
+ // Plain
+ {
+ double x = (double) vh.get(recv);
+ assertEquals(x, 1.0d, "get double value");
+ }
+
+
+ // Volatile
+ {
+ double x = (double) vh.getVolatile(recv);
+ assertEquals(x, 1.0d, "getVolatile double value");
+ }
+
+ // Lazy
+ {
+ double x = (double) vh.getAcquire(recv);
+ assertEquals(x, 1.0d, "getRelease double value");
+ }
+
+ // Opaque
+ {
+ double x = (double) vh.getOpaque(recv);
+ assertEquals(x, 1.0d, "getOpaque double value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessDouble recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(recv, 1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(recv, 1.0d);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ double x = (double) vh.get();
+ assertEquals(x, 1.0d, "get double value");
+ }
+
+
+ // Volatile
+ {
+ double x = (double) vh.getVolatile();
+ assertEquals(x, 1.0d, "getVolatile double value");
+ }
+
+ // Lazy
+ {
+ double x = (double) vh.getAcquire();
+ assertEquals(x, 1.0d, "getRelease double value");
+ }
+
+ // Opaque
+ {
+ double x = (double) vh.getOpaque();
+ assertEquals(x, 1.0d, "getOpaque double value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(2.0d);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(1.0d);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessDouble recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 1.0d);
+ double x = (double) vh.get(recv);
+ assertEquals(x, 1.0d, "set double value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 2.0d);
+ double x = (double) vh.getVolatile(recv);
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 1.0d);
+ double x = (double) vh.getAcquire(recv);
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 2.0d);
+ double x = (double) vh.getOpaque(recv);
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessDouble recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(recv, 1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(recv, 1.0d);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(1.0d);
+ double x = (double) vh.get();
+ assertEquals(x, 1.0d, "set double value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(2.0d);
+ double x = (double) vh.getVolatile();
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(1.0d);
+ double x = (double) vh.getAcquire();
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(2.0d);
+ double x = (double) vh.getOpaque();
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(1.0d);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ double[] array = new double[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 1.0d);
+ double x = (double) vh.get(array, i);
+ assertEquals(x, 1.0d, "get double value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 2.0d);
+ double x = (double) vh.getVolatile(array, i);
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 1.0d);
+ double x = (double) vh.getAcquire(array, i);
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 2.0d);
+ double x = (double) vh.getOpaque(array, i);
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ double[] array = new double[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 1.0d, 2.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(array, i, 1.0d);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(array, i, 1.0d);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ double[] array = new double[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ double x = (double) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 1.0d);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 1.0d);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 1.0d);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 1.0d);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessFloat
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessFloat
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessFloat
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessFloat
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessFloat extends VarHandleBaseTest {
+ static final float static_final_v = 1.0f;
+
+ static float static_v;
+
+ final float final_v = 1.0f;
+
+ float v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessFloat.class, "final_v", float.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessFloat.class, "v", float.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessFloat.class, "static_final_v", float.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessFloat.class, "static_v", float.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(float[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessFloat.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(float[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), float.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessFloat.class, "final_v", float.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessFloat.class, "v", float.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessFloat.class, "static_final_v", float.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessFloat.class, "static_v", float.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessFloat::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessFloat::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessFloat::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessFloat::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessFloat::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessFloat::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessFloat::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessFloat recv, VarHandle vh) {
+ // Plain
+ {
+ float x = (float) vh.get(recv);
+ assertEquals(x, 1.0f, "get float value");
+ }
+
+
+ // Volatile
+ {
+ float x = (float) vh.getVolatile(recv);
+ assertEquals(x, 1.0f, "getVolatile float value");
+ }
+
+ // Lazy
+ {
+ float x = (float) vh.getAcquire(recv);
+ assertEquals(x, 1.0f, "getRelease float value");
+ }
+
+ // Opaque
+ {
+ float x = (float) vh.getOpaque(recv);
+ assertEquals(x, 1.0f, "getOpaque float value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessFloat recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(recv, 1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(recv, 1.0f);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ float x = (float) vh.get();
+ assertEquals(x, 1.0f, "get float value");
+ }
+
+
+ // Volatile
+ {
+ float x = (float) vh.getVolatile();
+ assertEquals(x, 1.0f, "getVolatile float value");
+ }
+
+ // Lazy
+ {
+ float x = (float) vh.getAcquire();
+ assertEquals(x, 1.0f, "getRelease float value");
+ }
+
+ // Opaque
+ {
+ float x = (float) vh.getOpaque();
+ assertEquals(x, 1.0f, "getOpaque float value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(2.0f);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(1.0f);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessFloat recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 1.0f);
+ float x = (float) vh.get(recv);
+ assertEquals(x, 1.0f, "set float value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 2.0f);
+ float x = (float) vh.getVolatile(recv);
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 1.0f);
+ float x = (float) vh.getAcquire(recv);
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 2.0f);
+ float x = (float) vh.getOpaque(recv);
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessFloat recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(recv, 1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(recv, 1.0f);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(1.0f);
+ float x = (float) vh.get();
+ assertEquals(x, 1.0f, "set float value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(2.0f);
+ float x = (float) vh.getVolatile();
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(1.0f);
+ float x = (float) vh.getAcquire();
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(2.0f);
+ float x = (float) vh.getOpaque();
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(1.0f);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ float[] array = new float[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 1.0f);
+ float x = (float) vh.get(array, i);
+ assertEquals(x, 1.0f, "get float value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 2.0f);
+ float x = (float) vh.getVolatile(array, i);
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 1.0f);
+ float x = (float) vh.getAcquire(array, i);
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 2.0f);
+ float x = (float) vh.getOpaque(array, i);
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ float[] array = new float[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 1.0f, 2.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(array, i, 1.0f);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(array, i, 1.0f);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ float[] array = new float[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ float x = (float) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 1.0f);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 1.0f);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 1.0f);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 1.0f);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessInt
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessInt
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessInt
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessInt
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessInt extends VarHandleBaseTest {
+ static final int static_final_v = 1;
+
+ static int static_v;
+
+ final int final_v = 1;
+
+ int v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessInt.class, "final_v", int.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessInt.class, "v", int.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessInt.class, "static_final_v", int.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessInt.class, "static_v", int.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(int[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessInt.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(int[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), int.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessInt.class, "final_v", int.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessInt.class, "v", int.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessInt.class, "static_final_v", int.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessInt.class, "static_v", int.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessInt::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessInt::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessInt::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessInt::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessInt::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessInt::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessInt::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessInt recv, VarHandle vh) {
+ // Plain
+ {
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "get int value");
+ }
+
+
+ // Volatile
+ {
+ int x = (int) vh.getVolatile(recv);
+ assertEquals(x, 1, "getVolatile int value");
+ }
+
+ // Lazy
+ {
+ int x = (int) vh.getAcquire(recv);
+ assertEquals(x, 1, "getRelease int value");
+ }
+
+ // Opaque
+ {
+ int x = (int) vh.getOpaque(recv);
+ assertEquals(x, 1, "getOpaque int value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessInt recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 2);
+ });
+
+
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ int x = (int) vh.get();
+ assertEquals(x, 1, "get int value");
+ }
+
+
+ // Volatile
+ {
+ int x = (int) vh.getVolatile();
+ assertEquals(x, 1, "getVolatile int value");
+ }
+
+ // Lazy
+ {
+ int x = (int) vh.getAcquire();
+ assertEquals(x, 1, "getRelease int value");
+ }
+
+ // Opaque
+ {
+ int x = (int) vh.getOpaque();
+ assertEquals(x, 1, "getOpaque int value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(2);
+ });
+
+
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessInt recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 1);
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "set int value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 2);
+ int x = (int) vh.getVolatile(recv);
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 1);
+ int x = (int) vh.getAcquire(recv);
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 2);
+ int x = (int) vh.getOpaque(recv);
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ vh.set(recv, 1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(recv, 1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(recv, 1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(recv, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(recv, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(recv, 1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(recv, 1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(recv, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(recv, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(recv, 1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet(recv, 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) vh.get(recv);
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ vh.set(recv, 1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd(recv, 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) vh.addAndGet(recv, 3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessInt recv, VarHandle vh) {
+
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(1);
+ int x = (int) vh.get();
+ assertEquals(x, 1, "set int value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(2);
+ int x = (int) vh.getVolatile();
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(1);
+ int x = (int) vh.getAcquire();
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(2);
+ int x = (int) vh.getOpaque();
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ vh.set(1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSet(1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetAcquire(2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetRelease( 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get();
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet( 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) vh.get();
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ vh.set(1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd( 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) vh.addAndGet(3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+
+ }
+
+
+ static void testArray(VarHandle vh) {
+ int[] array = new int[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 1);
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "get int value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 2);
+ int x = (int) vh.getVolatile(array, i);
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 1);
+ int x = (int) vh.getAcquire(array, i);
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 2);
+ int x = (int) vh.getOpaque(array, i);
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ vh.set(array, i, 1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, 1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, 1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, 1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, 1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, 1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet(array, i, 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ vh.set(array, i, 1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd(array, i, 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) vh.addAndGet(array, i, 3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ int[] array = new int[10];
+
+ int i = 0;
+
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ int[] array = new int[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ int x = (int) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, 1, 2);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, 2, 1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, 2, 1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, 2, 1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, 1, 2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, 1, 2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, 1, 2);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndSet(array, ci, 1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, 3);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.addAndGet(array, ci, 3);
+ });
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,803 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessLong
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessLong
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessLong
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessLong
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessLong extends VarHandleBaseTest {
+ static final long static_final_v = 1L;
+
+ static long static_v;
+
+ final long final_v = 1L;
+
+ long v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessLong.class, "final_v", long.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessLong.class, "v", long.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessLong.class, "static_final_v", long.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessLong.class, "static_v", long.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(long[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessLong.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(long[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), long.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessLong.class, "final_v", long.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessLong.class, "v", long.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessLong.class, "static_final_v", long.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessLong.class, "static_v", long.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessLong::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessLong::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessLong::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessLong::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessLong::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessLong::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessLong::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessLong recv, VarHandle vh) {
+ // Plain
+ {
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "get long value");
+ }
+
+
+ // Volatile
+ {
+ long x = (long) vh.getVolatile(recv);
+ assertEquals(x, 1L, "getVolatile long value");
+ }
+
+ // Lazy
+ {
+ long x = (long) vh.getAcquire(recv);
+ assertEquals(x, 1L, "getRelease long value");
+ }
+
+ // Opaque
+ {
+ long x = (long) vh.getOpaque(recv);
+ assertEquals(x, 1L, "getOpaque long value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessLong recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, 2L);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, 2L);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, 2L);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, 2L);
+ });
+
+
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "get long value");
+ }
+
+
+ // Volatile
+ {
+ long x = (long) vh.getVolatile();
+ assertEquals(x, 1L, "getVolatile long value");
+ }
+
+ // Lazy
+ {
+ long x = (long) vh.getAcquire();
+ assertEquals(x, 1L, "getRelease long value");
+ }
+
+ // Opaque
+ {
+ long x = (long) vh.getOpaque();
+ assertEquals(x, 1L, "getOpaque long value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(2L);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(2L);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(2L);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(2L);
+ });
+
+
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessLong recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, 1L);
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "set long value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, 2L);
+ long x = (long) vh.getVolatile(recv);
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, 1L);
+ long x = (long) vh.getAcquire(recv);
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, 2L);
+ long x = (long) vh.getOpaque(recv);
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ vh.set(recv, 1L);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(recv, 1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(recv, 1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(recv, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(recv, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(recv, 1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(recv, 1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(recv, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(recv, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(recv, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(recv, 2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(recv, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet(recv, 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) vh.get(recv);
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ vh.set(recv, 1L);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd(recv, 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) vh.addAndGet(recv, 3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessLong recv, VarHandle vh) {
+
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set(1L);
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "set long value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(2L);
+ long x = (long) vh.getVolatile();
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(1L);
+ long x = (long) vh.getAcquire();
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(2L);
+ long x = (long) vh.getOpaque();
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ vh.set(1L);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSet(1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetAcquire(2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetRelease( 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get();
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet( 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) vh.get();
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ vh.set(1L);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd( 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) vh.addAndGet(3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+
+ }
+
+
+ static void testArray(VarHandle vh) {
+ long[] array = new long[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, 1L);
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "get long value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, 2L);
+ long x = (long) vh.getVolatile(array, i);
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, 1L);
+ long x = (long) vh.getAcquire(array, i);
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, 2L);
+ long x = (long) vh.getOpaque(array, i);
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ vh.set(array, i, 1L);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, 1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, 1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, 1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, 1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, 2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet(array, i, 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ vh.set(array, i, 1L);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd(array, i, 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) vh.addAndGet(array, i, 3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ long[] array = new long[10];
+
+ int i = 0;
+
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ long[] array = new long[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ long x = (long) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, 1L, 2L);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, 2L, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, 2L, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, 2L, 1L);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, 1L, 2L);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, 1L, 2L);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, 1L, 2L);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndSet(array, ci, 1L);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, 3L);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.addAndGet(array, ci, 3L);
+ });
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,647 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessShort
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessShort
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessShort
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessShort
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessShort extends VarHandleBaseTest {
+ static final short static_final_v = (short)1;
+
+ static short static_v;
+
+ final short final_v = (short)1;
+
+ short v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessShort.class, "final_v", short.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessShort.class, "v", short.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessShort.class, "static_final_v", short.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessShort.class, "static_v", short.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(short[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessShort.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(short[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), short.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessShort.class, "final_v", short.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessShort.class, "v", short.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessShort.class, "static_final_v", short.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessShort.class, "static_v", short.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessShort::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessShort::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessShort::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessShort::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessShort::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessShort::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessShort::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessShort recv, VarHandle vh) {
+ // Plain
+ {
+ short x = (short) vh.get(recv);
+ assertEquals(x, (short)1, "get short value");
+ }
+
+
+ // Volatile
+ {
+ short x = (short) vh.getVolatile(recv);
+ assertEquals(x, (short)1, "getVolatile short value");
+ }
+
+ // Lazy
+ {
+ short x = (short) vh.getAcquire(recv);
+ assertEquals(x, (short)1, "getRelease short value");
+ }
+
+ // Opaque
+ {
+ short x = (short) vh.getOpaque(recv);
+ assertEquals(x, (short)1, "getOpaque short value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessShort recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, (short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, (short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, (short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(recv, (short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(recv, (short)1);
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ short x = (short) vh.get();
+ assertEquals(x, (short)1, "get short value");
+ }
+
+
+ // Volatile
+ {
+ short x = (short) vh.getVolatile();
+ assertEquals(x, (short)1, "getVolatile short value");
+ }
+
+ // Lazy
+ {
+ short x = (short) vh.getAcquire();
+ assertEquals(x, (short)1, "getRelease short value");
+ }
+
+ // Opaque
+ {
+ short x = (short) vh.getOpaque();
+ assertEquals(x, (short)1, "getOpaque short value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set((short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile((short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease((short)2);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque((short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd((short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet((short)1);
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessShort recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, (short)1);
+ short x = (short) vh.get(recv);
+ assertEquals(x, (short)1, "set short value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, (short)2);
+ short x = (short) vh.getVolatile(recv);
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, (short)1);
+ short x = (short) vh.getAcquire(recv);
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, (short)2);
+ short x = (short) vh.getOpaque(recv);
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessShort recv, VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(recv, (short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(recv, (short)1);
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set((short)1);
+ short x = (short) vh.get();
+ assertEquals(x, (short)1, "set short value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile((short)2);
+ short x = (short) vh.getVolatile();
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease((short)1);
+ short x = (short) vh.getAcquire();
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque((short)2);
+ short x = (short) vh.getOpaque();
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease((short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd((short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet((short)1);
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ short[] array = new short[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, (short)1);
+ short x = (short) vh.get(array, i);
+ assertEquals(x, (short)1, "get short value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, (short)2);
+ short x = (short) vh.getVolatile(array, i);
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, (short)1);
+ short x = (short) vh.getAcquire(array, i);
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, (short)2);
+ short x = (short) vh.getOpaque(array, i);
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ short[] array = new short[10];
+
+ int i = 0;
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, (short)1, (short)2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(array, i, (short)1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(array, i, (short)1);
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ short[] array = new short[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ short x = (short) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, (short)1);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, (short)1);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, (short)1);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, (short)1);
+ });
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,804 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessString
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessString
+ * @run testng/othervm -Diters=20000 VarHandleTestAccessString
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessString
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccessString extends VarHandleBaseTest {
+ static final String static_final_v = "foo";
+
+ static String static_v;
+
+ final String final_v = "foo";
+
+ String v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessString.class, "final_v", String.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessString.class, "v", String.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessString.class, "static_final_v", String.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessString.class, "static_v", String.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(String[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessString.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList(String[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), String.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessString.class, "final_v", String.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccessString.class, "v", String.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessString.class, "static_final_v", String.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccessString.class, "static_v", String.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccessString::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccessString::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccessString::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccessString::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccessString::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccessString::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccessString::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccessString recv, VarHandle vh) {
+ // Plain
+ {
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "get String value");
+ }
+
+
+ // Volatile
+ {
+ String x = (String) vh.getVolatile(recv);
+ assertEquals(x, "foo", "getVolatile String value");
+ }
+
+ // Lazy
+ {
+ String x = (String) vh.getAcquire(recv);
+ assertEquals(x, "foo", "getRelease String value");
+ }
+
+ // Opaque
+ {
+ String x = (String) vh.getOpaque(recv);
+ assertEquals(x, "foo", "getOpaque String value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccessString recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, "bar");
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, "bar");
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, "bar");
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, "bar");
+ });
+
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd(recv, "foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet(recv, "foo");
+ });
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "get String value");
+ }
+
+
+ // Volatile
+ {
+ String x = (String) vh.getVolatile();
+ assertEquals(x, "foo", "getVolatile String value");
+ }
+
+ // Lazy
+ {
+ String x = (String) vh.getAcquire();
+ assertEquals(x, "foo", "getRelease String value");
+ }
+
+ // Opaque
+ {
+ String x = (String) vh.getOpaque();
+ assertEquals(x, "foo", "getOpaque String value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set("bar");
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile("bar");
+ });
+
+ checkUOE(() -> {
+ vh.setRelease("bar");
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque("bar");
+ });
+
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd("foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet("foo");
+ });
+ }
+
+
+ static void testInstanceField(VarHandleTestAccessString recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, "foo");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "set String value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, "bar");
+ String x = (String) vh.getVolatile(recv);
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, "foo");
+ String x = (String) vh.getAcquire(recv);
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, "bar");
+ String x = (String) vh.getOpaque(recv);
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ vh.set(recv, "foo");
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(recv, "foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(recv, "foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile(recv, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile(recv, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire(recv, "foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire(recv, "foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease(recv, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease(recv, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(recv, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(recv, "bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(recv, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) vh.getAndSet(recv, "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) vh.get(recv);
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccessString recv, VarHandle vh) {
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd(recv, "foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet(recv, "foo");
+ });
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set("foo");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "set String value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile("bar");
+ String x = (String) vh.getVolatile();
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease("foo");
+ String x = (String) vh.getAcquire();
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque("bar");
+ String x = (String) vh.getOpaque();
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ vh.set("foo");
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet("foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = vh.compareAndSet("foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile("bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile("bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire("foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire("foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease("bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease("bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSet("foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetAcquire("bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetRelease( "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) vh.get();
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) vh.getAndSet( "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) vh.get();
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd("foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet("foo");
+ });
+ }
+
+
+ static void testArray(VarHandle vh) {
+ String[] array = new String[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, "foo");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "get String value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, "bar");
+ String x = (String) vh.getVolatile(array, i);
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, "foo");
+ String x = (String) vh.getAcquire(array, i);
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, "bar");
+ String x = (String) vh.getOpaque(array, i);
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ vh.set(array, i, "foo");
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, "foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, "foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile(array, i, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeVolatile(array, i, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire(array, i, "foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeAcquire(array, i, "foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease(array, i, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) vh.compareAndExchangeRelease(array, i, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, "bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) vh.getAndSet(array, i, "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) vh.get(array, i);
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ String[] array = new String[10];
+
+ int i = 0;
+
+ checkUOE(() -> {
+ String o = (String) vh.getAndAdd(array, i, "foo");
+ });
+
+ checkUOE(() -> {
+ String o = (String) vh.addAndGet(array, i, "foo");
+ });
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ String[] array = new String[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ String x = (String) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, "foo");
+ });
+
+ checkIOOBE(() -> {
+ String x = (String) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, "foo");
+ });
+
+ checkIOOBE(() -> {
+ String x = (String) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, "foo");
+ });
+
+ checkIOOBE(() -> {
+ String x = (String) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, "foo");
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, "foo", "bar");
+ });
+
+ checkIOOBE(() -> {
+ String r = (String) vh.compareAndExchangeVolatile(array, ci, "bar", "foo");
+ });
+
+ checkIOOBE(() -> {
+ String r = (String) vh.compareAndExchangeAcquire(array, ci, "bar", "foo");
+ });
+
+ checkIOOBE(() -> {
+ String r = (String) vh.compareAndExchangeRelease(array, ci, "bar", "foo");
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, "foo", "bar");
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, "foo", "bar");
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, "foo", "bar");
+ });
+
+ checkIOOBE(() -> {
+ String o = (String) vh.getAndSet(array, ci, "foo");
+ });
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsChar
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsChar
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Character.BYTES;
+
+ static final char VALUE_1 = (char)0x0102;
+
+ static final char VALUE_2 = (char)0x1112;
+
+ static final char VALUE_3 = (char)0x2122;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(char[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(char[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), char.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char r = (char) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ char o = (char) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ char o = (char) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ char x = (char) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ char x = (char) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ char x = (char) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ char x = (char) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ char x = (char) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ char x = (char) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get char value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ char x = (char) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ char x = (char) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ char x = (char) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque char value");
+ }
+
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ char x = (char) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get char value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ char x = (char) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ char x = (char) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease char value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ char x = (char) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque char value");
+ }
+
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putChar(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ char v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ char x = (char) vh.get(array, i);
+ assertEquals(x, v, "get char value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ char x = (char) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile char value");
+ }
+
+ // Lazy
+ {
+ char x = (char) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease char value");
+ }
+
+ // Opaque
+ {
+ char x = (char) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque char value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,892 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsDouble
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsDouble
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Double.BYTES;
+
+ static final double VALUE_1 = 0x0102030405060708L;
+
+ static final double VALUE_2 = 0x1112131415161718L;
+
+ static final double VALUE_3 = 0x2122232425262728L;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(double[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(double[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), double.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ checkUOE(() -> {
+ double o = (double) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ double o = (double) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ double x = (double) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ double x = (double) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ double x = (double) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ double x = (double) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ double x = (double) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ double r = (double) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ double o = (double) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get double value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ double x = (double) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ double x = (double) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ double x = (double) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque double value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet double value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet double value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
+ }
+
+ // Compare set and get
+ {
+ double o = (double) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet double value");
+ }
+
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get double value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ double x = (double) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ double x = (double) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ double x = (double) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque double value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet double value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease double value");
+ }
+
+ {
+ double r = (double) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease double value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet double value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease double");
+ }
+
+ // Compare set and get
+ {
+ double o = (double) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet double");
+ double x = (double) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet double value");
+ }
+
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putDouble(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ double v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ double x = (double) vh.get(array, i);
+ assertEquals(x, v, "get double value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ double x = (double) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile double value");
+ }
+
+ // Lazy
+ {
+ double x = (double) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease double value");
+ }
+
+ // Opaque
+ {
+ double x = (double) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque double value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,892 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsFloat
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Float.BYTES;
+
+ static final float VALUE_1 = 0x01020304;
+
+ static final float VALUE_2 = 0x11121314;
+
+ static final float VALUE_3 = 0x21222324;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(float[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(float[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), float.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ checkUOE(() -> {
+ float o = (float) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ float o = (float) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ float x = (float) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ float x = (float) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ float x = (float) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ float x = (float) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ float x = (float) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ float r = (float) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ float o = (float) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get float value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ float x = (float) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ float x = (float) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ float x = (float) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque float value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet float value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease float value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet float value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease float");
+ }
+
+ // Compare set and get
+ {
+ float o = (float) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet float value");
+ }
+
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get float value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ float x = (float) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ float x = (float) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ float x = (float) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque float value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet float value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease float value");
+ }
+
+ {
+ float r = (float) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease float value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet float value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease float");
+ }
+
+ // Compare set and get
+ {
+ float o = (float) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet float");
+ float x = (float) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet float value");
+ }
+
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putFloat(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ float v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ float x = (float) vh.get(array, i);
+ assertEquals(x, v, "get float value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ float x = (float) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile float value");
+ }
+
+ // Lazy
+ {
+ float x = (float) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease float value");
+ }
+
+ // Opaque
+ {
+ float x = (float) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque float value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,924 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsInt
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsInt
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Integer.BYTES;
+
+ static final int VALUE_1 = 0x01020304;
+
+ static final int VALUE_2 = 0x11121314;
+
+ static final int VALUE_3 = 0x21222324;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(int[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(int[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), int.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ int x = (int) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ int x = (int) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ int x = (int) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ int x = (int) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ int x = (int) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int r = (int) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ int o = (int) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get int value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ int x = (int) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ int x = (int) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ int x = (int) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque int value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet int value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd int");
+ int c = (int) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd int value");
+ }
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get int value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ int x = (int) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ int x = (int) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ int x = (int) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque int value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet int");
+ int x = (int) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet int value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ int o = (int) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd int");
+ int c = (int) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd int value");
+ }
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putInt(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ int v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ int x = (int) vh.get(array, i);
+ assertEquals(x, v, "get int value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ int x = (int) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile int value");
+ }
+
+ // Lazy
+ {
+ int x = (int) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease int value");
+ }
+
+ // Opaque
+ {
+ int x = (int) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque int value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,924 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsLong
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsLong
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Long.BYTES;
+
+ static final long VALUE_1 = 0x0102030405060708L;
+
+ static final long VALUE_2 = 0x1112131415161718L;
+
+ static final long VALUE_3 = 0x2122232425262728L;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(long[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(long[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), long.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ long x = (long) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ long x = (long) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ long x = (long) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ long x = (long) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ long x = (long) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long r = (long) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ long o = (long) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get long value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ long x = (long) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ long x = (long) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ long x = (long) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque long value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet long value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd long");
+ long c = (long) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value");
+ }
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get long value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ long x = (long) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ long x = (long) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ long x = (long) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque long value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet long");
+ long x = (long) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet long value");
+ }
+
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ long o = (long) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd long");
+ long c = (long) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd long value");
+ }
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putLong(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ long v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ long x = (long) vh.get(array, i);
+ assertEquals(x, v, "get long value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ long x = (long) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile long value");
+ }
+
+ // Lazy
+ {
+ long x = (long) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease long value");
+ }
+
+ // Opaque
+ {
+ long x = (long) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque long value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsShort
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsShort
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest {
+ static final int SIZE = Short.BYTES;
+
+ static final short VALUE_1 = (short)0x0102;
+
+ static final short VALUE_2 = (short)0x1112;
+
+ static final short VALUE_3 = (short)0x2122;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle(short[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle(short[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), short.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndSet(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ else {
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short r = (short) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ short o = (short) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ short o = (short) vh.addAndGet(array, ci, VALUE_1);
+ });
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ short x = (short) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ short x = (short) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ short x = (short) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ short x = (short) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ short x = (short) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ short x = (short) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get short value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ short x = (short) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ short x = (short) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ short x = (short) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque short value");
+ }
+
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ short x = (short) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get short value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ short x = (short) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ short x = (short) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ short x = (short) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque short value");
+ }
+
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.putShort(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ short v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ short x = (short) vh.get(array, i);
+ assertEquals(x, v, "get short value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ short x = (short) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile short value");
+ }
+
+ // Lazy
+ {
+ short x = (short) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease short value");
+ }
+
+ // Opaque
+ {
+ short x = (short) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque short value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessBoolean
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessBoolean extends VarHandleBaseTest {
+ static final boolean static_final_v = true;
+
+ static boolean static_v;
+
+ final boolean final_v = true;
+
+ boolean v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessBoolean.class, "final_v", boolean.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessBoolean.class, "v", boolean.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessBoolean.class, "static_final_v", boolean.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessBoolean.class, "static_v", boolean.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(boolean[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessBoolean::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessBoolean::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessBoolean::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessBoolean recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, true);
+ boolean x = (boolean) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, true, "set boolean value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, false);
+ boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, true);
+ boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, false);
+ boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessBoolean recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, true);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, true);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(true);
+ boolean x = (boolean) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, true, "set boolean value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(false);
+ boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(true);
+ boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(false);
+ boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(true);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(true);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ boolean[] array = new boolean[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, true);
+ boolean x = (boolean) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, true, "get boolean value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, false);
+ boolean x = (boolean) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, false, "setVolatile boolean value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, true);
+ boolean x = (boolean) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, true, "setRelease boolean value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, false);
+ boolean x = (boolean) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, false, "setOpaque boolean value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ boolean[] array = new boolean[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, true, false);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, true);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ boolean o = (boolean) hs.get(am).invokeExact(array, i, true);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ boolean[] array = new boolean[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ boolean x = (boolean) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, true);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessByte
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessByte extends VarHandleBaseTest {
+ static final byte static_final_v = (byte)1;
+
+ static byte static_v;
+
+ final byte final_v = (byte)1;
+
+ byte v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessByte.class, "final_v", byte.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessByte.class, "v", byte.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessByte.class, "static_final_v", byte.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessByte.class, "static_v", byte.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(byte[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessByte::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessByte::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessByte::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessByte::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessByte::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessByte recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, (byte)1);
+ byte x = (byte) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, (byte)1, "set byte value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, (byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, (byte)1);
+ byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, (byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessByte recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, (byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(recv, (byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(recv, (byte)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(recv, (byte)1);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact((byte)1);
+ byte x = (byte) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, (byte)1, "set byte value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact((byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact((byte)1);
+ byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact((byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact((byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact((byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact((byte)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact((byte)1);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ byte[] array = new byte[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, (byte)1);
+ byte x = (byte) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, (byte)1, "get byte value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, (byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, (byte)2, "setVolatile byte value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, (byte)1);
+ byte x = (byte) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, (byte)1, "setRelease byte value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, (byte)2);
+ byte x = (byte) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, (byte)2, "setOpaque byte value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ byte[] array = new byte[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, (byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(array, i, (byte)1, (byte)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ byte r = (byte) hs.get(am).invokeExact(array, i, (byte)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ byte o = (byte) hs.get(am).invokeExact(array, i, (byte)1);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ byte[] array = new byte[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ byte x = (byte) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, (byte)1);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessChar
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessChar extends VarHandleBaseTest {
+ static final char static_final_v = 'a';
+
+ static char static_v;
+
+ final char final_v = 'a';
+
+ char v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessChar.class, "final_v", char.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessChar.class, "v", char.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessChar.class, "static_final_v", char.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessChar.class, "static_v", char.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(char[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessChar::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessChar::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessChar::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessChar::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessChar::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 'a');
+ char x = (char) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 'a', "set char value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 'b');
+ char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 'a');
+ char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 'b');
+ char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessChar recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, 'a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(recv, 'a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(recv, 'a');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(recv, 'a');
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact('a');
+ char x = (char) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 'a', "set char value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact('b');
+ char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact('a');
+ char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact('b');
+ char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact('a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact('a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact('a');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact('a');
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ char[] array = new char[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 'a');
+ char x = (char) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 'a', "get char value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 'b');
+ char x = (char) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 'b', "setVolatile char value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 'a');
+ char x = (char) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 'a', "setRelease char value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 'b');
+ char x = (char) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 'b', "setOpaque char value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ char[] array = new char[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, 'a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(array, i, 'a', 'b');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ char r = (char) hs.get(am).invokeExact(array, i, 'a');
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ char o = (char) hs.get(am).invokeExact(array, i, 'a');
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ char[] array = new char[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ char x = (char) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 'a');
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessDouble
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessDouble extends VarHandleBaseTest {
+ static final double static_final_v = 1.0d;
+
+ static double static_v;
+
+ final double final_v = 1.0d;
+
+ double v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessDouble.class, "final_v", double.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessDouble.class, "v", double.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessDouble.class, "static_final_v", double.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessDouble.class, "static_v", double.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(double[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessDouble::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessDouble::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessDouble::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessDouble::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessDouble::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 1.0d);
+ double x = (double) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1.0d, "set double value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2.0d);
+ double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 1.0d);
+ double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2.0d);
+ double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessDouble recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, 1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(recv, 1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(recv, 1.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(recv, 1.0d);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(1.0d);
+ double x = (double) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1.0d, "set double value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(2.0d);
+ double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(1.0d);
+ double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(2.0d);
+ double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(1.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(1.0d);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ double[] array = new double[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1.0d);
+ double x = (double) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1.0d, "get double value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2.0d);
+ double x = (double) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 2.0d, "setVolatile double value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1.0d);
+ double x = (double) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 1.0d, "setRelease double value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2.0d);
+ double x = (double) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 2.0d, "setOpaque double value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ double[] array = new double[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, 1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(array, i, 1.0d, 2.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ double r = (double) hs.get(am).invokeExact(array, i, 1.0d);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ double o = (double) hs.get(am).invokeExact(array, i, 1.0d);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ double[] array = new double[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ double x = (double) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 1.0d);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessFloat
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessFloat extends VarHandleBaseTest {
+ static final float static_final_v = 1.0f;
+
+ static float static_v;
+
+ final float final_v = 1.0f;
+
+ float v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessFloat.class, "final_v", float.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessFloat.class, "v", float.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessFloat.class, "static_final_v", float.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessFloat.class, "static_v", float.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(float[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessFloat::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessFloat::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessFloat::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessFloat::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessFloat::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessFloat recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 1.0f);
+ float x = (float) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1.0f, "set float value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2.0f);
+ float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 1.0f);
+ float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2.0f);
+ float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessFloat recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, 1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(recv, 1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(recv, 1.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(recv, 1.0f);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(1.0f);
+ float x = (float) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1.0f, "set float value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(2.0f);
+ float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(1.0f);
+ float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(2.0f);
+ float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(1.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(1.0f);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ float[] array = new float[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1.0f);
+ float x = (float) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1.0f, "get float value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2.0f);
+ float x = (float) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 2.0f, "setVolatile float value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1.0f);
+ float x = (float) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 1.0f, "setRelease float value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2.0f);
+ float x = (float) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 2.0f, "setOpaque float value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ float[] array = new float[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, 1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(array, i, 1.0f, 2.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ float r = (float) hs.get(am).invokeExact(array, i, 1.0f);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ float o = (float) hs.get(am).invokeExact(array, i, 1.0f);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ float[] array = new float[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ float x = (float) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 1.0f);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessInt
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest {
+ static final int static_final_v = 1;
+
+ static int static_v;
+
+ final int final_v = 1;
+
+ int v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessInt.class, "final_v", int.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessInt.class, "v", int.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessInt.class, "static_final_v", int.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessInt.class, "static_v", int.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(int[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessInt::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessInt::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessInt::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessInt::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessInt::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessInt recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 1);
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "set int value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2);
+ int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 1);
+ int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2);
+ int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, 1);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, 1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, 2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact(recv, 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, 1);
+
+ // get and add, add and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(recv, 3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessInt recv, Handles hs) throws Throwable {
+
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(1);
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "set int value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(2);
+ int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(1);
+ int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(2);
+ int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(1);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact( 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(1);
+
+ // get and add, add and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact( 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ int[] array = new int[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1);
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "get int value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2);
+ int x = (int) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 2, "setVolatile int value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1);
+ int x = (int) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 1, "setRelease int value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2);
+ int x = (int) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 2, "setOpaque int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1, 2);
+ assertEquals(r, true, "success compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "success compareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1, 3);
+ assertEquals(r, false, "failing compareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "failing compareAndSet int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "success compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeVolatile int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "failing compareAndExchangeVolatile int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1, 2);
+ assertEquals(r, 1, "success compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "success compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1, 3);
+ assertEquals(r, 2, "failing compareAndExchangeAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "failing compareAndExchangeAcquire int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2, 1);
+ assertEquals(r, 2, "success compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "success compareAndExchangeRelease int value");
+ }
+
+ {
+ int r = (int) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2, 3);
+ assertEquals(r, 1, "failing compareAndExchangeRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "failing compareAndExchangeRelease int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, 1, 2);
+ assertEquals(r, true, "weakCompareAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "weakCompareAndSet int value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, 2, 1);
+ assertEquals(r, true, "weakCompareAndSetAcquire int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "weakCompareAndSetAcquire int");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, 1, 2);
+ assertEquals(r, true, "weakCompareAndSetRelease int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2, "weakCompareAndSetRelease int");
+ }
+
+ // Compare set and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, 1);
+ assertEquals(o, 2, "getAndSet int");
+ int x = (int) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1, "getAndSet int value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1);
+
+ // get and add, add and get
+ {
+ int o = (int) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, 3);
+ assertEquals(o, 1, "getAndAdd int");
+ int c = (int) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, 3);
+ assertEquals(c, 1 + 3 + 3, "getAndAdd int value");
+ }
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ int[] array = new int[10];
+
+ final int i = 0;
+
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ int[] array = new int[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ int x = (int) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkIOOBE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1, 2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkIOOBE(am, () -> {
+ int r = (int) hs.get(am).invokeExact(array, ci, 2, 1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkIOOBE(am, () -> {
+ int o = (int) hs.get(am).invokeExact(array, ci, 1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkIOOBE(am, () -> {
+ int o = (int) hs.get(am).invokeExact(array, ci, 3);
+ });
+ }
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessLong
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest {
+ static final long static_final_v = 1L;
+
+ static long static_v;
+
+ final long final_v = 1L;
+
+ long v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessLong.class, "final_v", long.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessLong.class, "v", long.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessLong.class, "static_final_v", long.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessLong.class, "static_v", long.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(long[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessLong::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessLong::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessLong::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessLong::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessLong::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessLong recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, 1L);
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "set long value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, 2L);
+ long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, 1L);
+ long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, 2L);
+ long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, 1L);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, 1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, 1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, 2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact(recv, 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, 1L);
+
+ // get and add, add and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(recv, 3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessLong recv, Handles hs) throws Throwable {
+
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(1L);
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "set long value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(2L);
+ long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(1L);
+ long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(2L);
+ long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(1L);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact( 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(1L);
+
+ // get and add, add and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact( 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ long[] array = new long[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1L);
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "get long value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, 2L);
+ long x = (long) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, 2L, "setVolatile long value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, 1L);
+ long x = (long) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, 1L, "setRelease long value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, 2L);
+ long x = (long) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, 2L, "setOpaque long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1L);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1L, 2L);
+ assertEquals(r, true, "success compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "success compareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, 1L, 3L);
+ assertEquals(r, false, "failing compareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "failing compareAndSet long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "success compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeVolatile long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "failing compareAndExchangeVolatile long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1L, 2L);
+ assertEquals(r, 1L, "success compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "success compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, 1L, 3L);
+ assertEquals(r, 2L, "failing compareAndExchangeAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "failing compareAndExchangeAcquire long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2L, 1L);
+ assertEquals(r, 2L, "success compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "success compareAndExchangeRelease long value");
+ }
+
+ {
+ long r = (long) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, 2L, 3L);
+ assertEquals(r, 1L, "failing compareAndExchangeRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "failing compareAndExchangeRelease long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "weakCompareAndSet long value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, 2L, 1L);
+ assertEquals(r, true, "weakCompareAndSetAcquire long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "weakCompareAndSetAcquire long");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, 1L, 2L);
+ assertEquals(r, true, "weakCompareAndSetRelease long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 2L, "weakCompareAndSetRelease long");
+ }
+
+ // Compare set and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, 1L);
+ assertEquals(o, 2L, "getAndSet long");
+ long x = (long) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, 1L, "getAndSet long value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, 1L);
+
+ // get and add, add and get
+ {
+ long o = (long) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, 3L);
+ assertEquals(o, 1L, "getAndAdd long");
+ long c = (long) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, 3L);
+ assertEquals(c, 1L + 3L + 3L, "getAndAdd long value");
+ }
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ long[] array = new long[10];
+
+ final int i = 0;
+
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ long[] array = new long[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ long x = (long) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, 1L);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkIOOBE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, ci, 1L, 2L);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkIOOBE(am, () -> {
+ long r = (long) hs.get(am).invokeExact(array, ci, 2L, 1L);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkIOOBE(am, () -> {
+ long o = (long) hs.get(am).invokeExact(array, ci, 1L);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkIOOBE(am, () -> {
+ long o = (long) hs.get(am).invokeExact(array, ci, 3L);
+ });
+ }
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessShort
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessShort extends VarHandleBaseTest {
+ static final short static_final_v = (short)1;
+
+ static short static_v;
+
+ final short final_v = (short)1;
+
+ short v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessShort.class, "final_v", short.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessShort.class, "v", short.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessShort.class, "static_final_v", short.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessShort.class, "static_v", short.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(short[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessShort::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessShort::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessShort::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessShort::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessShort::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessShort recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, (short)1);
+ short x = (short) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, (short)1, "set short value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, (short)2);
+ short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, (short)1);
+ short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, (short)2);
+ short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessShort recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, (short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(recv, (short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(recv, (short)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(recv, (short)1);
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact((short)1);
+ short x = (short) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, (short)1, "set short value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact((short)2);
+ short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact((short)1);
+ short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact((short)2);
+ short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact((short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact((short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact((short)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact((short)1);
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ short[] array = new short[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, (short)1);
+ short x = (short) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, (short)1, "get short value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, (short)2);
+ short x = (short) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, (short)2, "setVolatile short value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, (short)1);
+ short x = (short) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, (short)1, "setRelease short value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, (short)2);
+ short x = (short) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, (short)2, "setOpaque short value");
+ }
+
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ short[] array = new short[10];
+
+ final int i = 0;
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, (short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(array, i, (short)1, (short)2);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ short r = (short) hs.get(am).invokeExact(array, i, (short)1);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ short o = (short) hs.get(am).invokeExact(array, i, (short)1);
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ short[] array = new short[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ short x = (short) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, (short)1);
+ });
+ }
+
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,556 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessString
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest {
+ static final String static_final_v = "foo";
+
+ static String static_v;
+
+ final String final_v = "foo";
+
+ String v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessString.class, "final_v", String.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccessString.class, "v", String.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessString.class, "static_final_v", String.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccessString.class, "static_v", String.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(String[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccessString::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccessString::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccessString::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccessString::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, "foo");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "set String value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, "bar");
+ String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, "foo");
+ String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, "bar");
+ String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(recv, "foo");
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, "foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, "foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, "foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, "foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, "bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact(recv, "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccessString recv, Handles hs) throws Throwable {
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ String r = (String) hs.get(am).invokeExact(recv, "foo");
+ });
+ }
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact("foo");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "set String value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact("bar");
+ String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact("foo");
+ String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact("bar");
+ String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact("foo");
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact("foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact("foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact("bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact("bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact("foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact("foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact("bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact("bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact("foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact("bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact( "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ String r = (String) hs.get(am).invokeExact("foo");
+ });
+ }
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ String[] array = new String[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, "foo");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "get String value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, "bar");
+ String x = (String) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, "bar", "setVolatile String value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, "foo");
+ String x = (String) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, "foo", "setRelease String value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, "bar");
+ String x = (String) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, "bar", "setOpaque String value");
+ }
+
+ hs.get(TestAccessMode.set).invokeExact(array, i, "foo");
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, "foo", "bar");
+ assertEquals(r, true, "success compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "success compareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, "foo", "baz");
+ assertEquals(r, false, "failing compareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "failing compareAndSet String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "success compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeVolatile String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "failing compareAndExchangeVolatile String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, "foo", "bar");
+ assertEquals(r, "foo", "success compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "success compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, "foo", "baz");
+ assertEquals(r, "bar", "failing compareAndExchangeAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "failing compareAndExchangeAcquire String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, "bar", "foo");
+ assertEquals(r, "bar", "success compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "success compareAndExchangeRelease String value");
+ }
+
+ {
+ String r = (String) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, "bar", "baz");
+ assertEquals(r, "foo", "failing compareAndExchangeRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "failing compareAndExchangeRelease String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "weakCompareAndSet String value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, "bar", "foo");
+ assertEquals(r, true, "weakCompareAndSetAcquire String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "weakCompareAndSetAcquire String");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, "foo", "bar");
+ assertEquals(r, true, "weakCompareAndSetRelease String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "bar", "weakCompareAndSetRelease String");
+ }
+
+ // Compare set and get
+ {
+ String o = (String) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, "foo");
+ assertEquals(o, "bar", "getAndSet String");
+ String x = (String) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, "foo", "getAndSet String value");
+ }
+
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ String[] array = new String[10];
+
+ final int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ String o = (String) hs.get(am).invokeExact(array, i, "foo");
+ });
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ String[] array = new String[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ String x = (String) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, "foo");
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkIOOBE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, ci, "foo", "bar");
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkIOOBE(am, () -> {
+ String r = (String) hs.get(am).invokeExact(array, ci, "bar", "foo");
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkIOOBE(am, () -> {
+ String o = (String) hs.get(am).invokeExact(array, ci, "foo");
+ });
+ }
+
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeBoolean
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeBoolean
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest {
+ static final boolean static_final_v = true;
+
+ static boolean static_v = true;
+
+ final boolean final_v = true;
+
+ boolean v = true;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeBoolean.class, "final_v", boolean.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeBoolean.class, "v", boolean.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeBoolean.class, "static_final_v", boolean.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeBoolean.class, "static_v", boolean.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(boolean[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeBoolean::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeBoolean::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeBoolean::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeBoolean::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeBoolean recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.get();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, true, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, true, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, true, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, true, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeBoolean recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeBoolean.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, boolean.class)).
+ invoke(null, true);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, boolean.class)).
+ invoke(Void.class, true);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, boolean.class)).
+ invoke(0, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, boolean.class, Class.class)).
+ invoke(recv, true, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(true, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(true, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(true, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(true, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ boolean x = (boolean) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, boolean.class, Class.class)).
+ invoke(true, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ boolean[] array = new boolean[10];
+ Arrays.fill(array, true);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.get();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, true, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, true, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, true, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, true, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ boolean[] array = new boolean[10];
+ Arrays.fill(array, true);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, boolean[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ int x = (int) hs.get(am, methodType(int.class, boolean[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, boolean.class)).
+ invoke(null, 0, true);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, boolean.class)).
+ invoke(Void.class, 0, true);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, boolean[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, boolean.class)).
+ invoke(0, 0, true);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, boolean[].class, Class.class, boolean.class)).
+ invoke(array, Void.class, true);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, boolean[].class, int.class, Class.class)).
+ invoke(array, 0, true, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeByte
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeByte
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeByte extends VarHandleBaseTest {
+ static final byte static_final_v = (byte)1;
+
+ static byte static_v = (byte)1;
+
+ final byte final_v = (byte)1;
+
+ byte v = (byte)1;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeByte.class, "final_v", byte.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeByte.class, "v", byte.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeByte.class, "static_final_v", byte.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeByte.class, "static_v", byte.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(byte[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeByte::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeByte::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeByte::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeByte::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeByte recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.get();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, (byte)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, (byte)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, (byte)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, (byte)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeByte recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ byte x = (byte) hs.get(am, methodType(byte.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ byte x = (byte) hs.get(am, methodType(byte.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ byte x = (byte) hs.get(am, methodType(byte.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeByte.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) hs.get(am, methodType(byte.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, byte.class)).
+ invoke(null, (byte)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, byte.class)).
+ invoke(Void.class, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, byte.class)).
+ invoke(0, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, byte.class, Class.class)).
+ invoke(recv, (byte)1, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set((byte)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile((byte)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque((byte)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease((byte)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ byte x = (byte) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, byte.class, Class.class)).
+ invoke((byte)1, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ byte[] array = new byte[10];
+ Arrays.fill(array, (byte)1);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.get();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, (byte)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, (byte)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, (byte)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, (byte)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ byte[] array = new byte[10];
+ Arrays.fill(array, (byte)1);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ byte x = (byte) hs.get(am, methodType(byte.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ byte x = (byte) hs.get(am, methodType(byte.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ byte x = (byte) hs.get(am, methodType(byte.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, byte[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, byte[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ byte x = (byte) hs.get(am, methodType(byte.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, byte.class)).
+ invoke(null, 0, (byte)1);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, byte.class)).
+ invoke(Void.class, 0, (byte)1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, byte[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, byte.class)).
+ invoke(0, 0, (byte)1);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, byte[].class, Class.class, byte.class)).
+ invoke(array, Void.class, (byte)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, byte[].class, int.class, Class.class)).
+ invoke(array, 0, (byte)1, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeChar
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeChar
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeChar extends VarHandleBaseTest {
+ static final char static_final_v = 'a';
+
+ static char static_v = 'a';
+
+ final char final_v = 'a';
+
+ char v = 'a';
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeChar.class, "final_v", char.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeChar.class, "v", char.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeChar.class, "static_final_v", char.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeChar.class, "static_v", char.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(char[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeChar::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeChar::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeChar::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeChar::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeChar recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.get();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 'a', Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 'a', Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 'a', Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 'a', Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeChar recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ char x = (char) hs.get(am, methodType(char.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ char x = (char) hs.get(am, methodType(char.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ char x = (char) hs.get(am, methodType(char.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeChar.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) hs.get(am, methodType(char.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, char.class)).
+ invoke(null, 'a');
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, char.class)).
+ invoke(Void.class, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, char.class)).
+ invoke(0, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, char.class, Class.class)).
+ invoke(recv, 'a', Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ char x = (char) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set('a', Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile('a', Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque('a', Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease('a', Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ char x = (char) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, char.class, Class.class)).
+ invoke('a', Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ char[] array = new char[10];
+ Arrays.fill(array, 'a');
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.get();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 'a', Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 'a', Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 'a', Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 'a', Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ char[] array = new char[10];
+ Arrays.fill(array, 'a');
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ char x = (char) hs.get(am, methodType(char.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ char x = (char) hs.get(am, methodType(char.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ char x = (char) hs.get(am, methodType(char.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ char x = (char) hs.get(am, methodType(char.class, char[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, char[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, char[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ char x = (char) hs.get(am, methodType(char.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ char x = (char) hs.get(am, methodType(char.class, char[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, char.class)).
+ invoke(null, 0, 'a');
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, char.class)).
+ invoke(Void.class, 0, 'a');
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, char[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, char.class)).
+ invoke(0, 0, 'a');
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, char[].class, Class.class, char.class)).
+ invoke(array, Void.class, 'a');
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, char[].class, int.class, Class.class)).
+ invoke(array, 0, 'a', Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeDouble
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeDouble
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest {
+ static final double static_final_v = 1.0d;
+
+ static double static_v = 1.0d;
+
+ final double final_v = 1.0d;
+
+ double v = 1.0d;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeDouble.class, "final_v", double.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeDouble.class, "v", double.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeDouble.class, "static_final_v", double.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeDouble.class, "static_v", double.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(double[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeDouble::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeDouble::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeDouble::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeDouble::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeDouble recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.get();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 1.0d, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 1.0d, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 1.0d, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 1.0d, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeDouble recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ double x = (double) hs.get(am, methodType(double.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ double x = (double) hs.get(am, methodType(double.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ double x = (double) hs.get(am, methodType(double.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) hs.get(am, methodType(double.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, double.class)).
+ invoke(null, 1.0d);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, double.class)).
+ invoke(Void.class, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, double.class)).
+ invoke(0, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, double.class, Class.class)).
+ invoke(recv, 1.0d, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ double x = (double) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(1.0d, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(1.0d, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(1.0d, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(1.0d, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ double x = (double) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, double.class, Class.class)).
+ invoke(1.0d, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ double[] array = new double[10];
+ Arrays.fill(array, 1.0d);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.get();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 1.0d, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 1.0d, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 1.0d, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 1.0d, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ double[] array = new double[10];
+ Arrays.fill(array, 1.0d);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ double x = (double) hs.get(am, methodType(double.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ double x = (double) hs.get(am, methodType(double.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ double x = (double) hs.get(am, methodType(double.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ double x = (double) hs.get(am, methodType(double.class, double[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, double[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ double x = (double) hs.get(am, methodType(double.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, double.class)).
+ invoke(null, 0, 1.0d);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, double.class)).
+ invoke(Void.class, 0, 1.0d);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, double[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, double.class)).
+ invoke(0, 0, 1.0d);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, double[].class, Class.class, double.class)).
+ invoke(array, Void.class, 1.0d);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, double[].class, int.class, Class.class)).
+ invoke(array, 0, 1.0d, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeFloat
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeFloat
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest {
+ static final float static_final_v = 1.0f;
+
+ static float static_v = 1.0f;
+
+ final float final_v = 1.0f;
+
+ float v = 1.0f;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeFloat.class, "final_v", float.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeFloat.class, "v", float.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeFloat.class, "static_final_v", float.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeFloat.class, "static_v", float.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(float[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeFloat::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeFloat::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeFloat::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeFloat::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeFloat recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.get();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 1.0f, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 1.0f, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 1.0f, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 1.0f, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeFloat recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ float x = (float) hs.get(am, methodType(float.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ float x = (float) hs.get(am, methodType(float.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ float x = (float) hs.get(am, methodType(float.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) hs.get(am, methodType(float.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, float.class)).
+ invoke(null, 1.0f);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, float.class)).
+ invoke(Void.class, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, float.class)).
+ invoke(0, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, float.class, Class.class)).
+ invoke(recv, 1.0f, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ float x = (float) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(1.0f, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(1.0f, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(1.0f, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(1.0f, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ float x = (float) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, float.class, Class.class)).
+ invoke(1.0f, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ float[] array = new float[10];
+ Arrays.fill(array, 1.0f);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.get();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 1.0f, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 1.0f, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 1.0f, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 1.0f, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ float[] array = new float[10];
+ Arrays.fill(array, 1.0f);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ float x = (float) hs.get(am, methodType(float.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ float x = (float) hs.get(am, methodType(float.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ float x = (float) hs.get(am, methodType(float.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ float x = (float) hs.get(am, methodType(float.class, float[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, float[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ float x = (float) hs.get(am, methodType(float.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, float.class)).
+ invoke(null, 0, 1.0f);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, float.class)).
+ invoke(Void.class, 0, 1.0f);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, float[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, float.class)).
+ invoke(0, 0, 1.0f);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, float[].class, Class.class, float.class)).
+ invoke(array, Void.class, 1.0f);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, float[].class, int.class, Class.class)).
+ invoke(array, 0, 1.0f, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,2075 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeInt
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeInt
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeInt extends VarHandleBaseTest {
+ static final int static_final_v = 1;
+
+ static int static_v = 1;
+
+ final int final_v = 1;
+
+ int v = 1;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeInt.class, "final_v", int.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeInt.class, "v", int.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeInt.class, "static_final_v", int.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeInt.class, "static_v", int.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(int[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeInt::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeInt::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeInt::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeInt::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeInt recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.get();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 1, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(recv, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(recv, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(recv, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeVolatile(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.compareAndExchangeVolatile(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeVolatile(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeVolatile(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.compareAndExchangeVolatile(0, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(recv, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(recv, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeVolatile(recv, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatileAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeAcquire(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.compareAndExchangeAcquire(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeAcquire(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeAcquire(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.compareAndExchangeAcquire(0, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(recv, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(recv, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeAcquire(recv, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeRelease(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.compareAndExchangeRelease(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeRelease(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeRelease(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.compareAndExchangeRelease(0, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(recv, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(recv, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeRelease(recv, 1, 1, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getAndSet(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getAndSet(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndSet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.getAndSet(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndSet(recv, 1, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.getAndAdd(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.getAndAdd(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndAdd(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.getAndAdd(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndAdd(recv, 1, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.addAndGet(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) vh.addAndGet(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.addAndGet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) vh.addAndGet(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.addAndGet(recv, 1, Void.class);
+ });
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeInt recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, int.class)).
+ invoke(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class)).
+ invoke(0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)).
+ invoke(recv, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, int.class)).
+ invoke(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, Class.class, int.class)).
+ invoke(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)).
+ invoke(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , int.class, int.class)).
+ invoke(0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, int.class, Class.class)).
+ invoke(recv, 1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)).
+ invoke(null, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class, int.class)).
+ invoke(recv, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)).
+ invoke(recv, 1, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class , int.class, int.class)).
+ invoke(0, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class , int.class, int.class)).
+ invoke(recv, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class , int.class, int.class)).
+ invoke(recv, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, int.class, Class.class)).
+ invoke(recv, 1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)).
+ invoke(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class)).
+ invoke(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)).
+ invoke(null, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class)).
+ invoke(0, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)).
+ invoke(recv, 1, Void.class);
+ });
+ }
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ int x = (int) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(1, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeVolatile(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeVolatile(1, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeVolatile(1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeAcquire(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeAcquire(1, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeAcquire(1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeRelease(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeRelease(1, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeRelease(1, 1, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndSet(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndSet(1, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndAdd(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndAdd(1, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.addAndGet(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.addAndGet(1, Void.class);
+ });
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, Class.class)).
+ invoke(1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)).
+ invoke(Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int.class, int.class)).
+ invoke(1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class)).
+ invoke(1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class, Class.class)).
+ invoke(1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int.class)).
+ invoke(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)).
+ invoke(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int.class)).
+ invoke(1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)).
+ invoke(1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)).
+ invoke(1, Void.class);
+ });
+ }
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ int[] array = new int[10];
+ Arrays.fill(array, 1);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.get();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 1, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.compareAndSet(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(array, 0, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSet(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(array, 0, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, 1, 1, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetRelease(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(array, 0, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeVolatile(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.compareAndExchangeVolatile(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeVolatile(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeVolatile(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.compareAndExchangeVolatile(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.compareAndExchangeVolatile(array, Void.class, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(array, 0, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeVolatile(array, 0, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeAcquire(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.compareAndExchangeAcquire(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeAcquire(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeAcquire(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.compareAndExchangeAcquire(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.compareAndExchangeAcquire(array, Void.class, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(array, 0, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeAcquire(array, 0, 1, 1, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) vh.compareAndExchangeRelease(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.compareAndExchangeRelease(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) vh.compareAndExchangeRelease(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) vh.compareAndExchangeRelease(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.compareAndExchangeRelease(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.compareAndExchangeRelease(array, Void.class, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(array, 0, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.compareAndExchangeRelease(array, 0, 1, 1, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getAndSet(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getAndSet(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndSet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // reciarrayever primitive class
+ int x = (int) vh.getAndSet(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getAndSet(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndSet(array, 0, 1, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.getAndAdd(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.getAndAdd(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.getAndAdd(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.getAndAdd(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.getAndAdd(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.getAndAdd(array, 0, 1, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) vh.addAndGet(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) vh.addAndGet(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) vh.addAndGet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) vh.addAndGet(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) vh.addAndGet(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) vh.addAndGet(array, 0, 1, Void.class);
+ });
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ int[] array = new int[10];
+ Arrays.fill(array, 1);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, int[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, int.class)).
+ invoke(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, int[].class, Class.class, int.class)).
+ invoke(array, Void.class, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, int.class, int.class)).
+ invoke(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, int.class, int.class)).
+ invoke(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, Class.class, int.class)).
+ invoke(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, Class.class, int.class, int.class)).
+ invoke(array, Void.class, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class, int.class)).
+ invoke(null, 0, 1, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class, int.class)).
+ invoke(Void.class, 0, 1, 1);
+ });
+ checkWMTE(() -> { // expected reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class, int.class)).
+ invoke(array, 0, Void.class, 1);
+ });
+ checkWMTE(() -> { // actual reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class, int.class)).
+ invoke(array, Void.class, 1, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class, int.class)).
+ invoke(array, 0, 1, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class)).
+ invoke(array, 0, 1, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)).
+ invoke(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class)).
+ invoke(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class)).
+ invoke(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class)).
+ invoke(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)).
+ invoke(null, 0, 1);
+ });
+ checkCCE(() -> { // array reference class
+ int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)).
+ invoke(Void.class, 0, 1);
+ });
+ checkWMTE(() -> { // value reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class)).
+ invoke(0, 0, 1);
+ });
+ checkWMTE(() -> { // index reference class
+ int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class)).
+ invoke(array, Void.class, 1);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class)).
+ invoke(array, 0, 1);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class)).
+ invoke(array, 0, 1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ int x = (int) hs.get(am, methodType(int.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)).
+ invoke(array, 0, 1, Void.class);
+ });
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,2075 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeLong
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeLong
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeLong extends VarHandleBaseTest {
+ static final long static_final_v = 1L;
+
+ static long static_v = 1L;
+
+ final long final_v = 1L;
+
+ long v = 1L;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeLong.class, "final_v", long.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeLong.class, "v", long.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeLong.class, "static_final_v", long.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeLong.class, "static_v", long.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(long[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeLong::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeLong::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeLong::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeLong::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeLong recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.get();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, 1L, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, 1L, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, 1L, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, 1L, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(recv, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(recv, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(recv, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(recv, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeVolatile(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.compareAndExchangeVolatile(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeVolatile(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeVolatile(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.compareAndExchangeVolatile(0, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(recv, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(recv, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeVolatile(recv, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatileAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeAcquire(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.compareAndExchangeAcquire(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeAcquire(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeAcquire(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.compareAndExchangeAcquire(0, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(recv, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(recv, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeAcquire(recv, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeRelease(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.compareAndExchangeRelease(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeRelease(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeRelease(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.compareAndExchangeRelease(0, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(recv, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(recv, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeRelease(recv, 1L, 1L, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getAndSet(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getAndSet(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndSet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.getAndSet(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndSet(recv, 1L, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.getAndAdd(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.getAndAdd(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndAdd(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.getAndAdd(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndAdd(recv, 1L, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.addAndGet(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) vh.addAndGet(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.addAndGet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) vh.addAndGet(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.addAndGet(recv, 1L, Void.class);
+ });
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeLong recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, long.class)).
+ invoke(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, long.class)).
+ invoke(0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, long.class, long.class)).
+ invoke(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, long.class, long.class)).
+ invoke(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, Class.class, long.class)).
+ invoke(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , long.class, long.class)).
+ invoke(0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, long.class, Class.class)).
+ invoke(recv, 1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class, long.class, long.class)).
+ invoke(null, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, long.class, long.class)).
+ invoke(Void.class, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class, long.class)).
+ invoke(recv, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class , long.class, long.class)).
+ invoke(0, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class , long.class, long.class)).
+ invoke(recv, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class , long.class, long.class)).
+ invoke(recv, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, long.class, Class.class)).
+ invoke(recv, 1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class, long.class)).
+ invoke(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, long.class)).
+ invoke(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class, long.class)).
+ invoke(null, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, long.class)).
+ invoke(0, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)).
+ invoke(recv, 1L, Void.class);
+ });
+ }
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ long x = (long) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(1L, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(1L, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(1L, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(1L, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeVolatile(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeVolatile(1L, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeVolatile(1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeAcquire(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeAcquire(1L, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeAcquire(1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeRelease(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeRelease(1L, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeRelease(1L, 1L, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndSet(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndSet(1L, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndAdd(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndAdd(1L, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.addAndGet(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.addAndGet(1L, Void.class);
+ });
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long.class, long.class, Class.class)).
+ invoke(1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // expected reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)).
+ invoke(Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long.class, long.class)).
+ invoke(1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class, long.class)).
+ invoke(1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long.class, long.class, Class.class)).
+ invoke(1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long.class)).
+ invoke(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class)).
+ invoke(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long.class)).
+ invoke(1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class)).
+ invoke(1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)).
+ invoke(1L, Void.class);
+ });
+ }
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ long[] array = new long[10];
+ Arrays.fill(array, 1L);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.get();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, 1L, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, 1L, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, 1L, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, 1L, Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.compareAndSet(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSet(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetRelease(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeVolatile(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.compareAndExchangeVolatile(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeVolatile(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeVolatile(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.compareAndExchangeVolatile(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.compareAndExchangeVolatile(array, Void.class, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(array, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeVolatile(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeAcquire(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.compareAndExchangeAcquire(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeAcquire(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeAcquire(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.compareAndExchangeAcquire(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.compareAndExchangeAcquire(array, Void.class, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(array, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeAcquire(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) vh.compareAndExchangeRelease(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.compareAndExchangeRelease(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) vh.compareAndExchangeRelease(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) vh.compareAndExchangeRelease(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.compareAndExchangeRelease(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.compareAndExchangeRelease(array, Void.class, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(array, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.compareAndExchangeRelease(array, 0, 1L, 1L, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getAndSet(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getAndSet(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndSet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // reciarrayever primitive class
+ long x = (long) vh.getAndSet(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getAndSet(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndSet(array, 0, 1L, Void.class);
+ });
+
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.getAndAdd(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.getAndAdd(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.getAndAdd(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.getAndAdd(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.getAndAdd(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndAdd(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.getAndAdd(array, 0, 1L, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) vh.addAndGet(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) vh.addAndGet(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) vh.addAndGet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) vh.addAndGet(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) vh.addAndGet(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) vh.addAndGet(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.addAndGet(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) vh.addAndGet(array, 0, 1L, Void.class);
+ });
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ long[] array = new long[10];
+ Arrays.fill(array, 1L);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) hs.get(am, methodType(long.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, long[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, long.class)).
+ invoke(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, long.class)).
+ invoke(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, long.class)).
+ invoke(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, long[].class, Class.class, long.class)).
+ invoke(array, Void.class, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, long.class, long.class)).
+ invoke(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, long.class, long.class)).
+ invoke(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, Class.class, long.class)).
+ invoke(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, long.class, long.class)).
+ invoke(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, Class.class, long.class, long.class)).
+ invoke(array, Void.class, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class, Class.class)).
+ invoke(array, 0, 1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class, long.class)).
+ invoke(null, 0, 1L, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class, long.class)).
+ invoke(Void.class, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // expected reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class, long.class)).
+ invoke(array, 0, Void.class, 1L);
+ });
+ checkWMTE(() -> { // actual reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class, long.class)).
+ invoke(0, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class, long.class)).
+ invoke(array, Void.class, 1L, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class, long.class)).
+ invoke(array, 0, 1L, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class)).
+ invoke(array, 0, 1L, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, long.class, Class.class)).
+ invoke(array, 0, 1L, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class)).
+ invoke(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class)).
+ invoke(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class)).
+ invoke(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class)).
+ invoke(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class)).
+ invoke(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class)).
+ invoke(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class)).
+ invoke(null, 0, 1L);
+ });
+ checkCCE(() -> { // array reference class
+ long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class)).
+ invoke(Void.class, 0, 1L);
+ });
+ checkWMTE(() -> { // value reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class)).
+ invoke(0, 0, 1L);
+ });
+ checkWMTE(() -> { // index reference class
+ long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class)).
+ invoke(array, Void.class, 1L);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class)).
+ invoke(array, 0, 1L);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class)).
+ invoke(array, 0, 1L);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ long x = (long) hs.get(am, methodType(long.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)).
+ invoke(array, 0, 1L, Void.class);
+ });
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,856 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeShort
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeShort
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeShort extends VarHandleBaseTest {
+ static final short static_final_v = (short)1;
+
+ static short static_v = (short)1;
+
+ final short final_v = (short)1;
+
+ short v = (short)1;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeShort.class, "final_v", short.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeShort.class, "v", short.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeShort.class, "static_final_v", short.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeShort.class, "static_v", short.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(short[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeShort::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeShort::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeShort::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeShort::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeShort recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) vh.get(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.get();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, (short)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, (short)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, (short)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, (short)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeShort recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ short x = (short) hs.get(am, methodType(short.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ short x = (short) hs.get(am, methodType(short.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ short x = (short) hs.get(am, methodType(short.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeShort.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) hs.get(am, methodType(short.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, short.class)).
+ invoke(null, (short)1);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, short.class)).
+ invoke(Void.class, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, short.class)).
+ invoke(0, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, short.class, Class.class)).
+ invoke(recv, (short)1, Void.class);
+ });
+ }
+
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ short x = (short) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set((short)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile((short)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque((short)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease((short)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ short x = (short) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, short.class, Class.class)).
+ invoke((short)1, Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ short[] array = new short[10];
+ Arrays.fill(array, (short)1);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.get();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, (short)1, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, (short)1, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, (short)1, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, (short)1, Void.class);
+ });
+
+
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ short[] array = new short[10];
+ Arrays.fill(array, (short)1);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ short x = (short) hs.get(am, methodType(short.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ short x = (short) hs.get(am, methodType(short.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ short x = (short) hs.get(am, methodType(short.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ short x = (short) hs.get(am, methodType(short.class, short[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkWMTE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, short[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, short[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ short x = (short) hs.get(am, methodType(short.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ short x = (short) hs.get(am, methodType(short.class, short[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, short.class)).
+ invoke(null, 0, (short)1);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, short.class)).
+ invoke(Void.class, 0, (short)1);
+ });
+ checkWMTE(() -> { // value reference class
+ hs.get(am, methodType(void.class, short[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, short.class)).
+ invoke(0, 0, (short)1);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, short[].class, Class.class, short.class)).
+ invoke(array, Void.class, (short)1);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, short[].class, int.class, Class.class)).
+ invoke(array, 0, (short)1, Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,1811 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodTypeString
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeString
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodTypeString extends VarHandleBaseTest {
+ static final String static_final_v = "foo";
+
+ static String static_v = "foo";
+
+ final String final_v = "foo";
+
+ String v = "foo";
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeString.class, "final_v", String.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodTypeString.class, "v", String.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeString.class, "static_final_v", String.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodTypeString.class, "static_v", String.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle(String[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodTypeString::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodTypeString::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) vh.get(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.get();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, "foo", Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, "foo", Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, "foo", Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, "foo", Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(recv, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(recv, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(recv, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(recv, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeVolatile(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.compareAndExchangeVolatile(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeVolatile(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeVolatile(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) vh.compareAndExchangeVolatile(0, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(recv, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(recv, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeVolatile(recv, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeVolatileAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeAcquire(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeAcquire(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeAcquire(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) vh.compareAndExchangeAcquire(0, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(recv, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(recv, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeAcquire(recv, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeRelease(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.compareAndExchangeRelease(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeRelease(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeRelease(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) vh.compareAndExchangeRelease(0, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(recv, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(recv, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeRelease(recv, "foo", "foo", Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.getAndSet(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) vh.getAndSet(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ String x = (String) vh.getAndSet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) vh.getAndSet(0, "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(recv, "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(recv, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAndSet(recv, "foo", Void.class);
+ });
+
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodTypeString recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) hs.get(am, methodType(String.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, String.class)).
+ invoke(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, String.class)).
+ invoke(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, String.class)).
+ invoke(0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
+ invoke(recv, "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, String.class, String.class)).
+ invoke(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class, String.class)).
+ invoke(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, Class.class, String.class)).
+ invoke(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
+ invoke(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , String.class, String.class)).
+ invoke(0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)).
+ invoke(recv, "foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkNPE(() -> { // null receiver
+ String x = (String) hs.get(am, methodType(String.class, Void.class, String.class, String.class)).
+ invoke(null, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, String.class, String.class)).
+ invoke(Void.class, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class, String.class)).
+ invoke(recv, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, Class.class)).
+ invoke(recv, "foo", Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class , String.class, String.class)).
+ invoke(0, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class , String.class, String.class)).
+ invoke(recv, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class , String.class, String.class)).
+ invoke(recv, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)).
+ invoke(recv, "foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkNPE(() -> { // null receiver
+ String x = (String) hs.get(am, methodType(String.class, Void.class, String.class)).
+ invoke(null, "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)).
+ invoke(Void.class, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class, String.class)).
+ invoke(0, "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class, String.class)).
+ invoke(recv, "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class)).
+ invoke(recv, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)).
+ invoke(recv, "foo", Void.class);
+ });
+ }
+
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ String x = (String) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set("foo", Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile("foo", Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque("foo", Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease("foo", Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.compareAndSet("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet("foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet("foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire("foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease("foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeVolatile(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeVolatile("foo", Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile("foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile("foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeVolatile("foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeAcquire(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeAcquire("foo", Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire("foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire("foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeAcquire("foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeRelease(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeRelease("foo", Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease("foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease("foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeRelease("foo", "foo", Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ String x = (String) vh.getAndSet(Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.getAndSet("foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet("foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAndSet("foo", Void.class);
+ });
+
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkCCE(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, String.class, Class.class)).
+ invoke("foo", Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class)).
+ invoke(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, Class.class)).
+ invoke("foo", Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class, Class.class)).
+ invoke("foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkCCE(() -> { // expected reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)).
+ invoke(Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)).
+ invoke("foo", Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, String.class, String.class)).
+ invoke("foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class)).
+ invoke("foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String.class, String.class, Class.class)).
+ invoke("foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkCCE(() -> { // value reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, String.class)).
+ invoke("foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class)).
+ invoke("foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)).
+ invoke("foo", Void.class);
+ });
+ }
+
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ String[] array = new String[10];
+ Arrays.fill(array, "foo");
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.get();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, "foo", Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, "foo", Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, "foo", Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, "foo", Void.class);
+ });
+
+
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.compareAndSet(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.compareAndSet(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.compareAndSet(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSet(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetRelease(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeVolatile(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.compareAndExchangeVolatile(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeVolatile(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeVolatile(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.compareAndExchangeVolatile(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.compareAndExchangeVolatile(array, Void.class, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(array, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeVolatile(array, 0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeVolatile(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeAcquire(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.compareAndExchangeAcquire(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeAcquire(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.compareAndExchangeAcquire(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.compareAndExchangeAcquire(array, Void.class, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(array, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeAcquire(array, 0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeAcquire(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) vh.compareAndExchangeRelease(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.compareAndExchangeRelease(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) vh.compareAndExchangeRelease(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) vh.compareAndExchangeRelease(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.compareAndExchangeRelease(array, Void.class, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(array, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.compareAndExchangeRelease(array, 0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.compareAndExchangeRelease(array, 0, "foo", "foo", Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) vh.getAndSet(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) vh.getAndSet(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ String x = (String) vh.getAndSet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // reciarrayever primitive class
+ String x = (String) vh.getAndSet(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) vh.getAndSet(array, Void.class, "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) vh.getAndSet(array, 0, "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) vh.getAndSet(array, 0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) vh.getAndSet(array, 0, "foo", Void.class);
+ });
+
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ String[] array = new String[10];
+ Arrays.fill(array, "foo");
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) hs.get(am, methodType(String.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, String[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, String.class)).
+ invoke(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, String.class)).
+ invoke(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ hs.get(am, methodType(void.class, String[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, String.class)).
+ invoke(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, String[].class, Class.class, String.class)).
+ invoke(array, Void.class, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, String[].class, int.class, Class.class)).
+ invoke(array, 0, "foo", Void.class);
+ });
+ }
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, String.class, String.class)).
+ invoke(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, String.class, String.class)).
+ invoke(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, Class.class, String.class)).
+ invoke(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, Class.class)).
+ invoke(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, String.class, String.class)).
+ invoke(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, Class.class, String.class, String.class)).
+ invoke(array, Void.class, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class, Class.class)).
+ invoke(array, 0, "foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ String x = (String) hs.get(am, methodType(String.class, Void.class, int.class, String.class, String.class)).
+ invoke(null, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class, String.class)).
+ invoke(Void.class, 0, "foo", "foo");
+ });
+ checkCCE(() -> { // expected reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class, String.class)).
+ invoke(array, 0, Void.class, "foo");
+ });
+ checkCCE(() -> { // actual reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)).
+ invoke(array, 0, "foo", Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class, String.class)).
+ invoke(0, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class, String.class)).
+ invoke(array, Void.class, "foo", "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class, String.class)).
+ invoke(array, 0, "foo", "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)).
+ invoke(array, 0, "foo", "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class, Class.class)).
+ invoke(array, 0, "foo", "foo", Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ String x = (String) hs.get(am, methodType(String.class, Void.class, int.class, String.class)).
+ invoke(null, 0, "foo");
+ });
+ checkCCE(() -> { // array reference class
+ String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class)).
+ invoke(Void.class, 0, "foo");
+ });
+ checkCCE(() -> { // value reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class)).
+ invoke(0, 0, "foo");
+ });
+ checkWMTE(() -> { // index reference class
+ String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class)).
+ invoke(array, Void.class, "foo");
+ });
+ // Incorrect return type
+ checkCCE(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class)).
+ invoke(array, 0, "foo");
+ });
+ checkWMTE(() -> { // primitive class
+ boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class)).
+ invoke(array, 0, "foo");
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ String x = (String) hs.get(am, methodType(String.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)).
+ invoke(array, 0, "foo", Void.class);
+ });
+ }
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestReflection.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng VarHandleTestReflection
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.lang.reflect.Method;
+import java.util.stream.Stream;
+
+public class VarHandleTestReflection extends VarHandleBaseTest {
+ String string;
+
+ @DataProvider
+ public static Object[][] accessModesProvider() {
+ return Stream.of(VarHandle.AccessMode.values()).
+ map(am -> new Object[]{am}).
+ toArray(Object[][]::new);
+ }
+
+ static VarHandle handle() throws Exception {
+ return MethodHandles.lookup().
+ findVarHandle(VarHandleTestReflection.class, "string", String.class);
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class)
+ public void methodInvocation(VarHandle.AccessMode accessMode) throws Exception {
+ VarHandle v = handle();
+
+ // Try a reflective invoke using a Method
+
+ Method vhm = VarHandle.class.getMethod(accessMode.name(), Object[].class);
+ vhm.invoke(v, new Object[]{});
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = UnsupportedOperationException.class)
+ public void methodHandleInvoke(VarHandle.AccessMode accessMode) throws Throwable {
+ VarHandle v = handle();
+
+ // Try a reflective invoke using a MethodHandle
+
+ MethodHandle mh = MethodHandles.lookup().unreflect(
+ VarHandle.class.getMethod(accessMode.name(), Object[].class));
+ // Use invoke to avoid WrongMethodTypeException for
+ // non-signature-polymorphic return types
+ Object o = (Object) mh.invoke(v, new Object[]{});
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class)
+ public void methodInvocationFromMethodInfo(VarHandle.AccessMode accessMode) throws Exception {
+ VarHandle v = handle();
+
+ // Try a reflective invoke using a Method obtained from cracking
+ // a MethodHandle
+
+ MethodHandle mh = MethodHandles.lookup().unreflect(
+ VarHandle.class.getMethod(accessMode.name(), Object[].class));
+ MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh);
+ Method im = info.reflectAs(Method.class, MethodHandles.lookup());
+ im.invoke(v, new Object[]{});
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class)
+ public void reflectAsFromVarHandleInvoker(VarHandle.AccessMode accessMode) throws Exception {
+ VarHandle v = handle();
+
+ MethodHandle mh = MethodHandles.varHandleInvoker(
+ accessMode, v.accessModeType(accessMode));
+
+ MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh);
+
+ info.reflectAs(Method.class, MethodHandles.lookup());
+ }
+
+ @Test(dataProvider = "accessModesProvider", expectedExceptions = IllegalArgumentException.class)
+ public void reflectAsFromFindVirtual(VarHandle.AccessMode accessMode) throws Exception {
+ VarHandle v = handle();
+
+ MethodHandle mh = MethodHandles.publicLookup().findVirtual(
+ VarHandle.class, accessMode.name(), v.accessModeType(accessMode));
+
+ MethodHandleInfo info = MethodHandles.lookup().revealDirect(mh);
+
+ info.reflectAs(Method.class, MethodHandles.lookup());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,1026 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=10 -Xint VarHandleTestAccess$Type$
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$
+ * @run testng/othervm -Diters=20000 VarHandleTestAccess$Type$
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccess$Type$
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestAccess$Type$ extends VarHandleBaseTest {
+ static final $type$ static_final_v = $value1$;
+
+ static $type$ static_v;
+
+ final $type$ final_v = $value1$;
+
+ $type$ v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccess$Type$.class, "final_v", $type$.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccess$Type$.class, "v", $type$.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccess$Type$.class, "static_final_v", $type$.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccess$Type$.class, "static_v", $type$.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] varHandlesProvider() throws Exception {
+ List<VarHandle> vhs = new ArrayList<>();
+ vhs.add(vhField);
+ vhs.add(vhStaticField);
+ vhs.add(vhArray);
+
+ return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandle vh) {
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+#if[CAS]
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+#else[CAS]
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+#end[CAS]
+
+#if[AtomicAdd]
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+#else[AtomicAdd]
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+#end[AtomicAdd]
+ }
+
+
+ @DataProvider
+ public Object[][] typesProvider() throws Exception {
+ List<Object[]> types = new ArrayList<>();
+ types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccess$Type$.class)});
+ types.add(new Object[] {vhStaticField, Arrays.asList()});
+ types.add(new Object[] {vhArray, Arrays.asList($type$[].class, int.class)});
+
+ return types.stream().toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<Class<?>> pts) {
+ assertEquals(vh.varType(), $type$.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @Test
+ public void testLookupInstanceToStatic() {
+ checkIAE("Lookup of static final field to instance final field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccess$Type$.class, "final_v", $type$.class);
+ });
+
+ checkIAE("Lookup of static field to instance field", () -> {
+ MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestAccess$Type$.class, "v", $type$.class);
+ });
+ }
+
+ @Test
+ public void testLookupStaticToInstance() {
+ checkIAE("Lookup of instance final field to static final field", () -> {
+ MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccess$Type$.class, "static_final_v", $type$.class);
+ });
+
+ checkIAE("Lookup of instance field to static field", () -> {
+ vhStaticField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestAccess$Type$.class, "static_v", $type$.class);
+ });
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance final field",
+ vhFinalField, vh -> testInstanceFinalField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance final field unsupported",
+ vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static final field",
+ vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalField));
+ cases.add(new VarHandleAccessTestCase("Static final field unsupported",
+ vhStaticFinalField, VarHandleTestAccess$Type$::testStaticFinalFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Instance field",
+ vhField, vh -> testInstanceField(this, vh)));
+ cases.add(new VarHandleAccessTestCase("Instance field unsupported",
+ vhField, vh -> testInstanceFieldUnsupported(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field",
+ vhStaticField, VarHandleTestAccess$Type$::testStaticField));
+ cases.add(new VarHandleAccessTestCase("Static field unsupported",
+ vhStaticField, VarHandleTestAccess$Type$::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array",
+ vhArray, VarHandleTestAccess$Type$::testArray));
+ cases.add(new VarHandleAccessTestCase("Array unsupported",
+ vhArray, VarHandleTestAccess$Type$::testArrayUnsupported,
+ false));
+ cases.add(new VarHandleAccessTestCase("Array index out of bounds",
+ vhArray, VarHandleTestAccess$Type$::testArrayIndexOutOfBounds,
+ false));
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+
+
+ static void testInstanceFinalField(VarHandleTestAccess$Type$ recv, VarHandle vh) {
+ // Plain
+ {
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "get $type$ value");
+ }
+
+
+ // Volatile
+ {
+ $type$ x = ($type$) vh.getVolatile(recv);
+ assertEquals(x, $value1$, "getVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ $type$ x = ($type$) vh.getAcquire(recv);
+ assertEquals(x, $value1$, "getRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ $type$ x = ($type$) vh.getOpaque(recv);
+ assertEquals(x, $value1$, "getOpaque $type$ value");
+ }
+ }
+
+ static void testInstanceFinalFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) {
+ checkUOE(() -> {
+ vh.set(recv, $value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile(recv, $value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease(recv, $value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque(recv, $value2$);
+ });
+
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(recv, $value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(recv, $value1$);
+ });
+#end[AtomicAdd]
+ }
+
+
+ static void testStaticFinalField(VarHandle vh) {
+ // Plain
+ {
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "get $type$ value");
+ }
+
+
+ // Volatile
+ {
+ $type$ x = ($type$) vh.getVolatile();
+ assertEquals(x, $value1$, "getVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ $type$ x = ($type$) vh.getAcquire();
+ assertEquals(x, $value1$, "getRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ $type$ x = ($type$) vh.getOpaque();
+ assertEquals(x, $value1$, "getOpaque $type$ value");
+ }
+ }
+
+ static void testStaticFinalFieldUnsupported(VarHandle vh) {
+ checkUOE(() -> {
+ vh.set($value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setVolatile($value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setRelease($value2$);
+ });
+
+ checkUOE(() -> {
+ vh.setOpaque($value2$);
+ });
+
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease($value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd($value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet($value1$);
+ });
+#end[AtomicAdd]
+ }
+
+
+ static void testInstanceField(VarHandleTestAccess$Type$ recv, VarHandle vh) {
+ // Plain
+ {
+ vh.set(recv, $value1$);
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "set $type$ value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(recv, $value2$);
+ $type$ x = ($type$) vh.getVolatile(recv);
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(recv, $value1$);
+ $type$ x = ($type$) vh.getAcquire(recv);
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(recv, $value2$);
+ $type$ x = ($type$) vh.getOpaque(recv);
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ vh.set(recv, $value1$);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(recv, $value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(recv, $value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet(recv, $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) vh.get(recv);
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set(recv, $value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd(recv, $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet(recv, $value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestAccess$Type$ recv, VarHandle vh) {
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(recv, $value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(recv, $value1$);
+ });
+#end[AtomicAdd]
+ }
+
+
+ static void testStaticField(VarHandle vh) {
+ // Plain
+ {
+ vh.set($value1$);
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "set $type$ value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile($value2$);
+ $type$ x = ($type$) vh.getVolatile();
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease($value1$);
+ $type$ x = ($type$) vh.getAcquire();
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque($value2$);
+ $type$ x = ($type$) vh.getOpaque();
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ vh.set($value1$);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet($value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet($value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile($value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease($value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSet($value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetAcquire($value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = (boolean) vh.weakCompareAndSetRelease( $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet( $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) vh.get();
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set($value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd( $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet($value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+
+ static void testStaticFieldUnsupported(VarHandle vh) {
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire($value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease($value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd($value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet($value1$);
+ });
+#end[AtomicAdd]
+ }
+
+
+ static void testArray(VarHandle vh) {
+ $type$[] array = new $type$[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ vh.set(array, i, $value1$);
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "get $type$ value");
+ }
+
+
+ // Volatile
+ {
+ vh.setVolatile(array, i, $value2$);
+ $type$ x = ($type$) vh.getVolatile(array, i);
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, $value1$);
+ $type$ x = ($type$) vh.getAcquire(array, i);
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, $value2$);
+ $type$ x = ($type$) vh.getOpaque(array, i);
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ vh.set(array, i, $value1$);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, $value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, $value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet(array, i, $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set(array, i, $value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd(array, i, $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet(array, i, $value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+ }
+
+ static void testArrayUnsupported(VarHandle vh) {
+ $type$[] array = new $type$[10];
+
+ int i = 0;
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, $value1$, $value2$);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, i, $value1$);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, i, $value1$);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable {
+ $type$[] array = new $type$[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, $value1$);
+ });
+
+#if[CAS]
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, $value1$, $value2$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, $value2$, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, $value2$, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, $value2$, $value1$);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, $value1$, $value2$);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, $value1$, $value2$);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, $value1$, $value2$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, $value1$);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, $value3$);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, $value3$);
+ });
+#end[AtomicAdd]
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,1089 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$
+ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$
+ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest {
+ static final int SIZE = $BoxType$.BYTES;
+
+ static final $type$ VALUE_1 = $value1$;
+
+ static final $type$ VALUE_2 = $value2$;
+
+ static final $type$ VALUE_3 = $value3$;
+
+
+ @Override
+ public void setupVarHandleSources() {
+ // Combinations of VarHandle byte[] or ByteBuffer
+ vhss = new ArrayList<>();
+ for (MemoryMode endianess : Arrays.asList(MemoryMode.BIG_ENDIAN, MemoryMode.LITTLE_ENDIAN)) {
+ VarHandleSource aeh = new VarHandleSource(
+ MethodHandles.byteArrayViewVarHandle($type$[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(aeh);
+
+ VarHandleSource bbh = new VarHandleSource(
+ MethodHandles.byteBufferViewVarHandle($type$[].class,
+ endianess == MemoryMode.BIG_ENDIAN),
+ endianess, MemoryMode.READ_WRITE);
+ vhss.add(bbh);
+ }
+ }
+
+
+ @Test(dataProvider = "varHandlesProvider")
+ public void testIsAccessModeSupported(VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.get));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.set));
+
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getOpaque));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.setOpaque));
+
+#if[CAS]
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+#else[CAS]
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeVolatile));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.compareAndExchangeRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSet));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetAcquire));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.weakCompareAndSetRelease));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndSet));
+#end[CAS]
+
+#if[AtomicAdd]
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+#else[AtomicAdd]
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.getAndAdd));
+ assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.addAndGet));
+#end[AtomicAdd]
+ }
+
+ @Test(dataProvider = "typesProvider")
+ public void testTypes(VarHandle vh, List<java.lang.Class<?>> pts) {
+ assertEquals(vh.varType(), $type$.class);
+
+ assertEquals(vh.coordinateTypes(), pts);
+
+ testTypes(vh);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (ByteArrayViewSource<?> bav : bavss) {
+ for (VarHandleSource vh : vhss) {
+ if (vh.matches(bav)) {
+ if (bav instanceof ByteArraySource) {
+ ByteArraySource bas = (ByteArraySource) bav;
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bas, h),
+ true));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bas, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bas, h),
+ false));
+ }
+ else {
+ ByteBufferSource bbs = (ByteBufferSource) bav;
+
+ if (MemoryMode.READ_WRITE.isSet(bav.memoryModes)) {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read write", bav, vh, h -> testArrayReadWrite(bbs, h),
+ true));
+ }
+ else {
+ cases.add(new VarHandleSourceAccessTestCase(
+ "read only", bav, vh, h -> testArrayReadOnly(bbs, h),
+ true));
+ }
+
+ cases.add(new VarHandleSourceAccessTestCase(
+ "unsupported", bav, vh, h -> testArrayUnsupported(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "index out of bounds", bav, vh, h -> testArrayIndexOutOfBounds(bbs, h),
+ false));
+ cases.add(new VarHandleSourceAccessTestCase(
+ "misaligned access", bav, vh, h -> testArrayMisalignedAccess(bbs, h),
+ false));
+ }
+ }
+ }
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testArrayUnsupported(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+ int ci = 1;
+
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testArrayUnsupported(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+ int ci = 0;
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ if (readOnly) {
+ checkROBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+#if[CAS]
+
+ checkROBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkROBE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+#else[CAS]
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkROBE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkROBE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#else[AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+ else {
+#if[!CAS]
+ checkUOE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+#if[!AtomicAdd]
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkUOE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+ }
+
+
+ static void testArrayIndexOutOfBounds(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int length = array.length - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.get(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+#if[CAS]
+
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+
+ }
+ }
+
+ static void testArrayIndexOutOfBounds(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i : new int[]{-1, Integer.MIN_VALUE, length, length + 1, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.get(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.set(array, ci, VALUE_1);
+ });
+ }
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkIOOBE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkIOOBE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+#if[CAS]
+ checkIOOBE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkIOOBE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteArraySource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+#if[CAS]
+
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkISE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+
+ }
+ }
+ }
+
+ static void testArrayMisalignedAccess(ByteBufferSource bs, VarHandleSource vhs) throws Throwable {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ boolean readOnly = MemoryMode.READ_ONLY.isSet(bs.memoryModes);
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+ final int ci = i;
+
+ if (!iAligned) {
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getVolatile(array, ci);
+ });
+
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getAcquire(array, ci);
+ });
+
+ checkISE(() -> {
+ $type$ x = ($type$) vh.getOpaque(array, ci);
+ });
+
+ if (!readOnly) {
+ checkISE(() -> {
+ vh.setVolatile(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setRelease(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ vh.setOpaque(array, ci, VALUE_1);
+ });
+
+#if[CAS]
+ checkISE(() -> {
+ boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, ci, VALUE_2, VALUE_1);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSet(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetAcquire(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ boolean r = vh.weakCompareAndSetRelease(array, ci, VALUE_1, VALUE_2);
+ });
+
+ checkISE(() -> {
+ $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ checkISE(() -> {
+ $type$ o = ($type$) vh.getAndAdd(array, ci, VALUE_1);
+ });
+
+ checkISE(() -> {
+ $type$ o = ($type$) vh.addAndGet(array, ci, VALUE_1);
+ });
+#end[AtomicAdd]
+ }
+ }
+ }
+ }
+
+ static void testArrayReadWrite(ByteArraySource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ byte[] array = bs.s;
+
+ int misalignmentAtZero = ByteBuffer.wrap(array).alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.length - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get $type$ value");
+ }
+
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ $type$ x = ($type$) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ $type$ x = ($type$) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ $type$ x = ($type$) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque $type$ value");
+ }
+#if[CAS]
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+ }
+ }
+
+
+ static void testArrayReadWrite(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ bs.fill((byte) 0xff);
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ // Plain
+ {
+ vh.set(array, i, VALUE_1);
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "get $type$ value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ vh.setVolatile(array, i, VALUE_2);
+ $type$ x = ($type$) vh.getVolatile(array, i);
+ assertEquals(x, VALUE_2, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ vh.setRelease(array, i, VALUE_1);
+ $type$ x = ($type$) vh.getAcquire(array, i);
+ assertEquals(x, VALUE_1, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ vh.setOpaque(array, i, VALUE_2);
+ $type$ x = ($type$) vh.getOpaque(array, i);
+ assertEquals(x, VALUE_2, "setOpaque $type$ value");
+ }
+#if[CAS]
+
+ vh.set(array, i, VALUE_1);
+
+ // Compare
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.compareAndSet(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeVolatile(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, VALUE_1, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeAcquire(array, i, VALUE_1, VALUE_3);
+ assertEquals(r, VALUE_2, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, VALUE_2, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) vh.compareAndExchangeRelease(array, i, VALUE_2, VALUE_3);
+ assertEquals(r, VALUE_1, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) vh.getAndSet(array, i, VALUE_1);
+ assertEquals(o, VALUE_2, "getAndSet $type$");
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, VALUE_1, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ vh.set(array, i, VALUE_1);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) vh.getAndAdd(array, i, VALUE_3);
+ assertEquals(o, VALUE_1, "getAndAdd $type$");
+ $type$ c = ($type$) vh.addAndGet(array, i, VALUE_3);
+ assertEquals(c, VALUE_1 + VALUE_3 + VALUE_3, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+ }
+ }
+
+ static void testArrayReadOnly(ByteBufferSource bs, VarHandleSource vhs) {
+ VarHandle vh = vhs.s;
+ ByteBuffer array = bs.s;
+
+ int misalignmentAtZero = array.alignmentOffset(0, SIZE);
+
+ ByteBuffer bb = ByteBuffer.allocate(SIZE);
+ bb.order(MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes) ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN);
+ bs.fill(bb.put$Type$(0, VALUE_2).array());
+
+ int length = array.limit() - SIZE + 1;
+ for (int i = 0; i < length; i++) {
+ boolean iAligned = ((i + misalignmentAtZero) & (SIZE - 1)) == 0;
+
+ $type$ v = MemoryMode.BIG_ENDIAN.isSet(vhs.memoryModes)
+ ? rotateLeft(VALUE_2, (i % SIZE) << 3)
+ : rotateRight(VALUE_2, (i % SIZE) << 3);
+ // Plain
+ {
+ $type$ x = ($type$) vh.get(array, i);
+ assertEquals(x, v, "get $type$ value");
+ }
+
+ if (iAligned) {
+ // Volatile
+ {
+ $type$ x = ($type$) vh.getVolatile(array, i);
+ assertEquals(x, v, "getVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ $type$ x = ($type$) vh.getAcquire(array, i);
+ assertEquals(x, v, "getRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ $type$ x = ($type$) vh.getOpaque(array, i);
+ assertEquals(x, v, "getOpaque $type$ value");
+ }
+ }
+ }
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,667 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccess$Type$
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest {
+ static final $type$ static_final_v = $value1$;
+
+ static $type$ static_v;
+
+ final $type$ final_v = $value1$;
+
+ $type$ v;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccess$Type$.class, "final_v", $type$.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodHandleAccess$Type$.class, "v", $type$.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccess$Type$.class, "static_final_v", $type$.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodHandleAccess$Type$.class, "static_v", $type$.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
+ }
+
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field",
+ vhField, f, hs -> testInstanceField(this, hs)));
+ cases.add(new MethodHandleAccessTestCase("Instance field unsupported",
+ vhField, f, hs -> testInstanceFieldUnsupported(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field",
+ vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticField));
+ cases.add(new MethodHandleAccessTestCase("Static field unsupported",
+ vhStaticField, f, VarHandleTestMethodHandleAccess$Type$::testStaticFieldUnsupported,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array",
+ vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArray));
+ cases.add(new MethodHandleAccessTestCase("Array unsupported",
+ vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayUnsupported,
+ false));
+ cases.add(new MethodHandleAccessTestCase("Array index out of bounds",
+ vhArray, f, VarHandleTestMethodHandleAccess$Type$::testArrayIndexOutOfBounds,
+ false));
+ }
+
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceField(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(recv, $value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "set $type$ value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(recv, $value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact(recv);
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(recv, $value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact(recv);
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(recv, $value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact(recv);
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ hs.get(TestAccessMode.set).invokeExact(recv, $value1$);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, $value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(recv, $value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(recv, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, $value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(recv, $value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(recv, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(recv, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(recv, $value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(recv, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact(recv, $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(recv);
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ hs.get(TestAccessMode.set).invokeExact(recv, $value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact(recv, $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact(recv, $value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+
+ static void testInstanceFieldUnsupported(VarHandleTestMethodHandleAccess$Type$ recv, Handles hs) throws Throwable {
+#if[!CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(recv, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
+ });
+ }
+#end[CAS]
+
+#if[!AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(recv, $value1$);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+
+ static void testStaticField(Handles hs) throws Throwable {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact($value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "set $type$ value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact($value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact();
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact($value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact();
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact($value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact();
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ hs.get(TestAccessMode.set).invokeExact($value1$);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact($value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact($value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact($value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact($value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact($value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact($value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact($value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact($value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact($value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact($value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact( $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact( $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact();
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ hs.get(TestAccessMode.set).invokeExact($value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact( $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact($value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+
+ static void testStaticFieldUnsupported(Handles hs) throws Throwable {
+#if[!CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact($value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact($value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact($value1$);
+ });
+ }
+#end[CAS]
+
+#if[!AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact($value1$);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+
+ static void testArray(Handles hs) throws Throwable {
+ $type$[] array = new $type$[10];
+
+ for (int i = 0; i < array.length; i++) {
+ // Plain
+ {
+ hs.get(TestAccessMode.set).invokeExact(array, i, $value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "get $type$ value");
+ }
+
+
+ // Volatile
+ {
+ hs.get(TestAccessMode.setVolatile).invokeExact(array, i, $value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getVolatile).invokeExact(array, i);
+ assertEquals(x, $value2$, "setVolatile $type$ value");
+ }
+
+ // Lazy
+ {
+ hs.get(TestAccessMode.setRelease).invokeExact(array, i, $value1$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getAcquire).invokeExact(array, i);
+ assertEquals(x, $value1$, "setRelease $type$ value");
+ }
+
+ // Opaque
+ {
+ hs.get(TestAccessMode.setOpaque).invokeExact(array, i, $value2$);
+ $type$ x = ($type$) hs.get(TestAccessMode.getOpaque).invokeExact(array, i);
+ assertEquals(x, $value2$, "setOpaque $type$ value");
+ }
+
+#if[CAS]
+ hs.get(TestAccessMode.set).invokeExact(array, i, $value1$);
+
+ // Compare
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, $value1$, $value2$);
+ assertEquals(r, true, "success compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "success compareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.compareAndSet).invokeExact(array, i, $value1$, $value3$);
+ assertEquals(r, false, "failing compareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "failing compareAndSet $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "success compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeVolatile).invokeExact(array, i, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeVolatile $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "failing compareAndExchangeVolatile $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, $value1$, $value2$);
+ assertEquals(r, $value1$, "success compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "success compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeAcquire).invokeExact(array, i, $value1$, $value3$);
+ assertEquals(r, $value2$, "failing compareAndExchangeAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "failing compareAndExchangeAcquire $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, $value2$, $value1$);
+ assertEquals(r, $value2$, "success compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "success compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ $type$ r = ($type$) hs.get(TestAccessMode.compareAndExchangeRelease).invokeExact(array, i, $value2$, $value3$);
+ assertEquals(r, $value1$, "failing compareAndExchangeRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "failing compareAndExchangeRelease $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSet).invokeExact(array, i, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "weakCompareAndSet $type$ value");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetAcquire).invokeExact(array, i, $value2$, $value1$);
+ assertEquals(r, true, "weakCompareAndSetAcquire $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$");
+ }
+
+ {
+ boolean r = (boolean) hs.get(TestAccessMode.weakCompareAndSetRelease).invokeExact(array, i, $value1$, $value2$);
+ assertEquals(r, true, "weakCompareAndSetRelease $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value2$, "weakCompareAndSetRelease $type$");
+ }
+
+ // Compare set and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndSet).invokeExact(array, i, $value1$);
+ assertEquals(o, $value2$, "getAndSet $type$");
+ $type$ x = ($type$) hs.get(TestAccessMode.get).invokeExact(array, i);
+ assertEquals(x, $value1$, "getAndSet $type$ value");
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ hs.get(TestAccessMode.set).invokeExact(array, i, $value1$);
+
+ // get and add, add and get
+ {
+ $type$ o = ($type$) hs.get(TestAccessMode.getAndAdd).invokeExact(array, i, $value3$);
+ assertEquals(o, $value1$, "getAndAdd $type$");
+ $type$ c = ($type$) hs.get(TestAccessMode.addAndGet).invokeExact(array, i, $value3$);
+ assertEquals(c, $value1$ + $value3$ + $value3$, "getAndAdd $type$ value");
+ }
+#end[AtomicAdd]
+ }
+ }
+
+ static void testArrayUnsupported(Handles hs) throws Throwable {
+ $type$[] array = new $type$[10];
+
+ final int i = 0;
+#if[!CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkUOE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, i, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkUOE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(array, i, $value1$);
+ });
+ }
+#end[CAS]
+
+#if[!AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkUOE(am, () -> {
+ $type$ o = ($type$) hs.get(am).invokeExact(array, i, $value1$);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+ static void testArrayIndexOutOfBounds(Handles hs) throws Throwable {
+ $type$[] array = new $type$[10];
+
+ for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) {
+ final int ci = i;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ checkIOOBE(am, () -> {
+ $type$ x = ($type$) hs.get(am).invokeExact(array, ci);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ checkIOOBE(am, () -> {
+ hs.get(am).invokeExact(array, ci, $value1$);
+ });
+ }
+
+#if[CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ checkIOOBE(am, () -> {
+ boolean r = (boolean) hs.get(am).invokeExact(array, ci, $value1$, $value2$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkIOOBE(am, () -> {
+ $type$ r = ($type$) hs.get(am).invokeExact(array, ci, $value2$, $value1$);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkIOOBE(am, () -> {
+ $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value1$);
+ });
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkIOOBE(am, () -> {
+ $type$ o = ($type$) hs.get(am).invokeExact(array, ci, $value3$);
+ });
+ }
+#end[AtomicAdd]
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,2099 @@
+/*
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @run testng/othervm VarHandleTestMethodType$Type$
+ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodType$Type$
+ */
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.testng.Assert.*;
+
+import static java.lang.invoke.MethodType.*;
+
+public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest {
+ static final $type$ static_final_v = $value1$;
+
+ static $type$ static_v = $value1$;
+
+ final $type$ final_v = $value1$;
+
+ $type$ v = $value1$;
+
+ VarHandle vhFinalField;
+
+ VarHandle vhField;
+
+ VarHandle vhStaticField;
+
+ VarHandle vhStaticFinalField;
+
+ VarHandle vhArray;
+
+ @BeforeClass
+ public void setup() throws Exception {
+ vhFinalField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodType$Type$.class, "final_v", $type$.class);
+
+ vhField = MethodHandles.lookup().findVarHandle(
+ VarHandleTestMethodType$Type$.class, "v", $type$.class);
+
+ vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodType$Type$.class, "static_final_v", $type$.class);
+
+ vhStaticField = MethodHandles.lookup().findStaticVarHandle(
+ VarHandleTestMethodType$Type$.class, "static_v", $type$.class);
+
+ vhArray = MethodHandles.arrayElementVarHandle($type$[].class);
+ }
+
+ @DataProvider
+ public Object[][] accessTestCaseProvider() throws Exception {
+ List<AccessTestCase<?>> cases = new ArrayList<>();
+
+ cases.add(new VarHandleAccessTestCase("Instance field wrong method type",
+ vhField, vh -> testInstanceFieldWrongMethodType(this, vh),
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, VarHandleTestMethodType$Type$::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new VarHandleAccessTestCase("Array wrong method type",
+ vhArray, VarHandleTestMethodType$Type$::testArrayWrongMethodType,
+ false));
+ for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) {
+ cases.add(new MethodHandleAccessTestCase("Instance field wrong method type",
+ vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs),
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Static field wrong method type",
+ vhStaticField, f, VarHandleTestMethodType$Type$::testStaticFieldWrongMethodType,
+ false));
+
+ cases.add(new MethodHandleAccessTestCase("Array wrong method type",
+ vhArray, f, VarHandleTestMethodType$Type$::testArrayWrongMethodType,
+ false));
+ }
+ // Work around issue with jtreg summary reporting which truncates
+ // the String result of Object.toString to 30 characters, hence
+ // the first dummy argument
+ return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new);
+ }
+
+ @Test(dataProvider = "accessTestCaseProvider")
+ public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable {
+ T t = atc.get();
+ int iters = atc.requiresLoop() ? ITERS : 1;
+ for (int c = 0; c < iters; c++) {
+ atc.testAccess(t);
+ }
+ }
+
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodType$Type$ recv, VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.get(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.get(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) vh.get(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.get(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.get();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.get(recv, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.set(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.set(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.set(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(recv, $value1$, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getVolatile(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getVolatile(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) vh.getVolatile(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getVolatile(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getVolatile(recv, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setVolatile(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setVolatile(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setVolatile(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(recv, $value1$, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getOpaque(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getOpaque(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) vh.getOpaque(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getOpaque(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getOpaque(recv, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setOpaque(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setOpaque(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setOpaque(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(recv, $value1$, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getAcquire(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getAcquire(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) vh.getAcquire(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getAcquire(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAcquire(recv, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ vh.setRelease(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ vh.setRelease(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setRelease(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(recv, $value1$, Void.class);
+ });
+
+
+#if[CAS]
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.compareAndSet(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.compareAndSet(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(0, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(recv, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile(recv, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatileAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(0, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(recv, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire(recv, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeRelease(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(0, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(recv, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease(recv, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeRelease(recv, $value1$, $value1$, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getAndSet(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getAndSet(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndSet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.getAndSet(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndSet(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndSet(recv, $value1$, Void.class);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.getAndAdd(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.getAndAdd(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndAdd(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.getAndAdd(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndAdd(recv, $value1$, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.addAndGet(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) vh.addAndGet(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.addAndGet(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) vh.addAndGet(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.addAndGet(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.addAndGet(recv, $value1$, Void.class);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testInstanceFieldWrongMethodType(VarHandleTestMethodType$Type$ recv, Handles hs) throws Throwable {
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class)).
+ invoke(null);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)).
+ invoke(Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class)).
+ invoke(0);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class)).
+ invoke(recv);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class)).
+ invoke(recv);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ hs.get(am, methodType(void.class, Void.class, $type$.class)).
+ invoke(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ hs.get(am, methodType(void.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, $type$.class)).
+ invoke(0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ }
+
+#if[CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, $type$.class, $type$.class)).
+ invoke(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, $type$.class, $type$.class)).
+ invoke(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, Class.class, $type$.class)).
+ invoke(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , $type$.class, $type$.class)).
+ invoke(0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class, $type$.class)).
+ invoke(null, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class, $type$.class)).
+ invoke(Void.class, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class, $type$.class)).
+ invoke(recv, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class , $type$.class, $type$.class)).
+ invoke(0, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class , $type$.class, $type$.class)).
+ invoke(recv, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class , $type$.class, $type$.class)).
+ invoke(recv, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class, Class.class)).
+ invoke(recv, $value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class)).
+ invoke(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, $type$.class)).
+ invoke(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class)).
+ invoke(null, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)).
+ invoke(recv, Void.class);
+ });
+ checkWMTE(() -> { // reciever primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, $type$.class)).
+ invoke(0, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)).
+ invoke(recv, $value1$, Void.class);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+
+ static void testStaticFieldWrongMethodType(VarHandle vh) throws Throwable {
+ // Get
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.get();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.get(Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.set(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set($value1$, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getVolatile();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getVolatile(Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setVolatile(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile($value1$, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getOpaque();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getOpaque(Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setOpaque(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque($value1$, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getAcquire();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAcquire(Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setRelease(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease($value1$, Void.class);
+ });
+
+
+#if[CAS]
+ // CompareAndSet
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.compareAndSet(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.compareAndSet($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet($value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet($value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire($value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease($value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile($value1$, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile($value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile($value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeVolatile($value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire($value1$, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire($value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire($value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeAcquire($value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease($value1$, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease($value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease($value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeRelease($value1$, $value1$, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndSet(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndSet($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndSet($value1$, Void.class);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ // GetAndAdd
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndAdd(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndAdd($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndAdd($value1$, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.addAndGet(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.addAndGet($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.addAndGet($value1$, Void.class);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testStaticFieldWrongMethodType(Handles hs) throws Throwable {
+ int i = 0;
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class)).
+ invoke();
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType(Class.class)).
+ invoke(Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ hs.get(am, methodType(void.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ }
+#if[CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$.class, $type$.class, Class.class)).
+ invoke($value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)).
+ invoke(Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$.class, $type$.class)).
+ invoke($value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class, $type$.class)).
+ invoke($value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, $type$.class, Class.class)).
+ invoke($value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$.class)).
+ invoke($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class)).
+ invoke($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)).
+ invoke(Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$.class)).
+ invoke($value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class)).
+ invoke($value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)).
+ invoke($value1$, Void.class);
+ });
+ }
+#end[AtomicAdd]
+ }
+
+
+ static void testArrayWrongMethodType(VarHandle vh) throws Throwable {
+ $type$[] array = new $type$[10];
+ Arrays.fill(array, $value1$);
+
+ // Get
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.get(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.get(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.get(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.get(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.get(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.get(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.get();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.get(array, 0, Void.class);
+ });
+
+
+ // Set
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.set(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ vh.set(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.set(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.set(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.set(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.set();
+ });
+ checkWMTE(() -> { // >
+ vh.set(array, 0, $value1$, Void.class);
+ });
+
+
+ // GetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getVolatile(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getVolatile(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.getVolatile(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getVolatile(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getVolatile(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getVolatile(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getVolatile(array, 0, Void.class);
+ });
+
+
+ // SetVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setVolatile(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setVolatile(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setVolatile(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setVolatile(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setVolatile(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setVolatile();
+ });
+ checkWMTE(() -> { // >
+ vh.setVolatile(array, 0, $value1$, Void.class);
+ });
+
+
+ // GetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getOpaque(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getOpaque(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.getOpaque(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getOpaque(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getOpaque(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getOpaque(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getOpaque();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getOpaque(array, 0, Void.class);
+ });
+
+
+ // SetOpaque
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setOpaque(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setOpaque(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setOpaque(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setOpaque(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setOpaque(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setOpaque();
+ });
+ checkWMTE(() -> { // >
+ vh.setOpaque(array, 0, $value1$, Void.class);
+ });
+
+
+ // GetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getAcquire(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getAcquire(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.getAcquire(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getAcquire(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) vh.getAcquire(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAcquire(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAcquire(array, 0, Void.class);
+ });
+
+
+ // SetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ vh.setRelease(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ vh.setRelease(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ vh.setRelease(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ vh.setRelease(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ vh.setRelease(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ vh.setRelease();
+ });
+ checkWMTE(() -> { // >
+ vh.setRelease(array, 0, $value1$, Void.class);
+ });
+
+
+#if[CAS]
+ // CompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.compareAndSet(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.compareAndSet(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.compareAndSet(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.compareAndSet(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.compareAndSet(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.compareAndSet(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.compareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.compareAndSet(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSet(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSet(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSet(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSet(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSet(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSet(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSet();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSet(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetAcquire(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetAcquire(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetAcquire(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetAcquire(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetAcquire();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetAcquire(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // WeakCompareAndSetRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = vh.weakCompareAndSetRelease(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = vh.weakCompareAndSetRelease(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = vh.weakCompareAndSetRelease(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = vh.weakCompareAndSetRelease(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = vh.weakCompareAndSetRelease(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = vh.weakCompareAndSetRelease();
+ });
+ checkWMTE(() -> { // >
+ boolean r = vh.weakCompareAndSetRelease(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeVolatile
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeVolatile();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeVolatile(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeAcquire
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeAcquire();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeAcquire(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // CompareAndExchangeRelease
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) vh.compareAndExchangeRelease(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.compareAndExchangeRelease(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.compareAndExchangeRelease();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.compareAndExchangeRelease(array, 0, $value1$, $value1$, Void.class);
+ });
+
+
+ // GetAndSet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getAndSet(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getAndSet(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndSet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // reciarrayever primitive class
+ $type$ x = ($type$) vh.getAndSet(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getAndSet(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndSet(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndSet(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndSet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndSet(array, 0, $value1$, Void.class);
+ });
+#end[CAS]
+
+#if[AtomicAdd]
+ // GetAndAdd
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.getAndAdd(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.getAndAdd(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.getAndAdd(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.getAndAdd(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.getAndAdd(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.getAndAdd(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.getAndAdd(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.getAndAdd();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.getAndAdd(array, 0, $value1$, Void.class);
+ });
+
+
+ // AddAndGet
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) vh.addAndGet(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) vh.addAndGet(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) vh.addAndGet(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) vh.addAndGet(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) vh.addAndGet(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) vh.addAndGet(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) vh.addAndGet(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) vh.addAndGet();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) vh.addAndGet(array, 0, $value1$, Void.class);
+ });
+#end[AtomicAdd]
+ }
+
+ static void testArrayWrongMethodType(Handles hs) throws Throwable {
+ $type$[] array = new $type$[10];
+ Arrays.fill(array, $value1$);
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.get)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class)).
+ invoke(null, 0);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class)).
+ invoke(Void.class, 0);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class)).
+ invoke(0, 0);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class)).
+ invoke(array, Void.class);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void x = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class)).
+ invoke(array, 0);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class)).
+ invoke(array, 0);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.set)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ hs.get(am, methodType(void.class, Void.class, int.class, $type$.class)).
+ invoke(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ hs.get(am, methodType(void.class, Class.class, int.class, $type$.class)).
+ invoke(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ hs.get(am, methodType(void.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ hs.get(am, methodType(void.class, int.class, int.class, $type$.class)).
+ invoke(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ hs.get(am, methodType(void.class, $type$[].class, Class.class, $type$.class)).
+ invoke(array, Void.class, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ hs.get(am, methodType(void.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ hs.get(am, methodType(void.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ }
+#if[CAS]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, $type$.class, $type$.class)).
+ invoke(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // receiver reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, $type$.class, $type$.class)).
+ invoke(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, Class.class, $type$.class)).
+ invoke(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // receiver primitive class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, $type$.class, $type$.class)).
+ invoke(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, Class.class, $type$.class, $type$.class)).
+ invoke(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ boolean r = (boolean) hs.get(am, methodType(boolean.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.compareAndExchange)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null receiver
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class, $type$.class)).
+ invoke(null, 0, $value1$, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class, $type$.class)).
+ invoke(Void.class, 0, $value1$, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // expected reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class, $type$.class)).
+ invoke(array, 0, Void.class, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // actual reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class, $type$.class)).
+ invoke(0, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class, $type$.class)).
+ invoke(array, Void.class, $value1$, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class, $type$.class)).
+ invoke(array, 0, $value1$, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class, $type$.class)).
+ invoke(array, 0, $value1$, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, $value1$, Void.class);
+ });
+ }
+
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndSet)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class)).
+ invoke(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class)).
+ invoke(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class)).
+ invoke(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class)).
+ invoke(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class)).
+ invoke(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class)).
+ invoke(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ }
+#end[CAS]
+
+#if[AtomicAdd]
+ for (TestAccessMode am : testAccessModesOfType(TestAccessType.getAndAdd)) {
+ // Incorrect argument types
+ checkNPE(() -> { // null array
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class)).
+ invoke(null, 0, $value1$);
+ });
+ checkCCE(() -> { // array reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class)).
+ invoke(Void.class, 0, $value1$);
+ });
+ check{#if[String]?CCE:WMTE}(() -> { // value reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)).
+ invoke(array, 0, Void.class);
+ });
+ checkWMTE(() -> { // array primitive class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class)).
+ invoke(0, 0, $value1$);
+ });
+ checkWMTE(() -> { // index reference class
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class)).
+ invoke(array, Void.class, $value1$);
+ });
+ // Incorrect return type
+ check{#if[String]?CCE:WMTE}(() -> { // reference class
+ Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class)).
+ invoke(array, 0, $value1$);
+ });
+ checkWMTE(() -> { // primitive class
+ $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class)).
+ invoke(array, 0, $value1$);
+ });
+ // Incorrect arity
+ checkWMTE(() -> { // 0
+ $type$ x = ($type$) hs.get(am, methodType($type$.class)).
+ invoke();
+ });
+ checkWMTE(() -> { // >
+ $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)).
+ invoke(array, 0, $value1$, Void.class);
+ });
+ }
+#end[AtomicAdd]
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,155 @@
+#!/bin/bash
+
+javac -d . ../../../../../make/src/classes/build/tools/spp/Spp.java
+
+SPP=build.tools.spp.Spp
+
+# Generates variable handle tests for objects and all primitive types
+# This is likely to be a temporary testing approach as it may be more
+# desirable to generate code using ASM which will allow more flexibility
+# in the kinds of tests that are generated.
+
+for type in boolean byte short char int long float double String
+do
+ Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}"
+ args="-K$type -Dtype=$type -DType=$Type"
+
+ case $type in
+ String|int|long)
+ args="$args -KCAS"
+ ;;
+ esac
+
+ case $type in
+ int|long)
+ args="$args -KAtomicAdd"
+ ;;
+ esac
+
+ wrong_primitive_type=boolean
+
+ case $type in
+ boolean)
+ value1=true
+ value2=false
+ value3=false
+ wrong_primitive_type=int
+ ;;
+ byte)
+ value1=(byte)1
+ value2=(byte)2
+ value3=(byte)3
+ ;;
+ short)
+ value1=(short)1
+ value2=(short)2
+ value3=(short)3
+ ;;
+ char)
+ value1=\'a\'
+ value2=\'b\'
+ value3=\'c\'
+ ;;
+ int)
+ value1=1
+ value2=2
+ value3=3
+ ;;
+ long)
+ value1=1L
+ value2=2L
+ value3=3L
+ ;;
+ float)
+ value1=1.0f
+ value2=2.0f
+ value3=3.0f
+ ;;
+ double)
+ value1=1.0d
+ value2=2.0d
+ value3=3.0d
+ ;;
+ String)
+ value1=\"foo\"
+ value2=\"bar\"
+ value3=\"baz\"
+ ;;
+ esac
+
+ args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3 -Dwrong_primitive_type=$wrong_primitive_type"
+
+ echo $args
+ java $SPP -nel $args < X-VarHandleTestAccess.java.template > VarHandleTestAccess${Type}.java
+ java $SPP -nel $args < X-VarHandleTestMethodHandleAccess.java.template > VarHandleTestMethodHandleAccess${Type}.java
+ java $SPP -nel $args < X-VarHandleTestMethodType.java.template > VarHandleTestMethodType${Type}.java
+done
+
+for type in short char int long float double
+do
+ Type="$(tr '[:lower:]' '[:upper:]' <<< ${type:0:1})${type:1}"
+ args="-K$type -Dtype=$type -DType=$Type"
+
+ BoxType=$Type
+ case $type in
+ char)
+ BoxType=Character
+ ;;
+ int)
+ BoxType=Integer
+ ;;
+ esac
+ args="$args -DBoxType=$BoxType"
+
+ case $type in
+ int|long|float|double)
+ args="$args -KCAS"
+ ;;
+ esac
+
+ case $type in
+ int|long)
+ args="$args -KAtomicAdd"
+ ;;
+ esac
+
+ case $type in
+ short)
+ value1=(short)0x0102
+ value2=(short)0x1112
+ value3=(short)0x2122
+ ;;
+ char)
+ value1=(char)0x0102
+ value2=(char)0x1112
+ value3=(char)0x2122
+ ;;
+ int)
+ value1=0x01020304
+ value2=0x11121314
+ value3=0x21222324
+ ;;
+ long)
+ value1=0x0102030405060708L
+ value2=0x1112131415161718L
+ value3=0x2122232425262728L
+ ;;
+ float)
+ value1=0x01020304
+ value2=0x11121314
+ value3=0x21222324
+ ;;
+ double)
+ value1=0x0102030405060708L
+ value2=0x1112131415161718L
+ value3=0x2122232425262728L
+ ;;
+ esac
+
+ args="$args -Dvalue1=$value1 -Dvalue2=$value2 -Dvalue3=$value3"
+
+ echo $args
+ java $SPP -nel $args < X-VarHandleTestByteArrayView.java.template > VarHandleTestByteArrayAs${Type}.java
+done
+
+rm -fr build
--- a/jdk/test/java/net/Authenticator/B4933582.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/net/Authenticator/B4933582.sh Thu Apr 07 11:03:59 2016 -0700
@@ -44,7 +44,7 @@
;;
esac
-EXTRAOPTS="-XaddExports:java.base/sun.net.www=ALL-UNNAMED,java.base/sun.net.www.protocol.http=ALL-UNNAMED"
+EXTRAOPTS="-XaddExports:java.base/sun.net.www=ALL-UNNAMED -XaddExports:java.base/sun.net.www.protocol.http=ALL-UNNAMED"
export EXTRAOPTS
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . \
--- a/jdk/test/java/nio/Buffer/Basic-X.java.template Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/Basic-X.java.template Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -336,6 +336,103 @@
}
+ private static void testAlign(final ByteBuffer b, boolean direct) {
+ // index out-of bounds
+ tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(-1, (short) 1));
+
+ // unit size values
+ tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0));
+ for (int us = 1; us < 65; us++) {
+ int _us = us;
+ if ((us & (us - 1)) != 0) {
+ // unit size not a power of two
+ tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us));
+ } else {
+ if (direct || us <= 8) {
+ b.alignmentOffset(0, us);
+ } else {
+ // unit size > 8 with non-direct buffer
+ tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us));
+ }
+ }
+ }
+
+ // Probe for long misalignment at index zero for a newly created buffer
+ ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0);
+ int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
+
+ if (direct) {
+ // Freshly created direct byte buffers should be aligned at index 0
+ // for ref and primitive values (see Unsafe.allocateMemory)
+ if (longMisalignmentAtZero != 0)
+ fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero);
+ } else {
+ // For heap byte buffers misalignment may occur on 32-bit systems
+ // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0
+ // Note the GC will preserve alignment of the base address of the
+ // array
+ if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero)
+ fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero);
+ }
+
+ // Ensure test buffer is correctly aligned at index 0
+ if (b.alignmentOffset(0, 8) != longMisalignmentAtZero)
+ fail("Test input buffer not correctly aligned at index 0", b);
+
+ // Test misalignment values
+ for (int us : new int[]{1, 2, 4, 8}) {
+ for (int i = 0; i < us * 2; i++) {
+ int am = b.alignmentOffset(i, us);
+ int expectedAm = (longMisalignmentAtZero + i) % us;
+
+ if (am != expectedAm)
+ fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm));
+ }
+ }
+
+ // Created aligned slice to test against
+ int ap = 8 - longMisalignmentAtZero;
+ int al = b.limit() - b.alignmentOffset(b.limit(), 8);
+ ByteBuffer ab = b.position(ap).limit(al).
+ slice();
+ if (ab.limit() == 0)
+ fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b);
+ if (ab.alignmentOffset(0, 8) != 0)
+ fail("Aligned test input buffer not correctly aligned at index 0", ab);
+
+ for (int us : new int[]{1, 2, 4, 8}) {
+ for (int p = 1; p < 16; p++) {
+ int l = ab.limit() - p;
+
+ ByteBuffer as = ab.slice().position(p).limit(l).
+ alignedSlice(us);
+
+ ck(as, 0, as.position());
+ ck(as, as.capacity(), as.limit());
+ if (b.isDirect() != as.isDirect())
+ fail("Lost direction", as);
+ if (b.isReadOnly() != as.isReadOnly())
+ fail("Lost read-only", as);
+
+ if (as.alignmentOffset(0, us) != 0)
+ fail("Buffer not correctly aligned at index 0", as);
+
+ if (as.alignmentOffset(as.limit(), us) != 0)
+ fail("Buffer not correctly aligned at limit", as);
+
+ int p_mod = ab.alignmentOffset(p, us);
+ int l_mod = ab.alignmentOffset(l, us);
+ // Round up position
+ p = (p_mod > 0) ? p + (us - p_mod) : p;
+ // Round down limit
+ l = l - l_mod;
+
+ int ec = l - p;
+ if (as.limit() != ec)
+ fail("Buffer capacity incorrect, expected: " + ec, as);
+ }
+ }
+ }
#end[byte]
private static void fail(String problem,
@@ -854,6 +951,11 @@
relPut(b); // Required by testViews
+#if[byte]
+ // Test alignment
+
+ testAlign(b, direct);
+#end[byte]
}
#if[char]
--- a/jdk/test/java/nio/Buffer/Basic.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/Basic.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -26,6 +26,8 @@
* @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725
* 4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 6231529
* 6221101 6234263 6535542 6591971 6593946 6795561 7190219 7199551 8065556
+ * 8149469
+ * @modules java.base/jdk.internal.misc
* @author Mark Reinhold
*/
--- a/jdk/test/java/nio/Buffer/BasicByte.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/BasicByte.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -336,6 +336,103 @@
}
+ private static void testAlign(final ByteBuffer b, boolean direct) {
+ // index out-of bounds
+ tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(-1, (short) 1));
+
+ // unit size values
+ tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0));
+ for (int us = 1; us < 65; us++) {
+ int _us = us;
+ if ((us & (us - 1)) != 0) {
+ // unit size not a power of two
+ tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us));
+ } else {
+ if (direct || us <= 8) {
+ b.alignmentOffset(0, us);
+ } else {
+ // unit size > 8 with non-direct buffer
+ tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us));
+ }
+ }
+ }
+
+ // Probe for long misalignment at index zero for a newly created buffer
+ ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0);
+ int longMisalignmentAtZero = empty.alignmentOffset(0, 8);
+
+ if (direct) {
+ // Freshly created direct byte buffers should be aligned at index 0
+ // for ref and primitive values (see Unsafe.allocateMemory)
+ if (longMisalignmentAtZero != 0)
+ fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero);
+ } else {
+ // For heap byte buffers misalignment may occur on 32-bit systems
+ // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0
+ // Note the GC will preserve alignment of the base address of the
+ // array
+ if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero)
+ fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero);
+ }
+
+ // Ensure test buffer is correctly aligned at index 0
+ if (b.alignmentOffset(0, 8) != longMisalignmentAtZero)
+ fail("Test input buffer not correctly aligned at index 0", b);
+
+ // Test misalignment values
+ for (int us : new int[]{1, 2, 4, 8}) {
+ for (int i = 0; i < us * 2; i++) {
+ int am = b.alignmentOffset(i, us);
+ int expectedAm = (longMisalignmentAtZero + i) % us;
+
+ if (am != expectedAm)
+ fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm));
+ }
+ }
+
+ // Created aligned slice to test against
+ int ap = 8 - longMisalignmentAtZero;
+ int al = b.limit() - b.alignmentOffset(b.limit(), 8);
+ ByteBuffer ab = b.position(ap).limit(al).
+ slice();
+ if (ab.limit() == 0)
+ fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b);
+ if (ab.alignmentOffset(0, 8) != 0)
+ fail("Aligned test input buffer not correctly aligned at index 0", ab);
+
+ for (int us : new int[]{1, 2, 4, 8}) {
+ for (int p = 1; p < 16; p++) {
+ int l = ab.limit() - p;
+
+ ByteBuffer as = ab.slice().position(p).limit(l).
+ alignedSlice(us);
+
+ ck(as, 0, as.position());
+ ck(as, as.capacity(), as.limit());
+ if (b.isDirect() != as.isDirect())
+ fail("Lost direction", as);
+ if (b.isReadOnly() != as.isReadOnly())
+ fail("Lost read-only", as);
+
+ if (as.alignmentOffset(0, us) != 0)
+ fail("Buffer not correctly aligned at index 0", as);
+
+ if (as.alignmentOffset(as.limit(), us) != 0)
+ fail("Buffer not correctly aligned at limit", as);
+
+ int p_mod = ab.alignmentOffset(p, us);
+ int l_mod = ab.alignmentOffset(l, us);
+ // Round up position
+ p = (p_mod > 0) ? p + (us - p_mod) : p;
+ // Round down limit
+ l = l - l_mod;
+
+ int ec = l - p;
+ if (as.limit() != ec)
+ fail("Buffer capacity incorrect, expected: " + ec, as);
+ }
+ }
+ }
private static void fail(String problem,
@@ -854,6 +951,11 @@
relPut(b); // Required by testViews
+
+ // Test alignment
+
+ testAlign(b, direct);
+
}
--- a/jdk/test/java/nio/Buffer/BasicChar.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/BasicChar.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -338,6 +338,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
private static void fail(String problem,
CharBuffer xb, CharBuffer yb,
char x, char y) {
@@ -854,6 +951,11 @@
relPut(b); // Required by testViews
+
+
+
+
+
}
--- a/jdk/test/java/nio/Buffer/BasicDouble.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/BasicDouble.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -338,6 +338,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
private static void fail(String problem,
DoubleBuffer xb, DoubleBuffer yb,
double x, double y) {
@@ -854,6 +951,11 @@
relPut(b); // Required by testViews
+
+
+
+
+
}
--- a/jdk/test/java/nio/Buffer/BasicFloat.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/BasicFloat.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -338,6 +338,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
private static void fail(String problem,
FloatBuffer xb, FloatBuffer yb,
float x, float y) {
@@ -854,6 +951,11 @@
relPut(b); // Required by testViews
+
+
+
+
+
}
--- a/jdk/test/java/nio/Buffer/BasicInt.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/BasicInt.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -338,6 +338,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
private static void fail(String problem,
IntBuffer xb, IntBuffer yb,
int x, int y) {
@@ -854,6 +951,11 @@
relPut(b); // Required by testViews
+
+
+
+
+
}
--- a/jdk/test/java/nio/Buffer/BasicLong.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/BasicLong.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -338,6 +338,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
private static void fail(String problem,
LongBuffer xb, LongBuffer yb,
long x, long y) {
@@ -854,6 +951,11 @@
relPut(b); // Required by testViews
+
+
+
+
+
}
--- a/jdk/test/java/nio/Buffer/BasicShort.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/BasicShort.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -338,6 +338,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
private static void fail(String problem,
ShortBuffer xb, ShortBuffer yb,
short x, short y) {
@@ -854,6 +951,11 @@
relPut(b); // Required by testViews
+
+
+
+
+
}
--- a/jdk/test/java/nio/Buffer/CopyDirectMemory.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/nio/Buffer/CopyDirectMemory.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016, 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
@@ -25,6 +25,7 @@
* @summary Test view buffer bulk operations for large buffers.
* @bug 4463011
*
+ * @modules java.base/jdk.internal.misc
* @build Basic
* @run main CopyDirectMemory
*/
--- a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh Thu Apr 07 11:03:59 2016 -0700
@@ -51,6 +51,10 @@
mkdir -p ext
$COMPILEJAVA/bin/jar ${TESTTOOLVMOPTS} cf ext/ext.jar -C $TESTCLASSES ExtLoadedImpl.class -C $TESTCLASSES ExtLoadedImpl_Stub.class -C $TESTCLASSES CheckLoader.class
-TESTVMOPTS="${TESTVMOPTS} -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED,java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED,java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED"
+TESTVMOPTS="${TESTVMOPTS} \
+ -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED \
+ -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED \
+ -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED \
+ -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED"
$TESTJAVA/bin/java ${TESTVMOPTS} -cp classes -Dtest.src=$TESTSRC -Dtest.classes=$TESTCLASSES -Djava.security.policy=$TESTSRC/security.policy -Djava.ext.dirs=ext ExtLoadedImplTest
--- a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java Thu Apr 07 11:03:59 2016 -0700
@@ -138,9 +138,11 @@
p.put("java.security.policy", TestParams.defaultGroupPolicy);
CommandEnvironment cmd = new ActivationGroupDesc.CommandEnvironment(
null,
- new String[] { "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED,"
- + "java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED,"
- + "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" });
+ new String[] {
+ "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED",
+ "-XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED",
+ "-XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED",
+ "-XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" });
ActivationGroupDesc groupDesc =
new ActivationGroupDesc("MyActivationGroupImpl",
--- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java Thu Apr 07 11:03:59 2016 -0700
@@ -120,9 +120,12 @@
//
System.err.println("Create activation group, in a new VM");
CommandEnvironment cmd = new ActivationGroupDesc.CommandEnvironment(null,
- new String[] { "-XaddExports:java.base/sun.security.provider=ALL-UNNAMED,"
- + "java.rmi/sun.rmi.registry=ALL-UNNAMED,java.rmi/sun.rmi.server=ALL-UNNAMED,"
- + "java.rmi/sun.rmi.transport=ALL-UNNAMED,java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" });
+ new String[] {
+ "-XaddExports:java.base/sun.security.provider=ALL-UNNAMED",
+ "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED",
+ "-XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED",
+ "-XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED",
+ "-XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" });
ActivationGroupDesc groupDesc =
new ActivationGroupDesc(p, cmd);
--- a/jdk/test/java/rmi/registry/readTest/readTest.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/rmi/registry/readTest/readTest.sh Thu Apr 07 11:03:59 2016 -0700
@@ -98,7 +98,11 @@
;;
esac
# trailing / after code base is important for rmi codebase property.
-TESTVMOPTS="${TESTVMOPTS} -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED,java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED,java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED"
+TESTVMOPTS="${TESTVMOPTS} \
+ -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED \
+ -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED \
+ -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED \
+ -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED"
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -cp $TEST_CLASSPATH ${ARGS} -Djava.rmi.server.codebase=${FILEURL}$CODEBASE/ readTest > OUT.TXT 2>&1 &
TEST_PID=$!
#bulk of testcase - let it run for a while
--- a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java Thu Apr 07 11:03:59 2016 -0700
@@ -123,9 +123,10 @@
propOption + property +
equal +
propertyValue + extraProp +
- " -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED,"
- + "java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED,"
- + "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" +
+ " -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED" +
+ " -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED" +
+ " -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED" +
+ " -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" +
" -Drmi.registry.port=" +
REGISTRY_PORT,
"");
--- a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java Thu Apr 07 11:03:59 2016 -0700
@@ -74,10 +74,10 @@
try {
String options = " -Djava.security.policy=" +
TestParams.defaultPolicy +
- " -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED," +
- "java.rmi/sun.rmi.server=ALL-UNNAMED," +
- "java.rmi/sun.rmi.transport=ALL-UNNAMED," +
- "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" +
+ " -XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED" +
+ " -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED" +
+ " -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED" +
+ " -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" +
" -Djava.rmi.dgc.leaseValue=500000" +
" -Dsun.rmi.dgc.checkInterval=" +
(HOLD_TARGET_TIME - 5000) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Format/DateFormat/DateFormatSymbolsCloneTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8151431
+ * @summary Make sure that clone() of a DateFormatSymbols subclass is not
+ * called from DateFormatSymbols constructor.
+ */
+import java.text.DateFormatSymbols;
+
+public class DateFormatSymbolsCloneTest extends DateFormatSymbols {
+ private int value;
+
+ public DateFormatSymbolsCloneTest() {
+ value = 1;
+ }
+
+ @Override
+ public Object clone() {
+ if (this.value == 0) {
+ throw new RuntimeException("clone() should not be called from a DateFormatSymbols constructor");
+ }
+ return super.clone();
+ }
+
+ public static void main(String[] args) {
+ new DateFormatSymbolsCloneTest();
+ }
+}
--- a/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKChronology.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -68,11 +68,16 @@
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.time.ZoneId;
import java.time.Clock;
import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
import java.time.chrono.ChronoLocalDate;
import java.time.chrono.Chronology;
+import java.time.chrono.Era;
import java.time.chrono.HijrahChronology;
import java.time.chrono.HijrahEra;
import java.time.chrono.IsoChronology;
@@ -97,6 +102,14 @@
@Test
public class TCKChronology {
+ private static final ZoneOffset OFFSET_P0100 = ZoneOffset.ofHours(1);
+ private static final ZoneOffset OFFSET_M0100 = ZoneOffset.ofHours(-1);
+
+ private static final int YDIFF_MEIJI = 1867;
+ private static final int YDIFF_SHOWA = 1925;
+ private static final int YDIFF_HEISEI = 1988;
+ private static final int YDIFF_MINGUO = 1911;
+ private static final int YDIFF_THAIBUDDHIST = 543;
//-----------------------------------------------------------------------
// regular data factory for ID and calendarType of available calendars
//-----------------------------------------------------------------------
@@ -323,7 +336,7 @@
}
}
- @Test(expectedExceptions=DateTimeException.class)
+ @Test(expectedExceptions = DateTimeException.class)
public void test_lookupLocale() {
Locale.Builder builder = new Locale.Builder().setLanguage("en").setRegion("CA");
builder.setUnicodeLocaleKeyword("ca", "xxx");
@@ -337,4 +350,78 @@
Chronology chrono = Chronology.of("FooFoo");
}
+ @DataProvider(name = "epochSecond_dataProvider")
+ Object[][] data_epochSecond() {
+ return new Object[][] {
+ {JapaneseChronology.INSTANCE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {JapaneseChronology.INSTANCE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100},
+ {JapaneseChronology.INSTANCE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100},
+ {HijrahChronology.INSTANCE, 1434, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {MinguoChronology.INSTANCE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {MinguoChronology.INSTANCE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100},
+ {MinguoChronology.INSTANCE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100},
+ {ThaiBuddhistChronology.INSTANCE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {ThaiBuddhistChronology.INSTANCE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100},
+ {ThaiBuddhistChronology.INSTANCE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100},
+ {IsoChronology.INSTANCE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {IsoChronology.INSTANCE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100},
+ {IsoChronology.INSTANCE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100},
+
+ };
+ }
+
+ @Test(dataProvider = "epochSecond_dataProvider")
+ public void test_epochSecond(Chronology chrono, int y, int m, int d, int h, int min, int s, ZoneOffset offset) {
+ ChronoLocalDate chronoLd = chrono.date(y, m, d);
+ assertEquals(chrono.epochSecond(y, m, d, h, min, s, offset),
+ OffsetDateTime.of(LocalDate.from(chronoLd), LocalTime.of(h, min, s), offset)
+ .toEpochSecond());
+ }
+
+ @DataProvider(name = "era_epochSecond_dataProvider")
+ Object[][] data_era_epochSecond() {
+ return new Object[][] {
+ {JapaneseChronology.INSTANCE, JapaneseEra.MEIJI, 1873 - YDIFF_MEIJI, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {JapaneseChronology.INSTANCE, JapaneseEra.SHOWA, 1928 - YDIFF_SHOWA, 2, 28, 1, 2, 2, OFFSET_M0100},
+ {JapaneseChronology.INSTANCE, JapaneseEra.HEISEI, 1989 - YDIFF_HEISEI, 1, 8, 1, 2, 2, OFFSET_P0100},
+ {HijrahChronology.INSTANCE, HijrahEra.AH, 1434, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {MinguoChronology.INSTANCE, MinguoEra.BEFORE_ROC, 1873 - YDIFF_MINGUO, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {MinguoChronology.INSTANCE, MinguoEra.ROC, 1928 - YDIFF_MINGUO, 2, 28, 1, 2, 2, OFFSET_M0100},
+ {MinguoChronology.INSTANCE, MinguoEra.ROC, 1989 - YDIFF_MINGUO, 1, 8, 1, 2, 2, OFFSET_P0100},
+ {ThaiBuddhistChronology.INSTANCE, ThaiBuddhistEra.BE, 1873 + YDIFF_THAIBUDDHIST, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {ThaiBuddhistChronology.INSTANCE, ThaiBuddhistEra.BE, 1928 + YDIFF_THAIBUDDHIST, 2, 28, 1, 2, 2, OFFSET_M0100},
+ {ThaiBuddhistChronology.INSTANCE, ThaiBuddhistEra.BE, 1989 + YDIFF_THAIBUDDHIST, 1, 8, 1, 2, 2, OFFSET_P0100},
+ {IsoChronology.INSTANCE, IsoEra.CE, 1873, 9, 7, 1, 2, 2, OFFSET_P0100},
+ {IsoChronology.INSTANCE, IsoEra.CE, 1928, 2, 28, 1, 2, 2, OFFSET_M0100},
+ {IsoChronology.INSTANCE, IsoEra.CE, 1989, 1, 8, 1, 2, 2, OFFSET_P0100},
+
+ };
+ }
+
+ @Test(dataProvider = "era_epochSecond_dataProvider")
+ public void test_epochSecond(Chronology chrono, Era era, int y, int m, int d, int h, int min, int s, ZoneOffset offset) {
+ ChronoLocalDate chronoLd = chrono.date(era, y, m, d);
+ assertEquals(chrono.epochSecond(era, y, m, d, h, min, s, offset),
+ OffsetDateTime.of(LocalDate.from(chronoLd), LocalTime.of(h, min, s), offset)
+ .toEpochSecond());
+ }
+
+ @DataProvider(name = "bad_epochSecond_dataProvider")
+ Object[][] bad_data_epochSecond() {
+ return new Object[][] {
+ {JapaneseChronology.INSTANCE, 1873, 13, 7, 1, 2, 2, OFFSET_P0100},
+ {HijrahChronology.INSTANCE, 1434, 9, 32, 1, 2, 2, OFFSET_P0100},
+ {MinguoChronology.INSTANCE, 1873, 9, 7, 31, 2, 2, OFFSET_P0100},
+ {ThaiBuddhistChronology.INSTANCE, 1928, 2, 28, -1, 2, 2, OFFSET_M0100},
+ {IsoChronology.INSTANCE, 1928, 2, 28, 1, 60, 2, OFFSET_M0100},
+ {IsoChronology.INSTANCE, 1989, 1, 8, 1, 2, -2, OFFSET_P0100},
+
+ };
+ }
+
+ @Test(dataProvider = "bad_epochSecond_dataProvider", expectedExceptions = DateTimeException.class)
+ public void test_bad_epochSecond(Chronology chrono, int y, int m, int d, int h, int min, int s, ZoneOffset offset) {
+ chrono.epochSecond(y, m, d, h, min, s, offset);
+ }
+
}
--- a/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/time/tck/java/time/chrono/TCKIsoChronology.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -63,10 +63,16 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
-import java.time.ZoneId;
+import java.time.OffsetDateTime;
+import java.time.Year;
import java.time.ZonedDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
import java.time.chrono.Chronology;
+import java.time.chrono.Era;
+import java.time.chrono.HijrahEra;
import java.time.chrono.IsoChronology;
+import java.time.chrono.IsoEra;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
@@ -87,6 +93,8 @@
public class TCKIsoChronology {
// Can only work with IsoChronology here
// others may be in separate module
+ private static final ZoneOffset OFFSET_P0100 = ZoneOffset.ofHours(1);
+ private static final ZoneOffset OFFSET_M0100 = ZoneOffset.ofHours(-1);
@Test
public void factory_from_TemporalAccessor_dateWithChronlogy() {
@@ -675,9 +683,114 @@
}
}
+ @DataProvider(name = "epochSecond_dataProvider")
+ Object[][] data_epochSecond() {
+ return new Object[][] {
+ {2008, 3, 3, 1, 2, 2, OFFSET_P0100},
+ {2008, 3, 3, 1, 2, 2, OFFSET_M0100},
+ {2008, 2, 28, 1, 2, 2, OFFSET_P0100},
+ {2009, 3, 3, 1, 2, 2, OFFSET_P0100},
+ {2009, 3, 3, 1, 2, 2, OFFSET_M0100},
+ {2009, 2, 28, 1, 2, 2, OFFSET_P0100},
+ {1968, 3, 3, 1, 2, 2, OFFSET_P0100},
+ {1968, 3, 3, 1, 2, 2, OFFSET_M0100},
+ {1968, 2, 28, 1, 2, 2, OFFSET_P0100},
+ {1969, 3, 3 , 1, 2, 2, OFFSET_P0100},
+ {1969, 3, 3, 1, 2, 2, OFFSET_M0100},
+ {1969, 2, 28, 1, 2, 2, OFFSET_P0100},
+ {1970, 1, 1, 1, 2, 2, OFFSET_P0100},
+ {1970, 1, 1, 1, 2, 2, OFFSET_M0100},
+ {-4, 3, 3 , 1, 2, 2, OFFSET_P0100},
+ {-1, 3, 3 , 1, 2, 2, OFFSET_P0100},
+ };
+ }
+
+ @Test(dataProvider = "epochSecond_dataProvider")
+ public void test_epochSecond_1(int y, int m, int d, int h , int min, int s, ZoneOffset offset) {
+ assertEquals(IsoChronology.INSTANCE.epochSecond(y, m, d, h, min, s, offset),
+ OffsetDateTime.of(y, m, d, h, min, s, 0, offset).toEpochSecond());
+ }
+
+ @Test
+ public void test_epochSecond_2() {
+ assertEquals(IsoChronology.INSTANCE.epochSecond(2008, 3, 3, 1, 2, 2, OFFSET_P0100),
+ ZonedDateTime.of(2008, 3, 3, 1, 2, 2, 0, ZoneId.of("+01:00")).toEpochSecond());
+ assertEquals(IsoChronology.INSTANCE.epochSecond(1969, 3, 3, 1, 2, 2, OFFSET_P0100),
+ ZonedDateTime.of(1969, 3, 3, 1, 2, 2, 0, ZoneId.of("+01:00")).toEpochSecond());
+ }
+
+ @Test
+ public void test_epochSecond_max() {
+ assertEquals(IsoChronology.INSTANCE.epochSecond(Year.MAX_VALUE, 12, 31, 23, 59, 59, ZoneOffset.MIN),
+ OffsetDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 59, 0, ZoneOffset.MIN).toEpochSecond());
+ }
+
+ @Test
+ public void test_epochSecond_min() {
+ assertEquals(IsoChronology.INSTANCE.epochSecond(Year.MIN_VALUE, 1, 1, 0, 0, 0, ZoneOffset.MAX),
+ OffsetDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0, 0, 0, ZoneOffset.MAX).toEpochSecond());
+ }
+
+ @DataProvider(name = "bad_epochSecond_dataProvider")
+ Object[][] bad_data_epochSecond() {
+ return new Object[][] {
+ {2009, 13, 1, 1, 1, 1, OFFSET_P0100},
+ {2009, 2, 29, 1, 1, 1, OFFSET_P0100},
+ {2009, 1, 1, 25, 1, 1, OFFSET_P0100},
+ {2009, 1, 1, 1, 60, 1, OFFSET_P0100},
+ {2009, 1, 1, 1, 1, -11, OFFSET_P0100},
+ };
+ }
+ @Test(dataProvider = "bad_epochSecond_dataProvider", expectedExceptions = DateTimeException.class)
+ public void test_epochSecond_bad(int y, int m, int d, int h , int min, int s, ZoneOffset offset) {
+ IsoChronology.INSTANCE.epochSecond(y, m, d, h, min, s, offset);
+ }
+
+ @DataProvider(name = "era_epochSecond_dataProvider")
+ Object[][] data_era_epochSecond() {
+ return new Object[][] {
+ {IsoEra.CE, 2008, 3, 3, 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 2008, 3, 3, 1, 2, 2, OFFSET_M0100},
+ {IsoEra.CE, 2008, 2, 28, 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 2009, 3, 3, 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 2009, 3, 3, 1, 2, 2, OFFSET_M0100},
+ {IsoEra.CE, 2009, 2, 28, 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 1968, 3, 3, 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 1968, 3, 3, 1, 2, 2, OFFSET_M0100},
+ {IsoEra.CE, 1968, 2, 28, 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 1969, 3, 3 , 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 1969, 3, 3, 1, 2, 2, OFFSET_M0100},
+ {IsoEra.CE, 1969, 2, 28, 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 1970, 1, 1, 1, 2, 2, OFFSET_P0100},
+ {IsoEra.CE, 1970, 1, 1, 1, 2, 2, OFFSET_M0100},
+ {IsoEra.BCE, 5, 3, 3 , 1, 2, 2, OFFSET_P0100},
+ {IsoEra.BCE, 2, 3, 3 , 1, 2, 2, OFFSET_P0100},
+ };
+ }
+
+ @Test(dataProvider = "era_epochSecond_dataProvider")
+ public void test_era_epochSecond_1(Era era, int y, int m, int d, int h , int min, int s, ZoneOffset offset) {
+ assertEquals(IsoChronology.INSTANCE.epochSecond(era, y, m, d, h, min, s, offset),
+ OffsetDateTime.of(IsoChronology.INSTANCE.date(era, y, m, d), LocalTime.of(h, min, s), offset)
+ .toEpochSecond());
+ }
+
+ @Test
+ public void test_era_epochSecond_2() {
+ assertEquals(IsoChronology.INSTANCE.epochSecond(IsoEra.CE, 2008, 3, 3, 1, 2, 2, OFFSET_P0100),
+ ZonedDateTime.of(2008, 3, 3, 1, 2, 2, 0, ZoneId.of("+01:00")).toEpochSecond());
+ assertEquals(IsoChronology.INSTANCE.epochSecond(IsoEra.CE, 1969, 3, 3, 1, 2, 2, OFFSET_P0100),
+ ZonedDateTime.of(1969, 3, 3, 1, 2, 2, 0, ZoneId.of("+01:00")).toEpochSecond());
+ }
+
+ @Test(expectedExceptions = ClassCastException.class)
+ public void test_era_epochSecond_bad() {
+ IsoChronology.INSTANCE.epochSecond(HijrahEra.AH, 2009, 2, 29, 1, 2, 2, OFFSET_P0100);
+ }
+
+
//-----------------------------------------------------------------------
private static LocalDate date(int y, int m, int d) {
return LocalDate.of(y, m, d);
}
-
}
--- a/jdk/test/java/util/Currency/PropertiesTest.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/util/Currency/PropertiesTest.sh Thu Apr 07 11:03:59 2016 -0700
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2016, 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
@@ -23,7 +23,7 @@
#
# @test
-# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246
+# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735
# @summary tests the capability of replacing the currency data with user
# specified currency properties file
# @build PropertiesTest
@@ -85,12 +85,13 @@
# Dump built-in currency data
run PropertiesTest -d dump1
-
+if [ ! -f dump1 ]; then echo "file dump1 not created. Test cannot execute. Failed."; exit 1; fi
# Dump built-in currency data + overrides in properties file specified
# by system property.
run -Djava.util.currency.data=${PROPS} PropertiesTest -d dump2
+if [ ! -f dump2 ]; then echo "file dump2 not created. Test cannot execute. Failed."; exit 1; fi
run PropertiesTest -c dump1 dump2 ${PROPS}
@@ -102,7 +103,7 @@
WRITABLEJDK=.${FS}testjava
cp -H -R $TESTJAVA $WRITABLEJDK || exit 1
PROPLOCATION=${WRITABLEJDK}${FS}lib
-chmod -R +w $WRITABLEJDK || exit 1
+chmod -R a+rx $WRITABLEJDK || exit 1
cp ${PROPS} $PROPLOCATION || exit 1
echo "Properties location: ${PROPLOCATION}"
@@ -110,6 +111,7 @@
echo ''
${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest -d dump3
if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+if [ ! -f dump3 ]; then echo "file dump3 not created. Test cannot execute. Failed."; exit 1; fi
# Cleanup
rm -rf $WRITABLEJDK
--- a/jdk/test/java/util/Locale/LocaleProviders.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/util/Locale/LocaleProviders.sh Thu Apr 07 11:03:59 2016 -0700
@@ -122,7 +122,8 @@
tznp8013086
EOF
-EXTRAOPTS="-XaddExports:java.base/sun.util.locale=ALL-UNNAMED,java.base/sun.util.locale.provider=ALL-UNNAMED"
+EXTRAOPTS="-XaddExports:java.base/sun.util.locale=ALL-UNNAMED \
+ -XaddExports:java.base/sun.util.locale.provider=ALL-UNNAMED"
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d ${SPIDIR}${FS}dest \
${SPIDIR}${FS}src${FS}tznp.java \
--- a/jdk/test/java/util/PluggableLocale/ExecTest.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/util/PluggableLocale/ExecTest.sh Thu Apr 07 11:03:59 2016 -0700
@@ -93,7 +93,8 @@
esac
-EXTRA_OPTS="-XaddExports:java.base/sun.util.locale.provider=ALL-UNNAMED,java.base/sun.util.resources=ALL-UNNAMED"
+EXTRA_OPTS="-XaddExports:java.base/sun.util.locale.provider=ALL-UNNAMED \
+ -XaddExports:java.base/sun.util.resources=ALL-UNNAMED"
# compile
cp ${TESTSRC}${FS}ProviderTest.java .
--- a/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/util/concurrent/locks/LockSupport/ParkLoops.java Thu Apr 07 11:03:59 2016 -0700
@@ -37,9 +37,11 @@
* @summary Stress test looks for lost unparks
* @library /lib/testlibrary/
* @modules java.management
+ * @run main/timeout=1200 ParkLoops
*/
import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
@@ -53,6 +55,7 @@
import jdk.testlibrary.Utils;
public final class ParkLoops {
+ static final long TEST_TIMEOUT_SECONDS = Utils.adjustTimeout(1000);
static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
static final int THREADS = 4;
static final int ITERS = 30_000;
@@ -130,7 +133,7 @@
pool.submit(unparker);
}
try {
- if (!done.await(LONG_DELAY_MS, MILLISECONDS)) {
+ if (!done.await(TEST_TIMEOUT_SECONDS, SECONDS)) {
dumpAllStacks();
throw new AssertionError("lost unpark");
}
--- a/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/util/concurrent/tck/CompletableFutureTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -3952,6 +3952,38 @@
Monad.plus(godot, Monad.unit(5L)));
}
+ /**
+ * A single CompletableFuture with many dependents.
+ * A demo of scalability - runtime is O(n).
+ */
+ public void testManyDependents() throws Throwable {
+ final int n = 1_000;
+ final CompletableFuture<Void> head = new CompletableFuture<>();
+ final CompletableFuture<Void> complete = CompletableFuture.completedFuture((Void)null);
+ final AtomicInteger count = new AtomicInteger(0);
+ for (int i = 0; i < n; i++) {
+ head.thenRun(() -> count.getAndIncrement());
+ head.thenAccept((x) -> count.getAndIncrement());
+ head.thenApply((x) -> count.getAndIncrement());
+
+ head.runAfterBoth(complete, () -> count.getAndIncrement());
+ head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement());
+ head.thenCombine(complete, (x, y) -> count.getAndIncrement());
+ complete.runAfterBoth(head, () -> count.getAndIncrement());
+ complete.thenAcceptBoth(head, (x, y) -> count.getAndIncrement());
+ complete.thenCombine(head, (x, y) -> count.getAndIncrement());
+
+ head.runAfterEither(new CompletableFuture<Void>(), () -> count.getAndIncrement());
+ head.acceptEither(new CompletableFuture<Void>(), (x) -> count.getAndIncrement());
+ head.applyToEither(new CompletableFuture<Void>(), (x) -> count.getAndIncrement());
+ new CompletableFuture<Void>().runAfterEither(head, () -> count.getAndIncrement());
+ new CompletableFuture<Void>().acceptEither(head, (x) -> count.getAndIncrement());
+ new CompletableFuture<Void>().applyToEither(head, (x) -> count.getAndIncrement());
+ }
+ head.complete(null);
+ assertEquals(5 * 3 * n, count.get());
+ }
+
// static <U> U join(CompletionStage<U> stage) {
// CompletableFuture<U> f = new CompletableFuture<>();
// stage.whenComplete((v, ex) -> {
--- a/jdk/test/java/util/concurrent/tck/JSR166TestCase.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/java/util/concurrent/tck/JSR166TestCase.java Thu Apr 07 11:03:59 2016 -0700
@@ -211,10 +211,13 @@
private static final int suiteRuns =
Integer.getInteger("jsr166.suiteRuns", 1);
- private static float systemPropertyValue(String name, float defaultValue) {
+ /**
+ * Returns the value of the system property, or NaN if not defined.
+ */
+ private static float systemPropertyValue(String name) {
String floatString = System.getProperty(name);
if (floatString == null)
- return defaultValue;
+ return Float.NaN;
try {
return Float.parseFloat(floatString);
} catch (NumberFormatException ex) {
@@ -226,16 +229,25 @@
/**
* The scaling factor to apply to standard delays used in tests.
+ * May be initialized from any of:
+ * - the "jsr166.delay.factor" system property
+ * - the "test.timeout.factor" system property (as used by jtreg)
+ * See: http://openjdk.java.net/jtreg/tag-spec.html
+ * - hard-coded fuzz factor when using a known slowpoke VM
*/
- private static final float delayFactor =
- systemPropertyValue("jsr166.delay.factor", 1.0f);
+ private static final float delayFactor = delayFactor();
- /**
- * The timeout factor as used in the jtreg test harness.
- * See: http://openjdk.java.net/jtreg/tag-spec.html
- */
- private static final float jtregTestTimeoutFactor
- = systemPropertyValue("test.timeout.factor", 1.0f);
+ private static float delayFactor() {
+ float x;
+ if (!Float.isNaN(x = systemPropertyValue("jsr166.delay.factor")))
+ return x;
+ if (!Float.isNaN(x = systemPropertyValue("test.timeout.factor")))
+ return x;
+ String prop = System.getProperty("java.vm.version");
+ if (prop != null && prop.matches(".*debug.*"))
+ return 4.0f; // How much slower is fastdebug than product?!
+ return 1.0f;
+ }
public JSR166TestCase() { super(); }
public JSR166TestCase(String name) { super(name); }
@@ -526,6 +538,7 @@
"StampedLockTest",
"SubmissionPublisherTest",
"ThreadLocalRandom8Test",
+ "TimeUnit8Test",
};
addNamedTestClasses(suite, java8TestClassNames);
}
@@ -616,7 +629,7 @@
* http://openjdk.java.net/jtreg/command-help.html
*/
protected long getShortDelay() {
- return (long) (50 * delayFactor * jtregTestTimeoutFactor);
+ return (long) (50 * delayFactor);
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/logging/Logger/getLogger/TestInferCaller.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Objects;
+import java.util.Queue;
+import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+/**
+ * @test
+ * @bug 8152389
+ * @summary Verify the correct behavior of LogRecord.inferCaller() in particular
+ * when a message is directly logged through the root logger.
+ * @run main/othervm TestInferCaller
+ * @author danielfuchs
+ */
+public class TestInferCaller {
+
+ static final class LogEvent {
+ public final String className;
+ public final String methodName;
+ public final LogRecord record;
+
+ public LogEvent(String className, String methodName, LogRecord record) {
+ this.className = className;
+ this.methodName = methodName;
+ this.record = record;
+ }
+
+ }
+
+ static final class TestHandler extends Handler {
+
+ public static final Queue<LogEvent> PUBLISHED = new LinkedList<LogEvent>();
+
+ public TestHandler() {
+ initLevel(Level.ALL);
+ }
+
+ @Override
+ public void close() throws SecurityException { }
+ @Override
+ public void publish(LogRecord record) {
+ LogEvent event = new LogEvent(record.getSourceClassName(),
+ record.getSourceMethodName(),
+ record);
+ PUBLISHED.add(event);
+ }
+ @Override
+ public void flush() {}
+
+ private void initLevel(Level newLevel) {
+ super.setLevel(newLevel);
+ }
+
+ }
+
+ public void test1(Logger logger) {
+ System.out.println("test1: " + loggerName(logger));
+
+ AtomicInteger count = new AtomicInteger();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ logger.setLevel(Level.ALL);
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+
+ logger.severe("message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ LogEvent event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test1", "message " + count.get());
+
+ logger.warning("message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test1", "message " + count.get());
+
+ logger.info("message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test1", "message " + count.get());
+
+ logger.config("message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test1", "message " + count.get());
+
+ logger.fine("message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test1", "message " + count.get());
+
+ logger.finer("message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test1", "message " + count.get());
+
+ logger.finest("message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test1", "message " + count.get());
+ }
+
+ void test2(Logger logger) {
+ AtomicInteger count = new AtomicInteger();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ logger.setLevel(Level.ALL);
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+
+ for (Level l : Arrays.asList(Level.SEVERE, Level.WARNING, Level.INFO,
+ Level.CONFIG, Level.FINE, Level.FINER, Level.FINEST)) {
+ System.out.println("test2: " + loggerName(logger) + " " + l);
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+
+ logger.log(l, "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ LogEvent event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test2", "message " + count.get());
+
+ logger.log(l, "message " + count.incrementAndGet(), "param");
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test2", "message " + count.get());
+
+ logger.log(l, "message " + count.incrementAndGet(), new Object[] {"foo", "bar"});
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test2", "message " + count.get());
+
+ logger.log(l, "message " + count.incrementAndGet(), new RuntimeException());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test2", "message " + count.get());
+
+ // JDK 8 & 9 only (uses lambda)
+ logger.log(l, () -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test2", "message " + count.get());
+
+ // JDK 8 & 9 only (uses lambda)
+ logger.log(l, new RuntimeException(), () -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test2", "message " + count.get());
+
+ // JDK 9 only: new API
+ logger.logrb(l, (ResourceBundle)null, "message " + count.incrementAndGet(), (Object[]) null);
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test2", "message " + count.get());
+
+ // JDK 9 only: new API
+ logger.logrb(l, (ResourceBundle)null, "message " + count.incrementAndGet(), new RuntimeException());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test2", "message " + count.get());
+
+ }
+ }
+
+ void test3(Logger logger) {
+ System.out.println("test3: " + loggerName(logger));
+ AtomicInteger count = new AtomicInteger();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ logger.setLevel(Level.ALL);
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+
+ testReflection(logger, count, "severe", "testReflection");
+ testReflection(logger, count, "warning", "testReflection");
+ testReflection(logger, count, "info", "testReflection");
+ testReflection(logger, count, "config", "testReflection");
+ testReflection(logger, count, "fine", "testReflection");
+ testReflection(logger, count, "finer", "testReflection");
+ testReflection(logger, count, "finest", "testReflection");
+ }
+
+ void testReflection(Logger logger, AtomicInteger count, String logm, String method) {
+ try {
+ Method m = Logger.class.getMethod(logm, String.class);
+ m.invoke(logger, "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ LogEvent event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), method, "message " + count.get());
+
+ Method m2 = Method.class.getMethod("invoke", Object.class, new Object[0].getClass());
+ m2.invoke(m, logger, new Object[] { "message " + count.incrementAndGet() });
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), method, "message " + count.get());
+
+ m2.invoke(m2, m, new Object[] {logger, new Object[] { "message " + count.incrementAndGet() }});
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), method, "message " + count.get());
+
+ m2.invoke(m2, m2, new Object[] { m, new Object[] {logger, new Object[] { "message " + count.incrementAndGet() }}});
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), method, "message " + count.get());
+
+ } catch (Error | RuntimeException x ) {
+ throw x;
+ } catch (Exception x) {
+ throw new RuntimeException(x);
+ }
+ }
+
+ // JDK 8 & 9 only (uses lambda)
+ public void test4(Logger logger) {
+ System.out.println("test4: " + loggerName(logger));
+ AtomicInteger count = new AtomicInteger();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ logger.setLevel(Level.ALL);
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+
+ logger.severe(() -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ LogEvent event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test4", "message " + count.get());
+
+ logger.warning(() -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test4", "message " + count.get());
+
+ logger.info(() -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test4", "message " + count.get());
+
+ logger.config(() -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test4", "message " + count.get());
+
+ logger.fine(() -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test4", "message " + count.get());
+
+ logger.finer(() -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test4", "message " + count.get());
+
+ logger.finest(() -> "message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), "test4", "message " + count.get());
+ }
+
+ // JDK 8 & 9 only (uses lambda)
+ void test5(Logger logger) {
+ System.out.println("test5: " + loggerName(logger));
+ AtomicInteger count = new AtomicInteger();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ logger.setLevel(Level.ALL);
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+
+ testLambda(count, logger::severe, "testLambda");
+ testLambda(count, logger::warning, "testLambda");
+ testLambda(count, logger::info, "testLambda");
+ testLambda(count, logger::config, "testLambda");
+ testLambda(count, logger::fine, "testLambda");
+ testLambda(count, logger::finer, "testLambda");
+ testLambda(count, logger::finest, "testLambda");
+ }
+
+ // JDK 8 & 9 only (uses lambda)
+ void testLambda(AtomicInteger count, Consumer<String> logm, String method) {
+ logm.accept("message " + count.incrementAndGet());
+ assertEquals(1, TestHandler.PUBLISHED.size(), "No event in queue: ");
+ LogEvent event = TestHandler.PUBLISHED.remove();
+ assertEquals(0, TestHandler.PUBLISHED.size(), "Queue should be empty: ");
+ checkEvent(event, this.getClass().getName(), method, "message " + count.get());
+ }
+
+ private static String loggerName(Logger logger) {
+ String name = logger.getName();
+ if (name == null) return "<anonymous>";
+ if (name.isEmpty()) return "<RootLogger>";
+ return "\"" + name + "\"";
+ }
+
+ public void test(Logger logger) {
+ test1(logger);
+ test2(logger);
+ test3(logger);
+
+ // JDK 8 & 9 only (uses lambda)
+ test4(logger);
+ test5(logger);
+ }
+
+ public static void main(String[] args) {
+ TestInferCaller test = new TestInferCaller();
+ Logger root = Logger.getLogger("");
+ for (Handler h : root.getHandlers()) {
+ h.setLevel(Level.OFF);
+ }
+ root.addHandler(new TestHandler());
+
+ for (Logger logger : Arrays.asList(root, Logger.getGlobal(),
+ Logger.getAnonymousLogger(), Logger.getLogger("foo.bar"))) {
+ System.out.println("Testing with: " + loggerName(logger) + " " + logger.getClass());
+ test.test(logger);
+ }
+ }
+
+ private static void assertEquals(int expected, int actual, String what) {
+ if (expected != actual) {
+ throw new RuntimeException(what
+ + "\n\texpected: " + expected
+ + "\n\tactual: " + actual);
+ }
+ }
+
+ private static void assertEquals(String expected, String actual, String what) {
+ if (!Objects.equals(expected, actual)) {
+ throw new RuntimeException(what
+ + "\n\texpected: " + expected
+ + "\n\tactual: " + actual);
+ }
+ }
+
+ private void checkEvent(LogEvent event, String className, String methodName, String message) {
+ assertEquals(className, event.className, "Bad class name: ");
+ assertEquals(className, event.record.getSourceClassName(), "Bad source class name: ");
+ assertEquals(methodName, event.methodName, "Bad method name: ");
+ assertEquals(methodName, event.record.getSourceMethodName(), "Bad source method name: ");
+ assertEquals(message, event.record.getMessage(), "Bad message: ");
+ }
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/shared/RepeatingWriteTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ *
+ * @bug 8144991 8150154
+ * @ignore 8150154
+ * @author a.stepanov
+ * @summary Check if repeating image writing doesn't fail
+ * (particularly, no AIOOB occurs)
+ *
+ * @run main RepeatingWriteTest
+ */
+
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import javax.imageio.*;
+import javax.imageio.stream.*;
+import java.util.Iterator;
+import java.util.Locale;
+import javax.imageio.plugins.bmp.BMPImageWriteParam;
+import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
+
+public class RepeatingWriteTest {
+
+ private static final int TYPES[] = new int[]{
+ BufferedImage.TYPE_INT_RGB, BufferedImage.TYPE_INT_ARGB,
+ BufferedImage.TYPE_INT_ARGB_PRE, BufferedImage.TYPE_INT_BGR,
+ BufferedImage.TYPE_3BYTE_BGR, BufferedImage.TYPE_4BYTE_ABGR,
+ BufferedImage.TYPE_4BYTE_ABGR_PRE, BufferedImage.TYPE_BYTE_GRAY,
+ BufferedImage.TYPE_USHORT_GRAY, BufferedImage.TYPE_BYTE_BINARY,
+ BufferedImage.TYPE_BYTE_INDEXED, BufferedImage.TYPE_USHORT_565_RGB,
+ BufferedImage.TYPE_USHORT_555_RGB};
+
+ private static final String NAMES[] = new String[]{
+ "TYPE_INT_RGB", "TYPE_INT_ARGB",
+ "TYPE_INT_ARGB_PRE", "TYPE_INT_BGR",
+ "TYPE_3BYTE_BGR", "TYPE_4BYTE_ABGR",
+ "TYPE_4BYTE_ABGR_PRE", "TYPE_BYTE_GRAY",
+ "TYPE_USHORT_GRAY", "TYPE_BYTE_BINARY",
+ "TYPE_BYTE_INDEXED", "TYPE_USHORT_565_RGB",
+ "TYPE_USHORT_555_RGB"};
+
+ private static final int SZ1 = 200, SZ2 = 100;
+ private static final Color C1 = Color.BLACK, C2 = Color.WHITE;
+
+ private static ImageWriter getWriter(String format) {
+ Iterator<ImageWriter> writers =
+ ImageIO.getImageWritersByFormatName(format);
+ if (!writers.hasNext()) {
+ throw new RuntimeException("no writers available for " + format);
+ }
+ return writers.next();
+ }
+
+ private static ImageReader getReader(String format) {
+ Iterator<ImageReader> readers =
+ ImageIO.getImageReadersByFormatName(format);
+ if (!readers.hasNext()) {
+ throw new RuntimeException("no readers available for " + format);
+ }
+ return readers.next();
+ }
+
+ private static class ImageCheckException extends Exception {
+ public ImageCheckException(String msg) { super(msg); }
+ }
+
+ private final String format;
+
+ public RepeatingWriteTest(String format) { this.format = format; }
+
+ private void checkImage(String fileName, boolean is1st) throws Exception {
+
+ Color cRef = is1st ? C1 : C2;
+ int szRef = is1st ? SZ1 : SZ2;
+
+ ImageReader reader = getReader(format);
+ ImageInputStream iis = ImageIO.createImageInputStream(new File(fileName));
+ reader.setInput(iis);
+ BufferedImage img = reader.read(0);
+ Color c = new Color(img.getRGB(szRef / 2, szRef / 2));
+
+ int w = img.getWidth(), h = img.getHeight();
+
+ if (w != szRef || h != szRef) {
+ throw new ImageCheckException(fileName +
+ ": invalid image size " + w + " x " + h);
+ }
+
+ if (!c.equals(cRef)) {
+ throw new ImageCheckException(fileName +
+ ": invalid image color " + c);
+ }
+ }
+
+ private void doTest(int i, int j) throws Exception {
+
+ String pair = NAMES[i] + " " + NAMES[j];
+
+ // some type checks: avoid IO exceptions
+ if ((format.equals("jpeg") || format.equals("bmp")) &&
+ (pair.contains("USHORT_GRAY") ||
+ pair.contains("ARGB") || pair.contains("ABGR"))) {
+ return;
+ }
+
+
+ String f1 = "test-1-" + NAMES[i] + "." + format;
+ String f2 = "test-2-" + NAMES[j] + "." + format;
+
+ ImageWriter writer = getWriter(format);
+
+ // --- write 1st image ---
+ OutputStream s = new BufferedOutputStream(new FileOutputStream(f1));
+ ImageOutputStream ios = ImageIO.createImageOutputStream(s);
+ writer.setOutput(ios);
+
+ BufferedImage img = new BufferedImage(SZ1, SZ1, TYPES[i]);
+ Graphics g = img.getGraphics();
+ g.setColor(C1);
+ g.fillRect(0, 0, SZ1, SZ1);
+ g.dispose();
+
+ if (format.equals("jpeg")) {
+ writer.write(null, new IIOImage(img, null, null),
+ new JPEGImageWriteParam(Locale.getDefault()));
+ } if (format.equals("bmp")) {
+ writer.write(null, new IIOImage(img, null, null),
+ new BMPImageWriteParam());
+ } else {
+ writer.write(img);
+ }
+ ios.flush();
+ s.close();
+
+ // --- write 2nd image ---
+ s = new BufferedOutputStream(new FileOutputStream(f2));
+ ios = ImageIO.createImageOutputStream(s);
+ writer.setOutput(ios);
+
+ img = new BufferedImage(SZ2, SZ2, TYPES[j]);
+ g = img.getGraphics();
+ g.setColor(C2);
+ g.fillRect(0, 0, SZ2, SZ2);
+ g.dispose();
+
+ if (format.equals("jpeg")) {
+ writer.write(null, new IIOImage(img, null, null),
+ new JPEGImageWriteParam(Locale.getDefault()));
+ } if (format.equals("bmp")) {
+ writer.write(null, new IIOImage(img, null, null),
+ new BMPImageWriteParam());
+ } else {
+ writer.write(img);
+ }
+ ios.flush();
+ s.close();
+
+ // --- check files ---
+ checkImage(f1, true);
+ checkImage(f2, false);
+ }
+
+ public static void main(String args[]) throws Exception {
+
+
+ int n = TYPES.length;
+ int nAIOOB = 0, nChecksFailed = 0;
+
+ String formats[] = {"bmp", "jpeg", "gif", "png", "tiff"};
+
+ for (String f: formats) {
+ System.out.println("\nformat: " + f);
+ RepeatingWriteTest test = new RepeatingWriteTest(f);
+ for (int i = 0; i < n; ++i) {
+ for (int j = 0; j < n; ++j) {
+ try {
+ test.doTest(i, j);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ System.err.println(f + ": AIOOB for pair " +
+ NAMES[i] + ", " + NAMES[j] + ": " + e.getMessage());
+ nAIOOB++;
+ } catch (ImageCheckException e) {
+ System.err.println(f +
+ ": image check failed for " + e.getMessage());
+ nChecksFailed++;
+ }
+ }
+ }
+ }
+
+ if (nAIOOB > 0 || nChecksFailed > 0) {
+ throw new RuntimeException("test failed: " + nAIOOB + " AIOOBs, " +
+ nChecksFailed + " image check failures");
+ }
+ }
+}
--- a/jdk/test/javax/imageio/plugins/tiff/MultiPageTest/MultiPageTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/javax/imageio/plugins/tiff/MultiPageTest/MultiPageTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -97,7 +97,7 @@
}
- private ImageWriter getTIFFWriter() throws Exception {
+ private ImageWriter getTIFFWriter() {
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("TIFF");
if (!writers.hasNext()) {
@@ -106,7 +106,7 @@
return writers.next();
}
- private ImageReader getTIFFReader() throws Exception {
+ private ImageReader getTIFFReader() {
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("TIFF");
if (!readers.hasNext()) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeWaveExtFiles.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 8132782
+ */
+public final class RecognizeHugeWaveExtFiles {
+
+ /**
+ * The maximum size in bytes per WAVE specification.
+ */
+ private static final /*unsigned int */ long MAX_UNSIGNED_INT = 0xffffffffL;
+
+ /**
+ * The supported wave ext format and sample size in bits.
+ */
+ private static final int[][] waveTypeBits = {
+ {0xFFFE/*WAVE_FORMAT_EXTENSIBLE*/, 8}
+ };
+
+ /**
+ * The list of supported sample rates(stored as unsigned int).
+ */
+ private static final int[] sampleRates = {
+ 8000, 11025, 16000, 22050, 32000, 37800, 44056, 44100, 47250, 48000,
+ 50000, 50400, 88200, 96000, 176400, 192000, 352800, 2822400,
+ 5644800, Integer.MAX_VALUE
+ };
+
+ /**
+ * The list of supported channels (stored as unsigned int).
+ */
+ private static final int[] channels = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
+ };
+
+ /**
+ * The list of supported size of data (stored as unsigned int).
+ * <p>
+ * The {@code MAX_UNSIGNED_INT} is a maximum size.
+ */
+ private static final long[] dataSizes = {
+ 0, 1, 2, 3, Integer.MAX_VALUE - 1, Integer.MAX_VALUE,
+ (long) Integer.MAX_VALUE + 1, MAX_UNSIGNED_INT - 1, MAX_UNSIGNED_INT
+ };
+
+ public static void main(final String[] args) throws Exception {
+ for (final int[] type : waveTypeBits) {
+ for (final int sampleRate : sampleRates) {
+ for (final int channel : channels) {
+ for (final long dataSize : dataSizes) {
+ testAFF(type, sampleRate, channel, dataSize);
+ testAIS(type, sampleRate, channel, dataSize);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests the {@code AudioFileFormat} fetched from the fake header.
+ * <p>
+ * Note that the frameLength and byteLength are stored as int which means
+ * that {@code AudioFileFormat} will store the data above {@code MAX_INT} as
+ * NOT_SPECIFIED.
+ */
+ private static void testAFF(final int[] type, final int rate,
+ final int channel, final long size)
+ throws Exception {
+ final byte[] header = createHeader(type, rate, channel, size);
+ final ByteArrayInputStream fake = new ByteArrayInputStream(header);
+ final AudioFileFormat aff = AudioSystem.getAudioFileFormat(fake);
+ final AudioFormat format = aff.getFormat();
+
+ if (aff.getType() != AudioFileFormat.Type.WAVE) {
+ throw new RuntimeException("Error");
+ }
+
+ final long frameLength = size / format.getFrameSize();
+ if (frameLength <= Integer.MAX_VALUE) {
+ if (aff.getFrameLength() != frameLength) {
+ System.err.println("Expected: " + frameLength);
+ System.err.println("Actual: " + aff.getFrameLength());
+ throw new RuntimeException();
+ }
+ } else {
+ if (aff.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
+ System.err.println("Expected: " + AudioSystem.NOT_SPECIFIED);
+ System.err.println("Actual: " + aff.getFrameLength());
+ throw new RuntimeException();
+ }
+ }
+ validateFormat(type[1], rate, channel, aff.getFormat());
+ }
+
+ /**
+ * Tests the {@code AudioInputStream} fetched from the fake header.
+ * <p>
+ * Note that the frameLength is stored as long which means that {@code
+ * AudioInputStream} must store all possible data from au file.
+ */
+ private static void testAIS(final int[] type, final int rate,
+ final int channel, final long size)
+ throws Exception {
+ final byte[] header = createHeader(type, rate, channel, size);
+ final ByteArrayInputStream fake = new ByteArrayInputStream(header);
+ final AudioInputStream ais = AudioSystem.getAudioInputStream(fake);
+ final AudioFormat format = ais.getFormat();
+ final long frameLength = size / format.getFrameSize();
+ if (frameLength != ais.getFrameLength()) {
+ System.err.println("Expected: " + frameLength);
+ System.err.println("Actual: " + ais.getFrameLength());
+ throw new RuntimeException();
+ }
+ if (ais.available() < 0) {
+ System.err.println("available should be >=0: " + ais.available());
+ throw new RuntimeException();
+ }
+
+ validateFormat(type[1], rate, channel, format);
+ }
+
+ /**
+ * Tests that format contains the same data as were provided to the fake
+ * stream.
+ */
+ private static void validateFormat(final int bits, final int rate,
+ final int channel,
+ final AudioFormat format) {
+
+ if (Float.compare(format.getSampleRate(), rate) != 0) {
+ System.err.println("Expected: " + rate);
+ System.err.println("Actual: " + format.getSampleRate());
+ throw new RuntimeException();
+ }
+ if (format.getChannels() != channel) {
+ System.err.println("Expected: " + channel);
+ System.err.println("Actual: " + format.getChannels());
+ throw new RuntimeException();
+ }
+ if (format.getFrameSize() != ((bits + 7) / 8) * channel) {
+ System.err.println("Expected: " + (bits * channel + 1) / 8);
+ System.err.println("Actual: " + format.getFrameSize());
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Creates the custom header of the WAVE file. It is expected that all
+ * passed data are supported.
+ */
+ private static byte[] createHeader(final int[] type, final int rate,
+ final int channel, final long size) {
+ final int frameSize = ((type[1] + 7) / 8) * channel;
+ return new byte[]{
+ // RIFF_MAGIC
+ 0x52, 0x49, 0x46, 0x46,
+ // fileLength
+ -1, -1, -1, -1,
+ // waveMagic
+ 0x57, 0x41, 0x56, 0x45,
+ // FMT_MAGIC
+ 0x66, 0x6d, 0x74, 0x20,
+ // size
+ 40, 0, 0, 0,
+ // wav_type WAVE_FORMAT_EXTENSIBLE
+ (byte) (type[0]), (byte) (type[0] >> 8),
+ // channels
+ (byte) (channel), (byte) (channel >> 8),
+ // samplerate
+ (byte) (rate), (byte) (rate >> 8), (byte) (rate >> 16),
+ (byte) (rate >> 24),
+ // framerate
+ 1, 0, 0, 0,
+ // framesize
+ (byte) (frameSize), (byte) (frameSize >> 8),
+ // bits
+ (byte) type[1], 0,
+ // cbsize
+ 22, 0,
+ // validBitsPerSample
+ 8, 0,
+ // channelMask
+ 0, 0, 0, 0,
+ // SUBTYPE_IEEE_FLOAT
+ // i1
+ 0x3, 0x0, 0x0, 0x0,
+ //s1
+ 0x0, 0x0,
+ //s2
+ 0x10, 0,
+ //x1
+ (byte) 0x80,
+ //x2
+ 0x0,
+ //x3
+ 0x0,
+ //x4
+ (byte) 0xaa,
+ //x5
+ 0x0,
+ //x6
+ 0x38,
+ //x7
+ (byte) 0x9b,
+ //x8
+ 0x71,
+ // DATA_MAGIC
+ 0x64, 0x61, 0x74, 0x61,
+ // data size
+ (byte) (size), (byte) (size >> 8), (byte) (size >> 16),
+ (byte) (size >> 24)
+ // data
+ , 0, 0, 0, 0, 0
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/sampled/spi/AudioFileReader/RecognizeHugeWaveFloatFiles.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * @test
+ * @bug 8132782
+ */
+public final class RecognizeHugeWaveFloatFiles {
+
+ /**
+ * The maximum size in bytes per WAVE specification.
+ */
+ private static final /*unsigned int */ long MAX_UNSIGNED_INT = 0xffffffffL;
+
+ /**
+ * The supported wave pcm_float format and sample size in bits.
+ */
+ private static final byte[][] waveTypeBits = {
+ {0x0003/*WAVE_FORMAT_IEEE_FLOAT*/, 32}
+ };
+
+ /**
+ * The list of supported sample rates(stored as unsigned int).
+ */
+ private static final int[] sampleRates = {
+ 8000, 11025, 16000, 22050, 32000, 37800, 44056, 44100, 47250, 48000,
+ 50000, 50400, 88200, 96000, 176400, 192000, 352800, 2822400,
+ 5644800, Integer.MAX_VALUE
+ };
+
+ /**
+ * The list of supported channels (stored as unsigned int).
+ */
+ private static final int[] channels = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
+ };
+
+ /**
+ * The list of supported size of data (stored as unsigned int).
+ * <p>
+ * The {@code MAX_UNSIGNED_INT} is a maximum size.
+ */
+ private static final long[] dataSizes = {
+ 0, 1, 2, 3, Integer.MAX_VALUE - 1, Integer.MAX_VALUE,
+ (long) Integer.MAX_VALUE + 1, MAX_UNSIGNED_INT - 1, MAX_UNSIGNED_INT
+ };
+
+ public static void main(final String[] args) throws Exception {
+ for (final byte[] type : waveTypeBits) {
+ for (final int sampleRate : sampleRates) {
+ for (final int channel : channels) {
+ for (final long dataSize : dataSizes) {
+ testAFF(type, sampleRate, channel, dataSize);
+ testAIS(type, sampleRate, channel, dataSize);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests the {@code AudioFileFormat} fetched from the fake header.
+ * <p>
+ * Note that the frameLength and byteLength are stored as int which means
+ * that {@code AudioFileFormat} will store the data above {@code MAX_INT} as
+ * NOT_SPECIFIED.
+ */
+ private static void testAFF(final byte[] type, final int rate,
+ final int channel, final long size)
+ throws Exception {
+ final byte[] header = createHeader(type, rate, channel, size);
+ final ByteArrayInputStream fake = new ByteArrayInputStream(header);
+ final AudioFileFormat aff = AudioSystem.getAudioFileFormat(fake);
+ final AudioFormat format = aff.getFormat();
+
+ if (aff.getType() != AudioFileFormat.Type.WAVE) {
+ throw new RuntimeException("Error");
+ }
+
+ final long frameLength = size / format.getFrameSize();
+ if (frameLength <= Integer.MAX_VALUE) {
+ if (aff.getFrameLength() != frameLength) {
+ System.err.println("Expected: " + frameLength);
+ System.err.println("Actual: " + aff.getFrameLength());
+ throw new RuntimeException();
+ }
+ } else {
+ if (aff.getFrameLength() != AudioSystem.NOT_SPECIFIED) {
+ System.err.println("Expected: " + AudioSystem.NOT_SPECIFIED);
+ System.err.println("Actual: " + aff.getFrameLength());
+ throw new RuntimeException();
+ }
+ }
+ validateFormat(type[1], rate, channel, aff.getFormat());
+ }
+
+ /**
+ * Tests the {@code AudioInputStream} fetched from the fake header.
+ * <p>
+ * Note that the frameLength is stored as long which means that {@code
+ * AudioInputStream} must store all possible data from au file.
+ */
+ private static void testAIS(final byte[] type, final int rate,
+ final int channel, final long size)
+ throws Exception {
+ final byte[] header = createHeader(type, rate, channel, size);
+ final ByteArrayInputStream fake = new ByteArrayInputStream(header);
+ final AudioInputStream ais = AudioSystem.getAudioInputStream(fake);
+ final AudioFormat format = ais.getFormat();
+ final long frameLength = size / format.getFrameSize();
+ if (frameLength != ais.getFrameLength()) {
+ System.err.println("Expected: " + frameLength);
+ System.err.println("Actual: " + ais.getFrameLength());
+ throw new RuntimeException();
+ }
+ if (ais.available() < 0) {
+ System.err.println("available should be >=0: " + ais.available());
+ throw new RuntimeException();
+ }
+
+ validateFormat(type[1], rate, channel, format);
+ }
+
+ /**
+ * Tests that format contains the same data as were provided to the fake
+ * stream.
+ */
+ private static void validateFormat(final byte bits, final int rate,
+ final int channel,
+ final AudioFormat format) {
+
+ if (Float.compare(format.getSampleRate(), rate) != 0) {
+ System.err.println("Expected: " + rate);
+ System.err.println("Actual: " + format.getSampleRate());
+ throw new RuntimeException();
+ }
+ if (format.getChannels() != channel) {
+ System.err.println("Expected: " + channel);
+ System.err.println("Actual: " + format.getChannels());
+ throw new RuntimeException();
+ }
+ if (format.getFrameSize() != ((bits + 7) / 8) * channel) {
+ System.err.println("Expected: " + (bits * channel + 1) / 8);
+ System.err.println("Actual: " + format.getFrameSize());
+ throw new RuntimeException();
+ }
+ }
+
+ /**
+ * Creates the custom header of the WAVE file. It is expected that all
+ * passed data are supported.
+ */
+ private static byte[] createHeader(final byte[] type, final int rate,
+ final int channel, final long size) {
+ final int frameSize = ((type[1] + 7) / 8) * channel;
+ return new byte[]{
+ // RIFF_MAGIC
+ 0x52, 0x49, 0x46, 0x46,
+ // fileLength
+ -1, -1, -1, -1,
+ // waveMagic
+ 0x57, 0x41, 0x56, 0x45,
+ // FMT_MAGIC
+ 0x66, 0x6d, 0x74, 0x20,
+ // size
+ 16, 0, 0, 0,
+ // wav_type WAVE_FORMAT_IEEE_FLOAT
+ type[0], 0,
+ // channels
+ (byte) (channel), (byte) (channel >> 8),
+ // samplerate
+ (byte) (rate), (byte) (rate >> 8), (byte) (rate >> 16),
+ (byte) (rate >> 24),
+ // framerate
+ 1, 0, 0, 0,
+ // framesize
+ (byte) (frameSize), (byte) (frameSize >> 8),
+ // bits
+ type[1], 0,
+ // DATA_MAGIC
+ 0x64, 0x61, 0x74, 0x61,
+ // data size
+ (byte) (size), (byte) (size >> 8), (byte) (size >> 16),
+ (byte) (size >> 24)
+ // data
+ , 0, 0, 0, 0, 0
+ };
+ }
+}
--- a/jdk/test/javax/swing/Action/8133039/bug8133039.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/javax/swing/Action/8133039/bug8133039.java Thu Apr 07 11:03:59 2016 -0700
@@ -37,6 +37,7 @@
* @test
* @bug 8133039
* @summary Provide public API to sun.swing.UIAction#isEnabled(Object)
+ * @modules java.desktop/sun.swing
* @author Alexander Scherbatiy
*/
public class bug8133039 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JDesktopPane/DesktopPaneBackgroundTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+ */
+
+ /*
+* @test
+* @bug 7012008
+* @summary Verify JDesktopPane Background Color for WLAF
+* @requires (os.family == "windows")
+* @run main DesktopPaneBackgroundTest
+ */
+import java.awt.Color;
+import java.awt.Toolkit;
+import javax.swing.JDesktopPane;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+public class DesktopPaneBackgroundTest {
+
+ private static Color defaultBackgroudColor;
+
+ public static void main(String[] args) throws Exception {
+ defaultBackgroudColor = (Color) Toolkit.getDefaultToolkit()
+ .getDesktopProperty("win.mdi.backgroundColor");
+
+ String[] lookAndFeel = new String[]{
+ "com.sun.java.swing.plaf.windows.WindowsLookAndFeel",
+ "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel"};
+
+ for (String laf : lookAndFeel) {
+ UIManager.setLookAndFeel(laf);
+
+ SwingUtilities.invokeAndWait(() -> {
+ JDesktopPane desktopPane = new JDesktopPane();
+
+ Color background = desktopPane.getBackground();
+ if (!background.equals(defaultBackgroudColor)) {
+ throw new RuntimeException("Invalid JDesktopPane "
+ + "Background Color for WLAF");
+ }
+ });
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JInternalFrame/8069348/bug8069348.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.JInternalFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import static sun.awt.OSInfo.*;
+
+/**
+ * @test
+ * @bug 8069348
+ * @summary SunGraphics2D.copyArea() does not properly work for scaled graphics
+ * @author Alexandr Scherbatiy
+ * @modules java.desktop/sun.awt
+ * @run main/othervm -Dsun.java2d.uiScale=2 bug8069348
+ * @run main/othervm -Dsun.java2d.opengl=true -Dsun.java2d.uiScale=2 bug8069348
+ * @run main/othervm -Dsun.java2d.d3d=true -Dsun.java2d.uiScale=2 bug8069348
+ */
+public class bug8069348 {
+
+ private static final int WIN_WIDTH = 500;
+ private static final int WIN_HEIGHT = 500;
+
+ private static final Color DESKTOPPANE_COLOR = Color.YELLOW;
+ private static final Color FRAME_COLOR = Color.ORANGE;
+
+ private static JFrame frame;
+ private static JInternalFrame internalFrame;
+
+ public static void main(String[] args) throws Exception {
+
+ if (!isSupported()) {
+ return;
+ }
+
+ try {
+
+ SwingUtilities.invokeAndWait(bug8069348::createAndShowGUI);
+
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+ robot.waitForIdle();
+
+ Rectangle screenBounds = getInternalFrameScreenBounds();
+
+ int x = screenBounds.x + screenBounds.width / 2;
+ int y = screenBounds.y + 10;
+ int dx = screenBounds.width / 2;
+ int dy = screenBounds.height / 2;
+
+ robot.mouseMove(x, y);
+ robot.waitForIdle();
+
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseMove(x + dx, y + dy);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+
+ int cx = screenBounds.x + screenBounds.width + dx / 2;
+ int cy = screenBounds.y + screenBounds.height + dy / 2;
+
+ robot.mouseMove(cx, cy);
+ if (!FRAME_COLOR.equals(robot.getPixelColor(cx, cy))) {
+ throw new RuntimeException("Internal frame is not correctly dragged!");
+ }
+ } finally {
+ if (frame != null) {
+ frame.dispose();
+ }
+ }
+ }
+
+ private static boolean isSupported() {
+ String d3d = System.getProperty("sun.java2d.d3d");
+ return !Boolean.getBoolean(d3d) || getOSType() == OSType.WINDOWS;
+ }
+
+ private static Rectangle getInternalFrameScreenBounds() throws Exception {
+ Rectangle[] points = new Rectangle[1];
+ SwingUtilities.invokeAndWait(() -> {
+ points[0] = new Rectangle(internalFrame.getLocationOnScreen(),
+ internalFrame.getSize());
+ });
+ return points[0];
+ }
+
+ private static void createAndShowGUI() {
+
+ frame = new JFrame();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JDesktopPane desktopPane = new JDesktopPane();
+ desktopPane.setBackground(DESKTOPPANE_COLOR);
+
+ internalFrame = new JInternalFrame("Test") {
+
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+ g.setColor(FRAME_COLOR);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ }
+ };
+ internalFrame.setSize(WIN_WIDTH / 3, WIN_HEIGHT / 3);
+ internalFrame.setVisible(true);
+ desktopPane.add(internalFrame);
+
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ panel.add(desktopPane, BorderLayout.CENTER);
+ frame.add(panel);
+ frame.setSize(WIN_WIDTH, WIN_HEIGHT);
+ frame.setVisible(true);
+ frame.requestFocus();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JInternalFrame/8145896/TestJInternalFrameMaximize.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8145896
+ * @summary JInternalFrame setMaximum before adding to desktop throws null pointer exception
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main TestJInternalFrameMaximize
+ */
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.beans.PropertyVetoException;
+import javax.swing.JFrame;
+import javax.swing.JDesktopPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JInternalFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+public class TestJInternalFrameMaximize {
+
+ private static JDesktopPane desktopPane;
+ private static JFrame frame;
+ private static int count = 0;
+ private static JMenu menu;
+ private static JMenuBar menuBar;
+ private static JMenuItem menuItem;
+ private static Robot robot;
+ private static volatile String errorMessage = "";
+
+ public static void main(String[] args) throws Exception {
+ robot = new Robot();
+ UIManager.LookAndFeelInfo[] lookAndFeelArray
+ = UIManager.getInstalledLookAndFeels();
+ for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
+ String lookAndFeelString = lookAndFeelItem.getClassName();
+ if (tryLookAndFeel(lookAndFeelString)) {
+ createUI();
+ robot.waitForIdle();
+ executeTest();
+ }
+ }
+ if (!"".equals(errorMessage)) {
+ throw new RuntimeException(errorMessage);
+ }
+ }
+
+ private static boolean tryLookAndFeel(String lookAndFeelString) {
+ try {
+ UIManager.setLookAndFeel(lookAndFeelString);
+ return true;
+ } catch (UnsupportedLookAndFeelException | ClassNotFoundException |
+ InstantiationException | IllegalAccessException e) {
+ errorMessage += e.getMessage() + "\n";
+ System.err.println("Caught Exception: " + e.getMessage());
+ return false;
+ }
+ }
+
+ private static void createUI() throws Exception {
+
+ SwingUtilities.invokeAndWait(() -> {
+ frame = new JFrame("Test Frame");
+ desktopPane = new JDesktopPane();
+ frame.getContentPane().add(desktopPane);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ menuBar = new JMenuBar();
+ frame.setJMenuBar(menuBar);
+
+ menu = new JMenu("File");
+ menuBar.add(menu);
+
+ menuItem = new JMenuItem("New Child");
+ menuItem.addActionListener((ActionEvent e) -> {
+ try {
+ JInternalFrame f = new JInternalFrame("Child "
+ + (++count), true, true, true, true);
+ f.setSize(200, 300);
+ f.setLocation(count * 20, count * 20);
+ f.setMaximum(true);
+ desktopPane.add(f);
+ f.setVisible(true);
+ } catch (PropertyVetoException ex) {
+ } catch (RuntimeException ex) {
+ errorMessage = "Test Failed";
+ } finally {
+ frame.dispose();
+ }
+ });
+ menu.add(menuItem);
+ frame.setSize(500, 500);
+ frame.setLocationRelativeTo(null);
+ frame.setVisible(true);
+ });
+ }
+
+ private static void executeTest() throws Exception {
+
+ Point point = Util.getCenterPoint(menu);
+ performMouseOperations(point);
+ point = Util.getCenterPoint(menuItem);
+ performMouseOperations(point);
+ }
+
+ private static void performMouseOperations(Point point) {
+ robot.mouseMove(point.x, point.y);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.delay(1000);
+ robot.waitForIdle();
+ }
+}
--- a/jdk/test/javax/swing/JInternalFrame/8146321/JInternalFrameIconTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/javax/swing/JInternalFrame/8146321/JInternalFrameIconTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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,7 +22,7 @@
*/
/* @test
- * @bug 8146321
+ * @bug 8146321 8151282
* @summary verifies JInternalFrame Icon and ImageIcon
* @library ../../regtesthelpers
* @build Util
@@ -53,8 +53,9 @@
private static Icon titleIcon;
private static BufferedImage imageIconImage;
private static BufferedImage iconImage;
+ private static Robot robot;
+ private static volatile String errorString = "";
- private static Robot robot;
public static void main(String[] args) throws Exception {
robot = new Robot();
@@ -64,6 +65,9 @@
for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
executeCase(lookAndFeelItem.getClassName());
}
+ if (!"".equals(errorString)) {
+ throw new RuntimeException("Error Log:\n" + errorString);
+ }
}
@@ -72,17 +76,18 @@
createImageIconUI(lookAndFeelString);
robot.delay(1000);
getImageIconBufferedImage();
- robot.waitForIdle();
+ robot.delay(1000);
cleanUp();
robot.waitForIdle();
createIconUI(lookAndFeelString);
robot.delay(1000);
getIconBufferedImage();
- robot.waitForIdle();
+ robot.delay(1000);
cleanUp();
robot.waitForIdle();
- testIfSame();
+
+ testIfSame(lookAndFeelString);
robot.waitForIdle();
}
@@ -198,11 +203,16 @@
= robot.createScreenCapture(captureRect);
}
- private static void testIfSame() throws Exception {
+ private static void testIfSame(final String lookAndFeelString)
+ throws Exception {
if (!bufferedImagesEqual(imageIconImage, iconImage)) {
- System.err.println("ERROR: icon and imageIcon not same.");
+ String error ="[" + lookAndFeelString
+ + "] : ERROR: icon and imageIcon not same.";
+ errorString += error;
+ System.err.println(error);
} else {
- System.out.println("SUCCESS: icon and imageIcon same.");
+ System.out.println("[" + lookAndFeelString
+ + "] : SUCCESS: icon and imageIcon same.");
}
}
@@ -260,6 +270,11 @@
private static boolean tryLookAndFeel(String lookAndFeelString)
throws Exception {
+ //This test case is not applicable for Motif and gtk LAFs
+ if(lookAndFeelString.contains("motif")
+ || lookAndFeelString.contains("gtk")) {
+ return false;
+ }
try {
UIManager.setLookAndFeel(
lookAndFeelString);
--- a/jdk/test/javax/swing/JPopupMenu/6544309/bug6544309.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/javax/swing/JPopupMenu/6544309/bug6544309.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, 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
@@ -30,9 +30,14 @@
@run main bug6544309
*/
-import javax.swing.*;
-import java.awt.event.*;
-import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JDialog;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
public class bug6544309 {
private JDialog dialog;
@@ -41,6 +46,8 @@
public static void main(String[] args) throws Exception {
robot = new ExtendedRobot();
+ // move mouse outside menu to prevent auto selection
+ robot.mouseMove(100,100);
final bug6544309 test = new bug6544309();
try {
SwingUtilities.invokeAndWait(new Runnable() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTextArea/8148555/JTextAreaEmojiTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
+
+/* @test
+ * @bug 8148555
+ * @summary verifies JTextArea emoji enter exception. Emoji is not supported.
+ * @requires (os.family=="mac")
+ * @run main JTextAreaEmojiTest
+ */
+public class JTextAreaEmojiTest implements
+ ActionListener {
+
+ private static GridBagLayout layout;
+ private static JPanel textAreaPanel;
+ private static JPanel mainControlPanel;
+ private static JPanel instructionPanel;
+ private static JPanel resultButtonPanel;
+ private static JPanel controlPanel;
+ private static JTextArea instructionTextArea;
+ private static JTextArea emojiTextArea;
+ private static JButton passButton;
+ private static JButton failButton;
+
+ private static JFrame mainFrame;
+
+ public static void main(String[] args) throws Exception {
+
+ JTextAreaEmojiTest test = new JTextAreaEmojiTest();
+ }
+
+ public JTextAreaEmojiTest() throws Exception {
+ createControlPanelUI();
+ }
+
+ public final void createControlPanelUI() throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ layout = new GridBagLayout();
+ mainControlPanel = new JPanel(layout);
+ instructionPanel = new JPanel(layout);
+ resultButtonPanel = new JPanel(layout);
+ textAreaPanel = new JPanel(layout);
+ controlPanel = new JPanel(layout);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ String instructions
+ = "1) Text Area size should be zero"
+ + "\n2) Select one emoji from Character Viewer"
+ + "\n3) If Text Area size increases displaying"
+ + "Blank or supported emoji for default font, click pass"
+ + "\n4) Else press fail";
+ instructionTextArea = new JTextArea();
+ instructionTextArea.setText(instructions);
+ instructionTextArea.setEnabled(false);
+ instructionTextArea.setDisabledTextColor(Color.black);
+ instructionTextArea.setBackground(Color.white);
+ instructionTextArea.setBorder(
+ BorderFactory.createLineBorder(Color.black));
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ instructionPanel.add(instructionTextArea, gbc);
+
+ emojiTextArea = new JTextArea();
+ emojiTextArea.setEnabled(true);
+ emojiTextArea.setDisabledTextColor(Color.black);
+ emojiTextArea.setBackground(Color.white);
+ emojiTextArea.setBorder(
+ BorderFactory.createLineBorder(Color.black));
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ textAreaPanel.add(emojiTextArea, gbc);
+
+ passButton = new JButton("Pass");
+ passButton.setActionCommand("Pass");
+ passButton.addActionListener(JTextAreaEmojiTest.this);
+ failButton = new JButton("Fail");
+ failButton.setActionCommand("Fail");
+ failButton.addActionListener(JTextAreaEmojiTest.this);
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ resultButtonPanel.add(passButton, gbc);
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ resultButtonPanel.add(failButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ mainControlPanel.add(instructionPanel, gbc);
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ mainControlPanel.add(textAreaPanel, gbc);
+ gbc.gridx = 0;
+ gbc.gridy = 2;
+ mainControlPanel.add(resultButtonPanel, gbc);
+
+ mainControlPanel.add(controlPanel, gbc);
+ mainFrame = new JFrame("Control Panel");
+ mainFrame.add(mainControlPanel);
+ mainFrame.pack();
+ mainFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
+ mainFrame.setVisible(true);
+ }
+ });
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource() instanceof JButton) {
+ JButton btn = (JButton) evt.getSource();
+ cleanUp();
+
+ switch (btn.getActionCommand()) {
+ case "Pass":
+ break;
+ case "Fail":
+ throw new AssertionError("Test case has failed!");
+ }
+ }
+ }
+
+ private static void cleanUp() {
+ mainFrame.dispose();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTextArea/8149849/DNDTextToScaledArea.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+/**
+ * @test
+ * @bug 8149849
+ * @summary [hidpi] DnD issues (cannot DnD from JFileChooser to JEditorPane or
+ * other text component) when scale > 1
+ * @run main/othervm -Dsun.java2d.uiScale=2 DNDTextToScaledArea
+ */
+public class DNDTextToScaledArea {
+
+ private static final String TEXT = "ABCDEFGH";
+ private static JFrame frame;
+ private static JTextArea srcTextArea;
+ private static JTextArea dstTextArea;
+ private static volatile Point srcPoint;
+ private static volatile Point dstPoint;
+ private static volatile boolean passed = false;
+
+ public static void main(String[] args) throws Exception {
+ Robot robot = new Robot();
+ robot.setAutoDelay(50);
+
+ SwingUtilities.invokeAndWait(DNDTextToScaledArea::createAndShowGUI);
+ robot.waitForIdle();
+
+ SwingUtilities.invokeAndWait(() -> {
+ srcPoint = getPoint(srcTextArea, 0.1);
+ dstPoint = getPoint(dstTextArea, 0.75);
+ });
+ robot.waitForIdle();
+
+ dragAndDrop(robot, srcPoint, dstPoint);
+ robot.waitForIdle();
+
+ SwingUtilities.invokeAndWait(() -> {
+ passed = TEXT.equals(dstTextArea.getText());
+ frame.dispose();
+ });
+ robot.waitForIdle();
+
+ if (!passed) {
+ throw new RuntimeException("Text Drag and Drop failed!");
+ }
+ }
+
+ private static void createAndShowGUI() {
+
+ frame = new JFrame();
+ frame.setSize(300, 300);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ JPanel panel = new JPanel(new BorderLayout());
+
+ srcTextArea = new JTextArea(TEXT);
+ srcTextArea.setDragEnabled(true);
+ srcTextArea.selectAll();
+ dstTextArea = new JTextArea();
+
+ panel.add(dstTextArea, BorderLayout.CENTER);
+ panel.add(srcTextArea, BorderLayout.SOUTH);
+
+ frame.getContentPane().add(panel);
+ frame.setVisible(true);
+ }
+
+ private static Point getPoint(Component component, double scale) {
+ Point point = component.getLocationOnScreen();
+ Dimension bounds = component.getSize();
+ point.translate((int) (bounds.width * scale), (int) (bounds.height * scale));
+ return point;
+ }
+
+ public static void dragAndDrop(Robot robot, Point src, Point dst) throws Exception {
+
+ int x1 = src.x;
+ int y1 = src.y;
+ int x2 = dst.x;
+ int y2 = dst.y;
+ robot.mouseMove(x1, y1);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+
+ float dmax = (float) Math.max(Math.abs(x2 - x1), Math.abs(y2 - y1));
+ float dx = (x2 - x1) / dmax;
+ float dy = (y2 - y1) / dmax;
+
+ for (int i = 0; i <= dmax; i += 5) {
+ robot.mouseMove((int) (x1 + dx * i), (int) (y1 + dy * i));
+ }
+
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/LookAndFeel/6439354/TitledBorderTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @bug 6439354
+ * @summary Verify TitleBorder appearance Color/Visibility for WLAF
+ * @requires (os.family == "windows")
+ * @run main/manual TitledBorderTest
+ */
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+public class TitledBorderTest implements ActionListener {
+
+ private static GridBagLayout layout;
+ private static JPanel mainControlPanel;
+ private static JPanel resultButtonPanel;
+ private static JTextArea instructionTextArea;
+ private static JButton passButton;
+ private static JButton failButton;
+ private static JFrame mainFrame;
+
+ public static void main(String[] args) throws Exception {
+ TitledBorderTest titledBorderTest = new TitledBorderTest();
+ }
+
+ public TitledBorderTest() throws Exception {
+ createUI();
+ }
+
+ public final void createUI() throws Exception {
+
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf."
+ + "windows.WindowsLookAndFeel");
+
+ SwingUtilities.invokeAndWait(() -> {
+
+ mainFrame = new JFrame("Window LAF TitledBorder Test");
+ layout = new GridBagLayout();
+ mainControlPanel = new JPanel(layout);
+ resultButtonPanel = new JPanel(layout);
+
+ GridBagConstraints gbc = new GridBagConstraints();
+ String instructions
+ = "INSTRUCTIONS:"
+ + "\n set Windows Theme to HighContrast#1."
+ + "\n (ControlPanel->Personalization->High Contrast#1)"
+ + "\n If Titled Border(Border Line) is visible then test"
+ + " passes else failed.";
+
+ instructionTextArea = new JTextArea();
+ instructionTextArea.setText(instructions);
+ instructionTextArea.setEnabled(false);
+ instructionTextArea.setDisabledTextColor(Color.black);
+ instructionTextArea.setBackground(Color.white);
+
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ gbc.fill = GridBagConstraints.HORIZONTAL;
+ mainControlPanel.add(instructionTextArea, gbc);
+
+ mainControlPanel.setBorder(BorderFactory.
+ createTitledBorder("Titled Border"));
+
+ passButton = new JButton("Pass");
+ passButton.setActionCommand("Pass");
+ passButton.addActionListener(TitledBorderTest.this);
+ failButton = new JButton("Fail");
+ failButton.setActionCommand("Fail");
+ failButton.addActionListener(TitledBorderTest.this);
+ gbc.gridx = 0;
+ gbc.gridy = 0;
+ resultButtonPanel.add(passButton, gbc);
+ gbc.gridx = 1;
+ gbc.gridy = 0;
+ resultButtonPanel.add(failButton, gbc);
+
+ gbc.gridx = 0;
+ gbc.gridy = 1;
+ mainControlPanel.add(resultButtonPanel, gbc);
+
+ mainFrame.add(mainControlPanel);
+ mainFrame.pack();
+ mainFrame.setVisible(true);
+ });
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent evt) {
+ if (evt.getSource() instanceof JButton) {
+ JButton btn = (JButton) evt.getSource();
+ cleanUp();
+ switch (btn.getActionCommand()) {
+ case "Pass":
+ break;
+ case "Fail":
+ throw new AssertionError("User Clicked Fail!");
+ }
+ }
+ }
+
+ private static void cleanUp() {
+ mainFrame.dispose();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/border/8152159/TitledBorderLabelUITest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.border.TitledBorder;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.UIResource;
+import javax.swing.plaf.metal.MetalLabelUI;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+
+/**
+ * @test
+ * @bug 8152159
+ * @summary LabelUI is not updated for TitledBorder
+ * @run main/othervm TitledBorderLabelUITest LAF
+ * @run main/othervm TitledBorderLabelUITest LabelUI
+ */
+
+public class TitledBorderLabelUITest {
+
+ private static final int SIZE = 50;
+ private static boolean useLAF;
+
+ public static void main(String[] args) throws Exception {
+ useLAF = "LAF".equals(args[0]);
+ SwingUtilities.invokeAndWait(TitledBorderLabelUITest::createAndShowGUI);
+ }
+
+ private static void createAndShowGUI() {
+
+ try {
+ UIManager.setLookAndFeel(new TestLookAndFeel());
+
+ JLabel label = new JLabel("Test Label");
+ label.setSize(SIZE, SIZE);
+ TitledBorder border = new TitledBorder("ABCDEF");
+ label.setBorder(new TitledBorder(border));
+
+ if (useLAF) {
+ UIManager.setLookAndFeel(new NimbusLookAndFeel());
+ } else {
+ UIManager.getDefaults().put("LabelUI", MetalLabelUI.class.getName());
+ }
+
+ SwingUtilities.updateComponentTreeUI(label);
+
+ paintToImage(label);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void paintToImage(JComponent comp) {
+ BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = image.createGraphics();
+ comp.paint(g);
+ g.dispose();
+ }
+
+ public static class TestLookAndFeel extends MetalLookAndFeel {
+
+ @Override
+ protected void initClassDefaults(UIDefaults table) {
+ super.initClassDefaults(table);
+ table.put("LabelUI", TestLabelUI.class.getName());
+ }
+ }
+
+ public static class TestLabelUI extends MetalLabelUI implements UIResource {
+
+ public static ComponentUI createUI(JComponent c) {
+ return new TestLabelUI();
+ }
+
+ @Override
+ public void paint(Graphics g, JComponent c) {
+ super.paint(g, c);
+ throw new RuntimeException("New LabelUI is not installed!");
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/TableView/I18nLayoutTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8133864
+ * @summary Wrong display, when the document I18n properties is true.
+ * @author Semyon Sadetsky
+ * @run main I18nLayoutTest
+ */
+
+import javax.swing.*;
+import javax.swing.text.*;
+import java.awt.*;
+import java.util.ArrayList;
+
+public class I18nLayoutTest extends JFrame {
+
+ private static int height;
+ JEditorPane edit = new JEditorPane();
+ private static I18nLayoutTest frame;
+
+ public I18nLayoutTest() {
+ super("Code example for a TableView bug");
+ setUndecorated(true);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ edit.setEditorKit(new CodeBugEditorKit());
+ initCodeBug();
+ this.getContentPane().add(new JScrollPane(edit));
+ this.pack();
+ this.setLocationRelativeTo(null);
+
+ }
+
+ private void initCodeBug() {
+ CodeBugDocument doc = (CodeBugDocument) edit.getDocument();
+ try {
+ doc.insertString(0, "TextB TextE", null);
+ } catch (BadLocationException ex) {
+ }
+ doc.insertTable(6, 4, 3);
+ try {
+ doc.insertString(7, "Cell11", null);
+ doc.insertString(14, "Cell12", null);
+ doc.insertString(21, "Cell13", null);
+ doc.insertString(28, "Cell21", null);
+ doc.insertString(35, "Cell22", null);
+ doc.insertString(42, "Cell23", null);
+ doc.insertString(49, "Cell31", null);
+ doc.insertString(56, "Cell32", null);
+ doc.insertString(63, "Cell33", null);
+ doc.insertString(70, "Cell41", null);
+ doc.insertString(77, "Cell42", null);
+ doc.insertString(84, "Cell43", null);
+ } catch (BadLocationException ex) {
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ frame = new I18nLayoutTest();
+ frame.setVisible(true);
+ }
+ });
+ Robot robot = new Robot();
+ robot.delay(200);
+ robot.waitForIdle();
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ height = frame.getHeight();
+ }
+ });
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ frame.dispose();
+ }
+ });
+ if (height < 32) {
+ throw new RuntimeException(
+ "TableView layout height is wrong " + height);
+ }
+ System.out.println("ok");
+ }
+}
+
+//------------------------------------------------------------------------------
+class CodeBugEditorKit extends StyledEditorKit {
+
+ ViewFactory defaultFactory = new TableFactory();
+
+ @Override
+ public ViewFactory getViewFactory() {
+ return defaultFactory;
+ }
+
+ @Override
+ public Document createDefaultDocument() {
+ return new CodeBugDocument();
+ }
+}
+//------------------------------------------------------------------------------
+
+class TableFactory implements ViewFactory {
+
+ @Override
+ public View create(Element elem) {
+ String kind = elem.getName();
+ if (kind != null) {
+ if (kind.equals(AbstractDocument.ContentElementName)) {
+ return new LabelView(elem);
+ } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
+ return new ParagraphView(elem);
+ } else if (kind.equals(AbstractDocument.SectionElementName)) {
+ return new BoxView(elem, View.Y_AXIS);
+ } else if (kind.equals(StyleConstants.ComponentElementName)) {
+ return new ComponentView(elem);
+ } else if (kind.equals(CodeBugDocument.ELEMENT_TABLE)) {
+ return new tableView(elem);
+ } else if (kind.equals(StyleConstants.IconElementName)) {
+ return new IconView(elem);
+ }
+ }
+ // default to text display
+ return new LabelView(elem);
+
+ }
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+class tableView extends TableView implements ViewFactory {
+
+ public tableView(Element elem) {
+ super(elem);
+ }
+
+ @Override
+ public void setParent(View parent) {
+ super.setParent(parent);
+ }
+
+ @Override
+ public void setSize(float width, float height) {
+ super.setSize(width, height);
+ }
+
+ @Override
+ public ViewFactory getViewFactory() {
+ return this;
+ }
+
+ @Override
+ public float getMinimumSpan(int axis) {
+ return getPreferredSpan(axis);
+ }
+
+ @Override
+ public float getMaximumSpan(int axis) {
+ return getPreferredSpan(axis);
+ }
+
+ @Override
+ public float getAlignment(int axis) {
+ return 0.5f;
+ }
+
+ @Override
+ public float getPreferredSpan(int axis) {
+ if (axis == 0) return super.getPreferredSpan(0);
+ float preferredSpan = super.getPreferredSpan(axis);
+ return preferredSpan;
+ }
+
+ @Override
+ public void paint(Graphics g, Shape allocation) {
+ super.paint(g, allocation);
+ Rectangle alloc = allocation.getBounds();
+ int lastY = alloc.y + alloc.height - 1;
+ g.drawLine(alloc.x, lastY, alloc.x + alloc.width, lastY);
+ }
+
+ @Override
+ protected void paintChild(Graphics g, Rectangle alloc, int index) {
+ super.paintChild(g, alloc, index);
+ int lastX = alloc.x + alloc.width;
+ g.drawLine(alloc.x, alloc.y, lastX, alloc.y);
+ }
+
+ @Override
+ public View create(Element elem) {
+ String kind = elem.getName();
+ if (kind != null) {
+ if (kind.equals(CodeBugDocument.ELEMENT_TR)) {
+ return new trView(elem);
+ } else if (kind.equals(CodeBugDocument.ELEMENT_TD)) {
+ return new BoxView(elem, View.Y_AXIS);
+
+ }
+ }
+
+ // default is to delegate to the normal factory
+ View p = getParent();
+ if (p != null) {
+ ViewFactory f = p.getViewFactory();
+ if (f != null) {
+ return f.create(elem);
+ }
+ }
+
+ return null;
+ }
+
+ public class trView extends TableRow {
+ @Override
+ public void setParent(View parent) {
+ super.setParent(parent);
+ }
+
+ public trView(Element elem) {
+ super(elem);
+ }
+
+ public float getMinimumSpan(int axis) {
+ return getPreferredSpan(axis);
+ }
+
+ public float getMaximumSpan(int axis) {
+ return getPreferredSpan(axis);
+ }
+
+ public float getAlignment(int axis) {
+ return 0f;
+ }
+
+ @Override
+ protected void paintChild(Graphics g, Rectangle alloc, int index) {
+ super.paintChild(g, alloc, index);
+ int lastY = alloc.y + alloc.height - 1;
+ g.drawLine(alloc.x, alloc.y, alloc.x, lastY);
+ int lastX = alloc.x + alloc.width;
+ g.drawLine(lastX, alloc.y, lastX, lastY);
+ }
+ }
+
+ ;
+}
+
+//------------------------------------------------------------------------------
+class CodeBugDocument extends DefaultStyledDocument {
+
+ public static final String ELEMENT_TABLE = "table";
+ public static final String ELEMENT_TR = "table cells row";
+ public static final String ELEMENT_TD = "table data cell";
+
+ public CodeBugDocument() {
+ putProperty("i18n", Boolean.TRUE);
+ }
+
+
+ protected void insertTable(int offset, int rowCount, int colCount) {
+ try {
+ ArrayList Specs = new ArrayList();
+ ElementSpec gapTag = new ElementSpec(new SimpleAttributeSet(),
+ ElementSpec.ContentType, "\n".toCharArray(), 0, 1);
+ Specs.add(gapTag);
+
+ SimpleAttributeSet tableAttrs = new SimpleAttributeSet();
+ tableAttrs.addAttribute(ElementNameAttribute, ELEMENT_TABLE);
+ ElementSpec tableStart =
+ new ElementSpec(tableAttrs, ElementSpec.StartTagType);
+ Specs.add(tableStart); //start table tag
+
+
+ fillRowSpecs(Specs, rowCount, colCount);
+
+ ElementSpec[] spec = new ElementSpec[Specs.size()];
+ Specs.toArray(spec);
+
+ this.insert(offset, spec);
+ } catch (BadLocationException ex) {
+ }
+ }
+
+ protected void fillRowSpecs(ArrayList Specs, int rowCount, int colCount) {
+ SimpleAttributeSet rowAttrs = new SimpleAttributeSet();
+ rowAttrs.addAttribute(ElementNameAttribute, ELEMENT_TR);
+ for (int i = 0; i < rowCount; i++) {
+ ElementSpec rowStart =
+ new ElementSpec(rowAttrs, ElementSpec.StartTagType);
+ Specs.add(rowStart);
+
+ fillCellSpecs(Specs, colCount);
+
+ ElementSpec rowEnd =
+ new ElementSpec(rowAttrs, ElementSpec.EndTagType);
+ Specs.add(rowEnd);
+ }
+
+ }
+
+ protected void fillCellSpecs(ArrayList Specs, int colCount) {
+ for (int i = 0; i < colCount; i++) {
+ SimpleAttributeSet cellAttrs = new SimpleAttributeSet();
+ cellAttrs.addAttribute(ElementNameAttribute, ELEMENT_TD);
+
+ ElementSpec cellStart =
+ new ElementSpec(cellAttrs, ElementSpec.StartTagType);
+ Specs.add(cellStart);
+
+ ElementSpec parStart = new ElementSpec(new SimpleAttributeSet(),
+ ElementSpec.StartTagType);
+ Specs.add(parStart);
+ ElementSpec parContent = new ElementSpec(new SimpleAttributeSet(),
+ ElementSpec.ContentType, "\n".toCharArray(), 0, 1);
+ Specs.add(parContent);
+ ElementSpec parEnd = new ElementSpec(new SimpleAttributeSet(),
+ ElementSpec.EndTagType);
+ Specs.add(parEnd);
+ ElementSpec cellEnd =
+ new ElementSpec(cellAttrs, ElementSpec.EndTagType);
+ Specs.add(cellEnd);
+ }
+ }
+}
\ No newline at end of file
--- a/jdk/test/javax/swing/text/html/HTMLEditorKit/7104635/HTMLEditorKitWriterBug.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/javax/swing/text/html/HTMLEditorKit/7104635/HTMLEditorKitWriterBug.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7104635
+ * @bug 7104635 8150225
* @summary HTMLEditorKit fails to write down some html files
* @run main HTMLEditorKitWriterBug
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/text/rtf/RTFWriteParagraphAlignTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ @bug 8139215
+ @summary RTFEditorKit does not save alignment
+ @author Semyon Sadetsky
+ */
+
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.text.rtf.RTFEditorKit;
+import java.awt.*;
+import java.io.*;
+
+public class RTFWriteParagraphAlignTest {
+
+ public static final String RTF_DATA[] = {
+ "{\\rtf1\\ansi\\ansicpg1252\\" +
+ "cocoartf949\\cocoasubrtf350" +
+ "{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}" +
+ "{\\colortbl;\\red255\\green255\\blue255;}" +
+ "\\margl1440\\margr1440\\vieww9000\\viewh8400\\viewkind0" +
+ "\\pard\\ql\\pardirnatural" +
+ "\\f0\\fs24 \\cf0 left}",
+ "{\\rtf1\\ansi\\ansicpg1252\\" +
+ "cocoartf949\\cocoasubrtf350" +
+ "{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}" +
+ "{\\colortbl;\\red255\\green255\\blue255;}" +
+ "\\margl1440\\margr1440\\vieww9000\\viewh8400\\viewkind0" +
+ "\\pard\\qc\\pardirnatural" +
+ "\\f0\\fs24 \\cf0 center}",
+ "{\\rtf1\\ansi\\ansicpg1252\\" +
+ "cocoartf949\\cocoasubrtf350" +
+ "{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}" +
+ "{\\colortbl;\\red255\\green255\\blue255;}" +
+ "\\margl1440\\margr1440\\vieww9000\\viewh8400\\viewkind0" +
+ "\\pard\\qr\\pardirnatural" +
+ "\\f0\\fs24 \\cf0 right}",
+ "{\\rtf1\\ansi\\ansicpg1252\\" +
+ "cocoartf949\\cocoasubrtf350" +
+ "{\\fonttbl\\f0\\fswiss\\fcharset0 Helvetica;}" +
+ "{\\colortbl;\\red255\\green255\\blue255;}" +
+ "\\margl1440\\margr1440\\vieww9000\\viewh8400\\viewkind0" +
+ "\\pard\\qj\\pardirnatural" +
+ "\\f0\\fs24 \\cf0 justifiedtextjustifiedtext " +
+ "justifiedtextjustifiedtext justifiedtextjustifiedtext " +
+ "justifiedtextjustifiedtext justifiedtextjustifiedtext }",
+ };
+ private static JFrame frame;
+ private static JTextPane jTextPane;
+ private static int position1;
+ private static int position2;
+ private static RTFEditorKit rtfEditorKit;
+ private static Robot robot;
+
+ public static void main(String[] args) throws Exception{
+ rtfEditorKit = new RTFEditorKit();
+ robot = new Robot();
+
+ SwingUtilities.invokeAndWait(() -> {
+ frame = new JFrame();
+ frame.setUndecorated(true);
+ frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+ frame.setSize(600, 200);
+ jTextPane = new JTextPane();
+ frame.getContentPane().add(jTextPane);
+ frame.setVisible(true);
+ });
+
+ test(StyleConstants.ALIGN_LEFT);
+ test(StyleConstants.ALIGN_CENTER);
+ test(StyleConstants.ALIGN_RIGHT);
+ test(StyleConstants.ALIGN_JUSTIFIED);
+
+ SwingUtilities.invokeAndWait(()->frame.dispose());
+
+ System.out.println("ok");
+ }
+
+ static void test(int align) throws Exception {
+ SwingUtilities.invokeAndWait(()->{
+ jTextPane.setDocument(rtfEditorKit.createDefaultDocument());
+ try {
+ rtfEditorKit.read(new ByteArrayInputStream(RTF_DATA[align].
+ getBytes()), jTextPane.getDocument(), 0);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ robot.waitForIdle();
+ SwingUtilities.invokeAndWait(()->{
+ try {
+ int endOffset = jTextPane.getDocument().getRootElements()[0].
+ getElement(0).getEndOffset();
+ position1 = jTextPane.modelToView(endOffset - 1).x;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ File tempFile = File.createTempFile("aaaa", ".rtf");
+ tempFile.deleteOnExit();
+ rtfEditorKit.write(new FileOutputStream(tempFile),
+ jTextPane.getDocument(), 0, jTextPane.getDocument().getLength());
+ Document d = rtfEditorKit.createDefaultDocument();
+ rtfEditorKit.read(new FileInputStream(tempFile), d, 0);
+ SwingUtilities.invokeAndWait(() -> jTextPane.setDocument(d));
+
+ robot.waitForIdle();
+ SwingUtilities.invokeAndWait(()->{
+ try {
+ int endOffset = jTextPane.getDocument().getRootElements()[0].
+ getElement(0).getEndOffset();
+ position2 = jTextPane.modelToView(endOffset-1).x;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ if (position1 != position2) {
+ throw new RuntimeException("Alignment is not preserved after the " +
+ "document write/read");
+ }
+ }
+}
--- a/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java Thu Apr 07 11:03:59 2016 -0700
@@ -26,7 +26,7 @@
* @summary Verify the defining class loader of each module never delegates
* to its child class loader. Also sanity check java.compact2
* requires.
- * @run testng VerifyModuleDelegation
+ * @run testng/othervm -Djdk.launcher.addmods=ALL-SYSTEM VerifyModuleDelegation
*/
import java.lang.module.ModuleDescriptor;
--- a/jdk/test/sun/java2d/marlin/CrashNaNTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/java2d/marlin/CrashNaNTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -21,14 +21,22 @@
* questions.
*/
+import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
import java.awt.geom.Path2D;
+import java.awt.geom.PathIterator;
import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
+import static java.lang.Double.NEGATIVE_INFINITY;
+import static java.lang.Double.POSITIVE_INFINITY;
import static java.lang.Double.NaN;
+import java.util.Arrays;
import java.util.Locale;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
@@ -37,8 +45,9 @@
/**
* @test
- * @bug 8149338
- * @summary Verifies that Marlin supports NaN coordinates and no JVM crash happens !
+ * @bug 8149338 8144938
+ * @summary Verifies that Marlin supports NaN coordinates (no JVM crash)
+ * but also it skips properly point coordinates with NaN / Infinity values
* @run main CrashNaNTest
*/
public class CrashNaNTest {
@@ -77,23 +86,108 @@
System.setProperty("sun.java2d.renderer.useLogger", "true");
System.setProperty("sun.java2d.renderer.doChecks", "true");
+ testFillDefaultAt();
+ testDrawComplexAt();
+
+ testPathClosed();
+
+ testStrokedShapes();
+ }
+
+ private static void testFillDefaultAt() {
final int width = 400;
final int height = 400;
final BufferedImage image = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_ARGB);
+ BufferedImage.TYPE_INT_ARGB);
final Graphics2D g2d = (Graphics2D) image.getGraphics();
try {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
- RenderingHints.VALUE_ANTIALIAS_ON);
+ RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setBackground(Color.WHITE);
g2d.clearRect(0, 0, width, height);
final Path2D.Double path = new Path2D.Double();
- path.moveTo(30, 30);
- path.lineTo(100, 100);
+ path.moveTo(100, 100);
+
+ for (int i = 0; i < 20000; i++) {
+ path.lineTo(110 + 0.01 * i, 110);
+ path.lineTo(111 + 0.01 * i, 100);
+ }
+
+ path.lineTo(NaN, 200);
+ path.lineTo(200, 200);
+ path.lineTo(200, NaN);
+ path.lineTo(300, 300);
+ path.lineTo(NaN, NaN);
+ path.lineTo(100, 200);
+ path.closePath();
+
+ final Path2D.Double path2 = new Path2D.Double();
+ path2.moveTo(0, 0);
+ path2.lineTo(100, height);
+ path2.lineTo(0, 200);
+ path2.closePath();
+
+ g2d.setColor(Color.BLUE);
+ g2d.fill(path);
+ g2d.setColor(Color.GREEN);
+ g2d.fill(path2);
+
+ g2d.setColor(Color.BLACK);
+ g2d.draw(path);
+ g2d.draw(path2);
+
+ if (SAVE_IMAGE) {
+ try {
+ final File file = new File("CrashNaNTest-fill.png");
+ System.out.println("Writing file: "
+ + file.getAbsolutePath());
+ ImageIO.write(image, "PNG", file);
+ } catch (IOException ex) {
+ System.out.println("Writing file failure:");
+ ex.printStackTrace();
+ }
+ }
+
+ // Check image on few pixels:
+ final Raster raster = image.getData();
+
+ checkPixel(raster, 200, 195, Color.BLUE.getRGB());
+ checkPixel(raster, 105, 195, Color.BLUE.getRGB());
+ checkPixel(raster, 286, 290, Color.BLUE.getRGB());
+
+ checkPixel(raster, 108, 105, Color.WHITE.getRGB());
+ checkPixel(raster, 205, 200, Color.WHITE.getRGB());
+
+ checkPixel(raster, 5, 200, Color.GREEN.getRGB());
+
+ } finally {
+ g2d.dispose();
+ }
+ }
+
+ private static void testDrawComplexAt() {
+ final int width = 400;
+ final int height = 400;
+
+ final BufferedImage image = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_ARGB);
+
+ final Graphics2D g2d = (Graphics2D) image.getGraphics();
+ try {
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
+ RenderingHints.VALUE_STROKE_PURE);
+
+ g2d.setBackground(Color.WHITE);
+ g2d.clearRect(0, 0, width, height);
+
+ final Path2D.Double path = new Path2D.Double();
+ path.moveTo(100, 100);
for (int i = 0; i < 20000; i++) {
path.lineTo(110 + 0.01 * i, 110);
@@ -105,39 +199,224 @@
path.lineTo(200, NaN);
path.lineTo(300, 300);
path.lineTo(NaN, NaN);
- path.lineTo(100, 100);
+ path.lineTo(100, 200);
path.closePath();
final Path2D.Double path2 = new Path2D.Double();
- path2.moveTo(0,0);
- path2.lineTo(width,height);
- path2.lineTo(10, 10);
+ path2.moveTo(0, 0);
+ path2.lineTo(100, height);
+ path2.lineTo(0, 200);
path2.closePath();
- for (int i = 0; i < 1; i++) {
- final long start = System.nanoTime();
- g2d.setColor(Color.BLUE);
- g2d.fill(path);
+ // Define an non-uniform transform:
+ g2d.scale(0.5, 1.0);
+ g2d.rotate(Math.PI / 31);
- g2d.fill(path2);
-
- final long time = System.nanoTime() - start;
- System.out.println("paint: duration= " + (1e-6 * time) + " ms.");
- }
+ g2d.setColor(Color.BLACK);
+ g2d.draw(path);
+ g2d.draw(path2);
if (SAVE_IMAGE) {
try {
- final File file = new File("CrashNaNTest.png");
+ final File file = new File("CrashNaNTest-draw.png");
System.out.println("Writing file: "
- + file.getAbsolutePath());
+ + file.getAbsolutePath());
+ ImageIO.write(image, "PNG", file);
+ } catch (IOException ex) {
+ System.out.println("Writing file failure:");
+ ex.printStackTrace();
+ }
+ }
+
+ // Check image on few pixels:
+ final Raster raster = image.getData();
+
+ checkPixelNotWhite(raster, 40, 210);
+ checkPixelNotWhite(raster, 44, 110);
+ checkPixelNotWhite(raster, 60, 120);
+ checkPixelNotWhite(raster, 89, 219);
+ checkPixelNotWhite(raster, 28, 399);
+ checkPixelNotWhite(raster, 134, 329);
+
+ } finally {
+ g2d.dispose();
+ }
+ }
+ private static void testPathClosed() {
+ final int width = 100;
+ final int height = 100;
+
+ final BufferedImage image = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_ARGB);
+
+ final Graphics2D g2d = (Graphics2D) image.getGraphics();
+ try {
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ g2d.setBackground(Color.WHITE);
+ g2d.clearRect(0, 0, width, height);
+
+ final Path2D.Double path = new Path2D.Double();
+ path.moveTo(40, 40);
+ path.lineTo(0, 0);
+ path.lineTo(80, 0);
+ path.closePath();
+ path.lineTo(80, 80);
+ path.lineTo(0, 80);
+ path.closePath();
+
+ g2d.setColor(Color.BLUE);
+ g2d.fill(path);
+
+ g2d.setColor(Color.BLACK);
+ g2d.draw(path);
+
+ if (SAVE_IMAGE) {
+ try {
+ final File file = new File("CrashNaNTest-path-closed.png");
+ System.out.println("Writing file: "
+ + file.getAbsolutePath());
ImageIO.write(image, "PNG", file);
} catch (IOException ex) {
System.out.println("Writing file failure:");
ex.printStackTrace();
}
}
+
+ // Check image on few pixels:
+ final Raster raster = image.getData();
+
+ checkPixel(raster, 10, 05, Color.BLUE.getRGB());
+ checkPixel(raster, 70, 05, Color.BLUE.getRGB());
+ checkPixel(raster, 40, 35, Color.BLUE.getRGB());
+
+ checkPixel(raster, 10, 75, Color.BLUE.getRGB());
+ checkPixel(raster, 70, 75, Color.BLUE.getRGB());
+ checkPixel(raster, 40, 45, Color.BLUE.getRGB());
+
} finally {
g2d.dispose();
}
}
+
+ private static void testStrokedShapes() {
+ final Stroke stroke = new BasicStroke();
+
+ final Path2D.Double path = new Path2D.Double();
+ Shape s;
+
+ // Check filtering NaN values:
+ path.reset();
+ path.moveTo(100, NaN);
+ path.lineTo(NaN, 100);
+ path.lineTo(NaN, NaN);
+
+ path.quadTo(NaN, 100, NaN, 100);
+ path.quadTo(100, NaN, 100, NaN);
+ path.quadTo(NaN, NaN, NaN, NaN);
+
+ path.curveTo(NaN, 100, NaN, 100, NaN, 100);
+ path.curveTo(100, NaN, 100, NaN, 100, NaN);
+ path.curveTo(NaN, NaN, NaN, NaN, NaN, NaN);
+ path.closePath();
+
+ s = stroke.createStrokedShape(path);
+ checkEmptyPath(s);
+
+ // Check filtering +Infinity values:
+ path.reset();
+ path.moveTo(100, POSITIVE_INFINITY);
+ path.lineTo(POSITIVE_INFINITY, 100);
+ path.lineTo(POSITIVE_INFINITY, POSITIVE_INFINITY);
+
+ path.quadTo(POSITIVE_INFINITY, 100,
+ POSITIVE_INFINITY, 100);
+ path.quadTo(100, POSITIVE_INFINITY,
+ 100, POSITIVE_INFINITY);
+ path.quadTo(POSITIVE_INFINITY, POSITIVE_INFINITY,
+ POSITIVE_INFINITY, POSITIVE_INFINITY);
+
+ path.curveTo(POSITIVE_INFINITY, 100,
+ POSITIVE_INFINITY, 100,
+ POSITIVE_INFINITY, 100);
+ path.curveTo(100, POSITIVE_INFINITY,
+ 100, POSITIVE_INFINITY,
+ 100, POSITIVE_INFINITY);
+ path.curveTo(POSITIVE_INFINITY, POSITIVE_INFINITY,
+ POSITIVE_INFINITY, POSITIVE_INFINITY,
+ POSITIVE_INFINITY, POSITIVE_INFINITY);
+ path.closePath();
+
+ s = stroke.createStrokedShape(path);
+ checkEmptyPath(s);
+
+ // Check filtering -Infinity values:
+ path.reset();
+ path.moveTo(100, NEGATIVE_INFINITY);
+ path.lineTo(NEGATIVE_INFINITY, 100);
+ path.lineTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY);
+
+ path.quadTo(NEGATIVE_INFINITY, 100,
+ NEGATIVE_INFINITY, 100);
+ path.quadTo(100, NEGATIVE_INFINITY,
+ 100, NEGATIVE_INFINITY);
+ path.quadTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY,
+ NEGATIVE_INFINITY, NEGATIVE_INFINITY);
+
+ path.curveTo(NEGATIVE_INFINITY, 100,
+ NEGATIVE_INFINITY, 100,
+ NEGATIVE_INFINITY, 100);
+ path.curveTo(100, NEGATIVE_INFINITY,
+ 100, NEGATIVE_INFINITY,
+ 100, NEGATIVE_INFINITY);
+ path.curveTo(NEGATIVE_INFINITY, NEGATIVE_INFINITY,
+ NEGATIVE_INFINITY, NEGATIVE_INFINITY,
+ NEGATIVE_INFINITY, NEGATIVE_INFINITY);
+ path.closePath();
+
+ s = stroke.createStrokedShape(path);
+ checkEmptyPath(s);
+ }
+
+ private static void checkEmptyPath(final Shape s) {
+ final float[] coords = new float[6];
+ final PathIterator it = s.getPathIterator(null);
+
+ int n = 0;
+ for (; !it.isDone(); it.next()) {
+ int type = it.currentSegment(coords);
+ System.out.println("unexpected segment type= " + type
+ + " with coords: " + Arrays.toString(coords));
+ n++;
+ }
+ if (n != 0) {
+ System.out.println("path elements = " + n);
+ throw new IllegalStateException("Not empty path: "
+ + n + " path elements !");
+ }
+ }
+
+ private static void checkPixel(final Raster raster,
+ final int x, final int y,
+ final int expected) {
+
+ final int[] rgb = (int[]) raster.getDataElements(x, y, null);
+
+ if (rgb[0] != expected) {
+ throw new IllegalStateException("bad pixel at (" + x + ", " + y
+ + ") = " + rgb[0] + " expected: " + expected);
+ }
+ }
+
+ private static void checkPixelNotWhite(final Raster raster,
+ final int x, final int y) {
+
+ final int[] rgb = (int[]) raster.getDataElements(x, y, null);
+
+ if (rgb[0] == Color.WHITE.getRGB()) {
+ throw new IllegalStateException("bad pixel at (" + x + ", " + y
+ + ") is white (empty)");
+ }
+ }
}
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh Thu Apr 07 11:03:59 2016 -0700
@@ -51,7 +51,8 @@
DEBUGOPTIONS=""
export DEBUGOPTIONS
-EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED,java.management/sun.management.jmxremote=ALL-UNNAMED"
+EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED \
+ -XaddExports:java.management/sun.management.jmxremote=ALL-UNNAMED"
export EXTRAOPTIONS
# Call the common generic test
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh Thu Apr 07 11:03:59 2016 -0700
@@ -49,7 +49,8 @@
DEBUGOPTIONS=""
export DEBUGOPTIONS
-EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED,java.management/sun.management.jmxremote=ALL-UNNAMED"
+EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED \
+ -XaddExports:java.management/sun.management.jmxremote=ALL-UNNAMED"
export EXTRAOPTIONS
# Call the common generic test
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh Thu Apr 07 11:03:59 2016 -0700
@@ -48,7 +48,8 @@
DEBUGOPTIONS=""
export DEBUGOPTIONS
-EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED,java.management/sun.management.jmxremote=ALL-UNNAMED"
+EXTRAOPTIONS="-XaddExports:java.management/sun.management=ALL-UNNAMED \
+ -XaddExports:java.management/sun.management.jmxremote=ALL-UNNAMED"
export EXTRAOPTIONS
# Call the common generic test
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/ftp/FtpURLConnectionLeak.java Thu Apr 07 11:03:59 2016 -0700
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 7167293
+ * @summary FtpURLConnection doesn't close FTP connection when FileNotFoundException is thrown
+ * @library ../www/ftptest/
+ * @build FtpServer FtpCommandHandler FtpAuthHandler FtpFileSystemHandler
+ * @run main FtpURLConnectionLeak
+ */
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+
+public class FtpURLConnectionLeak {
+
+ public static void main(String[] args) throws Exception {
+ FtpServer server = new FtpServer(0);
+ server.setFileSystemHandler(new CustomFileSystemHandler("/"));
+ server.setAuthHandler(new MyAuthHandler());
+ int port = server.getLocalPort();
+ server.start();
+ URL url = new URL("ftp://localhost:" + port + "/filedoesNotExist.txt");
+ for (int i = 0; i < 3; i++) {
+ try {
+ InputStream stream = url.openStream();
+ } catch (FileNotFoundException expectedFirstTimeAround) {
+ // should always reach this point since the path does not exist
+ } catch (IOException expected) {
+ System.out.println("caught expected " + expected);
+ int times = 1;
+ do {
+ // give some time to close the connection...
+ System.out.println("sleeping... " + times);
+ Thread.sleep(times * 1000);
+ } while (server.activeClientsCount() > 0 && times++ < 5);
+
+ if (server.activeClientsCount() > 0) {
+ server.killClients();
+ throw new RuntimeException("URLConnection didn't close the" +
+ " FTP connection on FileNotFoundException");
+ }
+ } finally {
+ server.terminate();
+ }
+ }
+ }
+
+ static class CustomFileSystemHandler implements FtpFileSystemHandler {
+
+ private String currentDir;
+
+ public CustomFileSystemHandler(String path) {
+ currentDir = path;
+ }
+
+ @Override
+ public boolean cd(String path) {
+ currentDir = path;
+ return true;
+ }
+
+ @Override
+ public boolean cdUp() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String pwd() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean fileExists(String name) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream getFile(String name) {
+ return null; //return null so that server will return 550 File not found.
+ }
+
+ @Override
+ public long getFileSize(String name) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public InputStream listCurrentDir() {
+ return null;
+ }
+
+ @Override
+ public OutputStream putFile(String name) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean removeFile(String name) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean mkdir(String name) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean rename(String from, String to) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ }
+
+ static class MyAuthHandler implements FtpAuthHandler {
+
+ @Override
+ public int authType() {
+ return 0;
+ }
+
+ @Override
+ public boolean authenticate(String user, String password) {
+ return true;
+ }
+
+ @Override
+ public boolean authenticate(String user, String password, String account) {
+ return true;
+ }
+ }
+}
--- a/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/net/www/ftptest/FtpCommandHandler.java Thu Apr 07 11:03:59 2016 -0700
@@ -442,7 +442,9 @@
// cmd.setSoTimeout(2000);
in = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
out = new PrintStream(cmd.getOutputStream(), true, "ISO8859_1");
- out.println("220 Java FTP test server (j2se 6.0) ready.");
+ out.println("---------------------------------\n220 Java FTP test server"
+ + " (j2se 6.0) ready.\n \n Please send commands\n"
+ + "-----------------------------\n\n\n");
out.flush();
if (auth.authType() == 0) // No auth needed
logged = true;
--- a/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java Thu Apr 07 11:03:59 2016 -0700
@@ -68,9 +68,10 @@
// (neither on standard output, nor on standard err streams).
JavaVM vm = new JavaVM(
DoRMIStuff.class.getName(),
- "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED,"
- + "java.rmi/sun.rmi.server=ALL-UNNAMED,java.rmi/sun.rmi.transport=ALL-UNNAMED,"
- + "java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED"
+ "-XaddExports:java.rmi/sun.rmi.registry=ALL-UNNAMED"
+ + " -XaddExports:java.rmi/sun.rmi.server=ALL-UNNAMED"
+ + " -XaddExports:java.rmi/sun.rmi.transport=ALL-UNNAMED"
+ + " -XaddExports:java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED"
+ " -Djava.util.logging.config.file="
+ loggingPropertiesFile, "", out, err);
vm.execute();
--- a/jdk/test/sun/security/krb5/tools/ktcheck.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/security/krb5/tools/ktcheck.sh Thu Apr 07 11:03:59 2016 -0700
@@ -61,7 +61,8 @@
EXTRA_OPTIONS="-Djava.security.krb5.conf=${TESTSRC}${FS}onlythree.conf"
KTAB="${TESTJAVA}${FS}bin${FS}ktab -J${EXTRA_OPTIONS} -k $KEYTAB -f"
CHECK="${TESTJAVA}${FS}bin${FS}java -cp ${TESTCLASSES} ${TESTVMOPTS} ${EXTRA_OPTIONS} \
- -XaddExports:java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED,java.security.jgss/sun.security.krb5=ALL-UNNAMED \
+ -XaddExports:java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED \
+ -XaddExports:java.security.jgss/sun.security.krb5=ALL-UNNAMED \
KtabCheck $KEYTAB"
echo ${EXTRA_OPTIONS}
--- a/jdk/test/sun/security/tools/jarsigner/ts.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/security/tools/jarsigner/ts.sh Thu Apr 07 11:03:59 2016 -0700
@@ -95,7 +95,11 @@
$KT -alias ca -gencert -ext eku:critical=cs | \
$KT -alias tsbad3 -importcert
-EXTRAOPTS="-XaddExports:java.base/sun.misc=ALL-UNNAMED,java.base/sun.security.pkcs=ALL-UNNAMED,java.base/sun.security.timestamp=ALL-UNNAMED,java.base/sun.security.x509=ALL-UNNAMED,java.base/sun.security.util=ALL-UNNAMED"
+EXTRAOPTS="-XaddExports:java.base/sun.misc=ALL-UNNAMED \
+ -XaddExports:java.base/sun.security.pkcs=ALL-UNNAMED \
+ -XaddExports:java.base/sun.security.timestamp=ALL-UNNAMED \
+ -XaddExports:java.base/sun.security.x509=ALL-UNNAMED \
+ -XaddExports:java.base/sun.security.util=ALL-UNNAMED"
$JAVAC ${EXTRAOPTS} -d . ${TESTSRC}/TimestampCheck.java
$JAVA ${TESTVMOPTS} ${EXTRAOPTS} "-Dtest.tool.vm.opts=${TESTTOOLVMOPTS}" TimestampCheck
--- a/jdk/test/sun/security/tools/keytool/autotest.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/security/tools/keytool/autotest.sh Thu Apr 07 11:03:59 2016 -0700
@@ -100,7 +100,9 @@
echo "Using NSS lib at $LIBNAME"
-EXTRAOPTS="-XaddExports:java.base/sun.security.tools.keytool=ALL-UNNAMED,java.base/sun.security.util=ALL-UNNAMED,java.base/sun.security.x509=ALL-UNNAMED"
+EXTRAOPTS="-XaddExports:java.base/sun.security.tools.keytool=ALL-UNNAMED \
+ -XaddExports:java.base/sun.security.util=ALL-UNNAMED \
+ -XaddExports:java.base/sun.security.x509=ALL-UNNAMED"
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . -XDignore.symbol.file \
${TESTSRC}${FS}KeyToolTest.java || exit 10
--- a/jdk/test/sun/security/tools/keytool/standard.sh Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/sun/security/tools/keytool/standard.sh Thu Apr 07 11:03:59 2016 -0700
@@ -57,7 +57,9 @@
;;
esac
-EXTRAOPTS="-XaddExports:java.base/sun.security.tools.keytool=ALL-UNNAMED,java.base/sun.security.util=ALL-UNNAMED,java.base/sun.security.x509=ALL-UNNAMED"
+EXTRAOPTS="-XaddExports:java.base/sun.security.tools.keytool=ALL-UNNAMED \
+ -XaddExports:java.base/sun.security.util=ALL-UNNAMED \
+ -XaddExports:java.base/sun.security.x509=ALL-UNNAMED"
${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} ${EXTRAOPTS} -d . -XDignore.symbol.file ${TESTSRC}${FS}KeyToolTest.java || exit 10
--- a/jdk/test/tools/jimage/VerifyJimage.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/tools/jimage/VerifyJimage.java Thu Apr 07 11:03:59 2016 -0700
@@ -49,6 +49,7 @@
* @test
* @summary Verify jimage
* @modules java.base/jdk.internal.jimage
+ * @run main/othervm -Djdk.launcher.addmods=ALL-SYSTEM VerifyJimage
*/
/**
--- a/jdk/test/tools/launcher/modules/patch/PatchTest.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/tools/launcher/modules/patch/PatchTest.java Thu Apr 07 11:03:59 2016 -0700
@@ -128,18 +128,15 @@
// value for -Xpatch
String patchPath = PATCHES1_DIR + File.pathSeparator + PATCHES2_DIR;
- // value for -XaddExports
- String addExportsValue = "java.base/java.lang2=test"
- + ",jdk.naming.dns/com.sun.jndi.dns=test"
- + ",jdk.naming.dns/com.sun.jndi.dns2=test"
- + ",jdk.compiler/com.sun.tools.javac2=test";
-
// the argument to the test is the list of classes overridden or added
String arg = Stream.of(CLASSES).collect(Collectors.joining(","));
int exitValue
= executeTestJava("-Xpatch:" + patchPath,
- "-XaddExports:" + addExportsValue,
+ "-XaddExports:java.base/java.lang2=test",
+ "-XaddExports:jdk.naming.dns/com.sun.jndi.dns=test",
+ "-XaddExports:jdk.naming.dns/com.sun.jndi.dns2=test",
+ "-XaddExports:jdk.compiler/com.sun.tools.javac2=test",
"-addmods", "jdk.naming.dns,jdk.compiler",
"-mp", MODS_DIR.toString(),
"-m", "test/jdk.test.Main", arg)
--- a/jdk/test/tools/pack200/ModuleAttributes.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/tools/pack200/ModuleAttributes.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, 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
@@ -39,38 +39,10 @@
}
public void run() throws Exception {
- File file = createModuleJar();
+ File file = Utils.createRtJar(".*module-info\\.class");
Utils.testWithRepack(file,
"--effort=1",
"--unknown-attribute=error");
- }
-
- File createModuleJar() throws IOException {
- File libDir = new File(Utils.JavaHome, "lib");
- File modules = new File(libDir, "modules");
- File outDir = new File("out");
-
- List<String> cmdList = new ArrayList<>();
- cmdList.add(Utils.getJimageCmd());
- cmdList.add("extract");
- cmdList.add(modules.getAbsolutePath());
- cmdList.add("--dir");
- cmdList.add(outDir.getName());
- Utils.runExec(cmdList);
-
- FileFilter filter = (File file) -> file.getName().equals("module-info.class");
- List<File> mfiles = Utils.findFiles(outDir, filter);
-
- List<String> contents = new ArrayList<>(mfiles.size());
- mfiles.stream().forEach((f) -> {
- contents.add(f.getAbsolutePath());
- });
-
- File listFile = new File("mfiles.list");
- Utils.createFile(listFile, contents);
- File testFile = new File("test.jar");
- Utils.jar("cvf", testFile.getName(), "@" + listFile.getName());
- Utils.recursiveDelete(outDir);
- return testFile;
+ Utils.cleanup();
}
}
--- a/jdk/test/tools/pack200/Pack200Props.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/tools/pack200/Pack200Props.java Thu Apr 07 11:03:59 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -31,13 +31,13 @@
*/
import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.Pack200;
import java.util.jar.Pack200.Packer;
+import java.util.logging.Logger;
/*
* Run this against a large jar file, by default the packer should generate only
@@ -46,20 +46,22 @@
public class Pack200Props {
- public static void main(String... args) throws IOException {
+ final static Logger log = Logger.getLogger("Pack200Props");
+
+ public static void main(String... args) throws Exception {
verifyDefaults();
File out = new File("test" + Utils.PACK_FILE_EXT);
out.delete();
verifySegmentLimit(out);
+ log.info("cleanup");
Utils.cleanup();
}
- static void verifySegmentLimit(File outFile) throws IOException {
- File sdkHome = Utils.JavaSDK;
+ static void verifySegmentLimit(File outFile) throws Exception {
+ log.info("creating jar");
File testJar = Utils.createRtJar();
- System.out.println("using pack200: " + Utils.getPack200Cmd());
-
+ log.info("using pack200: " + Utils.getPack200Cmd());
List<String> cmdsList = new ArrayList<>();
cmdsList.add(Utils.getPack200Cmd());
cmdsList.add("-J-Xshare:off");
@@ -71,6 +73,7 @@
cmdsList.add(testJar.getAbsolutePath());
List<String> outList = Utils.runExec(cmdsList);
+ log.info("verifying");
int count = 0;
for (String line : outList) {
System.out.println(line);
@@ -78,6 +81,7 @@
count++;
}
}
+ log.info("fini");
if (count == 0) {
throw new RuntimeException("no segments or no output ????");
} else if (count > 1) {
@@ -86,6 +90,7 @@
}
private static void verifyDefaults() {
+ log.info("start");
Map<String, String> expectedDefaults = new HashMap<>();
Packer p = Pack200.newPacker();
expectedDefaults.put("com.sun.java.util.jar.pack.disable.native",
@@ -121,6 +126,7 @@
}
}
}
+ log.info("fini");
if (errors > 0) {
throw new RuntimeException(errors +
" error(s) encountered in default properties verification");
--- a/jdk/test/tools/pack200/Utils.java Thu Apr 07 10:07:02 2016 -0700
+++ b/jdk/test/tools/pack200/Utils.java Thu Apr 07 11:03:59 2016 -0700
@@ -32,22 +32,33 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
+import java.net.URI;
+import java.net.URL;
import java.nio.charset.Charset;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.HashMap;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Pack200;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static java.nio.file.StandardCopyOption.*;
import static java.nio.file.StandardOpenOption.*;
+
/**
*
* @author ksrini
@@ -544,10 +555,6 @@
return getAjavaCmd("jar");
}
- static String getJimageCmd() {
- return getAjavaCmd("jimage");
- }
-
static String getAjavaCmd(String cmdStr) {
File binDir = new File(JavaHome, "bin");
File unpack200File = IsWindows
@@ -562,29 +569,88 @@
return cmd;
}
- static File createRtJar() throws IOException {
- File libDir = new File(JavaHome, "lib");
- File modules = new File(libDir, "modules");
- List<String> cmdList = new ArrayList<>();
- cmdList.add(getJimageCmd());
- cmdList.add("extract");
- cmdList.add(modules.getAbsolutePath());
- cmdList.add("--dir");
- cmdList.add("out");
- runExec(cmdList);
-
+ // used to get all classes
+ static File createRtJar() throws Exception {
File rtJar = new File("rt.jar");
- cmdList.clear();
- cmdList.add(getJarCmd());
- // cmdList.add("cvf"); too noisy
- cmdList.add("cf");
- cmdList.add(rtJar.getName());
- cmdList.add("-C");
- cmdList.add("out");
- cmdList.add(".");
- runExec(cmdList);
+ new JrtToZip(".*\\.class", rtJar).run();
+ return rtJar;
+ }
- recursiveDelete(new File("out"));
+ // used to select the contents
+ static File createRtJar(String pattern) throws Exception {
+ File rtJar = new File("rt.jar");
+ new JrtToZip(pattern, rtJar).run();
return rtJar;
}
+
+ /*
+ * A helper class to create a pseudo rt.jar.
+ */
+ static class JrtToZip {
+
+ final File outFile;
+ final Pattern pattern;
+
+ public static void main(String[] args) throws Exception {
+ new JrtToZip(args[0], new File(args[1])).run();
+ }
+
+ JrtToZip(String pattern, File outFile) throws Exception {
+ this.pattern = Pattern.compile(pattern);
+ this.outFile = outFile;
+ }
+
+ void run() throws Exception {
+ URI uri = URI.create("jar:" + outFile.toURI());
+ Map<String, String> env = new HashMap<>();
+ env.put("create", "true");
+ try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
+ toZipfs(zipfs);
+ }
+ }
+
+ void toZipfs(FileSystem zipfs) throws Exception {
+ FileSystem jrtfs = FileSystems.getFileSystem(URI.create("jrt:/"));
+ for (Path root : jrtfs.getRootDirectories()) {
+ Files.walkFileTree(root, new FileVisitor<Path>() {
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir,
+ BasicFileAttributes attrs) throws IOException {
+ // ignore unneeded directory
+ if (dir.startsWith("/packages"))
+ return FileVisitResult.SKIP_SUBTREE;
+
+ // pre-create required directories
+ Path zpath = zipfs.getPath(dir.toString());
+ Files.createDirectories(zpath);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file,
+ BasicFileAttributes attrs) throws IOException {
+ Matcher matcher = pattern.matcher(file.toString());
+ if (matcher.matches()) {
+ // System.out.println("x: " + file);
+ Path zpath = zipfs.getPath(file.toString());
+ Files.copy(file, zpath, REPLACE_EXISTING);
+ }
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFileFailed(Path file,
+ IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir,
+ IOException exc) throws IOException {
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ }
+ }
}