--- a/.hgtags-top-repo Thu Aug 21 09:55:18 2008 -0700
+++ b/.hgtags-top-repo Wed Jul 05 16:40:18 2017 +0200
@@ -7,3 +7,4 @@
2dab2f712e1832c92acfa63ec0337048b9422c20 jdk7-b30
3300a35a0bd56d695b92fe0b34f03ebbfc939064 jdk7-b31
64da805be725721bf2004e7409a0d7a16fc8ddbc jdk7-b32
+bb1ef4ee3d2c8cbf43a37d372325a7952be590b9 jdk7-b33
--- a/Makefile Thu Aug 21 09:55:18 2008 -0700
+++ b/Makefile Wed Jul 05 16:40:18 2017 +0200
@@ -74,7 +74,7 @@
all::
@$(START_ECHO)
-all:: openjdk_check sanity all_product_build
+all:: openjdk_check sanity
ifeq ($(SKIP_FASTDEBUG_BUILD), false)
all:: fastdebug_build
@@ -88,6 +88,8 @@
all:: openjdk_build
endif
+all:: all_product_build
+
all::
@$(FINISH_ECHO)
--- a/hotspot/.hgtags Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/.hgtags Wed Jul 05 16:40:18 2017 +0200
@@ -7,3 +7,4 @@
d1605aabd0a15ecf93787c47de63073c33fba52d jdk7-b30
9c2ecc2ffb125f14fab3857fe7689598956348a0 jdk7-b31
b727c32788a906c04839516ae7443a085185a300 jdk7-b32
+585535ec8a14adafa6bfea65d6975e29094c8cec jdk7-b33
--- a/hotspot/agent/make/Makefile Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/Makefile Wed Jul 05 16:40:18 2017 +0200
@@ -32,6 +32,12 @@
include $(GAMMADIR)/make/defs.make
endif
+ifeq "x$(HOTSPOT_BUILD_VERSION)" "x"
+SA_BUILD_VERSION=$(HOTSPOT_RELEASE_VERSION)
+else
+SA_BUILD_VERSION=$(HOTSPOT_RELEASE_VERSION)-$(HOTSPOT_BUILD_VERSION)
+endif
+
PKGLIST = \
sun.jvm.hotspot \
sun.jvm.hotspot.asm \
@@ -117,7 +123,9 @@
sun.jvm.hotspot.ui.treetable \
sun.jvm.hotspot.utilities \
sun.jvm.hotspot.utilities.memo \
-sun.jvm.hotspot.utilities.soql
+sun.jvm.hotspot.utilities.soql \
+com.sun.java.swing.action \
+com.sun.java.swing.ui
#END PKGLIST
# Generated using the build-filelist script
@@ -198,7 +206,9 @@
sun/jvm/hotspot/ui/treetable/*.java \
sun/jvm/hotspot/utilities/*.java \
sun/jvm/hotspot/utilities/memo/*.java \
-sun/jvm/hotspot/utilities/soql/*.java
+sun/jvm/hotspot/utilities/soql/*.java \
+com/sun/java/swing/action/*.java \
+com/sun/java/swing/ui/*.java
#END FILELIST
ifneq "x$(ALT_BOOTDIR)" "x"
@@ -220,8 +230,6 @@
endif
SRC_DIR = ../src/share/classes
-LIB_DIR = ../src/share/lib
-CLOSED_LIB_DIR = ../closed/src/share/lib
BUILD_DIR = ../build
OUTPUT_DIR = $(BUILD_DIR)/classes
DOC_DIR = $(BUILD_DIR)/doc
@@ -231,9 +239,9 @@
ALLFILES := $(patsubst %,$(SRC_DIR)/%,$(FILELIST))
ALLFILES := $(shell /bin/ls $(ALLFILES))
+# tools.jar is used by the sa-jdi binding
+CLASSPATH = $(JDK_HOME)/lib/tools.jar
-# tools.jar is needed by the JDI - SA binding
-CLASSPATH = $(LIB_DIR)/maf-1_0.jar$(CPS)$(JDK_HOME)/lib/tools.jar
CLASSPATH := $(subst \,/,$(CLASSPATH))
# FIXME: autogenerate call to rmic
@@ -241,24 +249,36 @@
SA_BUILD_VERSION_PROP = "sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)"
SA_PROPERTIES = $(OUTPUT_DIR)/sa.properties
+JAVAC = $(JDK_HOME)/bin/javac
+JAVADOC = $(JDK_HOME)/bin/javadoc
+RMIC = $(JDK_HOME)/bin/rmic
# Tagging it on because there's no reason not to run it
all: filelist
@mkdir -p $(OUTPUT_DIR)
@echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
- @${JDK_HOME}/bin/javac -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
- @${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
+ $(JAVAC) -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
+ $(RMIC) -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js
cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql
+ mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources
+ rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/*
+ cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/
+ cp -r $(SRC_DIR)/images/* $(OUTPUT_DIR)/
allprof: filelist
@mkdir -p $(OUTPUT_DIR)
@echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
- @${JDK_HOME}/bin/javac -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
- @${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
+ $(JAVAC) -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
+ $(RMIC) -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js
cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql
+ mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources
+ rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/*
+ cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/
+ cp -r $(SRC_DIR)/images/* $(OUTPUT_DIR)/
+.PHONY: filelist
filelist: $(ALLFILES)
@if [ ! -f $(JDK_HOME)/lib/tools.jar ] ; then \
echo "Missing $(JDK_HOME)/lib/tools.jar file. Use 1.6.0 or later version jdk to build SA."; \
@@ -274,36 +294,23 @@
.PHONY: sa-jdi.jar
sa-jdi.jar:
- if [ ! -f $(JDK_HOME)/lib/tools.jar ] ; then \
- echo "Missing $(JDK_HOME)/lib/tools.jar file. Use 1.6.0 or later version jdk to build SA.";\
- exit 1; \
- fi
- rm -f $(BUILD_DIR)/sa-jdi.jar
- rm -f $(OUTPUT_DIR)/jdi_class_files
- javac -source 1.4 ClosureFinder.java -d $(OUTPUT_DIR)
- cd $(OUTPUT_DIR) ; find sun/jvm/hotspot/jdi -name "*.class" > jdi_class_files
- cd $(OUTPUT_DIR) ; jar cvf ../sa-jdi.jar `java ClosureFinder jdi_class_files .`
- cd $(BUILD_DIR) ; jar uvf sa-jdi.jar -C $(SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
- cd $(BUILD_DIR) ; jar uvf sa-jdi.jar -C $(OUTPUT_DIR) sa.properties
- rm -f $(OUTPUT_DIR)/ClosureFinder.class
- rm -f $(OUTPUT_DIR)/jdi_class_files
+ echo "sa-jdi.jar is built by a hotspot build."
docs:
- @javadoc -private -classpath $(CLASSPATH) -sourcepath $(SRC_DIR) -d $(DOC_DIR) $(PKGLIST)
+ @$(JAVADOC) -private -classpath $(CLASSPATH) -sourcepath $(SRC_DIR) -d $(DOC_DIR) $(PKGLIST)
sizes: $(ALLFILES)
wc -l $(ALLFILES)
cscope: $(ALLFILES)
+ rm -f java.files
echo $(ALLFILES) > java.files
cscope -b -i java.files -f java.out
+ rm -f java.files
.PHONY: sa.jar
sa.jar:
rm -f $(BUILD_DIR)/sa.jar
- mkdir -p $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources
- rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/*
- cp $(SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(OUTPUT_DIR)/sun/jvm/hotspot/ui/resources/
cd $(OUTPUT_DIR) ; jar cvf ../sa.jar *
clean::
--- a/hotspot/agent/make/bugspot.bat Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/bugspot.bat Wed Jul 05 16:40:18 2017 +0200
@@ -22,4 +22,4 @@
REM
REM
-java -showversion -cp ..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main
+java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main
--- a/hotspot/agent/make/build.xml Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/build.xml Wed Jul 05 16:40:18 2017 +0200
@@ -42,7 +42,6 @@
<property name="app.name" value="sa"/>
<property name="dist.jar" value="${app.name}.jar"/>
- <property name="libs" value="../src/share/lib"/>
<property name="classes" value="../build/classes"/>
<!-- The "prepare" target is used to construct the deployment home
@@ -83,11 +82,6 @@
home directory structure will be created if needed the first time.
-->
- <path id="javac.classpath">
- <pathelement path="${libs}/maf-1_0.jar" />
- <pathelement path="${libs}/jlfgr-1_0.jar" />
- </path>
-
<target name="compile" depends="prepare" description="Compiles the sources">
<javac srcdir="../src/share/classes"
destdir="${classes}"
@@ -110,6 +104,18 @@
<copy todir="${classes}/sun/jvm/hotspot/ui/resources">
<fileset dir="../src/share/classes/sun/jvm/hotspot/ui/resources" includes="*.png" />
</copy>
+ <copy todir="${classes}/toolbarButtonGraphics/development/">
+ <fileset dir="../src/share/classes/images/toolbarButtonGraphics/development/" includes="*.gif" />
+ </copy>
+ <copy todir="${classes}/toolbarButtonGraphics/general/">
+ <fileset dir="../src/share/classes/images/toolbarButtonGraphics/general/" includes="*.gif" />
+ </copy>
+ <copy todir="${classes}/toolbarButtonGraphics/navigation/">
+ <fileset dir="../src/share/classes/images/toolbarButtonGraphics/navigation/" includes="*.gif" />
+ </copy>
+ <copy todir="${classes}/toolbarButtonGraphics/text/">
+ <fileset dir="../src/share/classes/images/toolbarButtonGraphics/text/" includes="*.gif" />
+ </copy>
<jar jarfile="${classes}/${dist.jar}"
basedir="${classes}"/>
--- a/hotspot/agent/make/hsdb.bat Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/hsdb.bat Wed Jul 05 16:40:18 2017 +0200
@@ -22,4 +22,4 @@
REM
REM
-java -showversion -cp ..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar sun.jvm.hotspot.HSDB %1 %2
+java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.HSDB %1 %2
--- a/hotspot/agent/make/hsdb.sh Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/hsdb.sh Wed Jul 05 16:40:18 2017 +0200
@@ -29,4 +29,4 @@
SA_JAVA=java
fi
-$SA_JAVA -showversion -cp $STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar sun.jvm.hotspot.HSDB $*
+$SA_JAVA -showversion -cp $STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/js.jar sun.jvm.hotspot.HSDB $*
--- a/hotspot/agent/make/saenv.bat Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/saenv.bat Wed Jul 05 16:40:18 2017 +0200
@@ -39,7 +39,7 @@
:sa_java_set
-set SA_CLASSPATH=..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar
+set SA_CLASSPATH=..\build\classes;..\src\share\lib\js.jar;sa.jar;lib\js.jar
set SA_LIBPATH=..\src\os\win32\windbg\i386;.\win32\i386
--- a/hotspot/agent/make/saenv.sh Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/saenv.sh Wed Jul 05 16:40:18 2017 +0200
@@ -58,7 +58,7 @@
fi
-SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar
+SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/js.jar
OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}"
--- a/hotspot/agent/make/saenv64.bat Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/saenv64.bat Wed Jul 05 16:40:18 2017 +0200
@@ -43,7 +43,7 @@
:sa_java_set
-set SA_CLASSPATH=..\build\classes;..\src\share\lib\maf-1_0.jar;..\src\share\lib\jlfgr-1_0.jar;..\src\share\lib\js.jar;sa.jar;lib\maf-1_0.jar;lib\jlfgr-1_0.jar;lib\js.jar
+set SA_CLASSPATH=..\build\classes;..\src\share\lib\js.jar;sa.jar;lib\js.jar
REM For now, only AMD-64, IA-64 stack walking is not working anyway
set SA_LIBPATH=.\src\os\win32\windbg\amd64;.\win32\amd64
--- a/hotspot/agent/make/saenv64.sh Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/make/saenv64.sh Wed Jul 05 16:40:18 2017 +0200
@@ -55,7 +55,7 @@
OPTIONS="-Dsun.jvm.hotspot.runtime.VM.disableVersionCheck ${OPTIONS}"
fi
-SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/maf-1_0.jar:$STARTDIR/../src/share/lib/jlfgr-1_0.jar:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar:$STARTDIR/lib/maf-1_0.jar:$STARTDIR/lib/jlfgr-1_0.jar:$STARTDIR/lib/js.jar
+SA_CLASSPATH=$STARTDIR/../build/classes:$STARTDIR/../src/share/lib/js.jar:$STARTDIR/sa.jar::$STARTDIR/lib/js.jar
OPTIONS="-Djava.system.class.loader=sun.jvm.hotspot.SALauncherLoader ${OPTIONS}"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AboutAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class AboutAction extends DelegateAction
+{
+
+ public AboutAction()
+ {
+ this("general/About16.gif");
+ }
+
+ public AboutAction(String iconPath)
+ {
+ super("About...", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "about-command");
+ putValue("ShortDescription", "About...");
+ putValue("LongDescription", "System information and version of the application.");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ }
+
+ public static final String VALUE_COMMAND = "about-command";
+ public static final String VALUE_NAME = "About...";
+ public static final String VALUE_SMALL_ICON = "general/About16.gif";
+ public static final String VALUE_LARGE_ICON = "general/About24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(65);
+ public static final String VALUE_SHORT_DESCRIPTION = "About...";
+ public static final String VALUE_LONG_DESCRIPTION = "System information and version of the application.";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionManager.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import java.util.HashMap;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, StateChangeAction, ActionUtilities
+
+public abstract class ActionManager
+{
+
+ protected ActionManager()
+ {
+ actions = new HashMap();
+ addActions();
+ }
+
+ public static ActionManager getInstance()
+ {
+ return manager;
+ }
+
+ protected abstract void addActions();
+
+ protected void addAction(String cmdname, Action action)
+ {
+ actions.put(cmdname, action);
+ }
+
+ public Action getAction(String key)
+ {
+ return (Action)actions.get(key);
+ }
+
+ public DelegateAction getDelegateAction(String name)
+ {
+ Action a = getAction(name);
+ if(a instanceof DelegateAction)
+ return (DelegateAction)a;
+ else
+ return null;
+ }
+
+ public StateChangeAction getStateChangeAction(String name)
+ {
+ Action a = getAction(name);
+ if(a instanceof StateChangeAction)
+ return (StateChangeAction)a;
+ else
+ return null;
+ }
+
+ public static ImageIcon getIcon(String name)
+ {
+ return utilities.getIcon(name);
+ }
+
+ public void setActionEnabled(String name, boolean enabled)
+ {
+ Action action = getAction(name);
+ if(action != null)
+ action.setEnabled(enabled);
+ }
+
+ private HashMap actions;
+ private static ActionUtilities utilities = new ActionUtilities();
+ protected static ActionManager manager;
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ActionUtilities.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.ImageIcon;
+
+class ActionUtilities
+{
+
+ ActionUtilities()
+ {
+ }
+
+ public ImageIcon getIcon(String name)
+ {
+ String imagePath = "/toolbarButtonGraphics/" + name;
+ java.net.URL url = getClass().getResource(imagePath);
+ if(url != null)
+ return new ImageIcon(url);
+ else
+ return null;
+ }
+
+ public static final String IMAGE_DIR = "/toolbarButtonGraphics/";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignCenterAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// StateChangeAction, ActionManager
+
+public class AlignCenterAction extends StateChangeAction
+{
+
+ public AlignCenterAction()
+ {
+ this("text/AlignCenter16.gif");
+ }
+
+ public AlignCenterAction(String iconPath)
+ {
+ super("Center", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "align-center-command");
+ putValue("ShortDescription", "Center");
+ putValue("LongDescription", "Adjust the placement of text to the center of the line");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "align-center-command";
+ public static final String VALUE_NAME = "Center";
+ public static final String VALUE_SMALL_ICON = "text/AlignCenter16.gif";
+ public static final String VALUE_LARGE_ICON = "text/AlignCenter24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(78);
+ public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(69, 2);
+ public static final String VALUE_SHORT_DESCRIPTION = "Center";
+ public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text to the center of the line";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignLeftAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// StateChangeAction, ActionManager
+
+public class AlignLeftAction extends StateChangeAction
+{
+
+ public AlignLeftAction()
+ {
+ this("text/AlignLeft16.gif");
+ }
+
+ public AlignLeftAction(String iconPath)
+ {
+ super("Left Align", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "align-left-command");
+ putValue("ShortDescription", "Left Align");
+ putValue("LongDescription", "Adjust the placement of text along the left edge");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "align-left-command";
+ public static final String VALUE_NAME = "Left Align";
+ public static final String VALUE_SMALL_ICON = "text/AlignLeft16.gif";
+ public static final String VALUE_LARGE_ICON = "text/AlignLeft24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(76);
+ public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(76, 2);
+ public static final String VALUE_SHORT_DESCRIPTION = "Left Align";
+ public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text along the left edge";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/AlignRightAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// StateChangeAction, ActionManager
+
+public class AlignRightAction extends StateChangeAction
+{
+
+ public AlignRightAction()
+ {
+ this("text/AlignRight16.gif");
+ }
+
+ public AlignRightAction(String iconPath)
+ {
+ super("Right Align", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "align-right-command");
+ putValue("ShortDescription", "Right Align");
+ putValue("LongDescription", "Adjust the placement of text along the right edge");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "align-right-command";
+ public static final String VALUE_NAME = "Right Align";
+ public static final String VALUE_SMALL_ICON = "text/AlignRight16.gif";
+ public static final String VALUE_LARGE_ICON = "text/AlignRight24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(82);
+ public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(82, 2);
+ public static final String VALUE_SHORT_DESCRIPTION = "Right Align";
+ public static final String VALUE_LONG_DESCRIPTION = "Adjust the placement of text along the right edge";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ApplyAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class ApplyAction extends DelegateAction
+{
+
+ public ApplyAction()
+ {
+ this(VALUE_SMALL_ICON);
+ }
+
+ public ApplyAction(String iconPath)
+ {
+ super("Apply", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "apply-command");
+ putValue("ShortDescription", "Apply the activity");
+ putValue("LongDescription", "Apply the activity");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "apply-command";
+ public static final String VALUE_NAME = "Apply";
+ public static final String VALUE_SMALL_ICON = null;
+ public static final String VALUE_LARGE_ICON = null;
+ public static final Integer VALUE_MNEMONIC = new Integer(65);
+ public static final KeyStroke VALUE_ACCELERATOR = null;
+ public static final String VALUE_SHORT_DESCRIPTION = "Apply the activity";
+ public static final String VALUE_LONG_DESCRIPTION = "Apply the activity";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/BackAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class BackAction extends DelegateAction
+{
+
+ public BackAction()
+ {
+ this(VALUE_SMALL_ICON);
+ }
+
+ public BackAction(String iconPath)
+ {
+ super("< Back", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "back-command");
+ putValue("ShortDescription", "Select previous item");
+ putValue("LongDescription", "Select previous item");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "back-command";
+ public static final String VALUE_NAME = "< Back";
+ public static final String VALUE_SMALL_ICON = null;
+ public static final String VALUE_LARGE_ICON = null;
+ public static final Integer VALUE_MNEMONIC = new Integer(66);
+ public static final KeyStroke VALUE_ACCELERATOR = null;
+ public static final String VALUE_SHORT_DESCRIPTION = "Select previous item";
+ public static final String VALUE_LONG_DESCRIPTION = "Select previous item";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/CancelAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class CancelAction extends DelegateAction
+{
+
+ public CancelAction()
+ {
+ this(VALUE_SMALL_ICON);
+ }
+
+ public CancelAction(String iconPath)
+ {
+ super("Cancel", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "cancel-command");
+ putValue("ShortDescription", "Cancels the action");
+ putValue("LongDescription", "Cancels the action");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "cancel-command";
+ public static final String VALUE_NAME = "Cancel";
+ public static final String VALUE_SMALL_ICON = null;
+ public static final String VALUE_LARGE_ICON = null;
+ public static final Integer VALUE_MNEMONIC = new Integer(67);
+ public static final KeyStroke VALUE_ACCELERATOR = null;
+ public static final String VALUE_SHORT_DESCRIPTION = "Cancels the action";
+ public static final String VALUE_LONG_DESCRIPTION = "Cancels the action";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/DelegateAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.AbstractAction;
+import javax.swing.Icon;
+
+public abstract class DelegateAction extends AbstractAction
+{
+
+ public DelegateAction(String name, Icon icon)
+ {
+ super(name, icon);
+ }
+
+ public void addActionListener(ActionListener listener)
+ {
+ this.listener = listener;
+ }
+
+ public void removeActionListener(ActionListener listener)
+ {
+ this.listener = null;
+ }
+
+ public ActionListener[] getActionListeners()
+ {
+ return (new ActionListener[] {
+ listener
+ });
+ }
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ if(listener != null)
+ listener.actionPerformed(evt);
+ }
+
+ private ActionListener listener;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ExitAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class ExitAction extends DelegateAction
+{
+
+ public ExitAction()
+ {
+ super("Exit", ActionManager.getIcon(VALUE_SMALL_ICON));
+ putValue("ActionCommandKey", "exit-command");
+ putValue("ShortDescription", "Exits the application");
+ putValue("LongDescription", "Exits the application");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "exit-command";
+ public static final String VALUE_NAME = "Exit";
+ public static final String VALUE_SMALL_ICON = null;
+ public static final String VALUE_LARGE_ICON = null;
+ public static final Integer VALUE_MNEMONIC = new Integer(88);
+ public static final KeyStroke VALUE_ACCELERATOR = null;
+ public static final String VALUE_SHORT_DESCRIPTION = "Exits the application";
+ public static final String VALUE_LONG_DESCRIPTION = "Exits the application";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FileMenu.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+
+public class FileMenu extends AbstractAction
+{
+
+ public FileMenu()
+ {
+ super("File");
+ putValue("ActionCommandKey", "file-menu-command");
+ putValue("ShortDescription", "File operations");
+ putValue("LongDescription", "File operations");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ }
+
+ public void actionPerformed(ActionEvent actionevent)
+ {
+ }
+
+ public static final String VALUE_COMMAND = "file-menu-command";
+ public static final String VALUE_NAME = "File";
+ public static final Integer VALUE_MNEMONIC = new Integer(70);
+ public static final String VALUE_SHORT_DESCRIPTION = "File operations";
+ public static final String VALUE_LONG_DESCRIPTION = "File operations";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/FinishAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class FinishAction extends DelegateAction
+{
+
+ public FinishAction()
+ {
+ this(VALUE_SMALL_ICON);
+ }
+
+ public FinishAction(String iconPath)
+ {
+ super("Finish", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "finish-command");
+ putValue("ShortDescription", "Finish the activity");
+ putValue("LongDescription", "Finish the activity");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "finish-command";
+ public static final String VALUE_NAME = "Finish";
+ public static final String VALUE_SMALL_ICON = null;
+ public static final String VALUE_LARGE_ICON = null;
+ public static final Integer VALUE_MNEMONIC = new Integer(70);
+ public static final KeyStroke VALUE_ACCELERATOR = null;
+ public static final String VALUE_SHORT_DESCRIPTION = "Finish the activity";
+ public static final String VALUE_LONG_DESCRIPTION = "Finish the activity";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class HelpAction extends DelegateAction
+{
+
+ public HelpAction()
+ {
+ this("general/Help16.gif");
+ }
+
+ public HelpAction(String iconPath)
+ {
+ super("Help", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "help-command");
+ putValue("ShortDescription", "Help...");
+ putValue("LongDescription", "Provide information which may aid the user.");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "help-command";
+ public static final String VALUE_NAME = "Help";
+ public static final String VALUE_SMALL_ICON = "general/Help16.gif";
+ public static final String VALUE_LARGE_ICON = "general/Help24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(72);
+ public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(112, 0);
+ public static final String VALUE_SHORT_DESCRIPTION = "Help...";
+ public static final String VALUE_LONG_DESCRIPTION = "Provide information which may aid the user.";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/HelpMenu.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+
+public class HelpMenu extends AbstractAction
+{
+
+ public HelpMenu()
+ {
+ super("Help");
+ putValue("ActionCommandKey", "help-menu-command");
+ putValue("ShortDescription", "Help operations");
+ putValue("LongDescription", "Help operations");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ }
+
+ public void actionPerformed(ActionEvent actionevent)
+ {
+ }
+
+ public static final String VALUE_COMMAND = "help-menu-command";
+ public static final String VALUE_NAME = "Help";
+ public static final Integer VALUE_MNEMONIC = new Integer(72);
+ public static final String VALUE_SHORT_DESCRIPTION = "Help operations";
+ public static final String VALUE_LONG_DESCRIPTION = "Help operations";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NewAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class NewAction extends DelegateAction
+{
+
+ public NewAction()
+ {
+ this("general/New16.gif");
+ }
+
+ public NewAction(String iconPath)
+ {
+ super("New", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "new-command");
+ putValue("ShortDescription", "Create a new object.");
+ putValue("LongDescription", "Create a new object.");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "new-command";
+ public static final String VALUE_NAME = "New";
+ public static final String VALUE_SMALL_ICON = "general/New16.gif";
+ public static final String VALUE_LARGE_ICON = "general/New24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(78);
+ public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(78, 2);
+ public static final String VALUE_SHORT_DESCRIPTION = "Create a new object.";
+ public static final String VALUE_LONG_DESCRIPTION = "Create a new object.";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/NextAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class NextAction extends DelegateAction
+{
+
+ public NextAction()
+ {
+ this(VALUE_SMALL_ICON);
+ }
+
+ public NextAction(String iconPath)
+ {
+ super("Next >", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "next-command");
+ putValue("ShortDescription", "Select next item");
+ putValue("LongDescription", "Select next item");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "next-command";
+ public static final String VALUE_NAME = "Next >";
+ public static final String VALUE_SMALL_ICON = null;
+ public static final String VALUE_LARGE_ICON = null;
+ public static final Integer VALUE_MNEMONIC = new Integer(78);
+ public static final KeyStroke VALUE_ACCELERATOR = null;
+ public static final String VALUE_SHORT_DESCRIPTION = "Select next item";
+ public static final String VALUE_LONG_DESCRIPTION = "Select next item";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OkAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class OkAction extends DelegateAction
+{
+
+ public OkAction()
+ {
+ this(VALUE_SMALL_ICON);
+ }
+
+ public OkAction(String iconPath)
+ {
+ super("OK", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "ok-command");
+ putValue("ShortDescription", "Acknowleges the action");
+ putValue("LongDescription", "Acknowleges the action");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "ok-command";
+ public static final String VALUE_NAME = "OK";
+ public static final String VALUE_SMALL_ICON = null;
+ public static final String VALUE_LARGE_ICON = null;
+ public static final Integer VALUE_MNEMONIC = new Integer(79);
+ public static final KeyStroke VALUE_ACCELERATOR = null;
+ public static final String VALUE_SHORT_DESCRIPTION = "Acknowleges the action";
+ public static final String VALUE_LONG_DESCRIPTION = "Acknowleges the action";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/OpenAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class OpenAction extends DelegateAction
+{
+
+ public OpenAction()
+ {
+ this("general/Open16.gif");
+ }
+
+ public OpenAction(String iconPath)
+ {
+ super("Open...", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "open-command");
+ putValue("ShortDescription", "Open the specified object.");
+ putValue("LongDescription", "Open the specified object.");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "open-command";
+ public static final String VALUE_NAME = "Open...";
+ public static final String VALUE_SMALL_ICON = "general/Open16.gif";
+ public static final String VALUE_LARGE_ICON = "general/Open24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(79);
+ public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(79, 2);
+ public static final String VALUE_SHORT_DESCRIPTION = "Open the specified object.";
+ public static final String VALUE_LONG_DESCRIPTION = "Open the specified object.";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import javax.swing.KeyStroke;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class SaveAction extends DelegateAction
+{
+
+ public SaveAction()
+ {
+ this("general/Save16.gif");
+ }
+
+ public SaveAction(String iconPath)
+ {
+ super("Save", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "save-command");
+ putValue("ShortDescription", "Commit changes to a permanent storage area");
+ putValue("LongDescription", "Commit changes to a permanent storage area");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ putValue("AcceleratorKey", VALUE_ACCELERATOR);
+ }
+
+ public static final String VALUE_COMMAND = "save-command";
+ public static final String VALUE_NAME = "Save";
+ public static final String VALUE_SMALL_ICON = "general/Save16.gif";
+ public static final String VALUE_LARGE_ICON = "general/Save24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(83);
+ public static final KeyStroke VALUE_ACCELERATOR = KeyStroke.getKeyStroke(83, 2);
+ public static final String VALUE_SHORT_DESCRIPTION = "Commit changes to a permanent storage area";
+ public static final String VALUE_LONG_DESCRIPTION = "Commit changes to a permanent storage area";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/SaveAsAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction, ActionManager
+
+public class SaveAsAction extends DelegateAction
+{
+
+ public SaveAsAction()
+ {
+ this("general/SaveAs16.gif");
+ }
+
+ public SaveAsAction(String iconPath)
+ {
+ super("Save As", ActionManager.getIcon(iconPath));
+ putValue("ActionCommandKey", "save-as-command");
+ putValue("ShortDescription", "Save as a new file");
+ putValue("LongDescription", "Saves the current object as another object");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ }
+
+ public static final String VALUE_COMMAND = "save-as-command";
+ public static final String VALUE_NAME = "Save As";
+ public static final String VALUE_SMALL_ICON = "general/SaveAs16.gif";
+ public static final String VALUE_LARGE_ICON = "general/SaveAs24.gif";
+ public static final Integer VALUE_MNEMONIC = new Integer(65);
+ public static final String VALUE_SHORT_DESCRIPTION = "Save as a new file";
+ public static final String VALUE_LONG_DESCRIPTION = "Saves the current object as another object";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/StateChangeAction.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import javax.swing.Icon;
+
+// Referenced classes of package com.sun.java.swing.action:
+// DelegateAction
+
+public abstract class StateChangeAction extends DelegateAction
+ implements ItemListener
+{
+
+ public StateChangeAction(String name)
+ {
+ super(name, null);
+ selected = false;
+ }
+
+ public StateChangeAction(String name, Icon icon)
+ {
+ super(name, icon);
+ selected = false;
+ }
+
+ public boolean isSelected()
+ {
+ return selected;
+ }
+
+ public synchronized void setSelected(boolean newValue)
+ {
+ boolean oldValue = selected;
+ if(oldValue != newValue)
+ {
+ selected = newValue;
+ firePropertyChange("selected", Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
+ }
+ }
+
+ public void setItemListener(ItemListener listener)
+ {
+ this.listener = listener;
+ }
+
+ public ItemListener getItemListener()
+ {
+ return listener;
+ }
+
+ public void itemStateChanged(ItemEvent evt)
+ {
+ if(evt.getStateChange() == 1)
+ setSelected(true);
+ else
+ setSelected(false);
+ if(listener != null)
+ listener.itemStateChanged(evt);
+ }
+
+ protected boolean selected;
+ private ItemListener listener;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/action/ViewMenu.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.action;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+
+public class ViewMenu extends AbstractAction
+{
+
+ public ViewMenu()
+ {
+ super("View");
+ putValue("ActionCommandKey", "view-menu-command");
+ putValue("ShortDescription", "View operations");
+ putValue("LongDescription", "View operations");
+ putValue("MnemonicKey", VALUE_MNEMONIC);
+ }
+
+ public void actionPerformed(ActionEvent actionevent)
+ {
+ }
+
+ public static final String VALUE_COMMAND = "view-menu-command";
+ public static final String VALUE_NAME = "View";
+ public static final Integer VALUE_MNEMONIC = new Integer(86);
+ public static final String VALUE_SHORT_DESCRIPTION = "View operations";
+ public static final String VALUE_LONG_DESCRIPTION = "View operations";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonMenuBar.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import com.sun.java.swing.action.ActionManager;
+import com.sun.java.swing.action.StateChangeAction;
+import javax.swing.*;
+
+// Referenced classes of package com.sun.java.swing.ui:
+// ToggleActionPropertyChangeListener, StatusBar
+
+public abstract class CommonMenuBar extends JMenuBar
+{
+
+ protected CommonMenuBar(ActionManager manager)
+ {
+ this(manager, StatusBar.getInstance());
+ }
+
+ protected CommonMenuBar(ActionManager manager, StatusBar status)
+ {
+ this.manager = manager;
+ statusBar = status;
+ configureMenu();
+ }
+
+ protected abstract void configureMenu();
+
+ protected void configureToggleMenuItem(JMenuItem menuItem, Action action)
+ {
+ configureMenuItem(menuItem, action);
+ action.addPropertyChangeListener(new ToggleActionPropertyChangeListener(menuItem));
+ }
+
+ protected void configureMenuItem(JMenuItem menuItem, Action action)
+ {
+ menuItem.addMouseListener(statusBar);
+ }
+
+ protected JMenu createMenu(String name, char mnemonic)
+ {
+ JMenu menu = new JMenu(name);
+ menu.setMnemonic(mnemonic);
+ return menu;
+ }
+
+ protected void addMenuItem(JMenu menu, Action action)
+ {
+ JMenuItem menuItem = menu.add(action);
+ configureMenuItem(menuItem, action);
+ }
+
+ protected void addCheckBoxMenuItem(JMenu menu, StateChangeAction a)
+ {
+ addCheckBoxMenuItem(menu, a, false);
+ }
+
+ protected void addCheckBoxMenuItem(JMenu menu, StateChangeAction a, boolean selected)
+ {
+ JCheckBoxMenuItem mi = new JCheckBoxMenuItem(a);
+ mi.addItemListener(a);
+ mi.setSelected(selected);
+ menu.add(mi);
+ configureToggleMenuItem(mi, a);
+ }
+
+ protected void addRadioButtonMenuItem(JMenu menu, ButtonGroup group, StateChangeAction a)
+ {
+ addRadioButtonMenuItem(menu, group, a, false);
+ }
+
+ protected void addRadioButtonMenuItem(JMenu menu, ButtonGroup group, StateChangeAction a, boolean selected)
+ {
+ JRadioButtonMenuItem mi = new JRadioButtonMenuItem(a);
+ mi.addItemListener(a);
+ mi.setSelected(selected);
+ menu.add(mi);
+ if(group != null)
+ group.add(mi);
+ configureToggleMenuItem(mi, a);
+ }
+
+ protected ActionManager manager;
+ private StatusBar statusBar;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonToolBar.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import com.sun.java.swing.action.ActionManager;
+import com.sun.java.swing.action.StateChangeAction;
+import java.awt.Dimension;
+import java.awt.Insets;
+import javax.swing.*;
+
+// Referenced classes of package com.sun.java.swing.ui:
+// ToggleActionPropertyChangeListener, StatusBar, CommonUI
+
+public abstract class CommonToolBar extends JToolBar
+{
+
+ protected CommonToolBar(ActionManager manager)
+ {
+ this(manager, StatusBar.getInstance());
+ }
+
+ protected CommonToolBar(ActionManager manager, StatusBar status)
+ {
+ this.manager = manager;
+ statusBar = status;
+ buttonSize = new Dimension(CommonUI.buttconPrefSize);
+ buttonInsets = new Insets(0, 0, 0, 0);
+ addComponents();
+ }
+
+ protected abstract void addComponents();
+
+ protected void addButton(Action action)
+ {
+ javax.swing.JButton button = add(action);
+ configureButton(button, action);
+ }
+
+ protected void addToggleButton(StateChangeAction a)
+ {
+ addToggleButton(a, null);
+ }
+
+ protected void addToggleButton(StateChangeAction a, ButtonGroup group)
+ {
+ JToggleButton button = new JToggleButton(a);
+ button.addItemListener(a);
+ button.setSelected(a.isSelected());
+ if(group != null)
+ group.add(button);
+ add(button);
+ configureToggleButton(button, a);
+ }
+
+ protected void configureToggleButton(JToggleButton button, Action action)
+ {
+ configureButton(button, action);
+ action.addPropertyChangeListener(new ToggleActionPropertyChangeListener(button));
+ }
+
+ protected void configureButton(AbstractButton button, Action action)
+ {
+ button.setToolTipText((String)action.getValue("Name"));
+ button.setText("");
+ button.addMouseListener(statusBar);
+ }
+
+ protected ActionManager manager;
+ private Dimension buttonSize;
+ private Insets buttonInsets;
+ private StatusBar statusBar;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/CommonUI.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyListener;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import javax.swing.*;
+import javax.swing.border.Border;
+import javax.swing.text.*;
+
+public class CommonUI
+{
+ private static class NumberDocument extends PlainDocument
+ {
+
+ public void insertString(int offs, String str, AttributeSet atts)
+ throws BadLocationException
+ {
+ if(!Character.isDigit(str.charAt(0)))
+ {
+ return;
+ } else
+ {
+ super.insertString(offs, str, atts);
+ return;
+ }
+ }
+
+ private NumberDocument()
+ {
+ }
+
+ }
+
+
+ public CommonUI()
+ {
+ }
+
+ public static JLabel createLabel(String text, int mnemonic, Component comp)
+ {
+ JLabel label = new JLabel(" " + text);
+ label.setMinimumSize(labelPrefSize);
+ if(mnemonic != -1)
+ label.setDisplayedMnemonic(mnemonic);
+ if(comp != null)
+ label.setLabelFor(comp);
+ if(text.length() == 0)
+ label.setPreferredSize(labelPrefSize);
+ return label;
+ }
+
+ public static JLabel createLabel(String text)
+ {
+ return createLabel(text, -1, null);
+ }
+
+ public static JTextField createTextField(String text, KeyListener listener, boolean numbers)
+ {
+ JTextField field = new JTextField(text);
+ field.setMinimumSize(textPrefSize);
+ if(text.length() == 0)
+ field.setPreferredSize(textPrefSize);
+ if(listener != null)
+ field.addKeyListener(listener);
+ if(numbers)
+ field.setDocument(new NumberDocument());
+ return field;
+ }
+
+ public static JTextField createTextField(String text, boolean numbers)
+ {
+ return createTextField(text, null, numbers);
+ }
+
+ public static JTextField createTextField(String text, KeyListener listener)
+ {
+ return createTextField(text, listener, false);
+ }
+
+ public static JTextField createTextField(String text)
+ {
+ return createTextField(text, null, false);
+ }
+
+ public static JRadioButton createRadioButton(String text, int mnemonic, ActionListener listener, boolean selected)
+ {
+ JRadioButton button = new JRadioButton(text);
+ button.setMnemonic(mnemonic);
+ button.setSelected(selected);
+ button.setMinimumSize(labelPrefSize);
+ if(listener != null)
+ button.addActionListener(listener);
+ if(text.length() == 0)
+ button.setPreferredSize(labelPrefSize);
+ return button;
+ }
+
+ public static JRadioButton createRadioButton(String text, int mnemonic, boolean selected)
+ {
+ return createRadioButton(text, mnemonic, null, selected);
+ }
+
+ public static JRadioButton createRadioButton(String text, int mnemonic, ActionListener listener)
+ {
+ return createRadioButton(text, mnemonic, listener, false);
+ }
+
+ public static JRadioButton createRadioButton(String text, int mnemonic)
+ {
+ return createRadioButton(text, mnemonic, null, false);
+ }
+
+ public static JRadioButton createRadioButton(String text)
+ {
+ return createRadioButton(text, -1, null, false);
+ }
+
+ public static JCheckBox createCheckBox(String text, int mnemonic, ActionListener listener, boolean selected)
+ {
+ JCheckBox checkbox = new JCheckBox(text);
+ checkbox.setMinimumSize(labelPrefSize);
+ if(mnemonic != -1)
+ checkbox.setMnemonic(mnemonic);
+ checkbox.setSelected(selected);
+ if(text.length() == 0)
+ checkbox.setPreferredSize(labelPrefSize);
+ if(listener != null)
+ checkbox.addActionListener(listener);
+ return checkbox;
+ }
+
+ public static JCheckBox createCheckBox(String text, int mnemonic, ActionListener listener)
+ {
+ return createCheckBox(text, mnemonic, listener, false);
+ }
+
+ public static JCheckBox createCheckBox(String text, int mnemonic, boolean selected)
+ {
+ return createCheckBox(text, mnemonic, null, selected);
+ }
+
+ public static JCheckBox createCheckBox(String text, int mnemonic)
+ {
+ return createCheckBox(text, mnemonic, null, false);
+ }
+
+ public static JCheckBox createCheckBox(String text)
+ {
+ return createCheckBox(text, -1, null, false);
+ }
+
+ public static JComboBox createComboBox(Object items[], ActionListener listener, boolean editable)
+ {
+ JComboBox comboBox = new JComboBox(items);
+ if(listener != null)
+ comboBox.addActionListener(listener);
+ comboBox.setEditable(editable);
+ return comboBox;
+ }
+
+ public static JComboBox createComboBox(Object items[], boolean editable)
+ {
+ return createComboBox(items, null, editable);
+ }
+
+ public static JComboBox createComboBox(Vector items, ActionListener listener, boolean editable)
+ {
+ JComboBox comboBox = new JComboBox(items);
+ if(listener != null)
+ comboBox.addActionListener(listener);
+ comboBox.setEditable(editable);
+ return comboBox;
+ }
+
+ public static JComboBox createComboBox(Vector items, boolean editable)
+ {
+ return createComboBox(items, null, editable);
+ }
+
+ public static JButton createButton(Action action)
+ {
+ JButton button = new JButton(action);
+ setButtonSize(button, buttonPrefSize);
+ return button;
+ }
+
+ public static JButton createButton(String text, ActionListener listener, int mnemonic)
+ {
+ JButton button = new JButton(text);
+ if(listener != null)
+ button.addActionListener(listener);
+ if(mnemonic != -1)
+ button.setMnemonic(mnemonic);
+ setButtonSize(button, buttonPrefSize);
+ return button;
+ }
+
+ private static void setButtonSize(JButton button, Dimension size)
+ {
+ String text = button.getText();
+ button.setMinimumSize(size);
+ if(text.length() == 0)
+ {
+ button.setPreferredSize(size);
+ } else
+ {
+ Dimension psize = button.getPreferredSize();
+ if(psize.width < size.width)
+ button.setPreferredSize(size);
+ }
+ }
+
+ public static JButton createButton(String text, ActionListener listener)
+ {
+ return createButton(text, listener, -1);
+ }
+
+ public static JButton createSmallButton(String text, ActionListener listener, int mnemonic)
+ {
+ JButton button = createButton(text, listener, mnemonic);
+ setButtonSize(button, smbuttonPrefSize);
+ return button;
+ }
+
+ public static JButton createSmallButton(String text, ActionListener listener)
+ {
+ return createSmallButton(text, listener, -1);
+ }
+
+ public static Border createBorder(String text)
+ {
+ Border border = BorderFactory.createEtchedBorder();
+ return BorderFactory.createTitledBorder(border, text, 0, 2);
+ }
+
+ public static Border createBorder()
+ {
+ return BorderFactory.createEmptyBorder(4, 4, 4, 4);
+ }
+
+ public static JScrollPane createListPane(JList list, String text)
+ {
+ JScrollPane pane = new JScrollPane(list);
+ pane.setBorder(BorderFactory.createCompoundBorder(createBorder(text), BorderFactory.createLoweredBevelBorder()));
+ return pane;
+ }
+
+ public static void centerComponent(Component source, Component parent)
+ {
+ Dimension dim = source.getSize();
+ Rectangle rect;
+ if(parent != null)
+ {
+ rect = parent.getBounds();
+ } else
+ {
+ Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
+ rect = new Rectangle(0, 0, d.width, d.height);
+ }
+ int x = rect.x + (rect.width - dim.width) / 2;
+ int y = rect.y + (rect.height - dim.height) / 2;
+ source.setLocation(x, y);
+ }
+
+ public static void centerComponent(Component source)
+ {
+ centerComponent(source, null);
+ }
+
+ public static JFrame getParentFrame(Component source)
+ {
+ Container parent;
+ for(parent = source.getParent(); parent != null; parent = parent.getParent())
+ if(parent instanceof JFrame)
+ break;
+
+ if(parent == null)
+ return null;
+ else
+ return (JFrame)parent;
+ }
+
+ public static Integer msToSec(Integer ms)
+ {
+ int value = ms.intValue();
+ value /= 1000;
+ return new Integer(value);
+ }
+
+ public static Integer secToMs(Integer sec)
+ {
+ int value = sec.intValue();
+ value *= 1000;
+ return new Integer(value);
+ }
+
+ public static String stringFromStringArray(String strings[], String delim)
+ {
+ String string = "";
+ String separator;
+ if(delim == null || delim.equals(""))
+ separator = " ";
+ else
+ separator = delim;
+ for(int i = 0; i < strings.length; i++)
+ {
+ string = string + strings[i];
+ string = string + separator;
+ }
+
+ return string;
+ }
+
+ public static String stringFromStringArray(String strings[])
+ {
+ return stringFromStringArray(strings, "");
+ }
+
+ public static String[] stringArrayFromString(String string, String delim)
+ {
+ StringTokenizer st;
+ if(delim == null || delim.equals(""))
+ st = new StringTokenizer(string);
+ else
+ st = new StringTokenizer(string, delim);
+ int numTokens = st.countTokens();
+ String strings[] = new String[numTokens];
+ int index = 0;
+ while(st.hasMoreTokens())
+ strings[index++] = st.nextToken();
+ return strings;
+ }
+
+ public static String[] stringArrayFromString(String string)
+ {
+ return stringArrayFromString(string, "");
+ }
+
+ public static void setWaitCursor(Component comp)
+ {
+ comp.setCursor(Cursor.getPredefinedCursor(3));
+ }
+
+ public static void setDefaultCursor(Component comp)
+ {
+ comp.setCursor(Cursor.getPredefinedCursor(0));
+ }
+
+ public static final int BUTTON_WIDTH = 100;
+ public static final int BUTTON_HEIGHT = 26;
+ public static final int BUTTCON_WIDTH = 28;
+ public static final int BUTTCON_HEIGHT = 28;
+ public static final int SM_BUTTON_WIDTH = 72;
+ public static final int SM_BUTTON_HEIGHT = 26;
+ public static final int LABEL_WIDTH = 100;
+ public static final int LABEL_HEIGHT = 20;
+ public static final int TEXT_WIDTH = 150;
+ public static final int TEXT_HEIGHT = 20;
+ public static Dimension buttonPrefSize = new Dimension(100, 26);
+ public static Dimension buttconPrefSize = new Dimension(28, 28);
+ public static Dimension smbuttonPrefSize = new Dimension(72, 26);
+ public static Dimension labelPrefSize = new Dimension(100, 20);
+ public static Dimension textPrefSize = new Dimension(150, 20);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelButtonPanel.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import com.sun.java.swing.action.*;
+import java.awt.event.ActionListener;
+import javax.swing.JPanel;
+
+// Referenced classes of package com.sun.java.swing.ui:
+// CommonUI
+
+public class OkCancelButtonPanel extends JPanel
+{
+
+ public OkCancelButtonPanel(ActionListener listener)
+ {
+ DelegateAction okAction = new OkAction();
+ okAction.addActionListener(listener);
+ DelegateAction cancelAction = new CancelAction();
+ cancelAction.addActionListener(listener);
+ add(CommonUI.createButton(okAction));
+ add(CommonUI.createButton(cancelAction));
+ }
+
+ public static final String OK_COMMAND = "ok-command";
+ public static final String CANCEL_COMMAND = "cancel-command";
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/OkCancelDialog.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+
+// Referenced classes of package com.sun.java.swing.ui:
+// OkCancelButtonPanel, CommonUI
+
+public class OkCancelDialog extends JDialog
+ implements ActionListener
+{
+
+ public OkCancelDialog(String title, JPanel panel)
+ {
+ this(title, panel, true);
+ }
+
+ public OkCancelDialog(String title, JPanel panel, boolean modal)
+ {
+ setTitle(title);
+ setModal(modal);
+ Container pane = getContentPane();
+ pane.setLayout(new BorderLayout());
+ pane.add(panel, "Center");
+ pane.add(new OkCancelButtonPanel(this), "South");
+ pack();
+ CommonUI.centerComponent(this);
+ }
+
+ public boolean isOk()
+ {
+ return okPressed;
+ }
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ String command = evt.getActionCommand();
+ if(command.equals("ok-command"))
+ {
+ okPressed = true;
+ setVisible(false);
+ dispose();
+ } else
+ if(command.equals("cancel-command"))
+ {
+ okPressed = false;
+ setVisible(false);
+ dispose();
+ }
+ }
+
+ private boolean okPressed;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/SplashScreen.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import java.awt.*;
+import javax.swing.ImageIcon;
+
+public class SplashScreen extends Window
+{
+
+ public SplashScreen(Frame f)
+ {
+ super(f);
+ setBackground(Color.white);
+ java.net.URL url = getClass().getResource("/images/SplashScreen.jpg");
+ if(url != null)
+ {
+ screen = new ImageIcon(url);
+ MediaTracker mt = new MediaTracker(this);
+ mt.addImage(screen.getImage(), 0);
+ try
+ {
+ mt.waitForAll();
+ }
+ catch(Exception ex) { }
+ }
+ }
+
+ public void setVisible(boolean val)
+ {
+ if(screen == null)
+ return;
+ if(val)
+ {
+ setSize(screen.getIconWidth(), screen.getIconHeight());
+ setLocation(-500, -500);
+ super.setVisible(true);
+ Dimension d = getToolkit().getScreenSize();
+ Insets i = getInsets();
+ int w = screen.getIconWidth() + i.left + i.right;
+ int h = screen.getIconHeight() + i.top + i.bottom;
+ setSize(w, h);
+ setLocation(d.width / 2 - w / 2, d.height / 2 - h / 2);
+ } else
+ {
+ super.setVisible(false);
+ }
+ }
+
+ public void paint(Graphics g)
+ {
+ if(screen != null)
+ {
+ Dimension d = getSize();
+ g.setColor(Color.black);
+ g.drawRect(0, 0, d.width - 1, d.height - 1);
+ g.drawImage(screen.getImage(), 1, 1, this);
+ }
+ }
+
+ private ImageIcon screen;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/StatusBar.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class StatusBar extends JPanel
+ implements ActionListener, MouseListener
+{
+
+ public StatusBar()
+ {
+ setLayout(new FlowLayout(0));
+ setBorder(BorderFactory.createEtchedBorder());
+ progressBar = new JProgressBar(0, 0, 100);
+ progressBar.setPreferredSize(new Dimension(60, progressBar.getPreferredSize().height + 2));
+ progressBar.setVisible(false);
+ label = new JLabel(" ");
+ preferredSize = new Dimension(getWidth(label.getText()), 2 * getFontHeight());
+ add(progressBar);
+ add(label);
+ }
+
+ public static StatusBar getInstance()
+ {
+ if(statusBar == null)
+ statusBar = new StatusBar();
+ return statusBar;
+ }
+
+ public static void setInstance(StatusBar sb)
+ {
+ statusBar = sb;
+ }
+
+ protected int getWidth(String s)
+ {
+ FontMetrics fm = getFontMetrics(getFont());
+ if(fm == null)
+ return 0;
+ else
+ return fm.stringWidth(s);
+ }
+
+ protected int getFontHeight()
+ {
+ FontMetrics fm = getFontMetrics(getFont());
+ if(fm == null)
+ return 0;
+ else
+ return fm.getHeight();
+ }
+
+ public Dimension getPreferredSize()
+ {
+ return preferredSize;
+ }
+
+ public void setMessage(String message)
+ {
+ label.setText(message);
+ label.repaint();
+ }
+
+ public void startBusyBar()
+ {
+ forward = true;
+ if(timer == null)
+ {
+ setMessage("");
+ progressBar.setVisible(true);
+ timer = new Timer(15, this);
+ timer.start();
+ }
+ }
+
+ public void stopBusyBar()
+ {
+ if(timer != null)
+ {
+ timer.stop();
+ timer = null;
+ }
+ setMessage("");
+ progressBar.setVisible(false);
+ progressBar.setValue(0);
+ }
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ int value = progressBar.getValue();
+ if(forward)
+ {
+ if(value < 100)
+ {
+ progressBar.setValue(value + 1);
+ } else
+ {
+ forward = false;
+ progressBar.setValue(value - 1);
+ }
+ } else
+ if(value > 0)
+ {
+ progressBar.setValue(value - 1);
+ } else
+ {
+ forward = true;
+ progressBar.setValue(value + 1);
+ }
+ }
+
+ public void mouseClicked(MouseEvent mouseevent)
+ {
+ }
+
+ public void mousePressed(MouseEvent mouseevent)
+ {
+ }
+
+ public void mouseReleased(MouseEvent mouseevent)
+ {
+ }
+
+ public void mouseExited(MouseEvent evt)
+ {
+ setMessage("");
+ }
+
+ public void mouseEntered(MouseEvent evt)
+ {
+ if(evt.getSource() instanceof AbstractButton)
+ {
+ AbstractButton button = (AbstractButton)evt.getSource();
+ Action action = button.getAction();
+ if(action != null)
+ {
+ String message = (String)action.getValue("LongDescription");
+ setMessage(message);
+ }
+ }
+ }
+
+ private static final int PROGRESS_MAX = 100;
+ private static final int PROGRESS_MIN = 0;
+ private JLabel label;
+ private Dimension preferredSize;
+ private JProgressBar progressBar;
+ private Timer timer;
+ private boolean forward;
+ private static StatusBar statusBar;
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/TabsDlg.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import com.sun.java.swing.action.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Vector;
+import javax.swing.*;
+
+// Referenced classes of package com.sun.java.swing.ui:
+// CommonUI
+
+public class TabsDlg extends JDialog
+{
+ private class ApplyListener
+ implements ActionListener
+ {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ if(applyListener != null)
+ {
+ applyListener.actionPerformed(evt);
+ enableApplyButton(false);
+ }
+ }
+
+ private ApplyListener()
+ {
+ }
+
+ }
+
+ private class CancelListener
+ implements ActionListener
+ {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ if(cancelListener != null)
+ cancelListener.actionPerformed(evt);
+ setVisible(false);
+ }
+
+ private CancelListener()
+ {
+ }
+
+ }
+
+ private class OkListener
+ implements ActionListener
+ {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ if(okListener != null)
+ okListener.actionPerformed(evt);
+ setVisible(false);
+ }
+
+ private OkListener()
+ {
+ }
+
+ }
+
+
+ public TabsDlg(String title, Vector panels)
+ {
+ super(new JFrame(), title, true);
+ okListener = null;
+ cancelListener = null;
+ applyListener = null;
+ Container pane = getContentPane();
+ pane.setLayout(new BorderLayout());
+ tabsPanel = new JTabbedPane();
+ int numPanels = panels.size();
+ for(int i = 0; i < numPanels; i++)
+ {
+ JPanel panel = (JPanel)panels.elementAt(i);
+ tabsPanel.addTab(panel.getName(), panel);
+ }
+
+ pane.add(tabsPanel, "Center");
+ pane.add(createButtonPanel(), "South");
+ pack();
+ CommonUI.centerComponent(this);
+ }
+
+ public static void main(String args[])
+ {
+ JPanel p1 = new JPanel();
+ p1.add(new JButton("One"));
+ p1.setName("One");
+ JPanel p2 = new JPanel();
+ p2.add(new JButton("Two"));
+ p2.setName("Two");
+ JPanel p3 = new JPanel();
+ p3.add(new JButton("Three"));
+ p3.setName("Three");
+ JPanel p4 = new JPanel();
+ p4.add(new JButton("Four"));
+ p4.setName("Four");
+ Vector panels = new Vector();
+ panels.addElement(p1);
+ panels.addElement(p2);
+ panels.addElement(p3);
+ panels.addElement(p4);
+ tabsDlg = new TabsDlg("Test Dialog", panels);
+ tabsDlg.addOkListener(new ActionListener() {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ System.exit(0);
+ }
+
+ }
+);
+ tabsDlg.addCancelListener(new ActionListener() {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ System.exit(0);
+ }
+
+ }
+);
+ tabsDlg.setVisible(true);
+ }
+
+ private JPanel createButtonPanel()
+ {
+ JPanel panel = new JPanel();
+ okAction = new OkAction();
+ cancelAction = new CancelAction();
+ applyAction = new ApplyAction();
+ okAction.addActionListener(new OkListener());
+ cancelAction.addActionListener(new CancelListener());
+ applyAction.addActionListener(new ApplyListener());
+ panel.add(CommonUI.createButton(okAction));
+ panel.add(CommonUI.createButton(cancelAction));
+ panel.add(CommonUI.createButton(applyAction));
+ JPanel p2 = new JPanel(new BorderLayout());
+ p2.add(panel, "Center");
+ p2.add(new JSeparator(), "North");
+ return p2;
+ }
+
+ public void enableApplyButton(boolean enabled)
+ {
+ applyAction.setEnabled(enabled);
+ }
+
+ public synchronized void addOkListener(ActionListener l)
+ {
+ okListener = AWTEventMulticaster.add(okListener, l);
+ }
+
+ public synchronized void removeOkListener(ActionListener l)
+ {
+ okListener = AWTEventMulticaster.remove(okListener, l);
+ }
+
+ public synchronized void addCancelListener(ActionListener l)
+ {
+ cancelListener = AWTEventMulticaster.add(cancelListener, l);
+ }
+
+ public synchronized void removeCancelListener(ActionListener l)
+ {
+ cancelListener = AWTEventMulticaster.remove(cancelListener, l);
+ }
+
+ public synchronized void addApplyListener(ActionListener l)
+ {
+ applyListener = AWTEventMulticaster.add(applyListener, l);
+ }
+
+ public synchronized void removeApplyListener(ActionListener l)
+ {
+ applyListener = AWTEventMulticaster.remove(applyListener, l);
+ }
+
+ private JTabbedPane tabsPanel;
+ private DelegateAction okAction;
+ private DelegateAction cancelAction;
+ private DelegateAction applyAction;
+ private ActionListener okListener;
+ private ActionListener cancelListener;
+ private ActionListener applyListener;
+ private static TabsDlg tabsDlg;
+
+
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/ToggleActionPropertyChangeListener.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.AbstractButton;
+
+public class ToggleActionPropertyChangeListener
+ implements PropertyChangeListener
+{
+
+ public ToggleActionPropertyChangeListener(AbstractButton button)
+ {
+ this.button = button;
+ }
+
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ String propertyName = evt.getPropertyName();
+ if(propertyName.equals("selected"))
+ {
+ Boolean selected = (Boolean)evt.getNewValue();
+ button.setSelected(selected.booleanValue());
+ }
+ }
+
+ private AbstractButton button;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/com/sun/java/swing/ui/WizardDlg.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+
+package com.sun.java.swing.ui;
+
+import com.sun.java.swing.action.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Vector;
+import javax.swing.*;
+
+// Referenced classes of package com.sun.java.swing.ui:
+// CommonUI
+
+public class WizardDlg extends JDialog
+{
+ private class CancelListener
+ implements ActionListener
+ {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ if(cancelListener != null)
+ cancelListener.actionPerformed(evt);
+ setVisible(false);
+ }
+
+ private CancelListener()
+ {
+ }
+
+ }
+
+ private class FinishListener
+ implements ActionListener
+ {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ if(finishListener != null)
+ finishListener.actionPerformed(evt);
+ setVisible(false);
+ }
+
+ private FinishListener()
+ {
+ }
+
+ }
+
+ private class NextListener
+ implements ActionListener
+ {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ cardShowing++;
+ if(cardShowing > numCards)
+ cardShowing = numCards;
+ else
+ panesLayout.next(panesPanel);
+ if(nextListener != null)
+ nextListener.actionPerformed(evt);
+ enableBackNextButtons();
+ }
+
+ private NextListener()
+ {
+ }
+
+ }
+
+ private class BackListener
+ implements ActionListener
+ {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ cardShowing--;
+ if(cardShowing < 1)
+ cardShowing = 1;
+ else
+ panesLayout.previous(panesPanel);
+ if(backListener != null)
+ backListener.actionPerformed(evt);
+ enableBackNextButtons();
+ }
+
+ private BackListener()
+ {
+ }
+
+ }
+
+
+ public WizardDlg(JFrame frame, String title, Vector panels, Vector images)
+ {
+ super(frame, title, true);
+ this.title = title;
+ this.images = images;
+ Container pane = getContentPane();
+ pane.setLayout(new BorderLayout());
+ panesLayout = new CardLayout();
+ panesPanel = new JPanel(panesLayout);
+ pane.add(panesPanel, "Center");
+ pane.add(createButtonPanel(), "South");
+ setPanels(panels);
+ pack();
+ CommonUI.centerComponent(this);
+ }
+
+ public WizardDlg(JFrame frame, String title, Vector panels)
+ {
+ this(frame, title, panels, null);
+ }
+
+ public WizardDlg(String title, Vector panels)
+ {
+ this(new JFrame(), title, panels, null);
+ }
+
+ public void setPanels(Vector panels)
+ {
+ numCards = panels.size();
+ cardShowing = 1;
+ this.panels = panels;
+ panesPanel.removeAll();
+ for(int i = 0; i < numCards; i++)
+ panesPanel.add((JPanel)panels.elementAt(i), (new Integer(i)).toString());
+
+ validate();
+ enableBackNextButtons();
+ }
+
+ public void reset()
+ {
+ cardShowing = 1;
+ panesLayout.first(panesPanel);
+ enableBackNextButtons();
+ }
+
+ public void setWestPanel(JPanel panel)
+ {
+ Container pane = getContentPane();
+ pane.add(panel, "West");
+ }
+
+ public static void main(String args[])
+ {
+ JPanel p1 = new JPanel();
+ p1.add(new JButton("One"));
+ JPanel p2 = new JPanel();
+ p2.add(new JButton("Two"));
+ JPanel p3 = new JPanel();
+ p3.add(new JButton("Three"));
+ JPanel p4 = new JPanel();
+ p4.add(new JButton("Four"));
+ Vector panels = new Vector();
+ panels.addElement(p1);
+ panels.addElement(p2);
+ panels.addElement(p3);
+ panels.addElement(p4);
+ wizardDlg = new WizardDlg("Test Dialog", panels);
+ wizardDlg.addFinishListener(new ActionListener() {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ System.exit(0);
+ }
+
+ }
+);
+ wizardDlg.addCancelListener(new ActionListener() {
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ System.exit(0);
+ }
+
+ }
+);
+ wizardDlg.setVisible(true);
+ }
+
+ private JPanel createButtonPanel()
+ {
+ JPanel panel = new JPanel();
+ backAction = new BackAction();
+ nextAction = new NextAction();
+ finishAction = new FinishAction();
+ cancelAction = new CancelAction();
+ backAction.setEnabled(false);
+ finishAction.setEnabled(false);
+ backAction.addActionListener(new BackListener());
+ nextAction.addActionListener(new NextListener());
+ finishAction.addActionListener(new FinishListener());
+ cancelAction.addActionListener(new CancelListener());
+ panel.add(CommonUI.createButton(backAction));
+ panel.add(CommonUI.createButton(nextAction));
+ panel.add(CommonUI.createButton(finishAction));
+ panel.add(CommonUI.createButton(cancelAction));
+ JPanel p2 = new JPanel(new BorderLayout());
+ p2.add(panel, "Center");
+ p2.add(new JSeparator(), "North");
+ return p2;
+ }
+
+ private void enableBackNextButtons()
+ {
+ if(cardShowing == 1)
+ {
+ backAction.setEnabled(false);
+ finishAction.setEnabled(false);
+ if(numCards > 1)
+ {
+ nextAction.setEnabled(true);
+ } else
+ {
+ finishAction.setEnabled(true);
+ nextAction.setEnabled(false);
+ }
+ } else
+ if(cardShowing == numCards)
+ {
+ nextAction.setEnabled(false);
+ finishAction.setEnabled(true);
+ if(numCards > 1)
+ backAction.setEnabled(true);
+ else
+ backAction.setEnabled(false);
+ } else
+ {
+ backAction.setEnabled(true);
+ nextAction.setEnabled(true);
+ finishAction.setEnabled(false);
+ }
+ setTitle();
+ }
+
+ private void setTitle()
+ {
+ JPanel panel = (JPanel)panels.elementAt(cardShowing - 1);
+ String newTitle = title;
+ String panelTitle = panel.getName();
+ if(panelTitle != null && panelTitle.equals(""))
+ {
+ newTitle = newTitle + " - ";
+ newTitle = newTitle + panelTitle;
+ }
+ super.setTitle(newTitle);
+ }
+
+ public synchronized void addFinishListener(ActionListener l)
+ {
+ finishListener = AWTEventMulticaster.add(finishListener, l);
+ }
+
+ public synchronized void removeFinishListener(ActionListener l)
+ {
+ finishListener = AWTEventMulticaster.remove(finishListener, l);
+ }
+
+ public synchronized void addCancelListener(ActionListener l)
+ {
+ cancelListener = AWTEventMulticaster.add(cancelListener, l);
+ }
+
+ public synchronized void removeCancelListener(ActionListener l)
+ {
+ cancelListener = AWTEventMulticaster.remove(cancelListener, l);
+ }
+
+ public synchronized void addNextListener(ActionListener l)
+ {
+ nextListener = AWTEventMulticaster.add(nextListener, l);
+ }
+
+ public synchronized void removeNextListener(ActionListener l)
+ {
+ nextListener = AWTEventMulticaster.remove(nextListener, l);
+ }
+
+ public synchronized void addBackListener(ActionListener l)
+ {
+ backListener = AWTEventMulticaster.add(backListener, l);
+ }
+
+ public synchronized void removeBackListener(ActionListener l)
+ {
+ backListener = AWTEventMulticaster.remove(backListener, l);
+ }
+
+ private CardLayout panesLayout;
+ private JPanel panesPanel;
+ private DelegateAction backAction;
+ private DelegateAction nextAction;
+ private DelegateAction finishAction;
+ private DelegateAction cancelAction;
+ private ActionListener finishListener;
+ private ActionListener cancelListener;
+ private ActionListener nextListener;
+ private ActionListener backListener;
+ private int numCards;
+ private int cardShowing;
+ private String title;
+ private Vector panels;
+ private Vector images;
+ private static WizardDlg wizardDlg;
+
+
+
+
+}
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/development/Server24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/About24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Delete24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Find16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Help24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/History24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Information24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/New24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Open24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Save24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/SaveAs24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/Zoom16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/general/ZoomIn24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Down16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/navigation/Up16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignCenter24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignLeft24.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight16.gif has changed
Binary file hotspot/agent/src/share/classes/images/toolbarButtonGraphics/text/AlignRight24.gif has changed
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Wed Jul 05 16:40:18 2017 +0200
@@ -193,8 +193,12 @@
private static final double FACTOR = 1024*1024;
private void printValMB(String title, long value) {
- double mb = value / FACTOR;
- System.out.println(alignment + title + value + " (" + mb + "MB)");
+ if (value < 0) {
+ System.out.println(alignment + title + (value >>> 20) + " MB");
+ } else {
+ double mb = value/FACTOR;
+ System.out.println(alignment + title + value + " (" + mb + "MB)");
+ }
}
private void printValue(String title, long value) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java Wed Jul 05 16:40:18 2017 +0200
@@ -266,45 +266,51 @@
out.println();
}
+ private static long objectSize(Oop oop) {
+ return oop == null ? 0L : oop.getObjectSize();
+ }
+
+ // Don't count the shared empty arrays
+ private static long arraySize(Array arr) {
+ return arr.getLength() != 0L ? arr.getObjectSize() : 0L;
+ }
+
private long computeSize(InstanceKlass k) {
long size = 0L;
- // InstanceKlass object size
+ // the InstanceKlass object itself
size += k.getObjectSize();
- // add ConstantPool size
- size += k.getConstants().getObjectSize();
+ // Constant pool
+ ConstantPool cp = k.getConstants();
+ size += cp.getObjectSize();
+ size += objectSize(cp.getCache());
+ size += objectSize(cp.getTags());
+
+ // Interfaces
+ size += arraySize(k.getLocalInterfaces());
+ size += arraySize(k.getTransitiveInterfaces());
+
+ // Inner classes
+ size += objectSize(k.getInnerClasses());
- // add ConstantPoolCache, if any
- ConstantPoolCache cpCache = k.getConstants().getCache();
- if (cpCache != null) {
- size += cpCache.getObjectSize();
+ // Fields
+ size += objectSize(k.getFields());
+
+ // Methods
+ ObjArray methods = k.getMethods();
+ int nmethods = (int) methods.getLength();
+ if (nmethods != 0L) {
+ size += methods.getObjectSize();
+ for (int i = 0; i < nmethods; ++i) {
+ Method m = (Method) methods.getObjAt(i);
+ size += m.getObjectSize();
+ size += objectSize(m.getConstMethod());
+ }
}
- // add interfaces size
- ObjArray interfaces = k.getLocalInterfaces();
- size += (interfaces.getLength() != 0L)? interfaces.getObjectSize() : 0L;
- ObjArray transitiveInterfaces = k.getTransitiveInterfaces();
- size += (transitiveInterfaces.getLength() != 0L)? transitiveInterfaces.getObjectSize() : 0L;
-
- // add inner classes size
- TypeArray innerClasses = k.getInnerClasses();
- size += innerClasses.getObjectSize();
-
- // add fields size
- size += k.getFields().getObjectSize();
-
- // add methods size
- ObjArray methods = k.getMethods();
- size += (methods.getLength() != 0L)? methods.getObjectSize() : 0L;
- TypeArray methodOrdering = k.getMethodOrdering();
- size += (methodOrdering.getLength() != 0L)? methodOrdering.getObjectSize() : 0;
-
- // add each method's size
- int numMethods = (int) methods.getLength();
- for (int i = 0; i < numMethods; i++) {
- Method m = (Method) methods.getObjAt(i);
- size += m.getObjectSize();
- }
+ // MethodOrdering - an int array that records the original
+ // ordering of methods in the class file
+ size += arraySize(k.getMethodOrdering());
return size;
}
Binary file hotspot/agent/src/share/lib/jlfgr-1_0.jar has changed
Binary file hotspot/agent/src/share/lib/maf-1_0.jar has changed
--- a/hotspot/make/hotspot_distro Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/make/hotspot_distro Wed Jul 05 16:40:18 2017 +0200
@@ -1,6 +1,24 @@
-#
-# Copyright 2006-2008 Sun Microsystems, Inc. All rights reserved.
-# SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+#
+# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
+# 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
#
#
--- a/hotspot/make/hotspot_version Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/make/hotspot_version Wed Jul 05 16:40:18 2017 +0200
@@ -35,7 +35,7 @@
HS_MAJOR_VER=14
HS_MINOR_VER=0
-HS_BUILD_NUMBER=01
+HS_BUILD_NUMBER=03
JDK_MAJOR_VER=1
JDK_MINOR_VER=7
--- a/hotspot/make/jprt.config Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/make/jprt.config Wed Jul 05 16:40:18 2017 +0200
@@ -77,9 +77,7 @@
# All jdk6 builds use SS11
compiler_name=SS11
else
- # FIXUP: Change to SS12 once it has been validated.
- #compiler_name=SS12
- compiler_name=SS11
+ compiler_name=SS12
fi
fi
--- a/hotspot/make/linux/makefiles/vm.make Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/make/linux/makefiles/vm.make Wed Jul 05 16:40:18 2017 +0200
@@ -195,7 +195,7 @@
if [ $$? = 0 ] ; then \
/usr/bin/chcon -t textrel_shlib_t $@; \
if [ $$? != 0 ]; then \
- echo "ERROR: Cannot chcon $@"; exit 1; \
+ echo "ERROR: Cannot chcon $@"; \
fi \
fi \
fi \
--- a/hotspot/make/solaris/makefiles/fastdebug.make Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/make/solaris/makefiles/fastdebug.make Wed Jul 05 16:40:18 2017 +0200
@@ -38,6 +38,8 @@
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
ifeq ($(COMPILER_REV), 5.9)
+ # To avoid jvm98 crash
+ OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER)
# Not clear this workaround could be skipped in some cases.
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER)
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER)
--- a/hotspot/make/solaris/makefiles/sparcWorks.make Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/make/solaris/makefiles/sparcWorks.make Wed Jul 05 16:40:18 2017 +0200
@@ -51,12 +51,9 @@
VALIDATED_COMPILER_REV := 5.8
VALIDATED_C_COMPILER_REV := 5.8
else
- # FIXUP: Change to SS12 (5.9) once it has been validated.
# Validated compiler for JDK7 is SS12 (5.9)
- #VALIDATED_COMPILER_REV := 5.9
- #VALIDATED_C_COMPILER_REV := 5.9
- VALIDATED_COMPILER_REV := 5.8
- VALIDATED_C_COMPILER_REV := 5.8
+ VALIDATED_COMPILER_REV := 5.9
+ VALIDATED_C_COMPILER_REV := 5.9
endif
# Warning messages about not using the above validated version
--- a/hotspot/make/windows/makefiles/defs.make Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/make/windows/makefiles/defs.make Wed Jul 05 16:40:18 2017 +0200
@@ -107,7 +107,7 @@
ABS_OUTPUTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(OUTPUTDIR)"))
ABS_BOOTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(BOOTDIR)"))
ABS_GAMMADIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(GAMMADIR)"))
- ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_BUILD_DIR)/$(OSNAME)")/build.make
+ ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_MAKE_DIR)/$(OSNAME)")/build.make
else
ABS_OUTPUTDIR := $(subst /,\\,$(shell $(CD) $(OUTPUTDIR);$(PWD)))
ABS_BOOTDIR := $(subst /,\\,$(shell $(CD) $(BOOTDIR);$(PWD)))
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -779,9 +779,9 @@
__ shrl(end, CardTableModRefBS::card_shift);
__ subl(end, start); // end --> count
__ BIND(L_loop);
- ExternalAddress base((address)ct->byte_map_base);
- Address index(start, count, Address::times_1, 0);
- __ movbyte(ArrayAddress(base, index), 0);
+ intptr_t disp = (intptr_t) ct->byte_map_base;
+ Address cardtable(start, count, Address::times_1, disp);
+ __ movb(cardtable, 0);
__ decrement(count);
__ jcc(Assembler::greaterEqual, L_loop);
}
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -1222,8 +1222,16 @@
__ shrq(end, CardTableModRefBS::card_shift);
__ subq(end, start); // number of bytes to copy
+ intptr_t disp = (intptr_t) ct->byte_map_base;
+ if (__ is_simm32(disp)) {
+ Address cardtable(noreg, noreg, Address::no_scale, disp);
+ __ lea(scratch, cardtable);
+ } else {
+ ExternalAddress cardtable((address)disp);
+ __ lea(scratch, cardtable);
+ }
+
const Register count = end; // 'end' register contains bytes count now
- __ lea(scratch, ExternalAddress((address)ct->byte_map_base));
__ addq(start, scratch);
__ BIND(L_loop);
__ movb(Address(start, count, Address::times_1), 0);
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -94,6 +94,9 @@
static int SR_signum = SIGUSR2;
sigset_t SR_sigset;
+/* Used to protect dlsym() calls */
+static pthread_mutex_t dl_mutex;
+
////////////////////////////////////////////////////////////////////////////////
// utility functions
@@ -1493,6 +1496,24 @@
const char* os::get_temp_directory() { return "/tmp/"; }
+void os::dll_build_name(
+ char* buffer, size_t buflen, const char* pname, const char* fname) {
+ // copied from libhpi
+ const size_t pnamelen = pname ? strlen(pname) : 0;
+
+ /* Quietly truncate on buffer overflow. Should be an error. */
+ if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
+ *buffer = '\0';
+ return;
+ }
+
+ if (pnamelen == 0) {
+ sprintf(buffer, "lib%s.so", fname);
+ } else {
+ sprintf(buffer, "%s/lib%s.so", pname, fname);
+ }
+}
+
const char* os::get_current_directory(char *buf, int buflen) {
return getcwd(buf, buflen);
}
@@ -1742,7 +1763,17 @@
return NULL;
}
-
+/*
+ * glibc-2.0 libdl is not MT safe. If you are building with any glibc,
+ * chances are you might want to run the generated bits against glibc-2.0
+ * libdl.so, so always use locking for any version of glibc.
+ */
+void* os::dll_lookup(void* handle, const char* name) {
+ pthread_mutex_lock(&dl_mutex);
+ void* res = dlsym(handle, name);
+ pthread_mutex_unlock(&dl_mutex);
+ return res;
+}
bool _print_ascii_file(const char* filename, outputStream* st) {
@@ -2278,7 +2309,7 @@
dlsym(RTLD_DEFAULT, "sched_getcpu")));
if (sched_getcpu() != -1) { // Does it work?
- void *handle = dlopen("libnuma.so", RTLD_LAZY);
+ void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
if (handle != NULL) {
set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t,
dlsym(handle, "numa_node_to_cpus")));
@@ -3581,6 +3612,7 @@
Linux::clock_init();
initial_time_count = os::elapsed_counter();
+ pthread_mutex_init(&dl_mutex, NULL);
}
// To install functions for atexit system call
--- a/hotspot/src/os/solaris/vm/osThread_solaris.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/os/solaris/vm/osThread_solaris.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -69,15 +69,15 @@
static intptr_t compare_and_exchange_current_callback (
intptr_t callback, intptr_t *addr, intptr_t compare_value, Mutex *sync) {
if (VM_Version::supports_compare_and_exchange()) {
- return Atomic::cmpxchg_ptr(callback, addr, compare_value);
+ return Atomic::cmpxchg_ptr(callback, addr, compare_value);
} else {
- MutexLockerEx(sync, Mutex::_no_safepoint_check_flag);
- if (*addr == compare_value) {
- *addr = callback;
- return compare_value;
- } else {
- return callback;
- }
+ MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
+ if (*addr == compare_value) {
+ *addr = callback;
+ return compare_value;
+ } else {
+ return callback;
+ }
}
}
@@ -86,7 +86,7 @@
if (VM_Version::supports_compare_and_exchange()) {
return Atomic::xchg_ptr(callback, addr);
} else {
- MutexLockerEx(sync, Mutex::_no_safepoint_check_flag);
+ MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
intptr_t cb = *addr;
*addr = callback;
return cb;
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -1783,6 +1783,24 @@
const char* os::get_temp_directory() { return "/tmp/"; }
+void os::dll_build_name(
+ char* buffer, size_t buflen, const char* pname, const char* fname) {
+ // copied from libhpi
+ const size_t pnamelen = pname ? strlen(pname) : 0;
+
+ /* Quietly truncate on buffer overflow. Should be an error. */
+ if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
+ *buffer = '\0';
+ return;
+ }
+
+ if (pnamelen == 0) {
+ sprintf(buffer, "lib%s.so", fname);
+ } else {
+ sprintf(buffer, "%s/lib%s.so", pname, fname);
+ }
+}
+
const char* os::get_current_directory(char *buf, int buflen) {
return getcwd(buf, buflen);
}
@@ -2034,6 +2052,9 @@
return NULL;
}
+void* os::dll_lookup(void* handle, const char* name) {
+ return dlsym(handle, name);
+}
bool _print_ascii_file(const char* filename, outputStream* st) {
@@ -2658,6 +2679,12 @@
top += r;
cur++;
}
+ if (bottom == 0) {
+ // Handle a situation, when the OS reports no memory available.
+ // Assume UMA architecture.
+ ids[0] = 0;
+ return 1;
+ }
return bottom;
}
@@ -4581,7 +4608,7 @@
}
void os::Solaris::liblgrp_init() {
- void *handle = dlopen("liblgrp.so", RTLD_LAZY);
+ void *handle = dlopen("liblgrp.so.1", RTLD_LAZY);
if (handle != NULL) {
os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home")));
os::Solaris::set_lgrp_init(CAST_TO_FN_PTR(lgrp_init_func_t, dlsym(handle, "lgrp_init")));
--- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -985,6 +985,28 @@
}
}
+void os::dll_build_name(char *holder, size_t holderlen,
+ const char* pname, const char* fname)
+{
+ // copied from libhpi
+ const size_t pnamelen = pname ? strlen(pname) : 0;
+ const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
+
+ /* Quietly truncates on buffer overflow. Should be an error. */
+ if (pnamelen + strlen(fname) + 10 > holderlen) {
+ *holder = '\0';
+ return;
+ }
+
+ if (pnamelen == 0) {
+ sprintf(holder, "%s.dll", fname);
+ } else if (c == ':' || c == '\\') {
+ sprintf(holder, "%s%s.dll", pname, fname);
+ } else {
+ sprintf(holder, "%s\\%s.dll", pname, fname);
+ }
+}
+
// Needs to be in os specific directory because windows requires another
// header file <direct.h>
const char* os::get_current_directory(char *buf, int buflen) {
@@ -1248,6 +1270,10 @@
return false;
}
+void* os::dll_lookup(void* handle, const char* name) {
+ return GetProcAddress((HMODULE)handle, name);
+}
+
// save the start and end address of jvm.dll into param[0] and param[1]
static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr,
unsigned size, void * param) {
@@ -1421,44 +1447,78 @@
enumerate_modules(pid, _print_module, (void *)st);
}
+// function pointer to Windows API "GetNativeSystemInfo".
+typedef void (WINAPI *GetNativeSystemInfo_func_type)(LPSYSTEM_INFO);
+static GetNativeSystemInfo_func_type _GetNativeSystemInfo;
+
void os::print_os_info(outputStream* st) {
- st->print("OS:");
-
- OSVERSIONINFOEX osvi;
- ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-
- if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
- st->print_cr("N/A");
- return;
- }
-
- int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
-
- if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- switch (os_vers) {
- case 3051: st->print(" Windows NT 3.51"); break;
- case 4000: st->print(" Windows NT 4.0"); break;
- case 5000: st->print(" Windows 2000"); break;
- case 5001: st->print(" Windows XP"); break;
- case 5002: st->print(" Windows Server 2003 family"); break;
- case 6000: st->print(" Windows Vista"); break;
- default: // future windows, print out its major and minor versions
- st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
- }
- } else {
- switch (os_vers) {
- case 4000: st->print(" Windows 95"); break;
- case 4010: st->print(" Windows 98"); break;
- case 4090: st->print(" Windows Me"); break;
- default: // future windows, print out its major and minor versions
- st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
- }
- }
-
- st->print(" Build %d", osvi.dwBuildNumber);
- st->print(" %s", osvi.szCSDVersion); // service pack
- st->cr();
+ st->print("OS:");
+
+ OSVERSIONINFOEX osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+ if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
+ st->print_cr("N/A");
+ return;
+ }
+
+ int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+ switch (os_vers) {
+ case 3051: st->print(" Windows NT 3.51"); break;
+ case 4000: st->print(" Windows NT 4.0"); break;
+ case 5000: st->print(" Windows 2000"); break;
+ case 5001: st->print(" Windows XP"); break;
+ case 5002:
+ case 6000: {
+ // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
+ // find out whether we are running on 64 bit processor or not.
+ SYSTEM_INFO si;
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+ // Check to see if _GetNativeSystemInfo has been initialized.
+ if (_GetNativeSystemInfo == NULL) {
+ HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));
+ _GetNativeSystemInfo =
+ CAST_TO_FN_PTR(GetNativeSystemInfo_func_type,
+ GetProcAddress(hKernel32,
+ "GetNativeSystemInfo"));
+ if (_GetNativeSystemInfo == NULL)
+ GetSystemInfo(&si);
+ } else {
+ _GetNativeSystemInfo(&si);
+ }
+ if (os_vers == 5002) {
+ if (osvi.wProductType == VER_NT_WORKSTATION &&
+ si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+ st->print(" Windows XP x64 Edition");
+ else
+ st->print(" Windows Server 2003 family");
+ } else { // os_vers == 6000
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ st->print(" Windows Vista");
+ else
+ st->print(" Windows Server 2008");
+ if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+ st->print(" , 64 bit");
+ }
+ break;
+ }
+ default: // future windows, print out its major and minor versions
+ st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+ }
+ } else {
+ switch (os_vers) {
+ case 4000: st->print(" Windows 95"); break;
+ case 4010: st->print(" Windows 98"); break;
+ case 4090: st->print(" Windows Me"); break;
+ default: // future windows, print out its major and minor versions
+ st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+ }
+ }
+ st->print(" Build %d", osvi.dwBuildNumber);
+ st->print(" %s", osvi.szCSDVersion); // service pack
+ st->cr();
}
void os::print_memory_info(outputStream* st) {
--- a/hotspot/src/share/vm/adlc/formssel.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/adlc/formssel.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -3825,6 +3825,8 @@
strcmp(opType,"ConvL2D")==0 ||
strcmp(opType,"ConvL2F")==0 ||
strcmp(opType,"ConvL2I")==0 ||
+ strcmp(opType,"DecodeN")==0 ||
+ strcmp(opType,"EncodeP")==0 ||
strcmp(opType,"RoundDouble")==0 ||
strcmp(opType,"RoundFloat")==0 ||
strcmp(opType,"ReverseBytesI")==0 ||
--- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -351,7 +351,7 @@
}
#ifndef PRODUCT
-static char *flagnames[] = {
+static const char *flagnames[] = {
"Processed",
"Handler",
"MayThrow",
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -649,8 +649,8 @@
}
oop java_lang_Thread::park_blocker(oop java_thread) {
- assert(JDK_Version::supports_thread_park_blocker() && _park_blocker_offset != 0,
- "Must support parkBlocker field");
+ assert(JDK_Version::current().supports_thread_park_blocker() &&
+ _park_blocker_offset != 0, "Must support parkBlocker field");
if (_park_blocker_offset > 0) {
return java_thread->obj_field(_park_blocker_offset);
--- a/hotspot/src/share/vm/compiler/oopMap.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/compiler/oopMap.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -188,10 +188,6 @@
}
}
-void OopMap::set_stack_obj(VMReg reg) {
- set_xxx(reg, OopMapValue::stack_obj, VMRegImpl::Bad());
-}
-
// OopMapSet
OopMapSet::OopMapSet() {
@@ -399,8 +395,7 @@
if ( loc != NULL ) {
if ( omv.type() == OopMapValue::oop_value ) {
#ifdef ASSERT
- if (COMPILER2_PRESENT(!DoEscapeAnalysis &&)
- (((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
+ if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
!Universe::heap()->is_in_or_null(*loc)) {
tty->print_cr("# Found non oop pointer. Dumping state at failure");
// try to dump out some helpful debugging information
@@ -431,17 +426,6 @@
}
}
}
-
-#ifdef COMPILER2
- if (DoEscapeAnalysis) {
- for (OopMapStream oms(map, OopMapValue::stack_obj); !oms.is_done(); oms.next()) {
- omv = oms.current();
- assert(omv.is_stack_loc(), "should refer to stack location");
- oop loc = (oop) fr->oopmapreg_to_location(omv.reg(),reg_map);
- oop_fn->do_oop(&loc);
- }
- }
-#endif // COMPILER2
}
@@ -540,9 +524,6 @@
st->print("Derived_oop_" );
optional->print_on(st);
break;
- case OopMapValue::stack_obj:
- st->print("Stack");
- break;
default:
ShouldNotReachHere();
}
--- a/hotspot/src/share/vm/compiler/oopMap.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/compiler/oopMap.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -46,7 +46,7 @@
public:
// Constants
- enum { type_bits = 6,
+ enum { type_bits = 5,
register_bits = BitsPerShort - type_bits };
enum { type_shift = 0,
@@ -63,8 +63,7 @@
value_value = 2,
narrowoop_value = 4,
callee_saved_value = 8,
- derived_oop_value= 16,
- stack_obj = 32 };
+ derived_oop_value= 16 };
// Constructors
OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
@@ -93,14 +92,12 @@
bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
- bool is_stack_obj() { return mask_bits(value(), type_mask_in_place) == stack_obj; }
void set_oop() { set_value((value() & register_mask_in_place) | oop_value); }
void set_value() { set_value((value() & register_mask_in_place) | value_value); }
void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); }
void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); }
void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); }
- void set_stack_obj() { set_value((value() & register_mask_in_place) | stack_obj); }
VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); }
@@ -180,7 +177,6 @@
void set_dead ( VMReg local);
void set_callee_saved( VMReg local, VMReg caller_machine_register );
void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
- void set_stack_obj( VMReg local);
void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
int heap_size() const;
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -71,8 +71,15 @@
TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) {
TreeChunk* tc = (TreeChunk*) addr;
assert(size >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk");
- assert(tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL,
- "Space should be clear");
+ // The space in the heap will have been mangled initially but
+ // is not remangled when a free chunk is returned to the free list
+ // (since it is used to maintain the chunk on the free list).
+ assert((ZapUnusedHeapArea &&
+ SpaceMangler::is_mangled((HeapWord*) tc->size_addr()) &&
+ SpaceMangler::is_mangled((HeapWord*) tc->prev_addr()) &&
+ SpaceMangler::is_mangled((HeapWord*) tc->next_addr())) ||
+ (tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL),
+ "Space should be clear or mangled");
tc->setSize(size);
tc->linkPrev(NULL);
tc->linkNext(NULL);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -54,7 +54,7 @@
_collector(NULL)
{
_bt.set_space(this);
- initialize(mr, true);
+ initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
// We have all of "mr", all of which we place in the dictionary
// as one big chunk. We'll need to decide here which of several
// possible alternative dictionary implementations to use. For
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -3195,31 +3195,16 @@
// YSR: All of this generation expansion/shrinking stuff is an exact copy of
// OneContigSpaceCardGeneration, which makes me wonder if we should move this
// to CardGeneration and share it...
+bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) {
+ return CardGeneration::expand(bytes, expand_bytes);
+}
+
void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes,
CMSExpansionCause::Cause cause)
{
- assert_locked_or_safepoint(Heap_lock);
-
- size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes);
- size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
- bool success = false;
- if (aligned_expand_bytes > aligned_bytes) {
- success = grow_by(aligned_expand_bytes);
- }
- if (!success) {
- success = grow_by(aligned_bytes);
- }
- if (!success) {
- size_t remaining_bytes = _virtual_space.uncommitted_size();
- if (remaining_bytes > 0) {
- success = grow_by(remaining_bytes);
- }
- }
- if (GC_locker::is_active()) {
- if (PrintGC && Verbose) {
- gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
- }
- }
+
+ bool success = expand(bytes, expand_bytes);
+
// remember why we expanded; this information is used
// by shouldConcurrentCollect() when making decisions on whether to start
// a new CMS cycle.
@@ -6882,11 +6867,9 @@
// during the preclean or remark phase. (CMSCleanOnEnter)
if (CMSCleanOnEnter) {
size_t sz = _collector->block_size_using_printezis_bits(addr);
- HeapWord* start_card_addr = (HeapWord*)round_down(
- (intptr_t)addr, CardTableModRefBS::card_size);
HeapWord* end_card_addr = (HeapWord*)round_to(
(intptr_t)(addr+sz), CardTableModRefBS::card_size);
- MemRegion redirty_range = MemRegion(start_card_addr, end_card_addr);
+ MemRegion redirty_range = MemRegion(addr, end_card_addr);
assert(!redirty_range.is_empty(), "Arithmetical tautology");
// Bump _threshold to end_card_addr; note that
// _threshold cannot possibly exceed end_card_addr, anyhow.
@@ -7475,12 +7458,25 @@
)
if (simulate_overflow || !_mark_stack->push(obj)) {
if (_concurrent_precleaning) {
- // During precleaning we can just dirty the appropriate card
+ // During precleaning we can just dirty the appropriate card(s)
// in the mod union table, thus ensuring that the object remains
- // in the grey set and continue. Note that no one can be intefering
- // with us in this action of dirtying the mod union table, so
- // no locking is required.
- _mod_union_table->mark(addr);
+ // in the grey set and continue. In the case of object arrays
+ // we need to dirty all of the cards that the object spans,
+ // since the rescan of object arrays will be limited to the
+ // dirty cards.
+ // Note that no one can be intefering with us in this action
+ // of dirtying the mod union table, so no locking or atomics
+ // are required.
+ if (obj->is_objArray()) {
+ size_t sz = obj->size();
+ HeapWord* end_card_addr = (HeapWord*)round_to(
+ (intptr_t)(addr+sz), CardTableModRefBS::card_size);
+ MemRegion redirty_range = MemRegion(addr, end_card_addr);
+ assert(!redirty_range.is_empty(), "Arithmetical tautology");
+ _mod_union_table->mark_range(redirty_range);
+ } else {
+ _mod_union_table->mark(addr);
+ }
_collector->_ser_pmc_preclean_ovflw++;
} else {
// During the remark phase, we need to remember this oop
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -1048,10 +1048,6 @@
double _initiating_occupancy;
protected:
- // Grow generation by specified size (returns false if unable to grow)
- bool grow_by(size_t bytes);
- // Grow generation to reserved size.
- bool grow_to_reserved();
// Shrink generation by specified size (returns false if unable to shrink)
virtual void shrink_by(size_t bytes);
@@ -1103,6 +1099,11 @@
// Override
virtual void ref_processor_init();
+ // Grow generation by specified size (returns false if unable to grow)
+ bool grow_by(size_t bytes);
+ // Grow generation to reserved size.
+ bool grow_to_reserved();
+
void clear_expansion_cause() { _expansion_cause = CMSExpansionCause::_no_expansion; }
// Space enquiries
@@ -1193,6 +1194,7 @@
// Allocation failure
void expand(size_t bytes, size_t expand_bytes,
CMSExpansionCause::Cause cause);
+ virtual bool expand(size_t bytes, size_t expand_bytes);
void shrink(size_t bytes);
HeapWord* expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz);
bool expand_and_ensure_spooling_space(PromotionInfo* promo);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -22,7 +22,6 @@
*
*/
-
// A FreeBlockDictionary is an abstract superclass that will allow
// a number of alternative implementations in the future.
class FreeBlockDictionary: public CHeapObj {
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -85,6 +85,8 @@
}
debug_only(void* prev_addr() const { return (void*)&_prev; })
+ debug_only(void* next_addr() const { return (void*)&_next; })
+ debug_only(void* size_addr() const { return (void*)&_size; })
size_t size() const volatile {
LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else )
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_concurrentMarkSweep Wed Jul 05 16:40:18 2017 +0200
@@ -28,6 +28,7 @@
binaryTreeDictionary.cpp binaryTreeDictionary.hpp
binaryTreeDictionary.cpp globals.hpp
binaryTreeDictionary.cpp ostream.hpp
+binaryTreeDictionary.cpp spaceDecorator.hpp
binaryTreeDictionary.hpp freeBlockDictionary.hpp
binaryTreeDictionary.hpp freeList.hpp
@@ -114,6 +115,7 @@
compactibleFreeListSpace.cpp liveRange.hpp
compactibleFreeListSpace.cpp oop.inline.hpp
compactibleFreeListSpace.cpp resourceArea.hpp
+compactibleFreeListSpace.cpp spaceDecorator.hpp
compactibleFreeListSpace.cpp universe.inline.hpp
compactibleFreeListSpace.cpp vmThread.hpp
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parNew Wed Jul 05 16:40:18 2017 +0200
@@ -22,16 +22,17 @@
//
//
-asParNewGeneration.hpp adaptiveSizePolicy.hpp
-asParNewGeneration.hpp parNewGeneration.hpp
+asParNewGeneration.hpp adaptiveSizePolicy.hpp
+asParNewGeneration.hpp parNewGeneration.hpp
-asParNewGeneration.cpp asParNewGeneration.hpp
-asParNewGeneration.cpp cmsAdaptiveSizePolicy.hpp
+asParNewGeneration.cpp asParNewGeneration.hpp
+asParNewGeneration.cpp cmsAdaptiveSizePolicy.hpp
asParNewGeneration.cpp cmsGCAdaptivePolicyCounters.hpp
-asParNewGeneration.cpp defNewGeneration.inline.hpp
-asParNewGeneration.cpp oop.pcgc.inline.hpp
-asParNewGeneration.cpp parNewGeneration.hpp
+asParNewGeneration.cpp defNewGeneration.inline.hpp
+asParNewGeneration.cpp oop.pcgc.inline.hpp
+asParNewGeneration.cpp parNewGeneration.hpp
asParNewGeneration.cpp referencePolicy.hpp
+asParNewGeneration.cpp spaceDecorator.hpp
parCardTableModRefBS.cpp allocation.inline.hpp
parCardTableModRefBS.cpp cardTableModRefBS.hpp
@@ -75,6 +76,7 @@
parNewGeneration.cpp resourceArea.hpp
parNewGeneration.cpp sharedHeap.hpp
parNewGeneration.cpp space.hpp
+parNewGeneration.cpp spaceDecorator.hpp
parNewGeneration.cpp workgroup.hpp
parNewGeneration.hpp defNewGeneration.hpp
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_parallelScavenge Wed Jul 05 16:40:18 2017 +0200
@@ -53,14 +53,15 @@
asPSOldGen.cpp oop.inline.hpp
asPSOldGen.cpp parallelScavengeHeap.hpp
asPSOldGen.cpp psMarkSweepDecorator.hpp
-asPSOldGen.cpp asPSOldGen.hpp
+asPSOldGen.cpp asPSOldGen.hpp
asPSYoungGen.hpp generationCounters.hpp
asPSYoungGen.hpp mutableSpace.hpp
asPSYoungGen.hpp objectStartArray.hpp
asPSYoungGen.hpp spaceCounters.hpp
asPSYoungGen.hpp psVirtualspace.hpp
-asPSYoungGen.hpp psYoungGen.hpp
+asPSYoungGen.hpp psYoungGen.hpp
+asPSYoungGen.hpp spaceDecorator.hpp
asPSYoungGen.cpp gcUtil.hpp
asPSYoungGen.cpp java.hpp
@@ -68,8 +69,9 @@
asPSYoungGen.cpp parallelScavengeHeap.hpp
asPSYoungGen.cpp psMarkSweepDecorator.hpp
asPSYoungGen.cpp psScavenge.hpp
-asPSYoungGen.cpp asPSYoungGen.hpp
-asPSYoungGen.cpp psYoungGen.hpp
+asPSYoungGen.cpp asPSYoungGen.hpp
+asPSYoungGen.cpp psYoungGen.hpp
+asPSYoungGen.cpp spaceDecorator.hpp
cardTableExtension.cpp cardTableExtension.hpp
cardTableExtension.cpp gcTaskManager.hpp
@@ -225,6 +227,7 @@
psMarkSweep.cpp referencePolicy.hpp
psMarkSweep.cpp referenceProcessor.hpp
psMarkSweep.cpp safepoint.hpp
+psMarkSweep.cpp spaceDecorator.hpp
psMarkSweep.cpp symbolTable.hpp
psMarkSweep.cpp systemDictionary.hpp
psMarkSweep.cpp vmThread.hpp
@@ -239,6 +242,7 @@
psMarkSweepDecorator.cpp parallelScavengeHeap.hpp
psMarkSweepDecorator.cpp psMarkSweep.hpp
psMarkSweepDecorator.cpp psMarkSweepDecorator.hpp
+psMarkSweepDecorator.cpp spaceDecorator.hpp
psMarkSweepDecorator.cpp systemDictionary.hpp
psMarkSweepDecorator.hpp mutableSpace.hpp
@@ -290,6 +294,7 @@
psOldGen.cpp parallelScavengeHeap.hpp
psOldGen.cpp psMarkSweepDecorator.hpp
psOldGen.cpp psOldGen.hpp
+psOldGen.cpp spaceDecorator.hpp
psOldGen.hpp psGenerationCounters.hpp
psOldGen.hpp mutableSpace.hpp
@@ -351,6 +356,7 @@
psScavenge.cpp referencePolicy.hpp
psScavenge.cpp referenceProcessor.hpp
psScavenge.cpp resourceArea.hpp
+psScavenge.cpp spaceDecorator.hpp
psScavenge.cpp threadCritical.hpp
psScavenge.cpp vmThread.hpp
psScavenge.cpp vm_operations.hpp
@@ -409,8 +415,8 @@
psVirtualspace.cpp os.hpp
psVirtualspace.cpp os_<os_family>.inline.hpp
-psVirtualspace.cpp psVirtualspace.hpp
-psVirtualspace.cpp virtualspace.hpp
+psVirtualspace.cpp psVirtualspace.hpp
+psVirtualspace.cpp virtualspace.hpp
psYoungGen.cpp gcUtil.hpp
psYoungGen.cpp java.hpp
@@ -419,7 +425,8 @@
psYoungGen.cpp psMarkSweepDecorator.hpp
psYoungGen.cpp psScavenge.hpp
psYoungGen.cpp psYoungGen.hpp
-psYoungGen.cpp mutableNUMASpace.hpp
+psYoungGen.cpp mutableNUMASpace.hpp
+psYoungGen.cpp spaceDecorator.hpp
psYoungGen.hpp psGenerationCounters.hpp
psYoungGen.hpp mutableSpace.hpp
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared Wed Jul 05 16:40:18 2017 +0200
@@ -56,6 +56,7 @@
mutableNUMASpace.cpp mutableNUMASpace.hpp
mutableNUMASpace.cpp oop.inline.hpp
mutableNUMASpace.cpp sharedHeap.hpp
+mutableNUMASpace.cpp spaceDecorator.hpp
mutableNUMASpace.cpp thread_<os_family>.inline.hpp
mutableNUMASpace.hpp mutableSpace.hpp
@@ -64,6 +65,7 @@
mutableSpace.cpp mutableSpace.hpp
mutableSpace.cpp oop.inline.hpp
mutableSpace.cpp safepoint.hpp
+mutableSpace.cpp spaceDecorator.hpp
mutableSpace.cpp thread.hpp
spaceCounters.cpp resourceArea.hpp
--- a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -162,10 +162,9 @@
// Grow the generation
size_t change = desired_size - orig_size;
assert(change % alignment == 0, "just checking");
- if (!virtual_space()->expand_by(change)) {
+ if (expand(change)) {
return false; // Error if we fail to resize!
}
-
size_changed = true;
} else if (desired_size < orig_size) {
size_t desired_change = orig_size - desired_size;
@@ -222,7 +221,9 @@
// Was there a shrink of the survivor space?
if (new_end < to()->end()) {
MemRegion mr(to()->bottom(), new_end);
- to()->initialize(mr, false /* clear */);
+ to()->initialize(mr,
+ SpaceDecorator::DontClear,
+ SpaceDecorator::DontMangle);
}
}
}
@@ -322,9 +323,7 @@
pointer_delta(from_start, eden_start, sizeof(char)));
}
-// tty->print_cr("eden_size before: " SIZE_FORMAT, eden_size);
eden_size = align_size_down(eden_size, alignment);
-// tty->print_cr("eden_size after: " SIZE_FORMAT, eden_size);
eden_end = eden_start + eden_size;
assert(eden_end >= eden_start, "addition overflowed")
@@ -501,11 +500,31 @@
size_t old_from = from()->capacity();
size_t old_to = to()->capacity();
+ // If not clearing the spaces, do some checking to verify that
+ // the spaces are already mangled.
+
+ // Must check mangling before the spaces are reshaped. Otherwise,
+ // the bottom or end of one space may have moved into another
+ // a failure of the check may not correctly indicate which space
+ // is not properly mangled.
+ if (ZapUnusedHeapArea) {
+ HeapWord* limit = (HeapWord*) virtual_space()->high();
+ eden()->check_mangled_unused_area(limit);
+ from()->check_mangled_unused_area(limit);
+ to()->check_mangled_unused_area(limit);
+ }
+
// The call to initialize NULL's the next compaction space
- eden()->initialize(edenMR, true);
+ eden()->initialize(edenMR,
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
eden()->set_next_compaction_space(from());
- to()->initialize(toMR , true);
- from()->initialize(fromMR, false); // Note, not cleared!
+ to()->initialize(toMR ,
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
+ from()->initialize(fromMR,
+ SpaceDecorator::DontClear,
+ SpaceDecorator::DontMangle);
assert(from()->top() == old_from_top, "from top changed!");
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -727,7 +727,7 @@
SpecializationStats::clear();
age_table()->clear();
- to()->clear();
+ to()->clear(SpaceDecorator::Mangle);
gch->save_marks();
assert(workers != NULL, "Need parallel worker threads.");
@@ -793,8 +793,18 @@
}
if (!promotion_failed()) {
// Swap the survivor spaces.
- eden()->clear();
- from()->clear();
+ eden()->clear(SpaceDecorator::Mangle);
+ from()->clear(SpaceDecorator::Mangle);
+ if (ZapUnusedHeapArea) {
+ // This is now done here because of the piece-meal mangling which
+ // can check for valid mangling at intermediate points in the
+ // collection(s). When a minor collection fails to collect
+ // sufficient space resizing of the young generation can occur
+ // an redistribute the spaces in the young generation. Mangle
+ // here so that unzapped regions don't get distributed to
+ // other spaces.
+ to()->mangle_unused_area();
+ }
swap_spaces();
assert(to()->is_empty(), "to space should be empty now");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -170,9 +170,20 @@
if (desired_size > orig_size) {
// Grow the generation
size_t change = desired_size - orig_size;
+ HeapWord* prev_low = (HeapWord*) virtual_space()->low();
if (!virtual_space()->expand_by(change)) {
return false;
}
+ if (ZapUnusedHeapArea) {
+ // Mangle newly committed space immediately because it
+ // can be done here more simply that after the new
+ // spaces have been computed.
+ HeapWord* new_low = (HeapWord*) virtual_space()->low();
+ assert(new_low < prev_low, "Did not grow");
+
+ MemRegion mangle_region(new_low, prev_low);
+ SpaceMangler::mangle_region(mangle_region);
+ }
size_changed = true;
} else if (desired_size < orig_size) {
size_t desired_change = orig_size - desired_size;
@@ -215,8 +226,10 @@
// current implementation does not allow holes between the spaces
// _young_generation_boundary has to be reset because it changes.
// so additional verification
+
void ASPSYoungGen::resize_spaces(size_t requested_eden_size,
size_t requested_survivor_size) {
+ assert(UseAdaptiveSizePolicy, "sanity check");
assert(requested_eden_size > 0 && requested_survivor_size > 0,
"just checking");
@@ -276,22 +289,42 @@
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
const size_t alignment = heap->intra_heap_alignment();
+ const bool maintain_minimum =
+ (requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
+ bool eden_from_to_order = from_start < to_start;
// Check whether from space is below to space
- if (from_start < to_start) {
+ if (eden_from_to_order) {
// Eden, from, to
+
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr(" Eden, from, to:");
}
// Set eden
- // Compute how big eden can be, then adjust end.
- // See comment in PSYoungGen::resize_spaces() on
- // calculating eden_end.
- const size_t eden_size = MIN2(requested_eden_size,
- pointer_delta(from_start,
- eden_start,
- sizeof(char)));
+ // "requested_eden_size" is a goal for the size of eden
+ // and may not be attainable. "eden_size" below is
+ // calculated based on the location of from-space and
+ // the goal for the size of eden. from-space is
+ // fixed in place because it contains live data.
+ // The calculation is done this way to avoid 32bit
+ // overflow (i.e., eden_start + requested_eden_size
+ // may too large for representation in 32bits).
+ size_t eden_size;
+ if (maintain_minimum) {
+ // Only make eden larger than the requested size if
+ // the minimum size of the generation has to be maintained.
+ // This could be done in general but policy at a higher
+ // level is determining a requested size for eden and that
+ // should be honored unless there is a fundamental reason.
+ eden_size = pointer_delta(from_start,
+ eden_start,
+ sizeof(char));
+ } else {
+ eden_size = MIN2(requested_eden_size,
+ pointer_delta(from_start, eden_start, sizeof(char)));
+ }
+
eden_end = eden_start + eden_size;
assert(eden_end >= eden_start, "addition overflowed")
@@ -371,12 +404,14 @@
to_start = MAX2(to_start, eden_start + alignment);
// Compute how big eden can be, then adjust end.
- // See comment in PSYoungGen::resize_spaces() on
- // calculating eden_end.
- const size_t eden_size = MIN2(requested_eden_size,
- pointer_delta(to_start,
- eden_start,
- sizeof(char)));
+ // See comments above on calculating eden_end.
+ size_t eden_size;
+ if (maintain_minimum) {
+ eden_size = pointer_delta(to_start, eden_start, sizeof(char));
+ } else {
+ eden_size = MIN2(requested_eden_size,
+ pointer_delta(to_start, eden_start, sizeof(char)));
+ }
eden_end = eden_start + eden_size;
assert(eden_end >= eden_start, "addition overflowed")
@@ -423,9 +458,47 @@
size_t old_from = from_space()->capacity_in_bytes();
size_t old_to = to_space()->capacity_in_bytes();
- eden_space()->initialize(edenMR, true);
- to_space()->initialize(toMR , true);
- from_space()->initialize(fromMR, false); // Note, not cleared!
+ if (ZapUnusedHeapArea) {
+ // NUMA is a special case because a numa space is not mangled
+ // in order to not prematurely bind its address to memory to
+ // the wrong memory (i.e., don't want the GC thread to first
+ // touch the memory). The survivor spaces are not numa
+ // spaces and are mangled.
+ if (UseNUMA) {
+ if (eden_from_to_order) {
+ mangle_survivors(from_space(), fromMR, to_space(), toMR);
+ } else {
+ mangle_survivors(to_space(), toMR, from_space(), fromMR);
+ }
+ }
+
+ // If not mangling the spaces, do some checking to verify that
+ // the spaces are already mangled.
+ // The spaces should be correctly mangled at this point so
+ // do some checking here. Note that they are not being mangled
+ // in the calls to initialize().
+ // Must check mangling before the spaces are reshaped. Otherwise,
+ // the bottom or end of one space may have moved into an area
+ // covered by another space and a failure of the check may
+ // not correctly indicate which space is not properly mangled.
+
+ HeapWord* limit = (HeapWord*) virtual_space()->high();
+ eden_space()->check_mangled_unused_area(limit);
+ from_space()->check_mangled_unused_area(limit);
+ to_space()->check_mangled_unused_area(limit);
+ }
+ // When an existing space is being initialized, it is not
+ // mangled because the space has been previously mangled.
+ eden_space()->initialize(edenMR,
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
+ to_space()->initialize(toMR,
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
+ from_space()->initialize(fromMR,
+ SpaceDecorator::DontClear,
+ SpaceDecorator::DontMangle);
+
PSScavenge::set_young_generation_boundary(eden_space()->bottom());
assert(from_space()->top() == old_from_top, "from top changed!");
@@ -446,7 +519,6 @@
}
space_invariants();
}
-
void ASPSYoungGen::reset_after_change() {
assert_locked_or_safepoint(Heap_lock);
@@ -458,7 +530,9 @@
HeapWord* eden_bottom = eden_space()->bottom();
if (new_eden_bottom != eden_bottom) {
MemRegion eden_mr(new_eden_bottom, eden_space()->end());
- eden_space()->initialize(eden_mr, true);
+ eden_space()->initialize(eden_mr,
+ SpaceDecorator::Clear,
+ SpaceDecorator::Mangle);
PSScavenge::set_young_generation_boundary(eden_space()->bottom());
}
MemRegion cmr((HeapWord*)virtual_space()->low(),
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -666,9 +666,9 @@
HeapWord* new_end_for_commit =
MIN2(cur_committed.end(), _guard_region.start());
- MemRegion new_committed =
- MemRegion(new_start_aligned, new_end_for_commit);
- if(!new_committed.is_empty()) {
+ if(new_start_aligned < new_end_for_commit) {
+ MemRegion new_committed =
+ MemRegion(new_start_aligned, new_end_for_commit);
if (!os::commit_memory((char*)new_committed.start(),
new_committed.byte_size())) {
vm_exit_out_of_memory(new_committed.byte_size(),
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -938,3 +938,23 @@
// Delegate the resize to the generation.
_old_gen->resize(desired_free_space);
}
+
+#ifndef PRODUCT
+void ParallelScavengeHeap::record_gen_tops_before_GC() {
+ if (ZapUnusedHeapArea) {
+ young_gen()->record_spaces_top();
+ old_gen()->record_spaces_top();
+ perm_gen()->record_spaces_top();
+ }
+}
+
+void ParallelScavengeHeap::gen_mangle_unused_area() {
+ if (ZapUnusedHeapArea) {
+ young_gen()->eden_space()->mangle_unused_area();
+ young_gen()->to_space()->mangle_unused_area();
+ young_gen()->from_space()->mangle_unused_area();
+ old_gen()->object_space()->mangle_unused_area();
+ perm_gen()->object_space()->mangle_unused_area();
+ }
+}
+#endif
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -213,6 +213,12 @@
// Resize the old generation. The reserved space for the
// generation may be expanded in preparation for the resize.
void resize_old_gen(size_t desired_free_space);
+
+ // Save the tops of the spaces in all generations
+ void record_gen_tops_before_GC() PRODUCT_RETURN;
+
+ // Mangle the unused parts of all spaces in the heap
+ void gen_mangle_unused_area() PRODUCT_RETURN;
};
inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val)
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -98,6 +98,9 @@
// Increment the invocation count
heap->increment_total_collections(true /* full */);
+ // Save information needed to minimize mangling
+ heap->record_gen_tops_before_GC();
+
// We need to track unique mark sweep invocations as well.
_total_invocations++;
@@ -188,6 +191,12 @@
deallocate_stacks();
+ if (ZapUnusedHeapArea) {
+ // Do a complete mangle (top to end) because the usage for
+ // scratch does not maintain a top pointer.
+ young_gen->to_space()->mangle_unused_area_complete();
+ }
+
eden_empty = young_gen->eden_space()->is_empty();
if (!eden_empty) {
eden_empty = absorb_live_data_from_eden(size_policy, young_gen, old_gen);
@@ -198,7 +207,7 @@
Universe::update_heap_info_at_gc();
survivors_empty = young_gen->from_space()->is_empty() &&
- young_gen->to_space()->is_empty();
+ young_gen->to_space()->is_empty();
young_gen_empty = eden_empty && survivors_empty;
BarrierSet* bs = heap->barrier_set();
@@ -344,6 +353,11 @@
perm_gen->verify_object_start_array();
}
+ if (ZapUnusedHeapArea) {
+ old_gen->object_space()->check_mangled_unused_area_complete();
+ perm_gen->object_space()->check_mangled_unused_area_complete();
+ }
+
NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
if (PrintHeapAtGC) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -438,5 +438,7 @@
"should point inside space");
space()->set_top(compaction_top());
- if (mangle_free_space) space()->mangle_unused_area();
+ if (mangle_free_space) {
+ space()->mangle_unused_area();
+ }
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -87,6 +87,15 @@
MemRegion cmr((HeapWord*)virtual_space()->low(),
(HeapWord*)virtual_space()->high());
+ if (ZapUnusedHeapArea) {
+ // Mangle newly committed space immediately rather than
+ // waiting for the initialization of the space even though
+ // mangling is related to spaces. Doing it here eliminates
+ // the need to carry along information that a complete mangling
+ // (bottom to end) needs to be done.
+ SpaceMangler::mangle_region(cmr);
+ }
+
Universe::heap()->barrier_set()->resize_covered_region(cmr);
CardTableModRefBS* _ct = (CardTableModRefBS*)Universe::heap()->barrier_set();
@@ -112,7 +121,9 @@
if (_object_space == NULL)
vm_exit_during_initialization("Could not allocate an old gen space");
- object_space()->initialize(cmr, true);
+ object_space()->initialize(cmr,
+ SpaceDecorator::Clear,
+ SpaceDecorator::Mangle);
_object_mark_sweep = new PSMarkSweepDecorator(_object_space, start_array(), MarkSweepDeadRatio);
@@ -204,10 +215,22 @@
}
void PSOldGen::expand(size_t bytes) {
+ if (bytes == 0) {
+ return;
+ }
MutexLocker x(ExpandHeap_lock);
const size_t alignment = virtual_space()->alignment();
size_t aligned_bytes = align_size_up(bytes, alignment);
size_t aligned_expand_bytes = align_size_up(MinHeapDeltaBytes, alignment);
+ if (aligned_bytes == 0){
+ // The alignment caused the number of bytes to wrap. An expand_by(0) will
+ // return true with the implication that and expansion was done when it
+ // was not. A call to expand implies a best effort to expand by "bytes"
+ // but not a guarantee. Align down to give a best effort. This is likely
+ // the most that the generation can expand since it has some capacity to
+ // start with.
+ aligned_bytes = align_size_down(bytes, alignment);
+ }
bool success = false;
if (aligned_expand_bytes > aligned_bytes) {
@@ -220,8 +243,8 @@
success = expand_to_reserved();
}
- if (GC_locker::is_active()) {
- if (PrintGC && Verbose) {
+ if (PrintGC && Verbose) {
+ if (success && GC_locker::is_active()) {
gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
}
}
@@ -230,8 +253,24 @@
bool PSOldGen::expand_by(size_t bytes) {
assert_lock_strong(ExpandHeap_lock);
assert_locked_or_safepoint(Heap_lock);
+ if (bytes == 0) {
+ return true; // That's what virtual_space()->expand_by(0) would return
+ }
bool result = virtual_space()->expand_by(bytes);
if (result) {
+ if (ZapUnusedHeapArea) {
+ // We need to mangle the newly expanded area. The memregion spans
+ // end -> new_end, we assume that top -> end is already mangled.
+ // Do the mangling before post_resize() is called because
+ // the space is available for allocation after post_resize();
+ HeapWord* const virtual_space_high = (HeapWord*) virtual_space()->high();
+ assert(object_space()->end() < virtual_space_high,
+ "Should be true before post_resize()");
+ MemRegion mangle_region(object_space()->end(), virtual_space_high);
+ // Note that the object space has not yet been updated to
+ // coincede with the new underlying virtual space.
+ SpaceMangler::mangle_region(mangle_region);
+ }
post_resize();
if (UsePerfData) {
_space_counters->update_capacity();
@@ -348,16 +387,7 @@
start_array()->set_covered_region(new_memregion);
Universe::heap()->barrier_set()->resize_covered_region(new_memregion);
- // Did we expand?
HeapWord* const virtual_space_high = (HeapWord*) virtual_space()->high();
- if (object_space()->end() < virtual_space_high) {
- // We need to mangle the newly expanded area. The memregion spans
- // end -> new_end, we assume that top -> end is already mangled.
- // This cannot be safely tested for, as allocation may be taking
- // place.
- MemRegion mangle_region(object_space()->end(), virtual_space_high);
- object_space()->mangle_region(mangle_region);
- }
// ALWAYS do this last!!
object_space()->set_end(virtual_space_high);
@@ -462,3 +492,10 @@
VerifyObjectStartArrayClosure check( this, &_start_array );
object_iterate(&check);
}
+
+#ifndef PRODUCT
+void PSOldGen::record_spaces_top() {
+ assert(ZapUnusedHeapArea, "Not mangling unused space");
+ object_space()->set_top_for_allocations();
+}
+#endif
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -185,4 +185,8 @@
// Printing support
virtual const char* name() const { return _name; }
+
+ // Debugging support
+ // Save the tops of all spaces for later use during mangling.
+ void record_spaces_top() PRODUCT_RETURN;
};
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -200,8 +200,8 @@
for (unsigned int id = 0; id < last_space_id; ++id) {
const MutableSpace* space = _space_info[id].space();
tty->print_cr("%u %s "
- SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " "
- SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " ",
+ SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "
+ SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",
id, space_names[id],
summary_data().addr_to_chunk_idx(space->bottom()),
summary_data().addr_to_chunk_idx(space->top()),
@@ -213,8 +213,8 @@
void
print_generic_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c)
{
-#define CHUNK_IDX_FORMAT SIZE_FORMAT_W("7")
-#define CHUNK_DATA_FORMAT SIZE_FORMAT_W("5")
+#define CHUNK_IDX_FORMAT SIZE_FORMAT_W(7)
+#define CHUNK_DATA_FORMAT SIZE_FORMAT_W(5)
ParallelCompactData& sd = PSParallelCompact::summary_data();
size_t dci = c->destination() ? sd.addr_to_chunk_idx(c->destination()) : 0;
@@ -269,9 +269,9 @@
const ParallelCompactData::ChunkData* c,
bool newline = true)
{
- tty->print(SIZE_FORMAT_W("5") " " PTR_FORMAT " "
- SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " "
- SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " %d",
+ tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " "
+ SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " "
+ SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
i, c->destination(),
c->partial_obj_size(), c->live_obj_size(),
c->data_size(), c->source_chunk(), c->destination_count());
@@ -326,7 +326,7 @@
}
print_initial_summary_chunk(i, c, false);
- tty->print_cr(" %12.10f " SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10"),
+ tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),
reclaimed_ratio, dead_to_right, live_to_right);
live_to_right -= c->data_size();
@@ -338,8 +338,8 @@
print_initial_summary_chunk(i, summary_data.chunk(i));
}
- tty->print_cr("max: " SIZE_FORMAT_W("4") " d2r=" SIZE_FORMAT_W("10") " "
- "l2r=" SIZE_FORMAT_W("10") " max_ratio=%14.12f",
+ tty->print_cr("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " "
+ "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",
max_reclaimed_ratio_chunk, max_dead_to_right,
max_live_to_right, max_reclaimed_ratio);
}
@@ -1060,6 +1060,10 @@
ref_processor()->enqueue_discovered_references(NULL);
+ if (ZapUnusedHeapArea) {
+ heap->gen_mangle_unused_area();
+ }
+
// Update time of last GC
reset_millis_since_last_gc();
}
@@ -1119,8 +1123,8 @@
HeapWord* chunk_destination = cp->destination();
const size_t cur_deadwood = pointer_delta(dense_prefix, chunk_destination);
if (TraceParallelOldGCDensePrefix && Verbose) {
- tty->print_cr("c#=" SIZE_FORMAT_W("04") " dst=" PTR_FORMAT " "
- "dp=" SIZE_FORMAT_W("08") " " "cdw=" SIZE_FORMAT_W("08"),
+ tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " "
+ "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8),
sd.chunk(cp), chunk_destination,
dense_prefix, cur_deadwood);
}
@@ -1145,7 +1149,7 @@
return dense_prefix;
}
if (TraceParallelOldGCDensePrefix && Verbose) {
- tty->print_cr("backing up from c=" SIZE_FORMAT_W("4") " d2r=%10.8f "
+ tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f "
"pc_d2r=%10.8f", sd.chunk(cp), density_to_right,
prev_chunk_density_to_right);
}
@@ -1182,7 +1186,7 @@
const size_t live_to_right = new_top - cp->destination();
const size_t dead_to_right = space->top() - addr - live_to_right;
- tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W("05") " "
+ tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " "
"spl=" SIZE_FORMAT " "
"d2l=" SIZE_FORMAT " d2l%%=%6.4f "
"d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT
@@ -1522,48 +1526,53 @@
PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)
{
assert(id < last_space_id, "id out of range");
+ assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom(),
+ "should have been set in summarize_spaces_quick()");
const MutableSpace* space = _space_info[id].space();
- HeapWord** new_top_addr = _space_info[id].new_top_addr();
-
- HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction);
- _space_info[id].set_dense_prefix(dense_prefix_end);
+ if (_space_info[id].new_top() != space->bottom()) {
+ HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction);
+ _space_info[id].set_dense_prefix(dense_prefix_end);
#ifndef PRODUCT
- if (TraceParallelOldGCDensePrefix) {
- print_dense_prefix_stats("ratio", id, maximum_compaction, dense_prefix_end);
- HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction);
- print_dense_prefix_stats("density", id, maximum_compaction, addr);
- }
+ if (TraceParallelOldGCDensePrefix) {
+ print_dense_prefix_stats("ratio", id, maximum_compaction,
+ dense_prefix_end);
+ HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction);
+ print_dense_prefix_stats("density", id, maximum_compaction, addr);
+ }
#endif // #ifndef PRODUCT
- // If dead space crosses the dense prefix boundary, it is (at least partially)
- // filled with a dummy object, marked live and added to the summary data.
- // This simplifies the copy/update phase and must be done before the final
- // locations of objects are determined, to prevent leaving a fragment of dead
- // space that is too small to fill with an object.
- if (!maximum_compaction && dense_prefix_end != space->bottom()) {
- fill_dense_prefix_end(id);
+ // If dead space crosses the dense prefix boundary, it is (at least
+ // partially) filled with a dummy object, marked live and added to the
+ // summary data. This simplifies the copy/update phase and must be done
+ // before the final locations of objects are determined, to prevent leaving
+ // a fragment of dead space that is too small to fill with an object.
+ if (!maximum_compaction && dense_prefix_end != space->bottom()) {
+ fill_dense_prefix_end(id);
+ }
+
+ // Compute the destination of each Chunk, and thus each object.
+ _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
+ _summary_data.summarize(dense_prefix_end, space->end(),
+ dense_prefix_end, space->top(),
+ _space_info[id].new_top_addr());
}
- // Compute the destination of each Chunk, and thus each object.
- _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
- _summary_data.summarize(dense_prefix_end, space->end(),
- dense_prefix_end, space->top(),
- new_top_addr);
-
if (TraceParallelOldGCSummaryPhase) {
const size_t chunk_size = ParallelCompactData::ChunkSize;
+ HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();
const size_t dp_chunk = _summary_data.addr_to_chunk_idx(dense_prefix_end);
const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom());
- const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(*new_top_addr);
+ HeapWord* const new_top = _space_info[id].new_top();
+ const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(new_top);
const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);
tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
"dp_chunk=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
"cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
id, space->capacity_in_words(), dense_prefix_end,
dp_chunk, dp_words / chunk_size,
- cr_words / chunk_size, *new_top_addr);
+ cr_words / chunk_size, new_top);
}
}
@@ -1632,7 +1641,7 @@
const size_t live = pointer_delta(_space_info[id].new_top(),
space->bottom());
const size_t available = pointer_delta(target_space_end, *new_top_addr);
- if (live <= available) {
+ if (live > 0 && live <= available) {
// All the live data will fit.
if (TraceParallelOldGCSummaryPhase) {
tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT,
@@ -1642,16 +1651,18 @@
space->bottom(), space->top(),
new_top_addr);
- // Reset the new_top value for the space.
- _space_info[id].set_new_top(space->bottom());
-
// Clear the source_chunk field for each chunk in the space.
+ HeapWord* const new_top = _space_info[id].new_top();
+ HeapWord* const clear_end = _summary_data.chunk_align_up(new_top);
ChunkData* beg_chunk = _summary_data.addr_to_chunk_ptr(space->bottom());
- ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(space->top() - 1);
- while (beg_chunk <= end_chunk) {
+ ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(clear_end);
+ while (beg_chunk < end_chunk) {
beg_chunk->set_source_chunk(0);
++beg_chunk;
}
+
+ // Reset the new_top value for the space.
+ _space_info[id].set_new_top(space->bottom());
}
}
@@ -1961,6 +1972,11 @@
PSPermGen* perm_gen = heap->perm_gen();
PSAdaptiveSizePolicy* size_policy = heap->size_policy();
+ if (ZapUnusedHeapArea) {
+ // Save information needed to minimize mangling
+ heap->record_gen_tops_before_GC();
+ }
+
_print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes;
// Make sure data structures are sane, make the heap parsable, and do other
@@ -2129,17 +2145,19 @@
size_t max_eden_size = young_gen->max_size() -
young_gen->from_space()->capacity_in_bytes() -
young_gen->to_space()->capacity_in_bytes();
- size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
- young_gen->eden_space()->used_in_bytes(),
- old_gen->used_in_bytes(),
- perm_gen->used_in_bytes(),
- young_gen->eden_space()->capacity_in_bytes(),
- old_gen->max_gen_size(),
- max_eden_size,
- true /* full gc*/,
- gc_cause);
-
- heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes());
+ size_policy->compute_generation_free_space(
+ young_gen->used_in_bytes(),
+ young_gen->eden_space()->used_in_bytes(),
+ old_gen->used_in_bytes(),
+ perm_gen->used_in_bytes(),
+ young_gen->eden_space()->capacity_in_bytes(),
+ old_gen->max_gen_size(),
+ max_eden_size,
+ true /* full gc*/,
+ gc_cause);
+
+ heap->resize_old_gen(
+ size_policy->calculated_old_free_size_in_bytes());
// Don't resize the young generation at an major collection. A
// desired young generation size may have been calculated but
@@ -2212,6 +2230,11 @@
perm_gen->verify_object_start_array();
}
+ if (ZapUnusedHeapArea) {
+ old_gen->object_space()->check_mangled_unused_area_complete();
+ perm_gen->object_space()->check_mangled_unused_area_complete();
+ }
+
NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
collection_exit.update();
@@ -2499,7 +2522,7 @@
if (TraceParallelOldGCCompactionPhase && Verbose) {
const size_t count_mod_8 = fillable_chunks & 7;
if (count_mod_8 == 0) gclog_or_tty->print("fillable: ");
- gclog_or_tty->print(" " SIZE_FORMAT_W("7"), cur);
+ gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur);
if (count_mod_8 == 7) gclog_or_tty->cr();
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -716,6 +716,99 @@
virtual IterationStatus do_addr(HeapWord* addr, size_t words);
};
+// The UseParallelOldGC collector is a stop-the-world garbage
+// collector that does parts of the collection using parallel threads.
+// The collection includes the tenured generation and the young
+// generation. The permanent generation is collected at the same
+// time as the other two generations but the permanent generation
+// is collect by a single GC thread. The permanent generation is
+// collected serially because of the requirement that during the
+// processing of a klass AAA, any objects reference by AAA must
+// already have been processed. This requirement is enforced by
+// a left (lower address) to right (higher address) sliding compaction.
+//
+// There are four phases of the collection.
+//
+// - marking phase
+// - summary phase
+// - compacting phase
+// - clean up phase
+//
+// Roughly speaking these phases correspond, respectively, to
+// - mark all the live objects
+// - calculate the destination of each object at the end of the collection
+// - move the objects to their destination
+// - update some references and reinitialize some variables
+//
+// These three phases are invoked in PSParallelCompact::invoke_no_policy().
+// The marking phase is implemented in PSParallelCompact::marking_phase()
+// and does a complete marking of the heap.
+// The summary phase is implemented in PSParallelCompact::summary_phase().
+// The move and update phase is implemented in PSParallelCompact::compact().
+//
+// A space that is being collected is divided into chunks and with
+// each chunk is associated an object of type ParallelCompactData.
+// Each chunk is of a fixed size and typically will contain more than
+// 1 object and may have parts of objects at the front and back of the
+// chunk.
+//
+// chunk -----+---------------------+----------
+// objects covered [ AAA )[ BBB )[ CCC )[ DDD )
+//
+// The marking phase does a complete marking of all live objects in the
+// heap. The marking also compiles the size of the data for
+// all live objects covered by the chunk. This size includes the
+// part of any live object spanning onto the chunk (part of AAA
+// if it is live) from the front, all live objects contained in the chunk
+// (BBB and/or CCC if they are live), and the part of any live objects
+// covered by the chunk that extends off the chunk (part of DDD if it is
+// live). The marking phase uses multiple GC threads and marking is
+// done in a bit array of type ParMarkBitMap. The marking of the
+// bit map is done atomically as is the accumulation of the size of the
+// live objects covered by a chunk.
+//
+// The summary phase calculates the total live data to the left of
+// each chunk XXX. Based on that total and the bottom of the space,
+// it can calculate the starting location of the live data in XXX.
+// The summary phase calculates for each chunk XXX quantites such as
+//
+// - the amount of live data at the beginning of a chunk from an object
+// entering the chunk.
+// - the location of the first live data on the chunk
+// - a count of the number of chunks receiving live data from XXX.
+//
+// See ParallelCompactData for precise details. The summary phase also
+// calculates the dense prefix for the compaction. The dense prefix
+// is a portion at the beginning of the space that is not moved. The
+// objects in the dense prefix do need to have their object references
+// updated. See method summarize_dense_prefix().
+//
+// The summary phase is done using 1 GC thread.
+//
+// The compaction phase moves objects to their new location and updates
+// all references in the object.
+//
+// A current exception is that objects that cross a chunk boundary
+// are moved but do not have their references updated. References are
+// not updated because it cannot easily be determined if the klass
+// pointer KKK for the object AAA has been updated. KKK likely resides
+// in a chunk to the left of the chunk containing AAA. These AAA's
+// have there references updated at the end in a clean up phase.
+// See the method PSParallelCompact::update_deferred_objects(). An
+// alternate strategy is being investigated for this deferral of updating.
+//
+// Compaction is done on a chunk basis. A chunk that is ready to be
+// filled is put on a ready list and GC threads take chunk off the list
+// and fill them. A chunk is ready to be filled if it
+// empty of live objects. Such a chunk may have been initially
+// empty (only contained
+// dead objects) or may have had all its live objects copied out already.
+// A chunk that compacts into itself is also ready for filling. The
+// ready list is initially filled with empty chunks and chunks compacting
+// into themselves. There is always at least 1 chunk that can be put on
+// the ready list. The chunks are atomically added and removed from
+// the ready list.
+//
class PSParallelCompact : AllStatic {
public:
// Convenient access to type names.
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -265,6 +265,11 @@
young_gen->eden_space()->accumulate_statistics();
}
+ if (ZapUnusedHeapArea) {
+ // Save information needed to minimize mangling
+ heap->record_gen_tops_before_GC();
+ }
+
if (PrintHeapAtGC) {
Universe::print_heap_before_gc();
}
@@ -315,7 +320,7 @@
if (!ScavengeWithObjectsInToSpace) {
assert(young_gen->to_space()->is_empty(),
"Attempt to scavenge with live objects in to_space");
- young_gen->to_space()->clear();
+ young_gen->to_space()->clear(SpaceDecorator::Mangle);
} else if (ZapUnusedHeapArea) {
young_gen->to_space()->mangle_unused_area();
}
@@ -437,8 +442,10 @@
if (!promotion_failure_occurred) {
// Swap the survivor spaces.
- young_gen->eden_space()->clear();
- young_gen->from_space()->clear();
+
+
+ young_gen->eden_space()->clear(SpaceDecorator::Mangle);
+ young_gen->from_space()->clear(SpaceDecorator::Mangle);
young_gen->swap_spaces();
size_t survived = young_gen->from_space()->used_in_bytes();
@@ -600,6 +607,12 @@
Universe::print_heap_after_gc();
}
+ if (ZapUnusedHeapArea) {
+ young_gen->eden_space()->check_mangled_unused_area_complete();
+ young_gen->from_space()->check_mangled_unused_area_complete();
+ young_gen->to_space()->check_mangled_unused_area_complete();
+ }
+
scavenge_exit.update();
if (PrintGCTaskTimeStamps) {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -36,7 +36,7 @@
void PSYoungGen::initialize_virtual_space(ReservedSpace rs, size_t alignment) {
assert(_init_gen_size != 0, "Should have a finite size");
_virtual_space = new PSVirtualSpace(rs, alignment);
- if (!_virtual_space->expand_by(_init_gen_size)) {
+ if (!virtual_space()->expand_by(_init_gen_size)) {
vm_exit_during_initialization("Could not reserve enough space for "
"object heap");
}
@@ -49,12 +49,19 @@
void PSYoungGen::initialize_work() {
- _reserved = MemRegion((HeapWord*)_virtual_space->low_boundary(),
- (HeapWord*)_virtual_space->high_boundary());
+ _reserved = MemRegion((HeapWord*)virtual_space()->low_boundary(),
+ (HeapWord*)virtual_space()->high_boundary());
+
+ MemRegion cmr((HeapWord*)virtual_space()->low(),
+ (HeapWord*)virtual_space()->high());
+ Universe::heap()->barrier_set()->resize_covered_region(cmr);
- MemRegion cmr((HeapWord*)_virtual_space->low(),
- (HeapWord*)_virtual_space->high());
- Universe::heap()->barrier_set()->resize_covered_region(cmr);
+ if (ZapUnusedHeapArea) {
+ // Mangle newly committed space immediately because it
+ // can be done here more simply that after the new
+ // spaces have been computed.
+ SpaceMangler::mangle_region(cmr);
+ }
if (UseNUMA) {
_eden_space = new MutableNUMASpace();
@@ -89,7 +96,7 @@
// Compute maximum space sizes for performance counters
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
size_t alignment = heap->intra_heap_alignment();
- size_t size = _virtual_space->reserved_size();
+ size_t size = virtual_space()->reserved_size();
size_t max_survivor_size;
size_t max_eden_size;
@@ -142,7 +149,7 @@
// Compute sizes
size_t alignment = heap->intra_heap_alignment();
- size_t size = _virtual_space->committed_size();
+ size_t size = virtual_space()->committed_size();
size_t survivor_size = size / InitialSurvivorRatio;
survivor_size = align_size_down(survivor_size, alignment);
@@ -164,18 +171,18 @@
}
void PSYoungGen::set_space_boundaries(size_t eden_size, size_t survivor_size) {
- assert(eden_size < _virtual_space->committed_size(), "just checking");
+ assert(eden_size < virtual_space()->committed_size(), "just checking");
assert(eden_size > 0 && survivor_size > 0, "just checking");
// Initial layout is Eden, to, from. After swapping survivor spaces,
// that leaves us with Eden, from, to, which is step one in our two
// step resize-with-live-data procedure.
- char *eden_start = _virtual_space->low();
+ char *eden_start = virtual_space()->low();
char *to_start = eden_start + eden_size;
char *from_start = to_start + survivor_size;
char *from_end = from_start + survivor_size;
- assert(from_end == _virtual_space->high(), "just checking");
+ assert(from_end == virtual_space()->high(), "just checking");
assert(is_object_aligned((intptr_t)eden_start), "checking alignment");
assert(is_object_aligned((intptr_t)to_start), "checking alignment");
assert(is_object_aligned((intptr_t)from_start), "checking alignment");
@@ -184,9 +191,9 @@
MemRegion to_mr ((HeapWord*)to_start, (HeapWord*)from_start);
MemRegion from_mr((HeapWord*)from_start, (HeapWord*)from_end);
- eden_space()->initialize(eden_mr, true);
- to_space()->initialize(to_mr , true);
- from_space()->initialize(from_mr, true);
+ eden_space()->initialize(eden_mr, true, ZapUnusedHeapArea);
+ to_space()->initialize(to_mr , true, ZapUnusedHeapArea);
+ from_space()->initialize(from_mr, true, ZapUnusedHeapArea);
}
#ifndef PRODUCT
@@ -207,7 +214,7 @@
char* to_start = (char*)to_space()->bottom();
char* to_end = (char*)to_space()->end();
- guarantee(eden_start >= _virtual_space->low(), "eden bottom");
+ guarantee(eden_start >= virtual_space()->low(), "eden bottom");
guarantee(eden_start < eden_end, "eden space consistency");
guarantee(from_start < from_end, "from space consistency");
guarantee(to_start < to_end, "to space consistency");
@@ -217,29 +224,29 @@
// Eden, from, to
guarantee(eden_end <= from_start, "eden/from boundary");
guarantee(from_end <= to_start, "from/to boundary");
- guarantee(to_end <= _virtual_space->high(), "to end");
+ guarantee(to_end <= virtual_space()->high(), "to end");
} else {
// Eden, to, from
guarantee(eden_end <= to_start, "eden/to boundary");
guarantee(to_end <= from_start, "to/from boundary");
- guarantee(from_end <= _virtual_space->high(), "from end");
+ guarantee(from_end <= virtual_space()->high(), "from end");
}
// More checks that the virtual space is consistent with the spaces
- assert(_virtual_space->committed_size() >=
+ assert(virtual_space()->committed_size() >=
(eden_space()->capacity_in_bytes() +
to_space()->capacity_in_bytes() +
from_space()->capacity_in_bytes()), "Committed size is inconsistent");
- assert(_virtual_space->committed_size() <= _virtual_space->reserved_size(),
+ assert(virtual_space()->committed_size() <= virtual_space()->reserved_size(),
"Space invariant");
char* eden_top = (char*)eden_space()->top();
char* from_top = (char*)from_space()->top();
char* to_top = (char*)to_space()->top();
- assert(eden_top <= _virtual_space->high(), "eden top");
- assert(from_top <= _virtual_space->high(), "from top");
- assert(to_top <= _virtual_space->high(), "to top");
+ assert(eden_top <= virtual_space()->high(), "eden top");
+ assert(from_top <= virtual_space()->high(), "from top");
+ assert(to_top <= virtual_space()->high(), "to top");
- _virtual_space->verify();
+ virtual_space()->verify();
}
#endif
@@ -265,8 +272,8 @@
bool PSYoungGen::resize_generation(size_t eden_size, size_t survivor_size) {
- const size_t alignment = _virtual_space->alignment();
- size_t orig_size = _virtual_space->committed_size();
+ const size_t alignment = virtual_space()->alignment();
+ size_t orig_size = virtual_space()->committed_size();
bool size_changed = false;
// There used to be this guarantee there.
@@ -288,10 +295,18 @@
// Grow the generation
size_t change = desired_size - orig_size;
assert(change % alignment == 0, "just checking");
- if (!_virtual_space->expand_by(change)) {
+ HeapWord* prev_high = (HeapWord*) virtual_space()->high();
+ if (!virtual_space()->expand_by(change)) {
return false; // Error if we fail to resize!
}
-
+ if (ZapUnusedHeapArea) {
+ // Mangle newly committed space immediately because it
+ // can be done here more simply that after the new
+ // spaces have been computed.
+ HeapWord* new_high = (HeapWord*) virtual_space()->high();
+ MemRegion mangle_region(prev_high, new_high);
+ SpaceMangler::mangle_region(mangle_region);
+ }
size_changed = true;
} else if (desired_size < orig_size) {
size_t desired_change = orig_size - desired_size;
@@ -321,19 +336,95 @@
post_resize();
if (Verbose && PrintGC) {
- size_t current_size = _virtual_space->committed_size();
+ size_t current_size = virtual_space()->committed_size();
gclog_or_tty->print_cr("PSYoung generation size changed: "
SIZE_FORMAT "K->" SIZE_FORMAT "K",
orig_size/K, current_size/K);
}
}
- guarantee(eden_plus_survivors <= _virtual_space->committed_size() ||
- _virtual_space->committed_size() == max_size(), "Sanity");
+ guarantee(eden_plus_survivors <= virtual_space()->committed_size() ||
+ virtual_space()->committed_size() == max_size(), "Sanity");
return true;
}
+#ifndef PRODUCT
+// In the numa case eden is not mangled so a survivor space
+// moving into a region previously occupied by a survivor
+// may find an unmangled region. Also in the PS case eden
+// to-space and from-space may not touch (i.e., there may be
+// gaps between them due to movement while resizing the
+// spaces). Those gaps must be mangled.
+void PSYoungGen::mangle_survivors(MutableSpace* s1,
+ MemRegion s1MR,
+ MutableSpace* s2,
+ MemRegion s2MR) {
+ // Check eden and gap between eden and from-space, in deciding
+ // what to mangle in from-space. Check the gap between from-space
+ // and to-space when deciding what to mangle.
+ //
+ // +--------+ +----+ +---+
+ // | eden | |s1 | |s2 |
+ // +--------+ +----+ +---+
+ // +-------+ +-----+
+ // |s1MR | |s2MR |
+ // +-------+ +-----+
+ // All of survivor-space is properly mangled so find the
+ // upper bound on the mangling for any portion above current s1.
+ HeapWord* delta_end = MIN2(s1->bottom(), s1MR.end());
+ MemRegion delta1_left;
+ if (s1MR.start() < delta_end) {
+ delta1_left = MemRegion(s1MR.start(), delta_end);
+ s1->mangle_region(delta1_left);
+ }
+ // Find any portion to the right of the current s1.
+ HeapWord* delta_start = MAX2(s1->end(), s1MR.start());
+ MemRegion delta1_right;
+ if (delta_start < s1MR.end()) {
+ delta1_right = MemRegion(delta_start, s1MR.end());
+ s1->mangle_region(delta1_right);
+ }
+
+ // Similarly for the second survivor space except that
+ // any of the new region that overlaps with the current
+ // region of the first survivor space has already been
+ // mangled.
+ delta_end = MIN2(s2->bottom(), s2MR.end());
+ delta_start = MAX2(s2MR.start(), s1->end());
+ MemRegion delta2_left;
+ if (s2MR.start() < delta_end) {
+ delta2_left = MemRegion(s2MR.start(), delta_end);
+ s2->mangle_region(delta2_left);
+ }
+ delta_start = MAX2(s2->end(), s2MR.start());
+ MemRegion delta2_right;
+ if (delta_start < s2MR.end()) {
+ s2->mangle_region(delta2_right);
+ }
+
+ if (TraceZapUnusedHeapArea) {
+ // s1
+ gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
+ "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
+ s1->bottom(), s1->end(), s1MR.start(), s1MR.end());
+ gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", "
+ PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
+ delta1_left.start(), delta1_left.end(), delta1_right.start(),
+ delta1_right.end());
+
+ // s2
+ gclog_or_tty->print_cr("Current region: [" PTR_FORMAT ", " PTR_FORMAT ") "
+ "New region: [" PTR_FORMAT ", " PTR_FORMAT ")",
+ s2->bottom(), s2->end(), s2MR.start(), s2MR.end());
+ gclog_or_tty->print_cr(" Mangle before: [" PTR_FORMAT ", "
+ PTR_FORMAT ") Mangle after: [" PTR_FORMAT ", " PTR_FORMAT ")",
+ delta2_left.start(), delta2_left.end(), delta2_right.start(),
+ delta2_right.end());
+ }
+
+}
+#endif // NOT PRODUCT
void PSYoungGen::resize_spaces(size_t requested_eden_size,
size_t requested_survivor_size) {
@@ -396,9 +487,11 @@
const bool maintain_minimum =
(requested_eden_size + 2 * requested_survivor_size) <= min_gen_size();
+ bool eden_from_to_order = from_start < to_start;
// Check whether from space is below to space
- if (from_start < to_start) {
+ if (eden_from_to_order) {
// Eden, from, to
+ eden_from_to_order = true;
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr(" Eden, from, to:");
}
@@ -435,7 +528,7 @@
// extra calculations.
// First calculate an optimal to-space
- to_end = (char*)_virtual_space->high();
+ to_end = (char*)virtual_space()->high();
to_start = (char*)pointer_delta(to_end, (char*)requested_survivor_size,
sizeof(char));
@@ -491,7 +584,7 @@
// to space as if we were able to resize from space, even though from
// space is not modified.
// Giving eden priority was tried and gave poorer performance.
- to_end = (char*)pointer_delta(_virtual_space->high(),
+ to_end = (char*)pointer_delta(virtual_space()->high(),
(char*)requested_survivor_size,
sizeof(char));
to_end = MIN2(to_end, from_start);
@@ -560,9 +653,45 @@
size_t old_from = from_space()->capacity_in_bytes();
size_t old_to = to_space()->capacity_in_bytes();
- eden_space()->initialize(edenMR, true);
- to_space()->initialize(toMR , true);
- from_space()->initialize(fromMR, false); // Note, not cleared!
+ if (ZapUnusedHeapArea) {
+ // NUMA is a special case because a numa space is not mangled
+ // in order to not prematurely bind its address to memory to
+ // the wrong memory (i.e., don't want the GC thread to first
+ // touch the memory). The survivor spaces are not numa
+ // spaces and are mangled.
+ if (UseNUMA) {
+ if (eden_from_to_order) {
+ mangle_survivors(from_space(), fromMR, to_space(), toMR);
+ } else {
+ mangle_survivors(to_space(), toMR, from_space(), fromMR);
+ }
+ }
+
+ // If not mangling the spaces, do some checking to verify that
+ // the spaces are already mangled.
+ // The spaces should be correctly mangled at this point so
+ // do some checking here. Note that they are not being mangled
+ // in the calls to initialize().
+ // Must check mangling before the spaces are reshaped. Otherwise,
+ // the bottom or end of one space may have moved into an area
+ // covered by another space and a failure of the check may
+ // not correctly indicate which space is not properly mangled.
+ HeapWord* limit = (HeapWord*) virtual_space()->high();
+ eden_space()->check_mangled_unused_area(limit);
+ from_space()->check_mangled_unused_area(limit);
+ to_space()->check_mangled_unused_area(limit);
+ }
+ // When an existing space is being initialized, it is not
+ // mangled because the space has been previously mangled.
+ eden_space()->initialize(edenMR,
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
+ to_space()->initialize(toMR,
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
+ from_space()->initialize(fromMR,
+ SpaceDecorator::DontClear,
+ SpaceDecorator::DontMangle);
assert(from_space()->top() == old_from_top, "from top changed!");
@@ -671,7 +800,7 @@
st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
capacity_in_bytes()/K, used_in_bytes()/K);
}
- _virtual_space->print_space_boundaries_on(st);
+ virtual_space()->print_space_boundaries_on(st);
st->print(" eden"); eden_space()->print_on(st);
st->print(" from"); from_space()->print_on(st);
st->print(" to "); to_space()->print_on(st);
@@ -774,7 +903,9 @@
// Was there a shrink of the survivor space?
if (new_end < space_shrinking->end()) {
MemRegion mr(space_shrinking->bottom(), new_end);
- space_shrinking->initialize(mr, false /* clear */);
+ space_shrinking->initialize(mr,
+ SpaceDecorator::DontClear,
+ SpaceDecorator::Mangle);
}
}
@@ -809,3 +940,12 @@
from_space()->verify(allow_dirty);
to_space()->verify(allow_dirty);
}
+
+#ifndef PRODUCT
+void PSYoungGen::record_spaces_top() {
+ assert(ZapUnusedHeapArea, "Not mangling unused space");
+ eden_space()->set_top_for_allocations();
+ from_space()->set_top_for_allocations();
+ to_space()->set_top_for_allocations();
+}
+#endif
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -179,4 +179,12 @@
// Space boundary invariant checker
void space_invariants() PRODUCT_RETURN;
+
+ // Helper for mangling survivor spaces.
+ void mangle_survivors(MutableSpace* s1,
+ MemRegion s1MR,
+ MutableSpace* s2,
+ MemRegion s2MR) PRODUCT_RETURN;
+
+ void record_spaces_top() PRODUCT_RETURN;
};
--- a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -58,6 +58,12 @@
_average(0.0), _sample_count(0), _weight(weight), _last_sample(0.0) {
}
+ void clear() {
+ _average = 0;
+ _sample_count = 0;
+ _last_sample = 0;
+ }
+
// Accessors
float average() const { return _average; }
unsigned weight() const { return _weight; }
@@ -115,6 +121,12 @@
float deviation() const { return _deviation; }
unsigned padding() const { return _padding; }
+ void clear() {
+ AdaptiveWeightedAverage::clear();
+ _padded_avg = 0;
+ _deviation = 0;
+ }
+
// Override
void sample(float new_sample);
};
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -42,19 +42,31 @@
delete lgrp_spaces();
}
+#ifndef PRODUCT
void MutableNUMASpace::mangle_unused_area() {
- for (int i = 0; i < lgrp_spaces()->length(); i++) {
- LGRPSpace *ls = lgrp_spaces()->at(i);
- MutableSpace *s = ls->space();
- if (!os::numa_has_static_binding()) {
- HeapWord *top = MAX2((HeapWord*)round_down((intptr_t)s->top(), page_size()), s->bottom());
- if (top < s->end()) {
- ls->add_invalid_region(MemRegion(top, s->end()));
- }
- }
- s->mangle_unused_area();
- }
+ // This method should do nothing.
+ // It can be called on a numa space during a full compaction.
+}
+void MutableNUMASpace::mangle_unused_area_complete() {
+ // This method should do nothing.
+ // It can be called on a numa space during a full compaction.
+}
+void MutableNUMASpace::mangle_region(MemRegion mr) {
+ // This method should do nothing because numa spaces are not mangled.
}
+void MutableNUMASpace::set_top_for_allocations(HeapWord* v) {
+ assert(false, "Do not mangle MutableNUMASpace's");
+}
+void MutableNUMASpace::set_top_for_allocations() {
+ // This method should do nothing.
+}
+void MutableNUMASpace::check_mangled_unused_area(HeapWord* limit) {
+ // This method should do nothing.
+}
+void MutableNUMASpace::check_mangled_unused_area_complete() {
+ // This method should do nothing.
+}
+#endif // NOT_PRODUCT
// There may be unallocated holes in the middle chunks
// that should be filled with dead objects to ensure parseability.
@@ -129,7 +141,20 @@
size_t MutableNUMASpace::tlab_capacity(Thread *thr) const {
guarantee(thr != NULL, "No thread");
int lgrp_id = thr->lgrp_id();
- assert(lgrp_id != -1, "No lgrp_id set");
+ if (lgrp_id == -1) {
+ // This case can occur after the topology of the system has
+ // changed. Thread can change their location, the new home
+ // group will be determined during the first allocation
+ // attempt. For now we can safely assume that all spaces
+ // have equal size because the whole space will be reinitialized.
+ if (lgrp_spaces()->length() > 0) {
+ return capacity_in_bytes() / lgrp_spaces()->length();
+ } else {
+ assert(false, "There should be at least one locality group");
+ return 0;
+ }
+ }
+ // That's the normal case, where we know the locality group of the thread.
int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
if (i == -1) {
return 0;
@@ -138,9 +163,17 @@
}
size_t MutableNUMASpace::unsafe_max_tlab_alloc(Thread *thr) const {
+ // Please see the comments for tlab_capacity().
guarantee(thr != NULL, "No thread");
int lgrp_id = thr->lgrp_id();
- assert(lgrp_id != -1, "No lgrp_id set");
+ if (lgrp_id == -1) {
+ if (lgrp_spaces()->length() > 0) {
+ return free_in_bytes() / lgrp_spaces()->length();
+ } else {
+ assert(false, "There should be at least one locality group");
+ return 0;
+ }
+ }
int i = lgrp_spaces()->find(&lgrp_id, LGRPSpace::equals);
if (i == -1) {
return 0;
@@ -238,12 +271,20 @@
void MutableNUMASpace::update() {
if (update_layout(false)) {
// If the topology has changed, make all chunks zero-sized.
+ // And clear the alloc-rate statistics.
+ // In future we may want to handle this more gracefully in order
+ // to avoid the reallocation of the pages as much as possible.
for (int i = 0; i < lgrp_spaces()->length(); i++) {
- MutableSpace *s = lgrp_spaces()->at(i)->space();
+ LGRPSpace *ls = lgrp_spaces()->at(i);
+ MutableSpace *s = ls->space();
s->set_end(s->bottom());
s->set_top(s->bottom());
+ ls->clear_alloc_rate();
}
- initialize(region(), true);
+ // A NUMA space is never mangled
+ initialize(region(),
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
} else {
bool should_initialize = false;
if (!os::numa_has_static_binding()) {
@@ -257,7 +298,10 @@
if (should_initialize ||
(UseAdaptiveNUMAChunkSizing && adaptation_cycles() < samples_count())) {
- initialize(region(), true);
+ // A NUMA space is never mangled
+ initialize(region(),
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
}
}
@@ -448,14 +492,17 @@
}
}
-void MutableNUMASpace::initialize(MemRegion mr, bool clear_space) {
+void MutableNUMASpace::initialize(MemRegion mr,
+ bool clear_space,
+ bool mangle_space) {
assert(clear_space, "Reallocation will destory data!");
assert(lgrp_spaces()->length() > 0, "There should be at least one space");
MemRegion old_region = region(), new_region;
set_bottom(mr.start());
set_end(mr.end());
- MutableSpace::set_top(bottom());
+ // Must always clear the space
+ clear(SpaceDecorator::DontMangle);
// Compute chunk sizes
size_t prev_page_size = page_size();
@@ -586,10 +633,8 @@
bias_region(top_region, ls->lgrp_id());
}
- // If we clear the region, we would mangle it in debug. That would cause page
- // allocation in a different place. Hence setting the top directly.
- s->initialize(new_region, false);
- s->set_top(s->bottom());
+ // Clear space (set top = bottom) but never mangle.
+ s->initialize(new_region, SpaceDecorator::Clear, SpaceDecorator::DontMangle);
set_adaptation_cycles(samples_count());
}
@@ -641,10 +686,12 @@
MutableSpace::set_top(value);
}
-void MutableNUMASpace::clear() {
+void MutableNUMASpace::clear(bool mangle_space) {
MutableSpace::set_top(bottom());
for (int i = 0; i < lgrp_spaces()->length(); i++) {
- lgrp_spaces()->at(i)->space()->clear();
+ // Never mangle NUMA spaces because the mangling will
+ // bind the memory to a possibly unwanted lgroup.
+ lgrp_spaces()->at(i)->space()->clear(SpaceDecorator::DontMangle);
}
}
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -112,6 +112,7 @@
int lgrp_id() const { return _lgrp_id; }
MutableSpace* space() const { return _space; }
AdaptiveWeightedAverage* alloc_rate() const { return _alloc_rate; }
+ void clear_alloc_rate() { _alloc_rate->clear(); }
SpaceStats* space_stats() { return &_space_stats; }
void clear_space_stats() { _space_stats = SpaceStats(); }
@@ -171,14 +172,21 @@
MutableNUMASpace();
virtual ~MutableNUMASpace();
// Space initialization.
- virtual void initialize(MemRegion mr, bool clear_space);
+ virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space);
// Update space layout if necessary. Do all adaptive resizing job.
virtual void update();
// Update allocation rate averages.
virtual void accumulate_statistics();
- virtual void clear();
- virtual void mangle_unused_area();
+ virtual void clear(bool mangle_space);
+ virtual void mangle_unused_area() PRODUCT_RETURN;
+ virtual void mangle_unused_area_complete() PRODUCT_RETURN;
+ virtual void mangle_region(MemRegion mr) PRODUCT_RETURN;
+ virtual void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN;
+ virtual void check_mangled_unused_area_complete() PRODUCT_RETURN;
+ virtual void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN;
+ virtual void set_top_for_allocations() PRODUCT_RETURN;
+
virtual void ensure_parsability();
virtual size_t used_in_words() const;
virtual size_t free_in_words() const;
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -25,7 +25,17 @@
# include "incls/_precompiled.incl"
# include "incls/_mutableSpace.cpp.incl"
-void MutableSpace::initialize(MemRegion mr, bool clear_space) {
+MutableSpace::MutableSpace(): ImmutableSpace(), _top(NULL) {
+ _mangler = new MutableSpaceMangler(this);
+}
+
+MutableSpace::~MutableSpace() {
+ delete _mangler;
+}
+
+void MutableSpace::initialize(MemRegion mr,
+ bool clear_space,
+ bool mangle_space) {
HeapWord* bottom = mr.start();
HeapWord* end = mr.end();
@@ -34,14 +44,51 @@
set_bottom(bottom);
set_end(end);
- if (clear_space) clear();
+ if (clear_space) {
+ clear(mangle_space);
+ }
+}
+
+void MutableSpace::clear(bool mangle_space) {
+ set_top(bottom());
+ if (ZapUnusedHeapArea && mangle_space) {
+ mangle_unused_area();
+ }
+}
+
+#ifndef PRODUCT
+void MutableSpace::check_mangled_unused_area(HeapWord* limit) {
+ mangler()->check_mangled_unused_area(limit);
+}
+
+void MutableSpace::check_mangled_unused_area_complete() {
+ mangler()->check_mangled_unused_area_complete();
}
-void MutableSpace::clear() {
- set_top(bottom());
- if (ZapUnusedHeapArea) mangle_unused_area();
+// Mangle only the unused space that has not previously
+// been mangled and that has not been allocated since being
+// mangled.
+void MutableSpace::mangle_unused_area() {
+ mangler()->mangle_unused_area();
+}
+
+void MutableSpace::mangle_unused_area_complete() {
+ mangler()->mangle_unused_area_complete();
}
+void MutableSpace::mangle_region(MemRegion mr) {
+ SpaceMangler::mangle_region(mr);
+}
+
+void MutableSpace::set_top_for_allocations(HeapWord* v) {
+ mangler()->set_top_for_allocations(v);
+}
+
+void MutableSpace::set_top_for_allocations() {
+ mangler()->set_top_for_allocations(top());
+}
+#endif
+
// This version requires locking. */
HeapWord* MutableSpace::allocate(size_t size) {
assert(Heap_lock->owned_by_self() ||
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -30,14 +30,23 @@
// Invariant: (ImmutableSpace +) bottom() <= top() <= end()
// top() is inclusive and end() is exclusive.
+class MutableSpaceMangler;
+
class MutableSpace: public ImmutableSpace {
friend class VMStructs;
+
+ // Helper for mangling unused space in debug builds
+ MutableSpaceMangler* _mangler;
+
protected:
HeapWord* _top;
+ MutableSpaceMangler* mangler() { return _mangler; }
+
public:
- virtual ~MutableSpace() {}
- MutableSpace() { _top = NULL; }
+ virtual ~MutableSpace();
+ MutableSpace();
+
// Accessors
HeapWord* top() const { return _top; }
virtual void set_top(HeapWord* value) { _top = value; }
@@ -52,21 +61,30 @@
MemRegion used_region() { return MemRegion(bottom(), top()); }
// Initialization
- virtual void initialize(MemRegion mr, bool clear_space);
- virtual void clear();
+ virtual void initialize(MemRegion mr,
+ bool clear_space,
+ bool mangle_space);
+ virtual void clear(bool mangle_space);
+ // Does the usual initialization but optionally resets top to bottom.
+#if 0 // MANGLE_SPACE
+ void initialize(MemRegion mr, bool clear_space, bool reset_top);
+#endif
virtual void update() { }
virtual void accumulate_statistics() { }
- // Overwrites the unused portion of this space. Note that some collectors
- // may use this "scratch" space during collections.
- virtual void mangle_unused_area() {
- mangle_region(MemRegion(_top, _end));
- }
+ // Methods used in mangling. See descriptions under SpaceMangler.
+ virtual void mangle_unused_area() PRODUCT_RETURN;
+ virtual void mangle_unused_area_complete() PRODUCT_RETURN;
+ virtual void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN;
+ virtual void check_mangled_unused_area_complete() PRODUCT_RETURN;
+ virtual void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN;
+
+ // Used to save the space's current top for later use during mangling.
+ virtual void set_top_for_allocations() PRODUCT_RETURN;
+
virtual void ensure_parsability() { }
- void mangle_region(MemRegion mr) {
- debug_only(Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord));
- }
+ virtual void mangle_region(MemRegion mr) PRODUCT_RETURN;
// Boolean querries.
bool is_empty() const { return used_in_words() == 0; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+# include "incls/_precompiled.incl"
+# include "incls/_spaceDecorator.cpp.incl"
+
+// Catch-all file for utility classes
+
+#ifndef PRODUCT
+
+// Returns true is the location q matches the mangling
+// pattern.
+bool SpaceMangler::is_mangled(HeapWord* q) {
+ // This test loses precision but is good enough
+ return badHeapWord == (max_juint & (uintptr_t) q->value());
+}
+
+
+void SpaceMangler::set_top_for_allocations(HeapWord* v) {
+ if (v < end()) {
+ assert(!CheckZapUnusedHeapArea || is_mangled(v),
+ "The high water mark is not mangled");
+ }
+ _top_for_allocations = v;
+}
+
+// Mangle only the unused space that has not previously
+// been mangled and that has not been allocated since being
+// mangled.
+void SpaceMangler::mangle_unused_area() {
+ assert(ZapUnusedHeapArea, "Mangling should not be in use");
+ // Mangle between top and the high water mark. Safeguard
+ // against the space changing since top_for_allocations was
+ // set.
+ HeapWord* mangled_end = MIN2(top_for_allocations(), end());
+ if (top() < mangled_end) {
+ MemRegion mangle_mr(top(), mangled_end);
+ SpaceMangler::mangle_region(mangle_mr);
+ // Light weight check of mangling.
+ check_mangled_unused_area(end());
+ }
+ // Complete check of unused area which is functional when
+ // DEBUG_MANGLING is defined.
+ check_mangled_unused_area_complete();
+}
+
+// A complete mangle is expected in the
+// exceptional case where top_for_allocations is not
+// properly tracking the high water mark for mangling.
+// This can be the case when to-space is being used for
+// scratch space during a mark-sweep-compact. See
+// contribute_scratch() and PSMarkSweep::allocate_stacks().
+void SpaceMangler::mangle_unused_area_complete() {
+ assert(ZapUnusedHeapArea, "Mangling should not be in use");
+ MemRegion mangle_mr(top(), end());
+ SpaceMangler::mangle_region(mangle_mr);
+}
+
+// Simply mangle the MemRegion mr.
+void SpaceMangler::mangle_region(MemRegion mr) {
+ assert(ZapUnusedHeapArea, "Mangling should not be in use");
+#ifdef ASSERT
+ if(TraceZapUnusedHeapArea) {
+ gclog_or_tty->print("Mangling [0x%x to 0x%x)", mr.start(), mr.end());
+ }
+ Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord);
+ if(TraceZapUnusedHeapArea) {
+ gclog_or_tty->print_cr(" done");
+ }
+#endif
+}
+
+// Check that top, top_for_allocations and the last
+// word of the space are mangled. In a tight memory
+// situation even this light weight mangling could
+// cause paging by touching the end of the space.
+void SpaceMangler::check_mangled_unused_area(HeapWord* limit) {
+ if (CheckZapUnusedHeapArea) {
+ // This method can be called while the spaces are
+ // being reshaped so skip the test if the end of the
+ // space is beyond the specified limit;
+ if (end() > limit) return;
+
+ assert(top() == end() ||
+ (is_mangled(top())), "Top not mangled");
+ assert((top_for_allocations() < top()) ||
+ (top_for_allocations() >= end()) ||
+ (is_mangled(top_for_allocations())),
+ "Older unused not mangled");
+ assert(top() == end() ||
+ (is_mangled(end() - 1)), "End not properly mangled");
+ // Only does checking when DEBUG_MANGLING is defined.
+ check_mangled_unused_area_complete();
+ }
+}
+
+#undef DEBUG_MANGLING
+// This should only be used while debugging the mangling
+// because of the high cost of checking the completeness.
+void SpaceMangler::check_mangled_unused_area_complete() {
+ if (CheckZapUnusedHeapArea) {
+ assert(ZapUnusedHeapArea, "Not mangling unused area");
+#ifdef DEBUG_MANGLING
+ HeapWord* q = top();
+ HeapWord* limit = end();
+
+ bool passed = true;
+ while (q < limit) {
+ if (!is_mangled(q)) {
+ passed = false;
+ break;
+ }
+ q++;
+ }
+ assert(passed, "Mangling is not complete");
+#endif
+ }
+}
+#undef DEBUG_MANGLING
+#endif // not PRODUCT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+class SpaceDecorator: public AllStatic {
+ public:
+ // Initialization flags.
+ static const bool Clear = true;
+ static const bool DontClear = false;
+ static const bool Mangle = true;
+ static const bool DontMangle = false;
+};
+
+// Functionality for use with class Space and class MutableSpace.
+// The approach taken with the mangling is to mangle all
+// the space initially and then to mangle areas that have
+// been allocated since the last collection. Mangling is
+// done in the context of a generation and in the context
+// of a space.
+// The space in a generation is mangled when it is first
+// initialized and when the generation grows. The spaces
+// are not necessarily up-to-date when this mangling occurs
+// and the method mangle_region() is used.
+// After allocations have been done in a space, the space generally
+// need to be remangled. Remangling is only done on the
+// recently allocated regions in the space. Typically, that is
+// the region between the new top and the top just before a
+// garbage collection.
+// An exception to the usual mangling in a space is done when the
+// space is used for an extraordinary purpose. Specifically, when
+// to-space is used as scratch space for a mark-sweep-compact
+// collection.
+// Spaces are mangled after a collection. If the generation
+// grows after a collection, the added space is mangled as part of
+// the growth of the generation. No additional mangling is needed when the
+// spaces are resized after an expansion.
+// The class SpaceMangler keeps a pointer to the top of the allocated
+// area and provides the methods for doing the piece meal mangling.
+// Methods for doing sparces and full checking of the mangling are
+// included. The full checking is done if DEBUG_MANGLING is defined.
+// GenSpaceMangler is used with the GenCollectedHeap collectors and
+// MutableSpaceMangler is used with the ParallelScavengeHeap collectors.
+// These subclasses abstract the differences in the types of spaces used
+// by each heap.
+
+class SpaceMangler: public CHeapObj {
+ friend class VMStructs;
+
+ // High water mark for allocations. Typically, the space above
+ // this point have been mangle previously and don't need to be
+ // touched again. Space belows this point has been allocated
+ // and remangling is needed between the current top and this
+ // high water mark.
+ HeapWord* _top_for_allocations;
+ HeapWord* top_for_allocations() { return _top_for_allocations; }
+
+ public:
+
+ // Setting _top_for_allocations to NULL at initialization
+ // makes it always below top so that mangling done as part
+ // of the initialize() call of a space does nothing (as it
+ // should since the mangling is done as part of the constructor
+ // for the space.
+ SpaceMangler() : _top_for_allocations(NULL) {}
+
+ // Methods for top and end that delegate to the specific
+ // space type.
+ virtual HeapWord* top() const = 0;
+ virtual HeapWord* end() const = 0;
+
+ // Return true if q matches the mangled pattern.
+ static bool is_mangled(HeapWord* q) PRODUCT_RETURN0;
+
+ // Used to save the an address in a space for later use during mangling.
+ void set_top_for_allocations(HeapWord* v);
+
+ // Overwrites the unused portion of this space.
+ // Mangle only the region not previously mangled [top, top_previously_mangled)
+ void mangle_unused_area();
+ // Mangle all the unused region [top, end)
+ void mangle_unused_area_complete();
+ // Do some sparse checking on the area that should have been mangled.
+ void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN;
+ // Do a complete check of the area that should be mangled.
+ void check_mangled_unused_area_complete() PRODUCT_RETURN;
+
+ // Mangle the MemRegion. This is a non-space specific mangler. It
+ // is used during the initial mangling of a space before the space
+ // is fully constructed. Also is used when a generation is expanded
+ // and possibly before the spaces have been reshaped to to the new
+ // size of the generation.
+ static void mangle_region(MemRegion mr);
+};
+
+class ContiguousSpace;
+
+// For use with GenCollectedHeap's
+class GenSpaceMangler: public SpaceMangler {
+ ContiguousSpace* _sp;
+
+ ContiguousSpace* sp() { return _sp; }
+
+ HeapWord* top() const { return _sp->top(); }
+ HeapWord* end() const { return _sp->end(); }
+
+ public:
+ GenSpaceMangler(ContiguousSpace* sp) : SpaceMangler(), _sp(sp) {}
+};
+
+// For use with ParallelScavengeHeap's.
+class MutableSpaceMangler: public SpaceMangler {
+ MutableSpace* _sp;
+
+ MutableSpace* sp() { return _sp; }
+
+ HeapWord* top() const { return _sp->top(); }
+ HeapWord* end() const { return _sp->end(); }
+
+ public:
+ MutableSpaceMangler(MutableSpace* sp) : SpaceMangler(), _sp(sp) {}
+};
--- a/hotspot/src/share/vm/includeDB_core Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/includeDB_core Wed Jul 05 16:40:18 2017 +0200
@@ -178,6 +178,7 @@
arguments.cpp universe.inline.hpp
arguments.cpp vm_version_<arch_model>.hpp
+arguments.hpp java.hpp
arguments.hpp perfData.hpp
arguments.hpp top.hpp
@@ -1405,6 +1406,7 @@
defNewGeneration.cpp oop.inline.hpp
defNewGeneration.cpp referencePolicy.hpp
defNewGeneration.cpp space.inline.hpp
+defNewGeneration.cpp spaceDecorator.hpp
defNewGeneration.cpp thread_<os_family>.inline.hpp
defNewGeneration.hpp ageTable.hpp
@@ -1789,6 +1791,7 @@
generation.cpp java.hpp
generation.cpp oop.hpp
generation.cpp oop.inline.hpp
+generation.cpp spaceDecorator.hpp
generation.cpp space.inline.hpp
generation.hpp allocation.hpp
@@ -3722,6 +3725,7 @@
space.cpp safepoint.hpp
space.cpp space.hpp
space.cpp space.inline.hpp
+space.cpp spaceDecorator.hpp
space.cpp systemDictionary.hpp
space.cpp universe.inline.hpp
space.cpp vmSymbols.hpp
@@ -3744,6 +3748,13 @@
space.inline.hpp space.hpp
space.inline.hpp universe.hpp
+spaceDecorator.hpp globalDefinitions.hpp
+spaceDecorator.hpp mutableSpace.hpp
+spaceDecorator.hpp space.hpp
+
+spaceDecorator.cpp copy.hpp
+spaceDecorator.cpp spaceDecorator.hpp
+
specialized_oop_closures.cpp ostream.hpp
specialized_oop_closures.cpp specialized_oop_closures.hpp
--- a/hotspot/src/share/vm/includeDB_features Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/includeDB_features Wed Jul 05 16:40:18 2017 +0200
@@ -51,6 +51,7 @@
dump.cpp oopFactory.hpp
dump.cpp resourceArea.hpp
dump.cpp signature.hpp
+dump.cpp spaceDecorator.hpp
dump.cpp symbolTable.hpp
dump.cpp systemDictionary.hpp
dump.cpp vmThread.hpp
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -421,28 +421,6 @@
}
-
-bool CompactingPermGenGen::grow_by(size_t bytes) {
- // Don't allow _virtual_size to expand into shared spaces.
- size_t max_bytes = _virtual_space.uncommitted_size() - _shared_space_size;
- if (bytes > _shared_space_size) {
- bytes = _shared_space_size;
- }
- return OneContigSpaceCardGeneration::grow_by(bytes);
-}
-
-
-void CompactingPermGenGen::grow_to_reserved() {
- // Don't allow _virtual_size to expand into shared spaces.
- if (_virtual_space.uncommitted_size() > _shared_space_size) {
- size_t remaining_bytes =
- _virtual_space.uncommitted_size() - _shared_space_size;
- bool success = OneContigSpaceCardGeneration::grow_by(remaining_bytes);
- DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
- }
-}
-
-
// No young generation references, clear this generation's main space's
// card table entries. Do NOT clear the card table entries for the
// read-only space (always clear) or the read-write space (valuable
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -183,8 +183,6 @@
void compact();
void post_compact();
size_t contiguous_available() const;
- bool grow_by(size_t bytes);
- void grow_to_reserved();
void clear_remembered_set();
void invalidate_remembered_set();
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -172,15 +172,25 @@
_to_counters = new CSpaceCounters("s1", 2, _max_survivor_size, _to_space,
_gen_counters);
- compute_space_boundaries(0);
+ compute_space_boundaries(0, SpaceDecorator::Clear, SpaceDecorator::Mangle);
update_counters();
_next_gen = NULL;
_tenuring_threshold = MaxTenuringThreshold;
_pretenure_size_threshold_words = PretenureSizeThreshold >> LogHeapWordSize;
}
-void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size) {
- uintx alignment = GenCollectedHeap::heap()->collector_policy()->min_alignment();
+void DefNewGeneration::compute_space_boundaries(uintx minimum_eden_size,
+ bool clear_space,
+ bool mangle_space) {
+ uintx alignment =
+ GenCollectedHeap::heap()->collector_policy()->min_alignment();
+
+ // If the spaces are being cleared (only done at heap initialization
+ // currently), the survivor spaces need not be empty.
+ // Otherwise, no care is taken for used areas in the survivor spaces
+ // so check.
+ assert(clear_space || (to()->is_empty() && from()->is_empty()),
+ "Initialization of the survivor spaces assumes these are empty");
// Compute sizes
uintx size = _virtual_space.committed_size();
@@ -214,16 +224,41 @@
MemRegion fromMR((HeapWord*)from_start, (HeapWord*)to_start);
MemRegion toMR ((HeapWord*)to_start, (HeapWord*)to_end);
- eden()->initialize(edenMR, (minimum_eden_size == 0));
- // If minumum_eden_size != 0, we will not have cleared any
+ // A minimum eden size implies that there is a part of eden that
+ // is being used and that affects the initialization of any
+ // newly formed eden.
+ bool live_in_eden = minimum_eden_size > 0;
+
+ // If not clearing the spaces, do some checking to verify that
+ // the space are already mangled.
+ if (!clear_space) {
+ // Must check mangling before the spaces are reshaped. Otherwise,
+ // the bottom or end of one space may have moved into another
+ // a failure of the check may not correctly indicate which space
+ // is not properly mangled.
+ if (ZapUnusedHeapArea) {
+ HeapWord* limit = (HeapWord*) _virtual_space.high();
+ eden()->check_mangled_unused_area(limit);
+ from()->check_mangled_unused_area(limit);
+ to()->check_mangled_unused_area(limit);
+ }
+ }
+
+ // Reset the spaces for their new regions.
+ eden()->initialize(edenMR,
+ clear_space && !live_in_eden,
+ SpaceDecorator::Mangle);
+ // If clear_space and live_in_eden, we will not have cleared any
// portion of eden above its top. This can cause newly
// expanded space not to be mangled if using ZapUnusedHeapArea.
// We explicitly do such mangling here.
- if (ZapUnusedHeapArea && (minimum_eden_size != 0)) {
+ if (ZapUnusedHeapArea && clear_space && live_in_eden && mangle_space) {
eden()->mangle_unused_area();
}
- from()->initialize(fromMR, true);
- to()->initialize(toMR , true);
+ from()->initialize(fromMR, clear_space, mangle_space);
+ to()->initialize(toMR, clear_space, mangle_space);
+
+ // Set next compaction spaces.
eden()->set_next_compaction_space(from());
// The to-space is normally empty before a compaction so need
// not be considered. The exception is during promotion
@@ -250,7 +285,16 @@
bool DefNewGeneration::expand(size_t bytes) {
MutexLocker x(ExpandHeap_lock);
+ HeapWord* prev_high = (HeapWord*) _virtual_space.high();
bool success = _virtual_space.expand_by(bytes);
+ if (success && ZapUnusedHeapArea) {
+ // Mangle newly committed space immediately because it
+ // can be done here more simply that after the new
+ // spaces have been computed.
+ HeapWord* new_high = (HeapWord*) _virtual_space.high();
+ MemRegion mangle_region(prev_high, new_high);
+ SpaceMangler::mangle_region(mangle_region);
+ }
// Do not attempt an expand-to-the reserve size. The
// request should properly observe the maximum size of
@@ -262,7 +306,8 @@
// value.
if (GC_locker::is_active()) {
if (PrintGC && Verbose) {
- gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
+ gclog_or_tty->print_cr("Garbage collection disabled, "
+ "expanded heap instead");
}
}
@@ -326,16 +371,24 @@
changed = true;
}
if (changed) {
- compute_space_boundaries(eden()->used());
- MemRegion cmr((HeapWord*)_virtual_space.low(), (HeapWord*)_virtual_space.high());
+ // The spaces have already been mangled at this point but
+ // may not have been cleared (set top = bottom) and should be.
+ // Mangling was done when the heap was being expanded.
+ compute_space_boundaries(eden()->used(),
+ SpaceDecorator::Clear,
+ SpaceDecorator::DontMangle);
+ MemRegion cmr((HeapWord*)_virtual_space.low(),
+ (HeapWord*)_virtual_space.high());
Universe::heap()->barrier_set()->resize_covered_region(cmr);
if (Verbose && PrintGC) {
size_t new_size_after = _virtual_space.committed_size();
size_t eden_size_after = eden()->capacity();
size_t survivor_size_after = from()->capacity();
- gclog_or_tty->print("New generation size " SIZE_FORMAT "K->" SIZE_FORMAT "K [eden="
+ gclog_or_tty->print("New generation size " SIZE_FORMAT "K->"
+ SIZE_FORMAT "K [eden="
SIZE_FORMAT "K,survivor=" SIZE_FORMAT "K]",
- new_size_before/K, new_size_after/K, eden_size_after/K, survivor_size_after/K);
+ new_size_before/K, new_size_after/K,
+ eden_size_after/K, survivor_size_after/K);
if (WizardMode) {
gclog_or_tty->print("[allowed " SIZE_FORMAT "K extra for %d threads]",
thread_increase_size/K, threads_count);
@@ -480,7 +533,7 @@
ScanWeakRefClosure scan_weak_ref(this);
age_table()->clear();
- to()->clear();
+ to()->clear(SpaceDecorator::Mangle);
gch->rem_set()->prepare_for_younger_refs_iterate(false);
@@ -525,8 +578,18 @@
soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, NULL);
if (!promotion_failed()) {
// Swap the survivor spaces.
- eden()->clear();
- from()->clear();
+ eden()->clear(SpaceDecorator::Mangle);
+ from()->clear(SpaceDecorator::Mangle);
+ if (ZapUnusedHeapArea) {
+ // This is now done here because of the piece-meal mangling which
+ // can check for valid mangling at intermediate points in the
+ // collection(s). When a minor collection fails to collect
+ // sufficient space resizing of the young generation can occur
+ // an redistribute the spaces in the young generation. Mangle
+ // here so that unzapped regions don't get distributed to
+ // other spaces.
+ to()->mangle_unused_area();
+ }
swap_spaces();
assert(to()->is_empty(), "to space should be empty now");
@@ -753,6 +816,15 @@
}
}
+void DefNewGeneration::reset_scratch() {
+ // If contributing scratch in to_space, mangle all of
+ // to_space if ZapUnusedHeapArea. This is needed because
+ // top is not maintained while using to-space as scratch.
+ if (ZapUnusedHeapArea) {
+ to()->mangle_unused_area_complete();
+ }
+}
+
bool DefNewGeneration::collection_attempt_is_safe() {
if (!to()->is_empty()) {
return false;
@@ -806,11 +878,25 @@
}
}
+ if (ZapUnusedHeapArea) {
+ eden()->check_mangled_unused_area_complete();
+ from()->check_mangled_unused_area_complete();
+ to()->check_mangled_unused_area_complete();
+ }
+
// update the generation and space performance counters
update_counters();
gch->collector_policy()->counters()->update_counters();
}
+void DefNewGeneration::record_spaces_top() {
+ assert(ZapUnusedHeapArea, "Not mangling unused space");
+ eden()->set_top_for_allocations();
+ to()->set_top_for_allocations();
+ from()->set_top_for_allocations();
+}
+
+
void DefNewGeneration::update_counters() {
if (UsePerfData) {
_eden_counters->update_all();
--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -279,6 +279,9 @@
virtual void gc_prologue(bool full);
virtual void gc_epilogue(bool full);
+ // Save the tops for eden, from, and to
+ virtual void record_spaces_top();
+
// Doesn't require additional work during GC prologue and epilogue
virtual bool performs_in_place_marking() const { return false; }
@@ -299,9 +302,12 @@
// For non-youngest collection, the DefNewGeneration can contribute
// "to-space".
- void contribute_scratch(ScratchBlock*& list, Generation* requestor,
+ virtual void contribute_scratch(ScratchBlock*& list, Generation* requestor,
size_t max_alloc_words);
+ // Reset for contribution of "to-space".
+ virtual void reset_scratch();
+
// GC support
virtual void compute_new_size();
virtual void collect(bool full,
@@ -331,7 +337,12 @@
void verify(bool allow_dirty);
protected:
- void compute_space_boundaries(uintx minimum_eden_size);
+ // If clear_space is true, clear the survivor spaces. Eden is
+ // cleared if the minimum size of eden is 0. If mangle_space
+ // is true, also mangle the space in debug mode.
+ void compute_space_boundaries(uintx minimum_eden_size,
+ bool clear_space,
+ bool mangle_space);
// Scavenge support
void swap_spaces();
};
--- a/hotspot/src/share/vm/memory/dump.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/dump.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -645,7 +645,7 @@
class ClearSpaceClosure : public SpaceClosure {
public:
void do_space(Space* s) {
- s->clear();
+ s->clear(SpaceDecorator::Mangle);
}
};
@@ -1200,10 +1200,12 @@
mapinfo->write_space(CompactingPermGenGen::rw, _rw_space, false);
_rw_space->set_saved_mark();
mapinfo->write_region(CompactingPermGenGen::md, _md_vs->low(),
- md_top - _md_vs->low(), SharedMiscDataSize,
+ pointer_delta(md_top, _md_vs->low(), sizeof(char)),
+ SharedMiscDataSize,
false, false);
mapinfo->write_region(CompactingPermGenGen::mc, _mc_vs->low(),
- mc_top - _mc_vs->low(), SharedMiscCodeSize,
+ pointer_delta(mc_top, _mc_vs->low(), sizeof(char)),
+ SharedMiscCodeSize,
true, true);
// Pass 2 - write data.
@@ -1212,10 +1214,12 @@
mapinfo->write_space(CompactingPermGenGen::ro, _ro_space, true);
mapinfo->write_space(CompactingPermGenGen::rw, _rw_space, false);
mapinfo->write_region(CompactingPermGenGen::md, _md_vs->low(),
- md_top - _md_vs->low(), SharedMiscDataSize,
+ pointer_delta(md_top, _md_vs->low(), sizeof(char)),
+ SharedMiscDataSize,
false, false);
mapinfo->write_region(CompactingPermGenGen::mc, _mc_vs->low(),
- mc_top - _mc_vs->low(), SharedMiscCodeSize,
+ pointer_delta(mc_top, _mc_vs->low(), sizeof(char)),
+ SharedMiscCodeSize,
true, true);
mapinfo->close();
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -465,6 +465,11 @@
_gens[i]->stat_record()->invocations++;
_gens[i]->stat_record()->accumulated_time.start();
+ // Must be done anew before each collection because
+ // a previous collection will do mangling and will
+ // change top of some spaces.
+ record_gen_tops_before_GC();
+
if (PrintGC && Verbose) {
gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT,
i,
@@ -1058,6 +1063,12 @@
return res;
}
+void GenCollectedHeap::release_scratch() {
+ for (int i = 0; i < _n_gens; i++) {
+ _gens[i]->reset_scratch();
+ }
+}
+
size_t GenCollectedHeap::large_typearray_limit() {
return gen_policy()->large_typearray_limit();
}
@@ -1285,6 +1296,24 @@
always_do_update_barrier = UseConcMarkSweepGC;
};
+#ifndef PRODUCT
+class GenGCSaveTopsBeforeGCClosure: public GenCollectedHeap::GenClosure {
+ private:
+ public:
+ void do_generation(Generation* gen) {
+ gen->record_spaces_top();
+ }
+};
+
+void GenCollectedHeap::record_gen_tops_before_GC() {
+ if (ZapUnusedHeapArea) {
+ GenGCSaveTopsBeforeGCClosure blk;
+ generation_iterate(&blk, false); // not old-to-young.
+ perm_gen()->record_spaces_top();
+ }
+}
+#endif // not PRODUCT
+
class GenEnsureParsabilityClosure: public GenCollectedHeap::GenClosure {
public:
void do_generation(Generation* gen) {
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -259,6 +259,9 @@
// be provided are returned as a list of ScratchBlocks, sorted by
// decreasing size.
ScratchBlock* gather_scratch(Generation* requestor, size_t max_alloc_words);
+ // Allow each generation to reset any scratch space that it has
+ // contributed as it needs.
+ void release_scratch();
size_t large_typearray_limit();
@@ -482,6 +485,9 @@
bool should_do_concurrent_full_gc(GCCause::Cause cause);
void collect_mostly_concurrent(GCCause::Cause cause);
+ // Save the tops of the spaces in all generations
+ void record_gen_tops_before_GC() PRODUCT_RETURN;
+
protected:
virtual void gc_prologue(bool full);
virtual void gc_epilogue(bool full);
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -190,6 +190,10 @@
void GenMarkSweep::deallocate_stacks() {
+
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+ gch->release_scratch();
+
if (_preserved_oop_stack) {
delete _preserved_mark_stack;
_preserved_mark_stack = NULL;
--- a/hotspot/src/share/vm/memory/generation.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/generation.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -32,6 +32,12 @@
vm_exit_during_initialization("Could not reserve enough space for "
"object heap");
}
+ // Mangle all of the the initial generation.
+ if (ZapUnusedHeapArea) {
+ MemRegion mangle_region((HeapWord*)_virtual_space.low(),
+ (HeapWord*)_virtual_space.high());
+ SpaceMangler::mangle_region(mangle_region);
+ }
_reserved = MemRegion((HeapWord*)_virtual_space.low_boundary(),
(HeapWord*)_virtual_space.high_boundary());
}
@@ -373,6 +379,41 @@
}
}
+bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
+ assert_locked_or_safepoint(Heap_lock);
+ if (bytes == 0) {
+ return true; // That's what grow_by(0) would return
+ }
+ size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes);
+ if (aligned_bytes == 0){
+ // The alignment caused the number of bytes to wrap. An expand_by(0) will
+ // return true with the implication that an expansion was done when it
+ // was not. A call to expand implies a best effort to expand by "bytes"
+ // but not a guarantee. Align down to give a best effort. This is likely
+ // the most that the generation can expand since it has some capacity to
+ // start with.
+ aligned_bytes = ReservedSpace::page_align_size_down(bytes);
+ }
+ size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
+ bool success = false;
+ if (aligned_expand_bytes > aligned_bytes) {
+ success = grow_by(aligned_expand_bytes);
+ }
+ if (!success) {
+ success = grow_by(aligned_bytes);
+ }
+ if (!success) {
+ success = grow_to_reserved();
+ }
+ if (PrintGC && Verbose) {
+ if (success && GC_locker::is_active()) {
+ gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
+ }
+ }
+
+ return success;
+}
+
// No young generation references, clear this generation's cards.
void CardGeneration::clear_remembered_set() {
@@ -435,25 +476,9 @@
}
}
-void OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) {
+bool OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) {
GCMutexLocker x(ExpandHeap_lock);
- size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes);
- size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
- bool success = false;
- if (aligned_expand_bytes > aligned_bytes) {
- success = grow_by(aligned_expand_bytes);
- }
- if (!success) {
- success = grow_by(aligned_bytes);
- }
- if (!success) {
- grow_to_reserved();
- }
- if (GC_locker::is_active()) {
- if (PrintGC && Verbose) {
- gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
- }
- }
+ return CardGeneration::expand(bytes, expand_bytes);
}
@@ -505,8 +530,11 @@
_bts->resize(new_word_size);
// Fix for bug #4668531
- MemRegion mangle_region(_the_space->end(), (HeapWord*)_virtual_space.high());
- _the_space->mangle_region(mangle_region);
+ if (ZapUnusedHeapArea) {
+ MemRegion mangle_region(_the_space->end(),
+ (HeapWord*)_virtual_space.high());
+ SpaceMangler::mangle_region(mangle_region);
+ }
// Expand space -- also expands space's BOT
// (which uses (part of) shared array above)
@@ -622,6 +650,14 @@
// update the generation and space performance counters
update_counters();
+ if (ZapUnusedHeapArea) {
+ the_space()->check_mangled_unused_area_complete();
+ }
+}
+
+void OneContigSpaceCardGeneration::record_spaces_top() {
+ assert(ZapUnusedHeapArea, "Not mangling unused space");
+ the_space()->set_top_for_allocations();
}
void OneContigSpaceCardGeneration::verify(bool allow_dirty) {
--- a/hotspot/src/share/vm/memory/generation.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/generation.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -376,6 +376,9 @@
// The default is to do nothing.
virtual void gc_epilogue(bool full) {};
+ // Save the high water marks for the used space in a generation.
+ virtual void record_spaces_top() {};
+
// Some generations may need to be "fixed-up" after some allocation
// activity to make them parsable again. The default is to do nothing.
virtual void ensure_parsability() {};
@@ -476,6 +479,10 @@
virtual void contribute_scratch(ScratchBlock*& list, Generation* requestor,
size_t max_alloc_words) {}
+ // Give each generation an opportunity to do clean up for any
+ // contributed scratch.
+ virtual void reset_scratch() {};
+
// When an older generation has been collected, and perhaps resized,
// this method will be invoked on all younger generations (from older to
// younger), allowing them to resize themselves as appropriate.
@@ -599,11 +606,21 @@
public:
+ // Attempt to expand the generation by "bytes". Expand by at a
+ // minimum "expand_bytes". Return true if some amount (not
+ // necessarily the full "bytes") was done.
+ virtual bool expand(size_t bytes, size_t expand_bytes);
+
virtual void clear_remembered_set();
virtual void invalidate_remembered_set();
virtual void prepare_for_verify();
+
+ // Grow generation with specified size (returns false if unable to grow)
+ virtual bool grow_by(size_t bytes) = 0;
+ // Grow generation to reserved size.
+ virtual bool grow_to_reserved() = 0;
};
// OneContigSpaceCardGeneration models a heap of old objects contained in a single
@@ -624,14 +641,14 @@
// and after last GC.
// Grow generation with specified size (returns false if unable to grow)
- bool grow_by(size_t bytes);
+ virtual bool grow_by(size_t bytes);
// Grow generation to reserved size.
- bool grow_to_reserved();
+ virtual bool grow_to_reserved();
// Shrink generation with specified size (returns false if unable to shrink)
void shrink_by(size_t bytes);
// Allocation failure
- void expand(size_t bytes, size_t expand_bytes);
+ virtual bool expand(size_t bytes, size_t expand_bytes);
void shrink(size_t bytes);
// Accessing spaces
@@ -699,6 +716,8 @@
virtual void gc_epilogue(bool full);
+ virtual void record_spaces_top();
+
virtual void verify(bool allow_dirty);
virtual void print_on(outputStream* st) const;
};
--- a/hotspot/src/share/vm/memory/space.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/space.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -232,30 +232,44 @@
return new ContiguousSpaceDCTOC(this, cl, precision, boundary);
}
-void Space::initialize(MemRegion mr, bool clear_space) {
+void Space::initialize(MemRegion mr,
+ bool clear_space,
+ bool mangle_space) {
HeapWord* bottom = mr.start();
HeapWord* end = mr.end();
assert(Universe::on_page_boundary(bottom) && Universe::on_page_boundary(end),
"invalid space boundaries");
set_bottom(bottom);
set_end(end);
- if (clear_space) clear();
+ if (clear_space) clear(mangle_space);
+}
+
+void Space::clear(bool mangle_space) {
+ if (ZapUnusedHeapArea && mangle_space) {
+ mangle_unused_area();
+ }
}
-void Space::clear() {
- if (ZapUnusedHeapArea) mangle_unused_area();
+ContiguousSpace::ContiguousSpace(): CompactibleSpace(), _top(NULL) {
+ _mangler = new GenSpaceMangler(this);
}
-void ContiguousSpace::initialize(MemRegion mr, bool clear_space)
+ContiguousSpace::~ContiguousSpace() {
+ delete _mangler;
+}
+
+void ContiguousSpace::initialize(MemRegion mr,
+ bool clear_space,
+ bool mangle_space)
{
- CompactibleSpace::initialize(mr, clear_space);
+ CompactibleSpace::initialize(mr, clear_space, mangle_space);
_concurrent_iteration_safe_limit = top();
}
-void ContiguousSpace::clear() {
+void ContiguousSpace::clear(bool mangle_space) {
set_top(bottom());
set_saved_mark();
- Space::clear();
+ Space::clear(mangle_space);
}
bool Space::is_in(const void* p) const {
@@ -271,8 +285,8 @@
return p >= _top;
}
-void OffsetTableContigSpace::clear() {
- ContiguousSpace::clear();
+void OffsetTableContigSpace::clear(bool mangle_space) {
+ ContiguousSpace::clear(mangle_space);
_offsets.initialize_threshold();
}
@@ -288,17 +302,46 @@
Space::set_end(new_end);
}
-void ContiguousSpace::mangle_unused_area() {
- // to-space is used for storing marks during mark-sweep
- mangle_region(MemRegion(top(), end()));
+#ifndef PRODUCT
+
+void ContiguousSpace::set_top_for_allocations(HeapWord* v) {
+ mangler()->set_top_for_allocations(v);
+}
+void ContiguousSpace::set_top_for_allocations() {
+ mangler()->set_top_for_allocations(top());
+}
+void ContiguousSpace::check_mangled_unused_area(HeapWord* limit) {
+ mangler()->check_mangled_unused_area(limit);
+}
+
+void ContiguousSpace::check_mangled_unused_area_complete() {
+ mangler()->check_mangled_unused_area_complete();
}
-void ContiguousSpace::mangle_region(MemRegion mr) {
- debug_only(Copy::fill_to_words(mr.start(), mr.word_size(), badHeapWord));
+// Mangled only the unused space that has not previously
+// been mangled and that has not been allocated since being
+// mangled.
+void ContiguousSpace::mangle_unused_area() {
+ mangler()->mangle_unused_area();
+}
+void ContiguousSpace::mangle_unused_area_complete() {
+ mangler()->mangle_unused_area_complete();
}
+void ContiguousSpace::mangle_region(MemRegion mr) {
+ // Although this method uses SpaceMangler::mangle_region() which
+ // is not specific to a space, the when the ContiguousSpace version
+ // is called, it is always with regard to a space and this
+ // bounds checking is appropriate.
+ MemRegion space_mr(bottom(), end());
+ assert(space_mr.contains(mr), "Mangling outside space");
+ SpaceMangler::mangle_region(mr);
+}
+#endif // NOT_PRODUCT
-void CompactibleSpace::initialize(MemRegion mr, bool clear_space) {
- Space::initialize(mr, clear_space);
+void CompactibleSpace::initialize(MemRegion mr,
+ bool clear_space,
+ bool mangle_space) {
+ Space::initialize(mr, clear_space, mangle_space);
_compaction_top = bottom();
_next_compaction_space = NULL;
}
@@ -820,8 +863,8 @@
}
}
-void EdenSpace::clear() {
- ContiguousSpace::clear();
+void EdenSpace::clear(bool mangle_space) {
+ ContiguousSpace::clear(mangle_space);
set_soft_end(end());
}
@@ -878,7 +921,7 @@
_par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true)
{
_offsets.set_contig_space(this);
- initialize(mr, true);
+ initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
}
--- a/hotspot/src/share/vm/memory/space.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/space.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -131,15 +131,17 @@
return MemRegion(bottom(), saved_mark_word());
}
- // Initialization
- virtual void initialize(MemRegion mr, bool clear_space);
- virtual void clear();
+ // Initialization. These may be run to reset an existing
+ // Space.
+ virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space);
+ virtual void clear(bool mangle_space);
// For detecting GC bugs. Should only be called at GC boundaries, since
// some unused space may be used as scratch space during GC's.
// Default implementation does nothing. We also call this when expanding
// a space to satisfy an allocation request. See bug #4668531
virtual void mangle_unused_area() {}
+ virtual void mangle_unused_area_complete() {}
virtual void mangle_region(MemRegion mr) {}
// Testers
@@ -354,7 +356,7 @@
CompactibleSpace* _next_compaction_space;
public:
- virtual void initialize(MemRegion mr, bool clear_space);
+ virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space);
// Used temporarily during a compaction phase to hold the value
// top should have when compaction is complete.
@@ -724,12 +726,14 @@
/* continuously, but those that weren't need to have their thresholds */ \
/* re-initialized. Also mangles unused area for debugging. */ \
if (is_empty()) { \
- clear(); \
+ clear(SpaceDecorator::Mangle); \
} else { \
if (ZapUnusedHeapArea) mangle_unused_area(); \
} \
}
+class GenSpaceMangler;
+
// A space in which the free area is contiguous. It therefore supports
// faster allocation, and compaction.
class ContiguousSpace: public CompactibleSpace {
@@ -738,13 +742,21 @@
protected:
HeapWord* _top;
HeapWord* _concurrent_iteration_safe_limit;
+ // A helper for mangling the unused area of the space in debug builds.
+ GenSpaceMangler* _mangler;
+
+ GenSpaceMangler* mangler() { return _mangler; }
// Allocation helpers (return NULL if full).
inline HeapWord* allocate_impl(size_t word_size, HeapWord* end_value);
inline HeapWord* par_allocate_impl(size_t word_size, HeapWord* end_value);
public:
- virtual void initialize(MemRegion mr, bool clear_space);
+
+ ContiguousSpace();
+ ~ContiguousSpace();
+
+ virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space);
// Accessors
HeapWord* top() const { return _top; }
@@ -753,15 +765,34 @@
void set_saved_mark() { _saved_mark_word = top(); }
void reset_saved_mark() { _saved_mark_word = bottom(); }
- virtual void clear();
+ virtual void clear(bool mangle_space);
WaterMark bottom_mark() { return WaterMark(this, bottom()); }
WaterMark top_mark() { return WaterMark(this, top()); }
WaterMark saved_mark() { return WaterMark(this, saved_mark_word()); }
bool saved_mark_at_top() const { return saved_mark_word() == top(); }
- void mangle_unused_area();
- void mangle_region(MemRegion mr);
+ // In debug mode mangle (write it with a particular bit
+ // pattern) the unused part of a space.
+
+ // Used to save the an address in a space for later use during mangling.
+ void set_top_for_allocations(HeapWord* v) PRODUCT_RETURN;
+ // Used to save the space's current top for later use during mangling.
+ void set_top_for_allocations() PRODUCT_RETURN;
+
+ // Mangle regions in the space from the current top up to the
+ // previously mangled part of the space.
+ void mangle_unused_area() PRODUCT_RETURN;
+ // Mangle [top, end)
+ void mangle_unused_area_complete() PRODUCT_RETURN;
+ // Mangle the given MemRegion.
+ void mangle_region(MemRegion mr) PRODUCT_RETURN;
+
+ // Do some sparse checking on the area that should have been mangled.
+ void check_mangled_unused_area(HeapWord* limit) PRODUCT_RETURN;
+ // Check the complete area that should have been mangled.
+ // This code may be NULL depending on the macro DEBUG_MANGLING.
+ void check_mangled_unused_area_complete() PRODUCT_RETURN;
// Size computations: sizes in bytes.
size_t capacity() const { return byte_size(bottom(), end()); }
@@ -956,7 +987,7 @@
void set_soft_end(HeapWord* value) { _soft_end = value; }
// Override.
- void clear();
+ void clear(bool mangle_space);
// Set both the 'hard' and 'soft' limits (_end and _soft_end).
void set_end(HeapWord* value) {
@@ -1000,7 +1031,7 @@
void set_bottom(HeapWord* value);
void set_end(HeapWord* value);
- void clear();
+ void clear(bool mangle_space);
inline HeapWord* block_start(const void* p) const;
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -367,26 +367,31 @@
// Only 1.3 or later has the java.lang.Shutdown class.
// Only 1.4 or later has the java.lang.CharSequence interface.
// Only 1.5 or later has the java.lang.management.MemoryUsage class.
- if (JDK_Version::is_pre_jdk16_version()) {
- klassOop k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD);
+ if (JDK_Version::is_partially_initialized()) {
+ uint8_t jdk_version;
+ klassOop k = SystemDictionary::resolve_or_null(
+ vmSymbolHandles::java_lang_management_MemoryUsage(), THREAD);
CLEAR_PENDING_EXCEPTION; // ignore exceptions
if (k == NULL) {
- k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_CharSequence(), THREAD);
+ k = SystemDictionary::resolve_or_null(
+ vmSymbolHandles::java_lang_CharSequence(), THREAD);
CLEAR_PENDING_EXCEPTION; // ignore exceptions
if (k == NULL) {
- k = SystemDictionary::resolve_or_null(vmSymbolHandles::java_lang_Shutdown(), THREAD);
+ k = SystemDictionary::resolve_or_null(
+ vmSymbolHandles::java_lang_Shutdown(), THREAD);
CLEAR_PENDING_EXCEPTION; // ignore exceptions
if (k == NULL) {
- JDK_Version::set_jdk12x_version();
+ jdk_version = 2;
} else {
- JDK_Version::set_jdk13x_version();
+ jdk_version = 3;
}
} else {
- JDK_Version::set_jdk14x_version();
+ jdk_version = 4;
}
} else {
- JDK_Version::set_jdk15x_version();
+ jdk_version = 5;
}
+ JDK_Version::fully_initialize(jdk_version);
}
#ifdef ASSERT
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -83,7 +83,7 @@
ciMethod* caller_method, Compile* C) {
// True when EA is ON and a java constructor is called or
// a super constructor is called from an inlined java constructor.
- return DoEscapeAnalysis && EliminateAllocations &&
+ return C->do_escape_analysis() && EliminateAllocations &&
( callee_method->is_initializer() ||
(caller_method->is_initializer() &&
caller_method != C->method() &&
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -388,6 +388,9 @@
product(intx, EliminateAllocationArraySizeLimit, 64, \
"Array size (number of elements) limit for scalar replacement") \
\
+ product(intx, ValueSearchLimit, 1000, \
+ "Recursion limit in PhaseMacroExpand::value_from_mem_phi") \
+ \
product(intx, MaxLabelRootDepth, 1100, \
"Maximum times call Label_Root to prevent stack overflow") \
\
--- a/hotspot/src/share/vm/opto/callnode.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -631,61 +631,13 @@
bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) {
const TypeOopPtr *adrInst_t = addr_t->isa_oopptr();
- // if not an InstPtr or not an instance type, assume the worst
- if (adrInst_t == NULL || !adrInst_t->is_known_instance_field()) {
+ // If not an OopPtr or not an instance type, assume the worst.
+ // Note: currently this method is called only for instance types.
+ if (adrInst_t == NULL || !adrInst_t->is_known_instance()) {
return true;
}
- Compile *C = phase->C;
- int offset = adrInst_t->offset();
- assert(adrInst_t->klass_is_exact() && offset >= 0, "should be valid offset");
- ciKlass* adr_k = adrInst_t->klass();
- assert(adr_k->is_loaded() &&
- adr_k->is_java_klass() &&
- !adr_k->is_interface(),
- "only non-abstract classes are expected");
-
- int base_idx = C->get_alias_index(adrInst_t);
- int size = BytesPerLong; // If we don't know the size, assume largest.
- if (adrInst_t->isa_instptr()) {
- ciField* field = C->alias_type(base_idx)->field();
- if (field != NULL) {
- size = field->size_in_bytes();
- }
- } else {
- assert(adrInst_t->isa_aryptr(), "only arrays are expected");
- size = type2aelembytes(adr_k->as_array_klass()->element_type()->basic_type());
- }
-
- ciMethod * meth = is_CallStaticJava() ? as_CallStaticJava()->method() : NULL;
- BCEscapeAnalyzer *bcea = (meth != NULL) ? meth->get_bcea() : NULL;
-
- const TypeTuple * d = tf()->domain();
- for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
- const Type* t = d->field_at(i);
- Node *arg = in(i);
- const Type *at = phase->type(arg);
- if (at == TypePtr::NULL_PTR || at == Type::TOP)
- continue; // null can't affect anything
-
- const TypeOopPtr *at_ptr = at->isa_oopptr();
- if (!arg->is_top() && (t->isa_oopptr() != NULL ||
- t->isa_ptr() && at_ptr != NULL)) {
- assert(at_ptr != NULL, "expecting an OopPtr");
- ciKlass* at_k = at_ptr->klass();
- if ((adrInst_t->base() == at_ptr->base()) &&
- at_k->is_loaded() &&
- at_k->is_java_klass()) {
- // If we have found an argument matching addr_t, check if the field
- // at the specified offset is modified.
- if ((at_k->is_interface() || adr_k == at_k ||
- adr_k->is_subclass_of(at_k) && !at_ptr->klass_is_exact()) &&
- (bcea == NULL ||
- bcea->is_arg_modified(i - TypeFunc::Parms, offset, size))) {
- return true;
- }
- }
- }
- }
+ // The instance_id is set only for scalar-replaceable allocations which
+ // are not passed as arguments according to Escape Analysis.
return false;
}
--- a/hotspot/src/share/vm/opto/cfgnode.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -713,7 +713,9 @@
assert(type() == Type::MEMORY &&
(t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
- t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop),
+ t->is_oopptr()->cast_to_exactness(true)
+ ->is_oopptr()->cast_to_ptr_type(t_oop->ptr())
+ ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop),
"bottom or raw memory required");
// Check if an appropriate node already exists.
@@ -1089,6 +1091,8 @@
if (rc == NULL || phase->type(rc) == Type::TOP)
continue; // ignore unreachable control path
Node* n = in(i);
+ if (n == NULL)
+ continue;
Node* un = n->uncast();
if (un == NULL || un == this || phase->type(un) == Type::TOP) {
continue; // ignore if top, or in(i) and "this" are in a data cycle
--- a/hotspot/src/share/vm/opto/compile.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -583,18 +583,32 @@
NOT_PRODUCT( verify_graph_edges(); )
// Perform escape analysis
- if (_do_escape_analysis)
- _congraph = new ConnectionGraph(this);
- if (_congraph != NULL) {
- NOT_PRODUCT( TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, TimeCompiler); )
- _congraph->compute_escape();
- if (failing()) return;
+ if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
+ TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true);
+ // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction.
+ PhaseGVN* igvn = initial_gvn();
+ Node* oop_null = igvn->zerocon(T_OBJECT);
+ Node* noop_null = igvn->zerocon(T_NARROWOOP);
+
+ _congraph = new(comp_arena()) ConnectionGraph(this);
+ bool has_non_escaping_obj = _congraph->compute_escape();
#ifndef PRODUCT
if (PrintEscapeAnalysis) {
_congraph->dump();
}
#endif
+ // Cleanup.
+ if (oop_null->outcnt() == 0)
+ igvn->hash_delete(oop_null);
+ if (noop_null->outcnt() == 0)
+ igvn->hash_delete(noop_null);
+
+ if (!has_non_escaping_obj) {
+ _congraph = NULL;
+ }
+
+ if (failing()) return;
}
// Now optimize
Optimize();
@@ -995,9 +1009,14 @@
int offset = tj->offset();
TypePtr::PTR ptr = tj->ptr();
+ // Known instance (scalarizable allocation) alias only with itself.
+ bool is_known_inst = tj->isa_oopptr() != NULL &&
+ tj->is_oopptr()->is_known_instance();
+
// Process weird unsafe references.
if (offset == Type::OffsetBot && (tj->isa_instptr() /*|| tj->isa_klassptr()*/)) {
assert(InlineUnsafeOps, "indeterminate pointers come only from unsafe ops");
+ assert(!is_known_inst, "scalarizable allocation should not have unsafe references");
tj = TypeOopPtr::BOTTOM;
ptr = tj->ptr();
offset = tj->offset();
@@ -1005,14 +1024,20 @@
// Array pointers need some flattening
const TypeAryPtr *ta = tj->isa_aryptr();
- if( ta && _AliasLevel >= 2 ) {
+ if( ta && is_known_inst ) {
+ if ( offset != Type::OffsetBot &&
+ offset > arrayOopDesc::length_offset_in_bytes() ) {
+ offset = Type::OffsetBot; // Flatten constant access into array body only
+ tj = ta = TypeAryPtr::make(ptr, ta->ary(), ta->klass(), true, offset, ta->instance_id());
+ }
+ } else if( ta && _AliasLevel >= 2 ) {
// For arrays indexed by constant indices, we flatten the alias
// space to include all of the array body. Only the header, klass
// and array length can be accessed un-aliased.
if( offset != Type::OffsetBot ) {
if( ta->const_oop() ) { // methodDataOop or methodOop
offset = Type::OffsetBot; // Flatten constant access into array body
- tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,Type::OffsetBot, ta->instance_id());
+ tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),ta->ary(),ta->klass(),false,offset);
} else if( offset == arrayOopDesc::length_offset_in_bytes() ) {
// range is OK as-is.
tj = ta = TypeAryPtr::RANGE;
@@ -1026,29 +1051,29 @@
ptr = TypePtr::BotPTR;
} else { // Random constant offset into array body
offset = Type::OffsetBot; // Flatten constant access into array body
- tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,Type::OffsetBot, ta->instance_id());
+ tj = ta = TypeAryPtr::make(ptr,ta->ary(),ta->klass(),false,offset);
}
}
// Arrays of fixed size alias with arrays of unknown size.
if (ta->size() != TypeInt::POS) {
const TypeAry *tary = TypeAry::make(ta->elem(), TypeInt::POS);
- tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset, ta->instance_id());
+ tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,ta->klass(),false,offset);
}
// Arrays of known objects become arrays of unknown objects.
if (ta->elem()->isa_narrowoop() && ta->elem() != TypeNarrowOop::BOTTOM) {
const TypeAry *tary = TypeAry::make(TypeNarrowOop::BOTTOM, ta->size());
- tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset, ta->instance_id());
+ tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset);
}
if (ta->elem()->isa_oopptr() && ta->elem() != TypeInstPtr::BOTTOM) {
const TypeAry *tary = TypeAry::make(TypeInstPtr::BOTTOM, ta->size());
- tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset, ta->instance_id());
+ tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,NULL,false,offset);
}
// Arrays of bytes and of booleans both use 'bastore' and 'baload' so
// cannot be distinguished by bytecode alone.
if (ta->elem() == TypeInt::BOOL) {
const TypeAry *tary = TypeAry::make(TypeInt::BYTE, ta->size());
ciKlass* aklass = ciTypeArrayKlass::make(T_BYTE);
- tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset, ta->instance_id());
+ tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset);
}
// During the 2nd round of IterGVN, NotNull castings are removed.
// Make sure the Bottom and NotNull variants alias the same.
@@ -1068,21 +1093,24 @@
if( ptr == TypePtr::Constant ) {
// No constant oop pointers (such as Strings); they alias with
// unknown strings.
+ assert(!is_known_inst, "not scalarizable allocation");
tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
- } else if( to->is_known_instance_field() ) {
+ } else if( is_known_inst ) {
tj = to; // Keep NotNull and klass_is_exact for instance type
} else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
// During the 2nd round of IterGVN, NotNull castings are removed.
// Make sure the Bottom and NotNull variants alias the same.
// Also, make sure exact and non-exact variants alias the same.
- tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset, to->instance_id());
+ tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
}
// Canonicalize the holder of this field
ciInstanceKlass *k = to->klass()->as_instance_klass();
if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
// First handle header references such as a LoadKlassNode, even if the
// object's klass is unloaded at compile time (4965979).
- tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset, to->instance_id());
+ if (!is_known_inst) { // Do it only for non-instance types
+ tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset);
+ }
} else if (offset < 0 || offset >= k->size_helper() * wordSize) {
to = NULL;
tj = TypeOopPtr::BOTTOM;
@@ -1090,7 +1118,11 @@
} else {
ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
if (!k->equals(canonical_holder) || tj->offset() != offset) {
- tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset, to->instance_id());
+ if( is_known_inst ) {
+ tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, NULL, offset, to->instance_id());
+ } else {
+ tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, NULL, offset);
+ }
}
}
}
@@ -1276,7 +1308,9 @@
assert(flat != TypePtr::BOTTOM, "cannot alias-analyze an untyped ptr");
if (flat->isa_oopptr() && !flat->isa_klassptr()) {
const TypeOopPtr* foop = flat->is_oopptr();
- const TypePtr* xoop = foop->cast_to_exactness(!foop->klass_is_exact())->is_ptr();
+ // Scalarizable allocations have exact klass always.
+ bool exact = !foop->klass_is_exact() || foop->is_known_instance();
+ const TypePtr* xoop = foop->cast_to_exactness(exact)->is_ptr();
assert(foop == flatten_alias_type(xoop), "exactness must not affect alias type");
}
assert(flat == flatten_alias_type(flat), "exact bit doesn't matter");
--- a/hotspot/src/share/vm/opto/escape.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -25,16 +25,6 @@
#include "incls/_precompiled.incl"
#include "incls/_escape.cpp.incl"
-uint PointsToNode::edge_target(uint e) const {
- assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index");
- return (_edges->at(e) >> EdgeShift);
-}
-
-PointsToNode::EdgeType PointsToNode::edge_type(uint e) const {
- assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index");
- return (EdgeType) (_edges->at(e) & EdgeMask);
-}
-
void PointsToNode::add_edge(uint targIdx, PointsToNode::EdgeType et) {
uint v = (targIdx << EdgeShift) + ((uint) et);
if (_edges == NULL) {
@@ -72,10 +62,14 @@
"F" // FieldEdge
};
-void PointsToNode::dump() const {
+void PointsToNode::dump(bool print_state) const {
NodeType nt = node_type();
- EscapeState es = escape_state();
- tty->print("%s %s %s [[", node_type_names[(int) nt], esc_names[(int) es], _scalar_replaceable ? "" : "NSR");
+ tty->print("%s ", node_type_names[(int) nt]);
+ if (print_state) {
+ EscapeState es = escape_state();
+ tty->print("%s %s ", esc_names[(int) es], _scalar_replaceable ? "":"NSR");
+ }
+ tty->print("[[");
for (uint i = 0; i < edge_count(); i++) {
tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]);
}
@@ -87,17 +81,29 @@
}
#endif
-ConnectionGraph::ConnectionGraph(Compile * C) : _processed(C->comp_arena()), _node_map(C->comp_arena()) {
- _collecting = true;
- this->_compile = C;
- const PointsToNode &dummy = PointsToNode();
- int sz = C->unique();
- _nodes = new(C->comp_arena()) GrowableArray<PointsToNode>(C->comp_arena(), sz, sz, dummy);
- _phantom_object = C->top()->_idx;
- PointsToNode *phn = ptnode_adr(_phantom_object);
- phn->_node = C->top();
- phn->set_node_type(PointsToNode::JavaObject);
- phn->set_escape_state(PointsToNode::GlobalEscape);
+ConnectionGraph::ConnectionGraph(Compile * C) :
+ _nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()),
+ _processed(C->comp_arena()),
+ _collecting(true),
+ _compile(C),
+ _node_map(C->comp_arena()) {
+
+ _phantom_object = C->top()->_idx,
+ add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true);
+
+ // Add ConP(#NULL) and ConN(#NULL) nodes.
+ PhaseGVN* igvn = C->initial_gvn();
+ Node* oop_null = igvn->zerocon(T_OBJECT);
+ _oop_null = oop_null->_idx;
+ assert(_oop_null < C->unique(), "should be created already");
+ add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
+
+ if (UseCompressedOops) {
+ Node* noop_null = igvn->zerocon(T_NARROWOOP);
+ _noop_null = noop_null->_idx;
+ assert(_noop_null < C->unique(), "should be created already");
+ add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
+ }
}
void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) {
@@ -182,32 +188,36 @@
// If we are still collecting or there were no non-escaping allocations
// we don't know the answer yet
- if (_collecting || !_has_allocations)
+ if (_collecting)
return PointsToNode::UnknownEscape;
// if the node was created after the escape computation, return
// UnknownEscape
- if (idx >= (uint)_nodes->length())
+ if (idx >= nodes_size())
return PointsToNode::UnknownEscape;
- es = _nodes->at_grow(idx).escape_state();
+ es = ptnode_adr(idx)->escape_state();
// if we have already computed a value, return it
if (es != PointsToNode::UnknownEscape)
return es;
+ // PointsTo() calls n->uncast() which can return a new ideal node.
+ if (n->uncast()->_idx >= nodes_size())
+ return PointsToNode::UnknownEscape;
+
// compute max escape state of anything this node could point to
VectorSet ptset(Thread::current()->resource_area());
PointsTo(ptset, n, phase);
for(VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i) {
uint pt = i.elem;
- PointsToNode::EscapeState pes = _nodes->adr_at(pt)->escape_state();
+ PointsToNode::EscapeState pes = ptnode_adr(pt)->escape_state();
if (pes > es)
es = pes;
}
// cache the computed escape state
assert(es != PointsToNode::UnknownEscape, "should have computed an escape state");
- _nodes->adr_at(idx)->set_escape_state(es);
+ ptnode_adr(idx)->set_escape_state(es);
return es;
}
@@ -220,48 +230,50 @@
#endif
n = n->uncast();
- PointsToNode npt = _nodes->at_grow(n->_idx);
+ PointsToNode* npt = ptnode_adr(n->_idx);
// If we have a JavaObject, return just that object
- if (npt.node_type() == PointsToNode::JavaObject) {
+ if (npt->node_type() == PointsToNode::JavaObject) {
ptset.set(n->_idx);
return;
}
#ifdef ASSERT
- if (npt._node == NULL) {
+ if (npt->_node == NULL) {
if (orig_n != n)
orig_n->dump();
n->dump();
- assert(npt._node != NULL, "unregistered node");
+ assert(npt->_node != NULL, "unregistered node");
}
#endif
worklist.push(n->_idx);
while(worklist.length() > 0) {
int ni = worklist.pop();
- PointsToNode pn = _nodes->at_grow(ni);
- if (!visited.test_set(ni)) {
- // ensure that all inputs of a Phi have been processed
- assert(!_collecting || !pn._node->is_Phi() || _processed.test(ni),"");
+ if (visited.test_set(ni))
+ continue;
+
+ PointsToNode* pn = ptnode_adr(ni);
+ // ensure that all inputs of a Phi have been processed
+ assert(!_collecting || !pn->_node->is_Phi() || _processed.test(ni),"");
- int edges_processed = 0;
- for (uint e = 0; e < pn.edge_count(); e++) {
- uint etgt = pn.edge_target(e);
- PointsToNode::EdgeType et = pn.edge_type(e);
- if (et == PointsToNode::PointsToEdge) {
- ptset.set(etgt);
- edges_processed++;
- } else if (et == PointsToNode::DeferredEdge) {
- worklist.push(etgt);
- edges_processed++;
- } else {
- assert(false,"neither PointsToEdge or DeferredEdge");
- }
+ int edges_processed = 0;
+ uint e_cnt = pn->edge_count();
+ for (uint e = 0; e < e_cnt; e++) {
+ uint etgt = pn->edge_target(e);
+ PointsToNode::EdgeType et = pn->edge_type(e);
+ if (et == PointsToNode::PointsToEdge) {
+ ptset.set(etgt);
+ edges_processed++;
+ } else if (et == PointsToNode::DeferredEdge) {
+ worklist.push(etgt);
+ edges_processed++;
+ } else {
+ assert(false,"neither PointsToEdge or DeferredEdge");
}
- if (edges_processed == 0) {
- // no deferred or pointsto edges found. Assume the value was set
- // outside this method. Add the phantom object to the pointsto set.
- ptset.set(_phantom_object);
- }
+ }
+ if (edges_processed == 0) {
+ // no deferred or pointsto edges found. Assume the value was set
+ // outside this method. Add the phantom object to the pointsto set.
+ ptset.set(_phantom_object);
}
}
}
@@ -272,11 +284,11 @@
deferred_edges->clear();
visited->Clear();
- uint i = 0;
+ visited->set(ni);
PointsToNode *ptn = ptnode_adr(ni);
// Mark current edges as visited and move deferred edges to separate array.
- while (i < ptn->edge_count()) {
+ for (uint i = 0; i < ptn->edge_count(); ) {
uint t = ptn->edge_target(i);
#ifdef ASSERT
assert(!visited->test_set(t), "expecting no duplications");
@@ -293,24 +305,23 @@
for (int next = 0; next < deferred_edges->length(); ++next) {
uint t = deferred_edges->at(next);
PointsToNode *ptt = ptnode_adr(t);
- for (uint j = 0; j < ptt->edge_count(); j++) {
- uint n1 = ptt->edge_target(j);
- if (visited->test_set(n1))
+ uint e_cnt = ptt->edge_count();
+ for (uint e = 0; e < e_cnt; e++) {
+ uint etgt = ptt->edge_target(e);
+ if (visited->test_set(etgt))
continue;
- switch(ptt->edge_type(j)) {
- case PointsToNode::PointsToEdge:
- add_pointsto_edge(ni, n1);
- if(n1 == _phantom_object) {
- // Special case - field set outside (globally escaping).
- ptn->set_escape_state(PointsToNode::GlobalEscape);
- }
- break;
- case PointsToNode::DeferredEdge:
- deferred_edges->append(n1);
- break;
- case PointsToNode::FieldEdge:
- assert(false, "invalid connection graph");
- break;
+
+ PointsToNode::EdgeType et = ptt->edge_type(e);
+ if (et == PointsToNode::PointsToEdge) {
+ add_pointsto_edge(ni, etgt);
+ if(etgt == _phantom_object) {
+ // Special case - field set outside (globally escaping).
+ ptn->set_escape_state(PointsToNode::GlobalEscape);
+ }
+ } else if (et == PointsToNode::DeferredEdge) {
+ deferred_edges->append(etgt);
+ } else {
+ assert(false,"invalid connection graph");
}
}
}
@@ -322,15 +333,15 @@
// a pointsto edge is added if it is a JavaObject
void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) {
- PointsToNode an = _nodes->at_grow(adr_i);
- PointsToNode to = _nodes->at_grow(to_i);
- bool deferred = (to.node_type() == PointsToNode::LocalVar);
+ PointsToNode* an = ptnode_adr(adr_i);
+ PointsToNode* to = ptnode_adr(to_i);
+ bool deferred = (to->node_type() == PointsToNode::LocalVar);
- for (uint fe = 0; fe < an.edge_count(); fe++) {
- assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
- int fi = an.edge_target(fe);
- PointsToNode pf = _nodes->at_grow(fi);
- int po = pf.offset();
+ for (uint fe = 0; fe < an->edge_count(); fe++) {
+ assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
+ int fi = an->edge_target(fe);
+ PointsToNode* pf = ptnode_adr(fi);
+ int po = pf->offset();
if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) {
if (deferred)
add_deferred_edge(fi, to_i);
@@ -343,13 +354,13 @@
// Add a deferred edge from node given by "from_i" to any field of adr_i
// whose offset matches "offset".
void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) {
- PointsToNode an = _nodes->at_grow(adr_i);
- for (uint fe = 0; fe < an.edge_count(); fe++) {
- assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
- int fi = an.edge_target(fe);
- PointsToNode pf = _nodes->at_grow(fi);
- int po = pf.offset();
- if (pf.edge_count() == 0) {
+ PointsToNode* an = ptnode_adr(adr_i);
+ for (uint fe = 0; fe < an->edge_count(); fe++) {
+ assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
+ int fi = an->edge_target(fe);
+ PointsToNode* pf = ptnode_adr(fi);
+ int po = pf->offset();
+ if (pf->edge_count() == 0) {
// we have not seen any stores to this field, assume it was set outside this method
add_pointsto_edge(fi, _phantom_object);
}
@@ -504,29 +515,30 @@
igvn->set_type(addp, tinst);
// record the allocation in the node map
set_map(addp->_idx, get_map(base->_idx));
- // if the Address input is not the appropriate instance type
- // (due to intervening casts,) insert a cast
- Node *adr = addp->in(AddPNode::Address);
- const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr();
- if (atype != NULL && atype->instance_id() != inst_id) {
- assert(!atype->is_known_instance(), "no conflicting instances");
- const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr();
- Node *acast = new (_compile, 2) CastPPNode(adr, new_atype);
- acast->set_req(0, adr->in(0));
- igvn->set_type(acast, new_atype);
- record_for_optimizer(acast);
- Node *bcast = acast;
- Node *abase = addp->in(AddPNode::Base);
- if (abase != adr) {
- bcast = new (_compile, 2) CastPPNode(abase, base_t);
- bcast->set_req(0, abase->in(0));
- igvn->set_type(bcast, base_t);
- record_for_optimizer(bcast);
+
+ // Set addp's Base and Address to 'base'.
+ Node *abase = addp->in(AddPNode::Base);
+ Node *adr = addp->in(AddPNode::Address);
+ if (adr->is_Proj() && adr->in(0)->is_Allocate() &&
+ adr->in(0)->_idx == (uint)inst_id) {
+ // Skip AddP cases #3 and #5.
+ } else {
+ assert(!abase->is_top(), "sanity"); // AddP case #3
+ if (abase != base) {
+ igvn->hash_delete(addp);
+ addp->set_req(AddPNode::Base, base);
+ if (abase == adr) {
+ addp->set_req(AddPNode::Address, base);
+ } else {
+ // AddP case #4 (adr is array's element offset AddP node)
+#ifdef ASSERT
+ const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr();
+ assert(adr->is_AddP() && atype != NULL &&
+ atype->instance_id() == inst_id, "array's element offset should be processed first");
+#endif
+ }
+ igvn->hash_insert(addp);
}
- igvn->hash_delete(addp);
- addp->set_req(AddPNode::Base, bcast);
- addp->set_req(AddPNode::Address, acast);
- igvn->hash_insert(addp);
}
// Put on IGVN worklist since at least addp's type was changed above.
record_for_optimizer(addp);
@@ -664,27 +676,31 @@
Compile* C = phase->C;
const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr();
bool is_instance = (tinst != NULL) && tinst->is_known_instance();
+ Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
Node *prev = NULL;
Node *result = orig_mem;
while (prev != result) {
prev = result;
+ if (result == start_mem)
+ break; // hit one of our sentinals
if (result->is_Mem()) {
- MemNode *mem = result->as_Mem();
- const Type *at = phase->type(mem->in(MemNode::Address));
+ const Type *at = phase->type(result->in(MemNode::Address));
if (at != Type::TOP) {
assert (at->isa_ptr() != NULL, "pointer type required.");
int idx = C->get_alias_index(at->is_ptr());
if (idx == alias_idx)
break;
}
- result = mem->in(MemNode::Memory);
+ result = result->in(MemNode::Memory);
}
if (!is_instance)
continue; // don't search further for non-instance types
// skip over a call which does not affect this memory slice
if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
Node *proj_in = result->in(0);
- if (proj_in->is_Call()) {
+ if (proj_in->is_Allocate() && proj_in->_idx == (uint)tinst->instance_id()) {
+ break; // hit one of our sentinals
+ } else if (proj_in->is_Call()) {
CallNode *call = proj_in->as_Call();
if (!call->may_modify(tinst, phase)) {
result = call->in(TypeFunc::Memory);
@@ -721,12 +737,17 @@
}
}
}
- if (is_instance && result->is_Phi()) {
+ if (result->is_Phi()) {
PhiNode *mphi = result->as_Phi();
assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
const TypePtr *t = mphi->adr_type();
if (C->get_alias_index(t) != alias_idx) {
+ // Create a new Phi with the specified alias index type.
result = split_memory_phi(mphi, alias_idx, orig_phis, phase);
+ } else if (!is_instance) {
+ // Push all non-instance Phis on the orig_phis worklist to update inputs
+ // during Phase 4 if needed.
+ orig_phis.append_if_missing(mphi);
}
}
// the result is either MemNode, PhiNode, InitializeNode.
@@ -835,6 +856,11 @@
// Phase 1: Process possible allocations from alloc_worklist.
// Create instance types for the CheckCastPP for allocations where possible.
+ //
+ // (Note: don't forget to change the order of the second AddP node on
+ // the alloc_worklist if the order of the worklist processing is changed,
+ // see the comment in find_second_addp().)
+ //
while (alloc_worklist.length() != 0) {
Node *n = alloc_worklist.pop();
uint ni = n->_idx;
@@ -842,7 +868,7 @@
if (n->is_Call()) {
CallNode *alloc = n->as_Call();
// copy escape information to call node
- PointsToNode* ptn = _nodes->adr_at(alloc->_idx);
+ PointsToNode* ptn = ptnode_adr(alloc->_idx);
PointsToNode::EscapeState es = escape_state(alloc, igvn);
// We have an allocation or call which returns a Java object,
// see if it is unescaped.
@@ -858,10 +884,14 @@
!n->is_CheckCastPP()) // not unique CheckCastPP.
continue;
// The inline code for Object.clone() casts the allocation result to
- // java.lang.Object and then to the the actual type of the allocated
+ // java.lang.Object and then to the actual type of the allocated
// object. Detect this case and use the second cast.
+ // Also detect j.l.reflect.Array.newInstance(jobject, jint) case when
+ // the allocation result is cast to java.lang.Object and then
+ // to the actual Array type.
if (alloc->is_Allocate() && n->as_Type()->type() == TypeInstPtr::NOTNULL
- && igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeKlassPtr::OBJECT) {
+ && (alloc->is_AllocateArray() ||
+ igvn->type(alloc->in(AllocateNode::KlassNode)) != TypeKlassPtr::OBJECT)) {
Node *cast2 = NULL;
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
Node *use = n->fast_out(i);
@@ -877,7 +907,7 @@
}
}
set_escape_state(n->_idx, es);
- // in order for an object to be stackallocatable, it must be:
+ // in order for an object to be scalar-replaceable, it must be:
// - a direct allocation (not a call returning an object)
// - non-escaping
// - eligible to be a unique type
@@ -887,7 +917,7 @@
const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
if (t == NULL)
continue; // not a TypeInstPtr
- tinst = t->cast_to_instance_id(ni);
+ tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni);
igvn->hash_delete(n);
igvn->set_type(n, tinst);
n->raise_bottom_type(tinst);
@@ -899,7 +929,7 @@
// First, put on the worklist all Field edges from Connection Graph
// which is more accurate then putting immediate users from Ideal Graph.
for (uint e = 0; e < ptn->edge_count(); e++) {
- Node *use = _nodes->adr_at(ptn->edge_target(e))->_node;
+ Node *use = ptnode_adr(ptn->edge_target(e))->_node;
assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(),
"only AddP nodes are Field edges in CG");
if (use->outcnt() > 0) { // Don't process dead nodes
@@ -996,12 +1026,12 @@
memnode_worklist.append_if_missing(use);
} else if (use->is_MergeMem()) {
mergemem_worklist.append_if_missing(use);
- } else if (use->is_Call() && tinst != NULL) {
+ } else if (use->is_SafePoint() && tinst != NULL) {
// Look for MergeMem nodes for calls which reference unique allocation
// (through CheckCastPP nodes) even for debug info.
Node* m = use->in(TypeFunc::Memory);
uint iid = tinst->instance_id();
- while (m->is_Proj() && m->in(0)->is_Call() &&
+ while (m->is_Proj() && m->in(0)->is_SafePoint() &&
m->in(0) != use && !m->in(0)->_idx != iid) {
m = m->in(0)->in(TypeFunc::Memory);
}
@@ -1062,7 +1092,7 @@
}
if (mem != n->in(MemNode::Memory)) {
set_map(n->_idx, mem);
- _nodes->adr_at(n->_idx)->_node = n;
+ ptnode_adr(n->_idx)->_node = n;
}
if (n->is_Load()) {
continue; // don't push users
@@ -1203,8 +1233,8 @@
// to recursively process Phi's encounted on the input memory
// chains as is done in split_memory_phi() since they will
// also be processed here.
- while (orig_phis.length() != 0) {
- PhiNode *phi = orig_phis.pop();
+ for (int j = 0; j < orig_phis.length(); j++) {
+ PhiNode *phi = orig_phis.at(j);
int alias_idx = _compile->get_alias_index(phi->adr_type());
igvn->hash_delete(phi);
for (uint i = 1; i < phi->req(); i++) {
@@ -1223,10 +1253,10 @@
// Update the memory inputs of MemNodes with the value we computed
// in Phase 2.
- for (int i = 0; i < _nodes->length(); i++) {
+ for (uint i = 0; i < nodes_size(); i++) {
Node *nmem = get_map(i);
if (nmem != NULL) {
- Node *n = _nodes->adr_at(i)->_node;
+ Node *n = ptnode_adr(i)->_node;
if (n != NULL && n->is_Mem()) {
igvn->hash_delete(n);
n->set_req(MemNode::Memory, nmem);
@@ -1237,28 +1267,48 @@
}
}
-void ConnectionGraph::compute_escape() {
+bool ConnectionGraph::has_candidates(Compile *C) {
+ // EA brings benefits only when the code has allocations and/or locks which
+ // are represented by ideal Macro nodes.
+ int cnt = C->macro_count();
+ for( int i=0; i < cnt; i++ ) {
+ Node *n = C->macro_node(i);
+ if ( n->is_Allocate() )
+ return true;
+ if( n->is_Lock() ) {
+ Node* obj = n->as_Lock()->obj_node()->uncast();
+ if( !(obj->is_Parm() || obj->is_Con()) )
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ConnectionGraph::compute_escape() {
+ Compile* C = _compile;
// 1. Populate Connection Graph (CG) with Ideal nodes.
Unique_Node_List worklist_init;
- worklist_init.map(_compile->unique(), NULL); // preallocate space
+ worklist_init.map(C->unique(), NULL); // preallocate space
// Initialize worklist
- if (_compile->root() != NULL) {
- worklist_init.push(_compile->root());
+ if (C->root() != NULL) {
+ worklist_init.push(C->root());
}
GrowableArray<int> cg_worklist;
- PhaseGVN* igvn = _compile->initial_gvn();
+ PhaseGVN* igvn = C->initial_gvn();
bool has_allocations = false;
// Push all useful nodes onto CG list and set their type.
for( uint next = 0; next < worklist_init.size(); ++next ) {
Node* n = worklist_init.at(next);
record_for_escape_analysis(n, igvn);
- if (n->is_Call() &&
- _nodes->adr_at(n->_idx)->node_type() == PointsToNode::JavaObject) {
+ // Only allocations and java static calls results are checked
+ // for an escape status. See process_call_result() below.
+ if (n->is_Allocate() || n->is_CallStaticJava() &&
+ ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) {
has_allocations = true;
}
if(n->is_AddP())
@@ -1269,24 +1319,23 @@
}
}
- if (has_allocations) {
- _has_allocations = true;
- } else {
- _has_allocations = false;
+ if (!has_allocations) {
_collecting = false;
- return; // Nothing to do.
+ return false; // Nothing to do.
}
// 2. First pass to create simple CG edges (doesn't require to walk CG).
- for( uint next = 0; next < _delayed_worklist.size(); ++next ) {
+ uint delayed_size = _delayed_worklist.size();
+ for( uint next = 0; next < delayed_size; ++next ) {
Node* n = _delayed_worklist.at(next);
build_connection_graph(n, igvn);
}
// 3. Pass to create fields edges (Allocate -F-> AddP).
- for( int next = 0; next < cg_worklist.length(); ++next ) {
+ uint cg_length = cg_worklist.length();
+ for( uint next = 0; next < cg_length; ++next ) {
int ni = cg_worklist.at(next);
- build_connection_graph(_nodes->adr_at(ni)->_node, igvn);
+ build_connection_graph(ptnode_adr(ni)->_node, igvn);
}
cg_worklist.clear();
@@ -1294,8 +1343,8 @@
// 4. Build Connection Graph which need
// to walk the connection graph.
- for (uint ni = 0; ni < (uint)_nodes->length(); ni++) {
- PointsToNode* ptn = _nodes->adr_at(ni);
+ for (uint ni = 0; ni < nodes_size(); ni++) {
+ PointsToNode* ptn = ptnode_adr(ni);
Node *n = ptn->_node;
if (n != NULL) { // Call, AddP, LoadP, StoreP
build_connection_graph(n, igvn);
@@ -1305,140 +1354,226 @@
}
VectorSet ptset(Thread::current()->resource_area());
- GrowableArray<Node*> alloc_worklist;
- GrowableArray<int> worklist;
GrowableArray<uint> deferred_edges;
VectorSet visited(Thread::current()->resource_area());
- // remove deferred edges from the graph and collect
- // information we will need for type splitting
- for( int next = 0; next < cg_worklist.length(); ++next ) {
+ // 5. Remove deferred edges from the graph and collect
+ // information needed for type splitting.
+ cg_length = cg_worklist.length();
+ for( uint next = 0; next < cg_length; ++next ) {
int ni = cg_worklist.at(next);
- PointsToNode* ptn = _nodes->adr_at(ni);
+ PointsToNode* ptn = ptnode_adr(ni);
PointsToNode::NodeType nt = ptn->node_type();
- Node *n = ptn->_node;
if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
remove_deferred(ni, &deferred_edges, &visited);
+ Node *n = ptn->_node;
if (n->is_AddP()) {
- // If this AddP computes an address which may point to more that one
- // object or more then one field (array's element), nothing the address
- // points to can be scalar replaceable.
+ // Search for objects which are not scalar replaceable.
+ // Mark their escape state as ArgEscape to propagate the state
+ // to referenced objects.
+ // Note: currently there are no difference in compiler optimizations
+ // for ArgEscape objects and NoEscape objects which are not
+ // scalar replaceable.
+
+ int offset = ptn->offset();
Node *base = get_addp_base(n);
ptset.Clear();
PointsTo(ptset, base, igvn);
- if (ptset.Size() > 1 ||
- (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) {
+ int ptset_size = ptset.Size();
+
+ // Check if a field's initializing value is recorded and add
+ // a corresponding NULL field's value if it is not recorded.
+ // Connection Graph does not record a default initialization by NULL
+ // captured by Initialize node.
+ //
+ // Note: it will disable scalar replacement in some cases:
+ //
+ // Point p[] = new Point[1];
+ // p[0] = new Point(); // Will be not scalar replaced
+ //
+ // but it will save us from incorrect optimizations in next cases:
+ //
+ // Point p[] = new Point[1];
+ // if ( x ) p[0] = new Point(); // Will be not scalar replaced
+ //
+ // Without a control flow analysis we can't distinguish above cases.
+ //
+ if (offset != Type::OffsetBot && ptset_size == 1) {
+ uint elem = ptset.getelem(); // Allocation node's index
+ // It does not matter if it is not Allocation node since
+ // only non-escaping allocations are scalar replaced.
+ if (ptnode_adr(elem)->_node->is_Allocate() &&
+ ptnode_adr(elem)->escape_state() == PointsToNode::NoEscape) {
+ AllocateNode* alloc = ptnode_adr(elem)->_node->as_Allocate();
+ InitializeNode* ini = alloc->initialization();
+ Node* value = NULL;
+ if (ini != NULL) {
+ BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
+ Node* store = ini->find_captured_store(offset, type2aelembytes(ft), igvn);
+ if (store != NULL && store->is_Store())
+ value = store->in(MemNode::ValueIn);
+ }
+ if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
+ // A field's initializing value was not recorded. Add NULL.
+ uint null_idx = UseCompressedOops ? _noop_null : _oop_null;
+ add_pointsto_edge(ni, null_idx);
+ }
+ }
+ }
+
+ // An object is not scalar replaceable if the field which may point
+ // to it has unknown offset (unknown element of an array of objects).
+ //
+ if (offset == Type::OffsetBot) {
+ uint e_cnt = ptn->edge_count();
+ for (uint ei = 0; ei < e_cnt; ei++) {
+ uint npi = ptn->edge_target(ei);
+ set_escape_state(npi, PointsToNode::ArgEscape);
+ ptnode_adr(npi)->_scalar_replaceable = false;
+ }
+ }
+
+ // Currently an object is not scalar replaceable if a LoadStore node
+ // access its field since the field value is unknown after it.
+ //
+ bool has_LoadStore = false;
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+ Node *use = n->fast_out(i);
+ if (use->is_LoadStore()) {
+ has_LoadStore = true;
+ break;
+ }
+ }
+ // An object is not scalar replaceable if the address points
+ // to unknown field (unknown element for arrays, offset is OffsetBot).
+ //
+ // Or the address may point to more then one object. This may produce
+ // the false positive result (set scalar_replaceable to false)
+ // since the flow-insensitive escape analysis can't separate
+ // the case when stores overwrite the field's value from the case
+ // when stores happened on different control branches.
+ //
+ if (ptset_size > 1 || ptset_size != 0 &&
+ (has_LoadStore || offset == Type::OffsetBot)) {
for( VectorSetI j(&ptset); j.test(); ++j ) {
- uint pt = j.elem;
- ptnode_adr(pt)->_scalar_replaceable = false;
+ set_escape_state(j.elem, PointsToNode::ArgEscape);
+ ptnode_adr(j.elem)->_scalar_replaceable = false;
}
}
}
- } else if (nt == PointsToNode::JavaObject && n->is_Call()) {
- // Push call on alloc_worlist (alocations are calls)
- // for processing by split_unique_types().
- alloc_worklist.append(n);
}
}
+ // 6. Propagate escape states.
+ GrowableArray<int> worklist;
+ bool has_non_escaping_obj = false;
+
// push all GlobalEscape nodes on the worklist
- for( int next = 0; next < cg_worklist.length(); ++next ) {
+ for( uint next = 0; next < cg_length; ++next ) {
int nk = cg_worklist.at(next);
- if (_nodes->adr_at(nk)->escape_state() == PointsToNode::GlobalEscape)
- worklist.append(nk);
+ if (ptnode_adr(nk)->escape_state() == PointsToNode::GlobalEscape)
+ worklist.push(nk);
}
- // mark all node reachable from GlobalEscape nodes
+ // mark all nodes reachable from GlobalEscape nodes
while(worklist.length() > 0) {
- PointsToNode n = _nodes->at(worklist.pop());
- for (uint ei = 0; ei < n.edge_count(); ei++) {
- uint npi = n.edge_target(ei);
+ PointsToNode* ptn = ptnode_adr(worklist.pop());
+ uint e_cnt = ptn->edge_count();
+ for (uint ei = 0; ei < e_cnt; ei++) {
+ uint npi = ptn->edge_target(ei);
PointsToNode *np = ptnode_adr(npi);
if (np->escape_state() < PointsToNode::GlobalEscape) {
np->set_escape_state(PointsToNode::GlobalEscape);
- worklist.append_if_missing(npi);
+ worklist.push(npi);
}
}
}
// push all ArgEscape nodes on the worklist
- for( int next = 0; next < cg_worklist.length(); ++next ) {
+ for( uint next = 0; next < cg_length; ++next ) {
int nk = cg_worklist.at(next);
- if (_nodes->adr_at(nk)->escape_state() == PointsToNode::ArgEscape)
+ if (ptnode_adr(nk)->escape_state() == PointsToNode::ArgEscape)
worklist.push(nk);
}
- // mark all node reachable from ArgEscape nodes
+ // mark all nodes reachable from ArgEscape nodes
while(worklist.length() > 0) {
- PointsToNode n = _nodes->at(worklist.pop());
- for (uint ei = 0; ei < n.edge_count(); ei++) {
- uint npi = n.edge_target(ei);
+ PointsToNode* ptn = ptnode_adr(worklist.pop());
+ if (ptn->node_type() == PointsToNode::JavaObject)
+ has_non_escaping_obj = true; // Non GlobalEscape
+ uint e_cnt = ptn->edge_count();
+ for (uint ei = 0; ei < e_cnt; ei++) {
+ uint npi = ptn->edge_target(ei);
PointsToNode *np = ptnode_adr(npi);
if (np->escape_state() < PointsToNode::ArgEscape) {
np->set_escape_state(PointsToNode::ArgEscape);
- worklist.append_if_missing(npi);
+ worklist.push(npi);
}
}
}
+ GrowableArray<Node*> alloc_worklist;
+
// push all NoEscape nodes on the worklist
- for( int next = 0; next < cg_worklist.length(); ++next ) {
+ for( uint next = 0; next < cg_length; ++next ) {
int nk = cg_worklist.at(next);
- if (_nodes->adr_at(nk)->escape_state() == PointsToNode::NoEscape)
+ if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape)
worklist.push(nk);
}
- // mark all node reachable from NoEscape nodes
+ // mark all nodes reachable from NoEscape nodes
while(worklist.length() > 0) {
- PointsToNode n = _nodes->at(worklist.pop());
- for (uint ei = 0; ei < n.edge_count(); ei++) {
- uint npi = n.edge_target(ei);
+ PointsToNode* ptn = ptnode_adr(worklist.pop());
+ if (ptn->node_type() == PointsToNode::JavaObject)
+ has_non_escaping_obj = true; // Non GlobalEscape
+ Node* n = ptn->_node;
+ if (n->is_Allocate() && ptn->_scalar_replaceable ) {
+ // Push scalar replaceable alocations on alloc_worklist
+ // for processing in split_unique_types().
+ alloc_worklist.append(n);
+ }
+ uint e_cnt = ptn->edge_count();
+ for (uint ei = 0; ei < e_cnt; ei++) {
+ uint npi = ptn->edge_target(ei);
PointsToNode *np = ptnode_adr(npi);
if (np->escape_state() < PointsToNode::NoEscape) {
np->set_escape_state(PointsToNode::NoEscape);
- worklist.append_if_missing(npi);
+ worklist.push(npi);
}
}
}
_collecting = false;
+ assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
- has_allocations = false; // Are there scalar replaceable allocations?
+ bool has_scalar_replaceable_candidates = alloc_worklist.length() > 0;
+ if ( has_scalar_replaceable_candidates &&
+ C->AliasLevel() >= 3 && EliminateAllocations ) {
- for( int next = 0; next < alloc_worklist.length(); ++next ) {
- Node* n = alloc_worklist.at(next);
- uint ni = n->_idx;
- PointsToNode* ptn = _nodes->adr_at(ni);
- PointsToNode::EscapeState es = ptn->escape_state();
- if (ptn->escape_state() == PointsToNode::NoEscape &&
- ptn->_scalar_replaceable) {
- has_allocations = true;
- break;
- }
- }
- if (!has_allocations) {
- return; // Nothing to do.
- }
+ // Now use the escape information to create unique types for
+ // scalar replaceable objects.
+ split_unique_types(alloc_worklist);
- if(_compile->AliasLevel() >= 3 && EliminateAllocations) {
- // Now use the escape information to create unique types for
- // unescaped objects
- split_unique_types(alloc_worklist);
- if (_compile->failing()) return;
+ if (C->failing()) return false;
// Clean up after split unique types.
ResourceMark rm;
- PhaseRemoveUseless pru(_compile->initial_gvn(), _compile->for_igvn());
+ PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
+
+ C->print_method("After Escape Analysis", 2);
#ifdef ASSERT
- } else if (PrintEscapeAnalysis || PrintEliminateAllocations) {
+ } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
tty->print("=== No allocations eliminated for ");
- C()->method()->print_short_name();
+ C->method()->print_short_name();
if(!EliminateAllocations) {
tty->print(" since EliminateAllocations is off ===");
- } else if(_compile->AliasLevel() < 3) {
+ } else if(!has_scalar_replaceable_candidates) {
+ tty->print(" since there are no scalar replaceable candidates ===");
+ } else if(C->AliasLevel() < 3) {
tty->print(" since AliasLevel < 3 ===");
}
tty->cr();
#endif
}
+ return has_non_escaping_obj;
}
void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) {
@@ -1538,7 +1673,7 @@
}
}
if (copy_dependencies)
- call_analyzer->copy_dependencies(C()->dependencies());
+ call_analyzer->copy_dependencies(_compile->dependencies());
break;
}
}
@@ -1561,7 +1696,6 @@
for( VectorSetI j(&ptset); j.test(); ++j ) {
uint pt = j.elem;
set_escape_state(pt, PointsToNode::GlobalEscape);
- PointsToNode *ptadr = ptnode_adr(pt);
}
}
}
@@ -1569,9 +1703,10 @@
}
}
void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) {
- PointsToNode *ptadr = ptnode_adr(resproj->_idx);
+ CallNode *call = resproj->in(0)->as_Call();
+ uint call_idx = call->_idx;
+ uint resproj_idx = resproj->_idx;
- CallNode *call = resproj->in(0)->as_Call();
switch (call->Opcode()) {
case Op_Allocate:
{
@@ -1587,7 +1722,6 @@
ciKlass* cik = kt->klass();
ciInstanceKlass* ciik = cik->as_instance_klass();
- PointsToNode *ptadr = ptnode_adr(call->_idx);
PointsToNode::EscapeState es;
uint edge_to;
if (cik->is_subclass_of(_compile->env()->Thread_klass()) || ciik->has_finalizer()) {
@@ -1595,25 +1729,24 @@
edge_to = _phantom_object; // Could not be worse
} else {
es = PointsToNode::NoEscape;
- edge_to = call->_idx;
+ edge_to = call_idx;
}
- set_escape_state(call->_idx, es);
- add_pointsto_edge(resproj->_idx, edge_to);
- _processed.set(resproj->_idx);
+ set_escape_state(call_idx, es);
+ add_pointsto_edge(resproj_idx, edge_to);
+ _processed.set(resproj_idx);
break;
}
case Op_AllocateArray:
{
- PointsToNode *ptadr = ptnode_adr(call->_idx);
int length = call->in(AllocateNode::ALength)->find_int_con(-1);
if (length < 0 || length > EliminateAllocationArraySizeLimit) {
// Not scalar replaceable if the length is not constant or too big.
- ptadr->_scalar_replaceable = false;
+ ptnode_adr(call_idx)->_scalar_replaceable = false;
}
- set_escape_state(call->_idx, PointsToNode::NoEscape);
- add_pointsto_edge(resproj->_idx, call->_idx);
- _processed.set(resproj->_idx);
+ set_escape_state(call_idx, PointsToNode::NoEscape);
+ add_pointsto_edge(resproj_idx, call_idx);
+ _processed.set(resproj_idx);
break;
}
@@ -1631,19 +1764,17 @@
// Note: we use isa_ptr() instead of isa_oopptr() here because the
// _multianewarray functions return a TypeRawPtr.
if (ret_type == NULL || ret_type->isa_ptr() == NULL) {
- _processed.set(resproj->_idx);
+ _processed.set(resproj_idx);
break; // doesn't return a pointer type
}
ciMethod *meth = call->as_CallJava()->method();
const TypeTuple * d = call->tf()->domain();
if (meth == NULL) {
// not a Java method, assume global escape
- set_escape_state(call->_idx, PointsToNode::GlobalEscape);
- if (resproj != NULL)
- add_pointsto_edge(resproj->_idx, _phantom_object);
+ set_escape_state(call_idx, PointsToNode::GlobalEscape);
+ add_pointsto_edge(resproj_idx, _phantom_object);
} else {
BCEscapeAnalyzer *call_analyzer = meth->get_bcea();
- VectorSet ptset(Thread::current()->resource_area());
bool copy_dependencies = false;
if (call_analyzer->is_return_allocated()) {
@@ -1651,13 +1782,12 @@
// update dependency information.
// Mark it as NoEscape so that objects referenced by
// it's fields will be marked as NoEscape at least.
- set_escape_state(call->_idx, PointsToNode::NoEscape);
- if (resproj != NULL)
- add_pointsto_edge(resproj->_idx, call->_idx);
+ set_escape_state(call_idx, PointsToNode::NoEscape);
+ add_pointsto_edge(resproj_idx, call_idx);
copy_dependencies = true;
- } else if (call_analyzer->is_return_local() && resproj != NULL) {
+ } else if (call_analyzer->is_return_local()) {
// determine whether any arguments are returned
- set_escape_state(call->_idx, PointsToNode::NoEscape);
+ set_escape_state(call_idx, PointsToNode::NoEscape);
for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
const Type* at = d->field_at(i);
@@ -1665,36 +1795,35 @@
Node *arg = call->in(i)->uncast();
if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) {
- PointsToNode *arg_esp = _nodes->adr_at(arg->_idx);
+ PointsToNode *arg_esp = ptnode_adr(arg->_idx);
if (arg_esp->node_type() == PointsToNode::UnknownType)
done = false;
else if (arg_esp->node_type() == PointsToNode::JavaObject)
- add_pointsto_edge(resproj->_idx, arg->_idx);
+ add_pointsto_edge(resproj_idx, arg->_idx);
else
- add_deferred_edge(resproj->_idx, arg->_idx);
+ add_deferred_edge(resproj_idx, arg->_idx);
arg_esp->_hidden_alias = true;
}
}
}
copy_dependencies = true;
} else {
- set_escape_state(call->_idx, PointsToNode::GlobalEscape);
- if (resproj != NULL)
- add_pointsto_edge(resproj->_idx, _phantom_object);
+ set_escape_state(call_idx, PointsToNode::GlobalEscape);
+ add_pointsto_edge(resproj_idx, _phantom_object);
for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
const Type* at = d->field_at(i);
if (at->isa_oopptr() != NULL) {
Node *arg = call->in(i)->uncast();
- PointsToNode *arg_esp = _nodes->adr_at(arg->_idx);
+ PointsToNode *arg_esp = ptnode_adr(arg->_idx);
arg_esp->_hidden_alias = true;
}
}
}
if (copy_dependencies)
- call_analyzer->copy_dependencies(C()->dependencies());
+ call_analyzer->copy_dependencies(_compile->dependencies());
}
if (done)
- _processed.set(resproj->_idx);
+ _processed.set(resproj_idx);
break;
}
@@ -1709,13 +1838,11 @@
// Note: we use isa_ptr() instead of isa_oopptr() here because the
// _multianewarray functions return a TypeRawPtr.
if (ret_type->isa_ptr() != NULL) {
- PointsToNode *ptadr = ptnode_adr(call->_idx);
- set_escape_state(call->_idx, PointsToNode::GlobalEscape);
- if (resproj != NULL)
- add_pointsto_edge(resproj->_idx, _phantom_object);
+ set_escape_state(call_idx, PointsToNode::GlobalEscape);
+ add_pointsto_edge(resproj_idx, _phantom_object);
}
}
- _processed.set(resproj->_idx);
+ _processed.set(resproj_idx);
}
}
}
@@ -1743,7 +1870,7 @@
// Check if a call returns an object.
const TypeTuple *r = n->as_Call()->tf()->range();
- if (r->cnt() > TypeFunc::Parms &&
+ if (n->is_CallStaticJava() && r->cnt() > TypeFunc::Parms &&
n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
// Note: use isa_ptr() instead of isa_oopptr() here because
// the _multianewarray functions return a TypeRawPtr.
@@ -1776,7 +1903,7 @@
{
add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
int ti = n->in(1)->_idx;
- PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type();
+ PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
if (nt == PointsToNode::UnknownType) {
_delayed_worklist.push(n); // Process it later.
break;
@@ -1828,7 +1955,7 @@
case Op_LoadN:
{
const Type *t = phase->type(n);
- if (!t->isa_narrowoop() && t->isa_ptr() == NULL) {
+ if (t->make_ptr() == NULL) {
_processed.set(n->_idx);
return;
}
@@ -1851,8 +1978,9 @@
}
case Op_Phi:
{
- if (n->as_Phi()->type()->isa_ptr() == NULL) {
- // nothing to do if not an oop
+ const Type *t = n->as_Phi()->type();
+ if (t->make_ptr() == NULL) {
+ // nothing to do if not an oop or narrow oop
_processed.set(n->_idx);
return;
}
@@ -1866,7 +1994,7 @@
if (in->is_top() || in == n)
continue; // ignore top or inputs which go back this node
int ti = in->_idx;
- PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type();
+ PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
if (nt == PointsToNode::UnknownType) {
break;
} else if (nt == PointsToNode::JavaObject) {
@@ -1904,7 +2032,7 @@
// Treat Return value as LocalVar with GlobalEscape escape state.
add_node(n, PointsToNode::LocalVar, PointsToNode::GlobalEscape, false);
int ti = n->in(TypeFunc::Parms)->_idx;
- PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type();
+ PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
if (nt == PointsToNode::UnknownType) {
_delayed_worklist.push(n); // Process it later.
break;
@@ -1968,17 +2096,17 @@
}
void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) {
+ uint n_idx = n->_idx;
+
// Don't set processed bit for AddP, LoadP, StoreP since
// they may need more then one pass to process.
- if (_processed.test(n->_idx))
+ if (_processed.test(n_idx))
return; // No need to redefine node's state.
- PointsToNode *ptadr = ptnode_adr(n->_idx);
-
if (n->is_Call()) {
CallNode *call = n->as_Call();
process_call_arguments(call, phase);
- _processed.set(n->_idx);
+ _processed.set(n_idx);
return;
}
@@ -1991,7 +2119,7 @@
PointsTo(ptset, base, phase);
for( VectorSetI i(&ptset); i.test(); ++i ) {
uint pt = i.elem;
- add_field_edge(pt, n->_idx, address_offset(n, phase));
+ add_field_edge(pt, n_idx, address_offset(n, phase));
}
break;
}
@@ -2006,12 +2134,12 @@
case Op_DecodeN:
{
int ti = n->in(1)->_idx;
- if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) {
- add_pointsto_edge(n->_idx, ti);
+ if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
+ add_pointsto_edge(n_idx, ti);
} else {
- add_deferred_edge(n->_idx, ti);
+ add_deferred_edge(n_idx, ti);
}
- _processed.set(n->_idx);
+ _processed.set(n_idx);
break;
}
case Op_ConP:
@@ -2040,7 +2168,7 @@
{
const Type *t = phase->type(n);
#ifdef ASSERT
- if (!t->isa_narrowoop() && t->isa_ptr() == NULL)
+ if (t->make_ptr() == NULL)
assert(false, "Op_LoadP");
#endif
@@ -2060,7 +2188,7 @@
int offset = address_offset(adr, phase);
for( VectorSetI i(&ptset); i.test(); ++i ) {
uint pt = i.elem;
- add_deferred_edge_to_fields(n->_idx, pt, offset);
+ add_deferred_edge_to_fields(n_idx, pt, offset);
}
break;
}
@@ -2072,7 +2200,8 @@
case Op_Phi:
{
#ifdef ASSERT
- if (n->as_Phi()->type()->isa_ptr() == NULL)
+ const Type *t = n->as_Phi()->type();
+ if (t->make_ptr() == NULL)
assert(false, "Op_Phi");
#endif
for (uint i = 1; i < n->req() ; i++) {
@@ -2083,13 +2212,13 @@
if (in->is_top() || in == n)
continue; // ignore top or inputs which go back this node
int ti = in->_idx;
- if (_nodes->adr_at(in->_idx)->node_type() == PointsToNode::JavaObject) {
- add_pointsto_edge(n->_idx, ti);
+ if (ptnode_adr(in->_idx)->node_type() == PointsToNode::JavaObject) {
+ add_pointsto_edge(n_idx, ti);
} else {
- add_deferred_edge(n->_idx, ti);
+ add_deferred_edge(n_idx, ti);
}
}
- _processed.set(n->_idx);
+ _processed.set(n_idx);
break;
}
case Op_Proj:
@@ -2097,7 +2226,7 @@
// we are only interested in the result projection from a call
if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) {
process_call_result(n->as_Proj(), phase);
- assert(_processed.test(n->_idx), "all call results should be processed");
+ assert(_processed.test(n_idx), "all call results should be processed");
} else {
assert(false, "Op_Proj");
}
@@ -2112,12 +2241,12 @@
}
#endif
int ti = n->in(TypeFunc::Parms)->_idx;
- if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) {
- add_pointsto_edge(n->_idx, ti);
+ if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
+ add_pointsto_edge(n_idx, ti);
} else {
- add_deferred_edge(n->_idx, ti);
+ add_deferred_edge(n_idx, ti);
}
- _processed.set(n->_idx);
+ _processed.set(n_idx);
break;
}
case Op_StoreP:
@@ -2162,9 +2291,9 @@
PhaseGVN *igvn = _compile->initial_gvn();
bool first = true;
- uint size = (uint)_nodes->length();
+ uint size = nodes_size();
for (uint ni = 0; ni < size; ni++) {
- PointsToNode *ptn = _nodes->adr_at(ni);
+ PointsToNode *ptn = ptnode_adr(ni);
PointsToNode::NodeType ptn_type = ptn->node_type();
if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL)
@@ -2174,7 +2303,7 @@
if (first) {
tty->cr();
tty->print("======== Connection graph for ");
- C()->method()->print_short_name();
+ _compile->method()->print_short_name();
tty->cr();
first = false;
}
@@ -2182,20 +2311,18 @@
ptn->dump();
// Print all locals which reference this allocation
for (uint li = ni; li < size; li++) {
- PointsToNode *ptn_loc = _nodes->adr_at(li);
+ PointsToNode *ptn_loc = ptnode_adr(li);
PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type();
if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL &&
ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) {
- tty->print("%6d LocalVar [[%d]]", li, ni);
- _nodes->adr_at(li)->_node->dump();
+ ptnode_adr(li)->dump(false);
}
}
if (Verbose) {
// Print all fields which reference this allocation
for (uint i = 0; i < ptn->edge_count(); i++) {
uint ei = ptn->edge_target(i);
- tty->print("%6d Field [[%d]]", ei, ni);
- _nodes->adr_at(ei)->_node->dump();
+ ptnode_adr(ei)->dump(false);
}
}
tty->cr();
--- a/hotspot/src/share/vm/opto/escape.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/escape.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -178,23 +178,33 @@
// count of outgoing edges
uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
+
// node index of target of outgoing edge "e"
- uint edge_target(uint e) const;
+ uint edge_target(uint e) const {
+ assert(_edges != NULL, "valid edge index");
+ return (_edges->at(e) >> EdgeShift);
+ }
// type of outgoing edge "e"
- EdgeType edge_type(uint e) const;
+ EdgeType edge_type(uint e) const {
+ assert(_edges != NULL, "valid edge index");
+ return (EdgeType) (_edges->at(e) & EdgeMask);
+ }
+
// add a edge of the specified type pointing to the specified target
void add_edge(uint targIdx, EdgeType et);
+
// remove an edge of the specified type pointing to the specified target
void remove_edge(uint targIdx, EdgeType et);
+
#ifndef PRODUCT
- void dump() const;
+ void dump(bool print_state=true) const;
#endif
};
class ConnectionGraph: public ResourceObj {
private:
- GrowableArray<PointsToNode>* _nodes; // Connection graph nodes indexed
+ GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed
// by ideal node index.
Unique_Node_List _delayed_worklist; // Nodes to be processed before
@@ -207,24 +217,22 @@
// is still being collected. If false,
// no new nodes will be processed.
- bool _has_allocations; // Indicates whether method has any
- // non-escaping allocations.
-
uint _phantom_object; // Index of globally escaping object
// that pointer values loaded from
// a field which has not been set
// are assumed to point to.
+ uint _oop_null; // ConP(#NULL)
+ uint _noop_null; // ConN(#NULL)
Compile * _compile; // Compile object for current compilation
- // address of an element in _nodes. Used when the element is to be modified
- PointsToNode *ptnode_adr(uint idx) {
- if ((uint)_nodes->length() <= idx) {
- // expand _nodes array
- PointsToNode dummy = _nodes->at_grow(idx);
- }
- return _nodes->adr_at(idx);
+ // Address of an element in _nodes. Used when the element is to be modified
+ PointsToNode *ptnode_adr(uint idx) const {
+ // There should be no new ideal nodes during ConnectionGraph build,
+ // growableArray::adr_at() will throw assert otherwise.
+ return _nodes.adr_at(idx);
}
+ uint nodes_size() const { return _nodes.length(); }
// Add node to ConnectionGraph.
void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
@@ -307,30 +315,30 @@
// Set the escape state of a node
void set_escape_state(uint ni, PointsToNode::EscapeState es);
- // Get Compile object for current compilation.
- Compile *C() const { return _compile; }
-
public:
ConnectionGraph(Compile *C);
+ // Check for non-escaping candidates
+ static bool has_candidates(Compile *C);
+
// Compute the escape information
- void compute_escape();
+ bool compute_escape();
// escape state of a node
PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase);
// other information we have collected
bool is_scalar_replaceable(Node *n) {
- if (_collecting)
+ if (_collecting || (n->_idx >= nodes_size()))
return false;
- PointsToNode ptn = _nodes->at_grow(n->_idx);
- return ptn.escape_state() == PointsToNode::NoEscape && ptn._scalar_replaceable;
+ PointsToNode* ptn = ptnode_adr(n->_idx);
+ return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable;
}
bool hidden_alias(Node *n) {
- if (_collecting)
+ if (_collecting || (n->_idx >= nodes_size()))
return true;
- PointsToNode ptn = _nodes->at_grow(n->_idx);
- return (ptn.escape_state() != PointsToNode::NoEscape) || ptn._hidden_alias;
+ PointsToNode* ptn = ptnode_adr(n->_idx);
+ return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias;
}
#ifndef PRODUCT
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -473,10 +473,12 @@
print_prop("is_dontcare", "false");
}
+#ifdef ASSERT
Node* old = C->matcher()->find_old_node(node);
if (old != NULL) {
print_prop("old_node_idx", old->_idx);
}
+#endif
}
if (node->is_Proj()) {
--- a/hotspot/src/share/vm/opto/ifnode.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/ifnode.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -725,6 +725,11 @@
int true_path = phi->is_diamond_phi();
if( true_path == 0 ) return NULL;
+ // Make sure that iff and the control of the phi are different. This
+ // should really only happen for dead control flow since it requires
+ // an illegal cycle.
+ if (phi->in(0)->in(1)->in(0) == iff) return NULL;
+
// phi->region->if_proj->ifnode->bool->cmp
BoolNode *bol2 = phi->in(0)->in(1)->in(0)->in(1)->as_Bool();
@@ -751,6 +756,7 @@
}
Node* new_bol = (flip ? phase->transform( bol2->negate(phase) ) : bol2);
+ assert(new_bol != iff->in(1), "must make progress");
iff->set_req(1, new_bol);
// Intervening diamond probably goes dead
phase->C->set_major_progress();
--- a/hotspot/src/share/vm/opto/lcm.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -322,7 +322,7 @@
uint choice = 0; // Bigger is most important
uint latency = 0; // Bigger is scheduled first
uint score = 0; // Bigger is better
- uint idx; // Index in worklist
+ int idx = -1; // Index in worklist
for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
// Order in worklist is used to break ties.
@@ -412,9 +412,10 @@
}
} // End of for all ready nodes in worklist
- Node *n = worklist[idx]; // Get the winner
+ assert(idx >= 0, "index should be set");
+ Node *n = worklist[(uint)idx]; // Get the winner
- worklist.map(idx,worklist.pop()); // Compress worklist
+ worklist.map((uint)idx, worklist.pop()); // Compress worklist
return n;
}
@@ -599,7 +600,14 @@
assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
}
}
- if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire ) {
+ if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_MemBarAcquire &&
+ n->req() > TypeFunc::Parms ) {
+ // MemBarAcquire could be created without Precedent edge.
+ // del_req() replaces the specified edge with the last input edge
+ // and then removes the last edge. If the specified edge > number of
+ // edges the last edge will be moved outside of the input edges array
+ // and the edge will be lost. This is why this code should be
+ // executed only when Precedent (== TypeFunc::Parms) edge is present.
Node *x = n->in(TypeFunc::Parms);
n->del_req(TypeFunc::Parms);
n->add_prec(x);
--- a/hotspot/src/share/vm/opto/loopopts.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/loopopts.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -578,7 +578,8 @@
Node *cmov = conditional_move( n );
if( cmov ) return cmov;
}
- if( n->is_CFG() || n_op == Op_StorePConditional || n_op == Op_StoreLConditional || n_op == Op_CompareAndSwapI || n_op == Op_CompareAndSwapL ||n_op == Op_CompareAndSwapP) return n;
+ if( n->is_CFG() || n->is_LoadStore() )
+ return n;
if( n_op == Op_Opaque1 || // Opaque nodes cannot be mod'd
n_op == Op_Opaque2 ) {
if( !C->major_progress() ) // If chance of no more loop opts...
@@ -1891,18 +1892,19 @@
_igvn.hash_delete(use);
use->set_req(j, n_clone);
_igvn._worklist.push(use);
+ Node* use_c;
if (!use->is_Phi()) {
- Node* use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0);
- set_ctrl(n_clone, use_c);
- assert(!loop->is_member(get_loop(use_c)), "should be outside loop");
- get_loop(use_c)->_body.push(n_clone);
+ use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0);
} else {
// Use in a phi is considered a use in the associated predecessor block
- Node *prevbb = use->in(0)->in(j);
- set_ctrl(n_clone, prevbb);
- assert(!loop->is_member(get_loop(prevbb)), "should be outside loop");
- get_loop(prevbb)->_body.push(n_clone);
+ use_c = use->in(0)->in(j);
}
+ if (use_c->is_CountedLoop()) {
+ use_c = use_c->in(LoopNode::EntryControl);
+ }
+ set_ctrl(n_clone, use_c);
+ assert(!loop->is_member(get_loop(use_c)), "should be outside loop");
+ get_loop(use_c)->_body.push(n_clone);
_igvn.register_new_node_with_optimizer(n_clone);
#if !defined(PRODUCT)
if (TracePartialPeeling) {
--- a/hotspot/src/share/vm/opto/macro.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -194,9 +194,10 @@
}
// Search for a memory operation for the specified memory slice.
-static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc) {
+static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_mem, Node *alloc, PhaseGVN *phase) {
Node *orig_mem = mem;
Node *alloc_mem = alloc->in(TypeFunc::Memory);
+ const TypeOopPtr *tinst = phase->C->get_adr_type(alias_idx)->isa_oopptr();
while (true) {
if (mem == alloc_mem || mem == start_mem ) {
return mem; // hit one of our sentinals
@@ -208,7 +209,13 @@
// already know that the object is safe to eliminate.
if (in->is_Initialize() && in->as_Initialize()->allocation() == alloc) {
return in;
- } else if (in->is_Call() || in->is_MemBar()) {
+ } else if (in->is_Call()) {
+ CallNode *call = in->as_Call();
+ if (!call->may_modify(tinst, phase)) {
+ mem = call->in(TypeFunc::Memory);
+ }
+ mem = in->in(TypeFunc::Memory);
+ } else if (in->is_MemBar()) {
mem = in->in(TypeFunc::Memory);
} else {
assert(false, "unexpected projection");
@@ -231,8 +238,7 @@
} else {
return mem;
}
- if (mem == orig_mem)
- return mem;
+ assert(mem != orig_mem, "dead memory loop");
}
}
@@ -241,27 +247,50 @@
// on the input paths.
// Note: this function is recursive, its depth is limied by the "level" argument
// Returns the computed Phi, or NULL if it cannot compute it.
-Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, int level) {
-
- if (level <= 0) {
- return NULL;
- }
+Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level) {
+ assert(mem->is_Phi(), "sanity");
int alias_idx = C->get_alias_index(adr_t);
int offset = adr_t->offset();
int instance_id = adr_t->instance_id();
+ // Check if an appropriate value phi already exists.
+ Node* region = mem->in(0);
+ for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
+ Node* phi = region->fast_out(k);
+ if (phi->is_Phi() && phi != mem &&
+ phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) {
+ return phi;
+ }
+ }
+ // Check if an appropriate new value phi already exists.
+ Node* new_phi = NULL;
+ uint size = value_phis->size();
+ for (uint i=0; i < size; i++) {
+ if ( mem->_idx == value_phis->index_at(i) ) {
+ return value_phis->node_at(i);
+ }
+ }
+
+ if (level <= 0) {
+ return NULL; // Give up: phi tree too deep
+ }
Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
Node *alloc_mem = alloc->in(TypeFunc::Memory);
uint length = mem->req();
GrowableArray <Node *> values(length, length, NULL);
+ // create a new Phi for the value
+ PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
+ transform_later(phi);
+ value_phis->push(phi, mem->_idx);
+
for (uint j = 1; j < length; j++) {
Node *in = mem->in(j);
if (in == NULL || in->is_top()) {
values.at_put(j, in);
} else {
- Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc);
+ Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn);
if (val == start_mem || val == alloc_mem) {
// hit a sentinel, return appropriate 0 value
values.at_put(j, _igvn.zerocon(ft));
@@ -280,33 +309,18 @@
} else if(val->is_Proj() && val->in(0) == alloc) {
values.at_put(j, _igvn.zerocon(ft));
} else if (val->is_Phi()) {
- // Check if an appropriate node already exists.
- Node* region = val->in(0);
- Node* old_phi = NULL;
- for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
- Node* phi = region->fast_out(k);
- if (phi->is_Phi() && phi != val &&
- phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) {
- old_phi = phi;
- break;
- }
+ val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, value_phis, level-1);
+ if (val == NULL) {
+ return NULL;
}
- if (old_phi == NULL) {
- val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, level-1);
- if (val == NULL) {
- return NULL;
- }
- values.at_put(j, val);
- } else {
- values.at_put(j, old_phi);
- }
+ values.at_put(j, val);
} else {
- return NULL; // unknown node on this path
+ assert(false, "unknown node on this path");
+ return NULL; // unknown node on this path
}
}
}
- // create a new Phi for the value
- PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
+ // Set Phi's inputs
for (uint j = 1; j < length; j++) {
if (values.at(j) == mem) {
phi->init_req(j, phi);
@@ -314,7 +328,6 @@
phi->init_req(j, values.at(j));
}
}
- transform_later(phi);
return phi;
}
@@ -329,7 +342,8 @@
Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
Node *alloc_ctrl = alloc->in(TypeFunc::Control);
Node *alloc_mem = alloc->in(TypeFunc::Memory);
- VectorSet visited(Thread::current()->resource_area());
+ Arena *a = Thread::current()->resource_area();
+ VectorSet visited(a);
bool done = sfpt_mem == alloc_mem;
@@ -338,7 +352,7 @@
if (visited.test_set(mem->_idx)) {
return NULL; // found a loop, give up
}
- mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc);
+ mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn);
if (mem == start_mem || mem == alloc_mem) {
done = true; // hit a sentinel, return appropriate 0 value
} else if (mem->is_Initialize()) {
@@ -362,7 +376,7 @@
Node *unique_input = NULL;
Node *top = C->top();
for (uint i = 1; i < mem->req(); i++) {
- Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc);
+ Node *n = scan_mem_chain(mem->in(i), alias_idx, offset, start_mem, alloc, &_igvn);
if (n == NULL || n == top || n == mem) {
continue;
} else if (unique_input == NULL) {
@@ -389,9 +403,18 @@
return mem->in(MemNode::ValueIn);
} else if (mem->is_Phi()) {
// attempt to produce a Phi reflecting the values on the input paths of the Phi
- Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, 8);
+ Node_Stack value_phis(a, 8);
+ Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, ValueSearchLimit);
if (phi != NULL) {
return phi;
+ } else {
+ // Kill all new Phis
+ while(value_phis.is_nonempty()) {
+ Node* n = value_phis.node();
+ _igvn.hash_delete(n);
+ _igvn.subsume_node(n, C->top());
+ value_phis.pop();
+ }
}
}
}
@@ -448,7 +471,7 @@
Node* n = use->fast_out(k);
if (!n->is_Store() && n->Opcode() != Op_CastP2X) {
DEBUG_ONLY(disq_node = n;)
- if (n->is_Load()) {
+ if (n->is_Load() || n->is_LoadStore()) {
NOT_PRODUCT(fail_eliminate = "Field load";)
} else {
NOT_PRODUCT(fail_eliminate = "Not store field referrence";)
--- a/hotspot/src/share/vm/opto/macro.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/macro.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -79,7 +79,7 @@
const TypeFunc* slow_call_type,
address slow_call_address);
Node *value_from_mem(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc);
- Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc, int level);
+ Node *value_from_mem_phi(Node *mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level);
bool eliminate_allocate_node(AllocateNode *alloc);
bool can_eliminate_allocation(AllocateNode *alloc, GrowableArray <SafePointNode *>& safepoints);
--- a/hotspot/src/share/vm/opto/memnode.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -94,14 +94,19 @@
if (tinst == NULL || !tinst->is_known_instance_field())
return mchain; // don't try to optimize non-instance types
uint instance_id = tinst->instance_id();
+ Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory);
Node *prev = NULL;
Node *result = mchain;
while (prev != result) {
prev = result;
+ if (result == start_mem)
+ break; // hit one of our sentinals
// skip over a call which does not affect this memory slice
if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
Node *proj_in = result->in(0);
- if (proj_in->is_Call()) {
+ if (proj_in->is_Allocate() && proj_in->_idx == instance_id) {
+ break; // hit one of our sentinals
+ } else if (proj_in->is_Call()) {
CallNode *call = proj_in->as_Call();
if (!call->may_modify(t_adr, phase)) {
result = call->in(TypeFunc::Memory);
@@ -115,6 +120,8 @@
}
} else if (proj_in->is_MemBar()) {
result = proj_in->in(TypeFunc::Memory);
+ } else {
+ assert(false, "unexpected projection");
}
} else if (result->is_MergeMem()) {
result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty);
@@ -135,7 +142,9 @@
const TypePtr *t = mphi->adr_type();
if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
- t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) {
+ t->is_oopptr()->cast_to_exactness(true)
+ ->is_oopptr()->cast_to_ptr_type(t_oop->ptr())
+ ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) {
// clone the Phi with our address type
result = mphi->split_out_instance(t_adr, igvn);
} else {
--- a/hotspot/src/share/vm/opto/memnode.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/memnode.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -607,6 +607,7 @@
};
//------------------------------LoadStoreNode---------------------------
+// Note: is_Mem() method returns 'true' for this class.
class LoadStoreNode : public Node {
public:
enum {
--- a/hotspot/src/share/vm/opto/node.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/node.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -1399,6 +1399,10 @@
uint index() const {
return _inode_top->indx;
}
+ uint index_at(uint i) const {
+ assert(_inodes + i <= _inode_top, "in range");
+ return _inodes[i].indx;
+ }
void set_node(Node *n) {
_inode_top->node = n;
}
--- a/hotspot/src/share/vm/opto/parse.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/parse.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -479,7 +479,7 @@
float branch_prediction(float &cnt, BoolTest::mask btest, int target_bci);
bool seems_never_taken(float prob);
- void do_ifnull(BoolTest::mask btest);
+ void do_ifnull(BoolTest::mask btest, Node* c);
void do_if(BoolTest::mask btest, Node* c);
void repush_if_args();
void adjust_map_after_if(BoolTest::mask btest, Node* c, float prob,
--- a/hotspot/src/share/vm/opto/parse2.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/parse2.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -875,6 +875,8 @@
return prob < PROB_MIN;
}
+//-------------------------------repush_if_args--------------------------------
+// Push arguments of an "if" bytecode back onto the stack by adjusting _sp.
inline void Parse::repush_if_args() {
#ifndef PRODUCT
if (PrintOpto && WizardMode) {
@@ -892,7 +894,7 @@
}
//----------------------------------do_ifnull----------------------------------
-void Parse::do_ifnull(BoolTest::mask btest) {
+void Parse::do_ifnull(BoolTest::mask btest, Node *c) {
int target_bci = iter().get_dest();
Block* branch_block = successor_for_bci(target_bci);
@@ -904,7 +906,7 @@
// (An earlier version of do_ifnull omitted this trap for OSR methods.)
#ifndef PRODUCT
if (PrintOpto && Verbose)
- tty->print_cr("Never-taken backedge stops compilation at bci %d",bci());
+ tty->print_cr("Never-taken edge stops compilation at bci %d",bci());
#endif
repush_if_args(); // to gather stats on loop
// We need to mark this branch as taken so that if we recompile we will
@@ -923,18 +925,7 @@
return;
}
- // If this is a backwards branch in the bytecodes, add Safepoint
- maybe_add_safepoint(target_bci);
-
explicit_null_checks_inserted++;
- Node* a = null();
- Node* b = pop();
- Node* c = _gvn.transform( new (C, 3) CmpPNode(b, a) );
-
- // Make a cast-away-nullness that is control dependent on the test
- const Type *t = _gvn.type(b);
- const Type *t_not_null = t->join(TypePtr::NOTNULL);
- Node *cast = new (C, 2) CastPPNode(b,t_not_null);
// Generate real control flow
Node *tst = _gvn.transform( new (C, 2) BoolNode( c, btest ) );
@@ -996,7 +987,7 @@
if (prob == PROB_UNKNOWN) {
#ifndef PRODUCT
if (PrintOpto && Verbose)
- tty->print_cr("Never-taken backedge stops compilation at bci %d",bci());
+ tty->print_cr("Never-taken edge stops compilation at bci %d",bci());
#endif
repush_if_args(); // to gather stats on loop
// We need to mark this branch as taken so that if we recompile we will
@@ -2100,11 +2091,15 @@
break;
}
- case Bytecodes::_ifnull:
- do_ifnull(BoolTest::eq);
- break;
- case Bytecodes::_ifnonnull:
- do_ifnull(BoolTest::ne);
+ case Bytecodes::_ifnull: btest = BoolTest::eq; goto handle_if_null;
+ case Bytecodes::_ifnonnull: btest = BoolTest::ne; goto handle_if_null;
+ handle_if_null:
+ // If this is a backwards branch in the bytecodes, add Safepoint
+ maybe_add_safepoint(iter().get_dest());
+ a = null();
+ b = pop();
+ c = _gvn.transform( new (C, 3) CmpPNode(b, a) );
+ do_ifnull(btest, c);
break;
case Bytecodes::_if_acmpeq: btest = BoolTest::eq; goto handle_if_acmp;
--- a/hotspot/src/share/vm/opto/superword.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/superword.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -1196,8 +1196,10 @@
Node *n = lp()->fast_out(i);
if (in_bb(n) && (n->is_Phi() && n->bottom_type() == Type::MEMORY)) {
Node* n_tail = n->in(LoopNode::LoopBackControl);
- _mem_slice_head.push(n);
- _mem_slice_tail.push(n_tail);
+ if (n_tail != n->in(LoopNode::EntryControl)) {
+ _mem_slice_head.push(n);
+ _mem_slice_tail.push(n_tail);
+ }
}
}
--- a/hotspot/src/share/vm/opto/type.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -2218,7 +2218,7 @@
return make(ptr, _offset);
}
-//-----------------------------cast_to_instance-------------------------------
+//-----------------------------cast_to_instance_id----------------------------
const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const {
// There are no instances of a general oop.
// Return self unchanged.
@@ -2610,8 +2610,7 @@
// Ptr is never Null
assert( ptr != Null, "NULL pointers are not typed" );
- if ( instance_id > 0 )
- xk = true; // instances are always exactly typed
+ assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
if (!UseExactTypes) xk = false;
if (ptr == Constant) {
// Note: This case includes meta-object constants, such as methods.
@@ -2650,16 +2649,10 @@
return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id);
}
-//-----------------------------cast_to_instance-------------------------------
+//-----------------------------cast_to_instance_id----------------------------
const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const {
if( instance_id == _instance_id ) return this;
- bool exact = _klass_is_exact;
- PTR ptr_t = _ptr;
- if ( instance_id > 0 ) { // instances are always exactly typed
- if (UseExactTypes) exact = true;
- ptr_t = NotNull;
- }
- return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id);
+ return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id);
}
//------------------------------xmeet_unloaded---------------------------------
@@ -2899,6 +2892,7 @@
xk = above_centerline(ptr) ? tinst_xk : false;
// Watch out for Constant vs. AnyNull interface.
if (ptr == Constant) ptr = NotNull; // forget it was a constant
+ instance_id = InstanceBot;
}
ciObject* o = NULL; // the Constant value, if any
if (ptr == Constant) {
@@ -2989,6 +2983,7 @@
// class hierarchy - which means we have to fall to at least NotNull.
if( ptr == TopPTR || ptr == AnyNull || ptr == Constant )
ptr = NotNull;
+ instance_id = InstanceBot;
// Now we find the LCA of Java classes
ciKlass* k = this_klass->least_common_ancestor(tinst_klass);
@@ -3101,8 +3096,7 @@
assert(!(k == NULL && ary->_elem->isa_int()),
"integral arrays must be pre-equipped with a class");
if (!xk) xk = ary->ary_must_be_exact();
- if ( instance_id > 0 )
- xk = true; // instances are always exactly typed
+ assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
if (!UseExactTypes) xk = (ptr == Constant);
return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id))->hashcons();
}
@@ -3113,8 +3107,7 @@
"integral arrays must be pre-equipped with a class");
assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
if (!xk) xk = (o != NULL) || ary->ary_must_be_exact();
- if ( instance_id > 0 )
- xk = true; // instances are always exactly typed
+ assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed");
if (!UseExactTypes) xk = (ptr == Constant);
return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id))->hashcons();
}
@@ -3134,16 +3127,10 @@
return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id);
}
-//-----------------------------cast_to_instance-------------------------------
+//-----------------------------cast_to_instance_id----------------------------
const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const {
if( instance_id == _instance_id ) return this;
- bool exact = _klass_is_exact;
- PTR ptr_t = _ptr;
- if ( instance_id > 0 ) { // instances are always exactly typed
- if (UseExactTypes) exact = true;
- ptr_t = NotNull;
- }
- return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id);
+ return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id);
}
//-----------------------------narrow_size_type-------------------------------
@@ -3300,6 +3287,7 @@
} else {
// Something like byte[int+] meets char[int+].
// This must fall to bottom, not (int[-128..65535])[int+].
+ instance_id = InstanceBot;
tary = TypeAry::make(Type::BOTTOM, tary->_size);
}
}
@@ -3316,6 +3304,7 @@
if( tap->const_oop() != NULL && !o->equals(tap->const_oop()) ) {
ptr = NotNull;
o = NULL;
+ instance_id = InstanceBot;
}
} else if( above_centerline(_ptr) ) {
o = tap->const_oop();
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -153,37 +153,56 @@
os::init_system_properties_values();
}
-// String containing commands that will be ignored and cause a
-// warning to be issued. These commands should be accepted
-// for 1.6 but not 1.7. The string should be cleared at the
-// beginning of 1.7.
-static const char* obsolete_jvm_flags_1_5_0[] = {
- "UseTrainGC",
- "UseSpecialLargeObjectHandling",
- "UseOversizedCarHandling",
- "TraceCarAllocation",
- "PrintTrainGCProcessingStats",
- "LogOfCarSpaceSize",
- "OversizedCarThreshold",
- "MinTickInterval",
- "DefaultTickInterval",
- "MaxTickInterval",
- "DelayTickAdjustment",
- "ProcessingToTenuringRatio",
- "MinTrainLength",
- 0};
+/**
+ * Provide a slightly more user-friendly way of eliminating -XX flags.
+ * When a flag is eliminated, it can be added to this list in order to
+ * continue accepting this flag on the command-line, while issuing a warning
+ * and ignoring the value. Once the JDK version reaches the 'accept_until'
+ * limit, we flatly refuse to admit the existence of the flag. This allows
+ * a flag to die correctly over JDK releases using HSX.
+ */
+typedef struct {
+ const char* name;
+ JDK_Version obsoleted_in; // when the flag went away
+ JDK_Version accept_until; // which version to start denying the existence
+} ObsoleteFlag;
-bool Arguments::made_obsolete_in_1_5_0(const char *s) {
+static ObsoleteFlag obsolete_jvm_flags[] = {
+ { "UseTrainGC", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "UseSpecialLargeObjectHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "UseOversizedCarHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "TraceCarAllocation", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "PrintTrainGCProcessingStats", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "LogOfCarSpaceSize", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "OversizedCarThreshold", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "MinTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "DefaultTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "MaxTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "DelayTickAdjustment", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "ProcessingToTenuringRatio", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "MinTrainLength", JDK_Version::jdk(5), JDK_Version::jdk(7) },
+ { "AppendRatio", JDK_Version::jdk_update(6,10), JDK_Version::jdk(7) },
+ { NULL, JDK_Version(0), JDK_Version(0) }
+};
+
+// Returns true if the flag is obsolete and fits into the range specified
+// for being ignored. In the case that the flag is ignored, the 'version'
+// value is filled in with the version number when the flag became
+// obsolete so that that value can be displayed to the user.
+bool Arguments::is_newly_obsolete(const char *s, JDK_Version* version) {
int i = 0;
- while (obsolete_jvm_flags_1_5_0[i] != NULL) {
+ assert(version != NULL, "Must provide a version buffer");
+ while (obsolete_jvm_flags[i].name != NULL) {
+ const ObsoleteFlag& flag_status = obsolete_jvm_flags[i];
// <flag>=xxx form
// [-|+]<flag> form
- if ((strncmp(obsolete_jvm_flags_1_5_0[i], s,
- strlen(obsolete_jvm_flags_1_5_0[i])) == 0) ||
+ if ((strncmp(flag_status.name, s, strlen(flag_status.name)) == 0) ||
((s[0] == '+' || s[0] == '-') &&
- (strncmp(obsolete_jvm_flags_1_5_0[i], &s[1],
- strlen(obsolete_jvm_flags_1_5_0[i])) == 0))) {
- return true;
+ (strncmp(flag_status.name, &s[1], strlen(flag_status.name)) == 0))) {
+ if (JDK_Version::current().compare(flag_status.accept_until) == -1) {
+ *version = flag_status.obsoleted_in;
+ return true;
+ }
}
i++;
}
@@ -705,14 +724,20 @@
}
}
-bool Arguments::process_argument(const char* arg, jboolean ignore_unrecognized, FlagValueOrigin origin) {
+bool Arguments::process_argument(const char* arg,
+ jboolean ignore_unrecognized, FlagValueOrigin origin) {
+
+ JDK_Version since = JDK_Version();
if (parse_argument(arg, origin)) {
// do nothing
- } else if (made_obsolete_in_1_5_0(arg)) {
+ } else if (is_newly_obsolete(arg, &since)) {
+ enum { bufsize = 256 };
+ char buffer[bufsize];
+ since.to_string(buffer, bufsize);
jio_fprintf(defaultStream::error_stream(),
- "Warning: The flag %s has been EOL'd as of 1.5.0 and will"
- " be ignored\n", arg);
+ "Warning: The flag %s has been EOL'd as of %s and will"
+ " be ignored\n", arg, buffer);
} else {
if (!ignore_unrecognized) {
jio_fprintf(defaultStream::error_stream(),
@@ -2471,6 +2496,9 @@
if (match_option(option, "-XX:+PrintVMOptions", &tail)) {
PrintVMOptions = true;
}
+ if (match_option(option, "-XX:-PrintVMOptions", &tail)) {
+ PrintVMOptions = false;
+ }
}
// Parse default .hotspotrc settings file
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -357,9 +357,11 @@
short* methodsNum, short* methodsMax, char*** methods, bool** allClasses
);
- // Returns true if the string s is in the list of
- // flags made obsolete in 1.5.0.
- static bool made_obsolete_in_1_5_0(const char* s);
+ // Returns true if the string s is in the list of flags that have recently
+ // been made obsolete. If we detect one of these flags on the command
+ // line, instead of failing we print a warning message and ignore the
+ // flag. This gives the user a release or so to stop using the flag.
+ static bool is_newly_obsolete(const char* s, JDK_Version* buffer);
static short CompileOnlyClassesNum;
static short CompileOnlyClassesMax;
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -589,9 +589,15 @@
develop(bool, ZapJNIHandleArea, trueInDebug, \
"Zap freed JNI handle space with 0xFEFEFEFE") \
\
- develop(bool, ZapUnusedHeapArea, false, \
+ develop(bool, ZapUnusedHeapArea, trueInDebug, \
"Zap unused heap space with 0xBAADBABE") \
\
+ develop(bool, TraceZapUnusedHeapArea, false, \
+ "Trace zapping of unused heap space") \
+ \
+ develop(bool, CheckZapUnusedHeapArea, false, \
+ "Check zapping of unused heap space") \
+ \
develop(bool, PrintVMMessages, true, \
"Print vm messages on console") \
\
--- a/hotspot/src/share/vm/runtime/init.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/init.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -39,7 +39,6 @@
void classLoader_init();
void codeCache_init();
void VM_Version_init();
-void JDK_Version_init();
void stubRoutines_init1();
jint universe_init(); // dependent on codeCache_init and stubRoutines_init
void interpreter_init(); // before any methods loaded
@@ -88,7 +87,6 @@
classLoader_init();
codeCache_init();
VM_Version_init();
- JDK_Version_init();
stubRoutines_init1();
jint status = universe_init(); // dependent on codeCache_init and stubRoutines_init
if (status != JNI_OK)
--- a/hotspot/src/share/vm/runtime/java.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/java.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -563,32 +563,104 @@
vm_shutdown();
}
-jdk_version_info JDK_Version::_version_info = {0};
-bool JDK_Version::_pre_jdk16_version = false;
-int JDK_Version::_jdk_version = 0;
+JDK_Version JDK_Version::_current;
void JDK_Version::initialize() {
+ jdk_version_info info;
+ assert(!_current.is_valid(), "Don't initialize twice");
+
void *lib_handle = os::native_java_library();
- jdk_version_info_fn_t func =
- CAST_TO_FN_PTR(jdk_version_info_fn_t, hpi::dll_lookup(lib_handle, "JDK_GetVersionInfo0"));
+ jdk_version_info_fn_t func = CAST_TO_FN_PTR(jdk_version_info_fn_t,
+ os::dll_lookup(lib_handle, "JDK_GetVersionInfo0"));
if (func == NULL) {
// JDK older than 1.6
- _pre_jdk16_version = true;
- return;
- }
+ _current._partially_initialized = true;
+ } else {
+ (*func)(&info, sizeof(info));
- if (func != NULL) {
- (*func)(&_version_info, sizeof(_version_info));
+ int major = JDK_VERSION_MAJOR(info.jdk_version);
+ int minor = JDK_VERSION_MINOR(info.jdk_version);
+ int micro = JDK_VERSION_MICRO(info.jdk_version);
+ int build = JDK_VERSION_BUILD(info.jdk_version);
+ if (major == 1 && minor > 4) {
+ // We represent "1.5.0" as "5.0", but 1.4.2 as itself.
+ major = minor;
+ minor = micro;
+ micro = 0;
+ }
+ _current = JDK_Version(major, minor, micro, info.update_version,
+ info.special_update_version, build,
+ info.thread_park_blocker == 1);
}
- if (jdk_major_version() == 1) {
- _jdk_version = jdk_minor_version();
- } else {
- // If the release version string is changed to n.x.x (e.g. 7.0.0) in a future release
- _jdk_version = jdk_major_version();
+}
+
+void JDK_Version::fully_initialize(
+ uint8_t major, uint8_t minor, uint8_t micro, uint8_t update) {
+ // This is only called when current is less than 1.6 and we've gotten
+ // far enough in the initialization to determine the exact version.
+ assert(major < 6, "not needed for JDK version >= 6");
+ assert(is_partially_initialized(), "must not initialize");
+ if (major < 5) {
+ // JDK verison sequence: 1.2.x, 1.3.x, 1.4.x, 5.0.x, 6.0.x, etc.
+ micro = minor;
+ minor = major;
+ major = 1;
}
+ _current = JDK_Version(major, minor, micro, update);
}
void JDK_Version_init() {
JDK_Version::initialize();
}
+
+static int64_t encode_jdk_version(const JDK_Version& v) {
+ return
+ ((int64_t)v.major_version() << (BitsPerByte * 5)) |
+ ((int64_t)v.minor_version() << (BitsPerByte * 4)) |
+ ((int64_t)v.micro_version() << (BitsPerByte * 3)) |
+ ((int64_t)v.update_version() << (BitsPerByte * 2)) |
+ ((int64_t)v.special_update_version() << (BitsPerByte * 1)) |
+ ((int64_t)v.build_number() << (BitsPerByte * 0));
+}
+
+int JDK_Version::compare(const JDK_Version& other) const {
+ assert(is_valid() && other.is_valid(), "Invalid version (uninitialized?)");
+ if (!is_partially_initialized() && other.is_partially_initialized()) {
+ return -(other.compare(*this)); // flip the comparators
+ }
+ assert(!other.is_partially_initialized(), "Not initialized yet");
+ if (is_partially_initialized()) {
+ assert(other.major_version() >= 6,
+ "Invalid JDK version comparison during initialization");
+ return -1;
+ } else {
+ uint64_t e = encode_jdk_version(*this);
+ uint64_t o = encode_jdk_version(other);
+ return (e > o) ? 1 : ((e == o) ? 0 : -1);
+ }
+}
+
+void JDK_Version::to_string(char* buffer, size_t buflen) const {
+ size_t index = 0;
+ if (!is_valid()) {
+ jio_snprintf(buffer, buflen, "%s", "(uninitialized)");
+ } else if (is_partially_initialized()) {
+ jio_snprintf(buffer, buflen, "%s", "(uninitialized) pre-1.6.0");
+ } else {
+ index += jio_snprintf(
+ &buffer[index], buflen - index, "%d.%d", _major, _minor);
+ if (_micro > 0) {
+ index += jio_snprintf(&buffer[index], buflen - index, ".%d", _micro);
+ }
+ if (_update > 0) {
+ index += jio_snprintf(&buffer[index], buflen - index, "_%02d", _update);
+ }
+ if (_special > 0) {
+ index += jio_snprintf(&buffer[index], buflen - index, "%c", _special);
+ }
+ if (_build > 0) {
+ index += jio_snprintf(&buffer[index], buflen - index, "-b%02d", _build);
+ }
+ }
+}
--- a/hotspot/src/share/vm/runtime/java.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/java.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -48,100 +48,163 @@
extern void vm_exit_during_initialization(const char* error, const char* message = NULL);
extern void vm_shutdown_during_initialization(const char* error, const char* message = NULL);
-class JDK_Version : AllStatic {
+/**
+ * Discovering the JDK_Version during initialization is tricky when the
+ * running JDK is less than JDK6. For JDK6 and greater, a "GetVersion"
+ * function exists in libjava.so and we simply call it during the
+ * 'initialize()' call to find the version. For JDKs with version < 6, no
+ * such call exists and we have to probe the JDK in order to determine
+ * the exact version. This probing cannot happen during late in
+ * the VM initialization process so there's a period of time during
+ * initialization when we don't know anything about the JDK version other than
+ * that it less than version 6. This is the "partially initialized" time,
+ * when we can answer only certain version queries (such as, is the JDK
+ * version greater than 5? Answer: no). Once the JDK probing occurs, we
+ * know the version and are considered fully initialized.
+ */
+class JDK_Version VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
+ friend class Universe;
+ friend void JDK_Version_init();
private:
- static jdk_version_info _version_info;
- static bool _pre_jdk16_version;
- static int _jdk_version; // JDK version number representing the release
- // i.e. n in 1.n.x (= jdk_minor_version())
+
+ static JDK_Version _current;
+
+ // In this class, we promote the minor version of release to be the
+ // major version for releases >= 5 in anticipation of the JDK doing the
+ // same thing. For example, we represent "1.5.0" as major version 5 (we
+ // drop the leading 1 and use 5 as the 'major').
+
+ uint8_t _major;
+ uint8_t _minor;
+ uint8_t _micro;
+ uint8_t _update;
+ uint8_t _special;
+ uint8_t _build;
+
+ // If partially initialized, the above fields are invalid and we know
+ // that we're less than major version 6.
+ bool _partially_initialized;
+
+ bool _thread_park_blocker;
+
+ bool is_valid() const {
+ return (_major != 0 || _partially_initialized);
+ }
+
+ // initializes or partially initializes the _current static field
+ static void initialize();
+
+ // Completes initialization for a pre-JDK6 version.
+ static void fully_initialize(uint8_t major, uint8_t minor = 0,
+ uint8_t micro = 0, uint8_t update = 0);
public:
- static void initialize();
- static int jdk_major_version() { return JDK_VERSION_MAJOR(_version_info.jdk_version); }
- static int jdk_minor_version() { return JDK_VERSION_MINOR(_version_info.jdk_version); }
- static int jdk_micro_version() { return JDK_VERSION_MICRO(_version_info.jdk_version); }
- static int jdk_build_number() { return JDK_VERSION_BUILD(_version_info.jdk_version); }
+
+ // Returns true if the the current version has only been partially initialized
+ static bool is_partially_initialized() {
+ return _current._partially_initialized;
+ }
+
+ JDK_Version() : _major(0), _minor(0), _micro(0), _update(0),
+ _special(0), _build(0), _partially_initialized(false),
+ _thread_park_blocker(false) {}
- static bool is_pre_jdk16_version() { return _pre_jdk16_version; }
- static bool is_jdk12x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 2; }
- static bool is_jdk13x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 3; }
- static bool is_jdk14x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 4; }
- static bool is_jdk15x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 5; }
+ JDK_Version(uint8_t major, uint8_t minor = 0, uint8_t micro = 0,
+ uint8_t update = 0, uint8_t special = 0, uint8_t build = 0,
+ bool thread_park_blocker = false) :
+ _major(major), _minor(minor), _micro(micro), _update(update),
+ _special(special), _build(build), _partially_initialized(false),
+ _thread_park_blocker(thread_park_blocker) {}
- static bool is_jdk16x_version() {
- if (is_jdk_version_initialized()) {
- return _jdk_version == 6;
- } else {
- assert(is_pre_jdk16_version(), "must have been initialized");
- return false;
- }
+ // Returns the current running JDK version
+ static JDK_Version current() { return _current; }
+
+ // Factory methods for convenience
+ static JDK_Version jdk(uint8_t m) {
+ return JDK_Version(m);
+ }
+
+ static JDK_Version jdk_update(uint8_t major, uint8_t update_number) {
+ return JDK_Version(major, 0, 0, update_number);
}
- static bool is_jdk17x_version() {
- if (is_jdk_version_initialized()) {
- return _jdk_version == 7;
+ uint8_t major_version() const { return _major; }
+ uint8_t minor_version() const { return _minor; }
+ uint8_t micro_version() const { return _micro; }
+ uint8_t update_version() const { return _update; }
+ uint8_t special_update_version() const { return _special; }
+ uint8_t build_number() const { return _build; }
+
+ bool supports_thread_park_blocker() const {
+ return _thread_park_blocker;
+ }
+
+ // Performs a full ordering comparison using all fields (update, build, etc.)
+ int compare(const JDK_Version& other) const;
+
+ /**
+ * Performs comparison using only the major version, returning negative
+ * if the major version of 'this' is less than the parameter, 0 if it is
+ * equal, and a positive value if it is greater.
+ */
+ int compare_major(int version) const {
+ if (_partially_initialized) {
+ if (version >= 6) {
+ return -1;
+ } else {
+ assert(false, "Can't make this comparison during init time");
+ return -1; // conservative
+ }
} else {
- assert(is_pre_jdk16_version(), "must have been initialized");
- return false;
+ return major_version() - version;
}
}
- static bool supports_thread_park_blocker() { return _version_info.thread_park_blocker; }
+ void to_string(char* buffer, size_t buflen) const;
+
+ // Convenience methods for queries on the current major/minor version
+ static bool is_jdk12x_version() {
+ return current().compare_major(2) == 0;
+ }
+
+ static bool is_jdk13x_version() {
+ return current().compare_major(3) == 0;
+ }
+
+ static bool is_jdk14x_version() {
+ return current().compare_major(4) == 0;
+ }
+
+ static bool is_jdk15x_version() {
+ return current().compare_major(5) == 0;
+ }
+
+ static bool is_jdk16x_version() {
+ return current().compare_major(6) == 0;
+ }
+
+ static bool is_jdk17x_version() {
+ return current().compare_major(7) == 0;
+ }
+
+ static bool is_gte_jdk13x_version() {
+ return current().compare_major(3) >= 0;
+ }
static bool is_gte_jdk14x_version() {
- // Keep the semantics of this that the version number is >= 1.4
- assert(is_jdk_version_initialized(), "Not initialized");
- return _jdk_version >= 4;
- }
- static bool is_gte_jdk15x_version() {
- // Keep the semantics of this that the version number is >= 1.5
- assert(is_jdk_version_initialized(), "Not initialized");
- return _jdk_version >= 5;
+ return current().compare_major(4) >= 0;
}
+
+ static bool is_gte_jdk15x_version() {
+ return current().compare_major(5) >= 0;
+ }
+
static bool is_gte_jdk16x_version() {
- // Keep the semantics of this that the version number is >= 1.6
- if (is_jdk_version_initialized()) {
- return _jdk_version >= 6;
- } else {
- assert(is_pre_jdk16_version(), "Not initialized");
- return false;
- }
+ return current().compare_major(6) >= 0;
}
static bool is_gte_jdk17x_version() {
- // Keep the semantics of this that the version number is >= 1.7
- if (is_jdk_version_initialized()) {
- return _jdk_version >= 7;
- } else {
- assert(is_pre_jdk16_version(), "Not initialized");
- return false;
- }
- }
-
- static bool is_jdk_version_initialized() {
- return _jdk_version > 0;
- }
-
- // These methods are defined to deal with pre JDK 1.6 versions
- static void set_jdk12x_version() {
- assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize");
- _jdk_version = 2;
- _version_info.jdk_version = (1 << 24) | (2 << 16);
- }
- static void set_jdk13x_version() {
- assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize");
- _jdk_version = 3;
- _version_info.jdk_version = (1 << 24) | (3 << 16);
- }
- static void set_jdk14x_version() {
- assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize");
- _jdk_version = 4;
- _version_info.jdk_version = (1 << 24) | (4 << 16);
- }
- static void set_jdk15x_version() {
- assert(_pre_jdk16_version && !is_jdk_version_initialized(), "must not initialize");
- _jdk_version = 5;
- _version_info.jdk_version = (1 << 24) | (5 << 16);
+ return current().compare_major(7) >= 0;
}
};
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -336,29 +336,38 @@
char buffer[JVM_MAXPATHLEN];
char ebuf[1024];
- // Try to load verify dll first. In 1.3 java dll depends on it and is not always
- // able to find it when the loading executable is outside the JDK.
+ // Try to load verify dll first. In 1.3 java dll depends on it and is not
+ // always able to find it when the loading executable is outside the JDK.
// In order to keep working with 1.2 we ignore any loading errors.
- hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify");
- hpi::dll_load(buffer, ebuf, sizeof(ebuf));
+ dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify");
+ dll_load(buffer, ebuf, sizeof(ebuf));
// Load java dll
- hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java");
- _native_java_library = hpi::dll_load(buffer, ebuf, sizeof(ebuf));
+ dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), "java");
+ _native_java_library = dll_load(buffer, ebuf, sizeof(ebuf));
if (_native_java_library == NULL) {
vm_exit_during_initialization("Unable to load native library", ebuf);
}
- // The JNI_OnLoad handling is normally done by method load in java.lang.ClassLoader$NativeLibrary,
- // but the VM loads the base library explicitly so we have to check for JNI_OnLoad as well
- const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
- JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR(JNI_OnLoad_t, hpi::dll_lookup(_native_java_library, onLoadSymbols[0]));
- if (JNI_OnLoad != NULL) {
- JavaThread* thread = JavaThread::current();
- ThreadToNativeFromVM ttn(thread);
- HandleMark hm(thread);
- jint ver = (*JNI_OnLoad)(&main_vm, NULL);
- if (!Threads::is_supported_jni_version_including_1_1(ver)) {
- vm_exit_during_initialization("Unsupported JNI version");
+ }
+ static jboolean onLoaded = JNI_FALSE;
+ if (onLoaded) {
+ // We may have to wait to fire OnLoad until TLS is initialized.
+ if (ThreadLocalStorage::is_initialized()) {
+ // The JNI_OnLoad handling is normally done by method load in
+ // java.lang.ClassLoader$NativeLibrary, but the VM loads the base library
+ // explicitly so we have to check for JNI_OnLoad as well
+ const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS;
+ JNI_OnLoad_t JNI_OnLoad = CAST_TO_FN_PTR(
+ JNI_OnLoad_t, dll_lookup(_native_java_library, onLoadSymbols[0]));
+ if (JNI_OnLoad != NULL) {
+ JavaThread* thread = JavaThread::current();
+ ThreadToNativeFromVM ttn(thread);
+ HandleMark hm(thread);
+ jint ver = (*JNI_OnLoad)(&main_vm, NULL);
+ onLoaded = JNI_TRUE;
+ if (!Threads::is_supported_jni_version_including_1_1(ver)) {
+ vm_exit_during_initialization("Unsupported JNI version");
+ }
}
}
}
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -390,6 +390,10 @@
static const char* get_temp_directory();
static const char* get_current_directory(char *buf, int buflen);
+ // Builds a platform-specific full library path given a ld path and lib name
+ static void dll_build_name(char* buffer, size_t size,
+ const char* pathname, const char* fname);
+
// Symbol lookup, find nearest function name; basically it implements
// dladdr() for all platforms. Name of the nearest function is copied
// to buf. Distance from its base address is returned as offset.
@@ -413,6 +417,9 @@
// same architecture as Hotspot is running on
static void* dll_load(const char *name, char *ebuf, int ebuflen);
+ // lookup symbol in a shared library
+ static void* dll_lookup(void* handle, const char* name);
+
// Print out system information; they are called by fatal error handler.
// Output format may be different on different platforms.
static void print_os_info(outputStream* st);
--- a/hotspot/src/share/vm/runtime/statSampler.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/statSampler.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -217,6 +217,7 @@
"java.class.path",
"java.endorsed.dirs",
"java.ext.dirs",
+ "java.version",
"java.home",
NULL
};
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -2578,7 +2578,8 @@
oop JavaThread::current_park_blocker() {
// Support for JSR-166 locks
oop thread_oop = threadObj();
- if (thread_oop != NULL && JDK_Version::supports_thread_park_blocker()) {
+ if (thread_oop != NULL &&
+ JDK_Version::current().supports_thread_park_blocker()) {
return java_lang_Thread::park_blocker(thread_oop);
}
return NULL;
@@ -2755,12 +2756,20 @@
// For now, just manually iterate through them.
tc->do_thread(VMThread::vm_thread());
Universe::heap()->gc_threads_do(tc);
- tc->do_thread(WatcherThread::watcher_thread());
+ {
+ // Grab the Terminator_lock to prevent watcher_thread from being terminated.
+ MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag);
+ WatcherThread *wt = WatcherThread::watcher_thread();
+ if (wt != NULL)
+ tc->do_thread(wt);
+ }
// If CompilerThreads ever become non-JavaThreads, add them here
}
jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
+ extern void JDK_Version_init();
+
// Check version
if (!is_supported_jni_version(args->version)) return JNI_EVERSION;
@@ -2776,6 +2785,9 @@
// Initialize system properties.
Arguments::init_system_properties();
+ // So that JDK version can be used as a discrimintor when parsing arguments
+ JDK_Version_init();
+
// Parse arguments
jint parse_result = Arguments::parse(args);
if (parse_result != JNI_OK) return parse_result;
--- a/hotspot/src/share/vm/runtime/threadLocalStorage.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/threadLocalStorage.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -42,8 +42,13 @@
}
void ThreadLocalStorage::init() {
- assert(ThreadLocalStorage::thread_index() == -1, "More than one attempt to initialize threadLocalStorage");
+ assert(!is_initialized(),
+ "More than one attempt to initialize threadLocalStorage");
pd_init();
set_thread_index(os::allocate_thread_local_storage());
generate_code_for_get_thread();
}
+
+bool ThreadLocalStorage::is_initialized() {
+ return (thread_index() != -1);
+}
--- a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -47,6 +47,7 @@
// Initialization
// Called explicitly from VMThread::activate_system instead of init_globals.
static void init();
+ static bool is_initialized();
private:
static int _thread_index;
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -761,8 +761,9 @@
static_field(Abstract_VM_Version, _vm_minor_version, int) \
static_field(Abstract_VM_Version, _vm_build_number, int) \
\
- static_field(JDK_Version, _pre_jdk16_version, bool) \
- static_field(JDK_Version, _jdk_version, int) \
+ static_field(JDK_Version, _current, JDK_Version) \
+ nonstatic_field(JDK_Version, _partially_initialized, bool) \
+ nonstatic_field(JDK_Version, _major, unsigned char) \
\
\
\
--- a/hotspot/src/share/vm/services/threadService.cpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/services/threadService.cpp Wed Jul 05 16:40:18 2017 +0200
@@ -744,7 +744,7 @@
}
// Support for JSR-166 locks
- if (JDK_Version::supports_thread_park_blocker() &&
+ if (JDK_Version::current().supports_thread_park_blocker() &&
(_thread_status == java_lang_Thread::PARKED ||
_thread_status == java_lang_Thread::PARKED_TIMED)) {
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jul 05 16:40:18 2017 +0200
@@ -97,8 +97,12 @@
// object size.
class HeapWord {
friend class VMStructs;
-private:
+ private:
char* i;
+#ifdef ASSERT
+ public:
+ char* value() { return i; }
+#endif
};
// HeapWordSize must be 2^LogHeapWordSize.
--- a/hotspot/test/compiler/6646019/Test.java Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/test/compiler/6646019/Test.java Wed Jul 05 16:40:18 2017 +0200
@@ -1,23 +1,24 @@
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
*
*/
--- a/hotspot/test/compiler/6689060/Test.java Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/test/compiler/6689060/Test.java Wed Jul 05 16:40:18 2017 +0200
@@ -1,24 +1,24 @@
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
*
*/
--- a/hotspot/test/compiler/6695810/Test.java Thu Aug 21 09:55:18 2008 -0700
+++ b/hotspot/test/compiler/6695810/Test.java Wed Jul 05 16:40:18 2017 +0200
@@ -1,24 +1,24 @@
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
*
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6700047/Test6700047.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6700047
+ * @summary C2 failed in idom_no_update
+ * @run main Test6700047
+ */
+
+public class Test6700047 {
+ public static void main(String[] args) {
+ for (int i = 0; i < 100000; i++) {
+ intToLeftPaddedAsciiBytes();
+ }
+ }
+
+ public static int intToLeftPaddedAsciiBytes() {
+ int offset = 40;
+ int q;
+ int r;
+ int i = 100;
+ int result = 1;
+ while (offset > 0) {
+ q = (i * 52429);
+ r = i;
+ offset--;
+ i = q;
+ if (i == 0) {
+ break;
+ }
+ }
+ if (offset > 0) {
+ for(int j = 0; j < offset; j++) {
+ result++;
+ }
+ }
+ return result;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6712835/Test6712835.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,1578 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6712835
+ * @summary Server compiler fails with assertion (loop_count < K,"infinite loop in PhaseIterGVN::transform")
+ * @run main/othervm -Xcomp Test6712835
+ */
+
+/* Complexity upper bound: 349851 ops */
+
+abstract class Tester_Class_0 {
+ boolean var_1 = true;
+ static double var_2;
+ float var_3 = 1.8301116E38F;
+ final String var_4 = "wck";
+ final static short var_5 = 25624;
+
+
+ public Tester_Class_0()
+ {
+ var_2 = (byte)1.7374809293839066E308;
+ {
+ double var_18 = false ? 8027040614338917376L * var_3 + - (var_2 = var_5) : (var_3 += (char)4.491494085158084E307);
+ var_3 *= ~ ((byte)702579792) / 6600332715431236608L;
+ long var_19 = 0L;
+ var_18 -= 1759091496;
+ do
+ {
+ final long var_20 = (new long[(byte)(var_3 += + +1.6695243696502334E308)][(byte)((byte)1110410742 | ~var_19)])[var_1 & var_1 ? (byte)1047514041090199552L : (byte)var_5][(byte)(var_1 ? 123309551 : - ((byte)5932930312361050112L))];
+ var_19++;
+ final short var_21 = var_5;
+ } while (var_19 < 1 && var_1 ^ var_3 == + ((byte)var_5));
+ {
+ int var_22;
+ }
+ {
+ var_4.endsWith("o");
+ }
+ int var_23 = 0;
+ var_1 &= (var_1 = true);
+ for (byte var_24 = 26; (var_1 = !var_1) && var_23 < 1; var_18 += var_1 ^ (var_1 |= false) ^ true ? var_24 : (byte)1504077779675035648L)
+ {
+ var_18 *= var_23;
+ var_23++;
+ float var_25;
+ (((new Tester_Class_0[var_24][var_24][var_24])[var_24])[var_24 >>= var_19][var_24 &= 6702582681202665472L]).var_3 *= var_5;
+ }
+ var_1 = (var_3 -= var_5) > (byte)func_2(1317089759, var_5, (byte)var_19) % (false & true ? 475183200 : 8947159119888251904L);
+ var_18 /= ~var_19 ^ ((byte)(var_18 %= (int)var_5) >= 6773554922270913536L ? (byte)var_5 : (byte)'u');
+ var_3 = ~ ((byte)var_19);
+ }
+ double var_26 = 0;
+ var_1 &= (var_1 |= ! (var_1 |= true));
+ while (var_26 < 1)
+ {
+ var_2 = 'e';
+ var_26++;
+ var_1 ^= !true | 'j' * ((var_2 = 93384362) + var_5) <= var_5;
+ var_2 = true ? 2056852215 : var_5;
+ }
+ switch ((new char[(byte)var_3])[(byte)(short)var_4.charAt(438929928)] / (new byte[(byte)1779353916050551808L][(byte)+ ~8903539475459755008L])[(byte)836413337621087232L][(byte)784406244])
+ {
+ case 101:
+ var_3 -= var_5;
+ break;
+
+ case 'L':
+
+ case 20:
+ final int var_27 = 2146473580;
+ break;
+
+ case 18:
+
+ default:
+ "mwh".substring((byte)(float)'A' % var_5, ']' | var_5 ^ ~ ((byte)'E'));
+ break;
+
+ case 'H':
+
+ }
+ var_3 = var_5;
+ long var_28;
+ var_28 = (var_1 = 'u' != (var_3 = var_1 ? 1384770002488557568L : ~ ~6691557565676772352L)) ? - ((byte)938410603) : var_5;
+ ((new Tester_Class_0[(byte)var_26])[(byte)'w']).var_3 = (byte)(short)'I';
+ var_2 = (var_1 ^= "sfltwylm".startsWith("ytmeds")) ? 1837260339 * 434565574 : (new double[(byte)var_26])[(byte)var_3];
+ }
+
+
+
+ public boolean equals(Object obj)
+ {
+ var_2 = 785819716 / 'i';
+ switch ((! (var_1 ^= var_1) ^ (! ((false | (var_1 |= var_1)) ^ !false) ? false : (var_1 |= !false)) ? var_1 : ! !var_1 ^ var_1) ? 1426689390 : var_5 * var_5)
+ {
+ case '`':
+
+ case 89:
+
+ case 13:
+ char var_9 = 'W';
+ break;
+
+ case 31:
+
+ case 15:
+
+ case 'm':
+ var_1 &= var_1;
+ break;
+
+ case 'Z':
+
+ case 34:
+ String[] var_10 = (new String[(byte)5534253842608756736L][(byte)'M'])[(byte)8717534666212195328L];
+ break;
+
+ case 124:
+
+ }
+ var_3 += var_5;
+ var_1 |= (var_1 |= (var_1 = (var_1 |= var_5 >= (var_2 = (byte)var_3))));
+ var_1 ^= (var_1 = var_4.endsWith(new String()));
+ var_2 = (var_3 %= 664966429);
+ {
+ var_4.lastIndexOf((int)('i' * (! !true & (true & !var_1) ? (byte)2.2562587635371023E307 : (byte)(var_3 %= var_3)) / var_3), 'P' % (false ? (byte)'N' : (byte)943393108));
+ }
+ var_3 /= false | ! !var_1 ? (char)1.3721055E38F : '\\';
+ if (var_1)
+ {
+ var_4.compareTo("uaqmqwg");
+ }
+ else
+ {
+ var_1 ^= var_1 & (var_1 &= (var_1 ^= (var_1 ^= var_1)));
+ }
+ var_3 *= (new int[(byte)1980200282][(byte)'i'])[(byte)(var_2 = (byte)'O')][false ? (byte)2.4739911E38F : (byte)- ((byte)1.6045903096088714E308)];
+ var_1 = var_5 != (byte)var_5 & (1.5002759009669559E308 < (byte)5110733568033040384L ^ (var_1 ? (var_1 ^= true) : var_1));
+ long var_11;
+ return (var_2 = (byte)'B') < 550125954;
+ }
+
+
+ public static char func_0(final int arg_0, long[] arg_1, final boolean arg_2)
+ {
+ var_2 = (short)(false ? (byte)1.2577737E38F : (byte)'t');
+ "xdf".codePointBefore((!arg_2 ? (byte)1426638765 : (byte)541094055) * ((byte)var_5 / var_5));
+ ((new Tester_Class_0[(byte)(short)(var_2 = 'A')])[(byte)arg_0]).var_3 = 7823141134226481152L;
+ ((new Tester_Class_0[(byte)- ~1368497135389664256L])[!false || true ? (byte)2.5393905E38F : (byte)2.4415902E38F]).var_3 -= (int)(false ? (byte)var_5 : (byte)"musnlk".charAt(785792957));
+ ((new Tester_Class_0[(byte)357672172])[(byte)7.709380171237795E307]).var_3 = arg_0;
+ ((new Tester_Class_0[(byte)var_5])[(byte)('Z' / + + -2.6037312E38F)]).var_3 %= arg_2 ? + - - + - + +4.6761156E37F : (byte)- (var_2 = - - ~3113191255384341504L);
+ (("exseqpham" + "uigdxg").equalsIgnoreCase("oeutvibnv") ? "l" : "qra").replace(false ^ true ? 't' : "jwpf".charAt(+ ((byte)arg_0)), 6.624090730243228E307 > 2.7771497E38F ? 't' : "tcfesyg".charAt(arg_0));
+ ((new Tester_Class_0[(byte)arg_0][(byte)6943189372481268736L])[(byte)2.6713643513095145E307][(byte)var_5]).var_1 &= !"ipgqq".endsWith("aecnyvpmf");
+ ((new Tester_Class_0[(byte)(+ +2158971337956592640L ^ var_5)])[false ? (byte)8594725249859841024L : (byte)var_5]).var_3 = (byte)"jd".charAt((byte)1.6298661301128909E307 << (byte)'B');
+ var_2 = (float)1014982842 * (byte)var_5 * ((new Tester_Class_0[(byte)2.7842814E38F])[(byte)"n".charAt('e' ^ (byte)arg_0)]).var_3;
+ if (false)
+ {
+ ((new Tester_Class_0[(byte)8.702990410251979E307][(byte)8.865924E37F])[(byte)var_5][(byte)+ ((long)var_5)]).var_1 ^= arg_2;
+ }
+ else
+ {
+ ((new Tester_Class_0[(byte)('I' | var_5)])[(byte)('L' + (+ - - (var_2 = 'N') + 1.324025E38F))]).var_3 = var_5 % '[' + (byte)var_5;
+ }
+ ((new Tester_Class_0[(byte)7.41761E37F][(byte)(var_2 = var_5)])[(byte)var_5][(byte)'o']).var_1 &= false;
+ ((new Tester_Class_0[(byte)+ ((byte)7.9065203E37F)])[(byte)var_5]).var_1 ^= 630582880 > - (var_2 = var_5);
+ return 'K';
+ }
+
+ protected float func_1(int arg_0, final Object arg_1, Object arg_2)
+ {
+ var_1 ^= (var_1 ^= true) & !var_1;
+ {
+ var_3 -= var_3;
+ var_2 = var_1 && (var_1 &= ! !true) | + ~3353396000385141760L < 7949306917320622080L ? (byte)306954754 : (byte)var_5;
+ final long var_12 = 1048994076885686272L;
+ }
+ short var_13 = 8706;
+ byte var_14 = (new byte[(byte)6.697464316212731E307])[(byte)var_4.indexOf("clbr", (byte)var_5 + 'F')];
+ ((new Tester_Class_0[var_14][var_14 &= 'b'])[var_14][var_14]).var_1 |= var_14 >= var_3;
+ (((new String[var_14][var_14])[var_14])[var_14]).codePointAt(585064460);
+ var_14 -= 2121015302;
+ var_2 = 1.241922E38F;
+ {
+ (((new Tester_Class_0[var_14][var_14 ^= 'y'])[var_14])[var_14 |= var_14]).var_3 *= 5756647686007829504L;
+ }
+ {
+ var_13--;
+ }
+ double var_15;
+ var_1 = (var_1 = true) ? false : true;
+ arg_0--;
+ return var_3;
+ }
+
+ public final static short func_2(int arg_0, final short arg_1, byte arg_2)
+ {
+ arg_0 %= (((new Tester_Class_0[arg_2][arg_2])[arg_2++][--arg_2]).var_1 |= true) ? 'e' : var_5 >>> arg_2;
+ float var_16 = ((false ? ~3951083684045828096L >>> - -3880809660598466560L : arg_0) ^ arg_1) - 1.1257035E37F;
+ var_2 = var_5 + 3.3679594E38F;
+ arg_2 += true & (((new Tester_Class_0[arg_2])[arg_2 *= 4301185995603340288L]).var_1 = arg_1 != arg_1) ? (var_2 = arg_0) : 988311987505040384L + ']' >>> --arg_2;
+ arg_2 = arg_2;
+ var_16 /= (arg_2 += (arg_0 += (var_16 %= arg_2)) + (var_16 -= arg_2));
+ var_16 += 7416220016668043264L;
+ ((new Tester_Class_0[arg_2])[arg_2]).var_1 &= false;
+ ((new Tester_Class_0[--arg_2])[--arg_2]).var_1 = true | (true & true ? true : false);
+ arg_2 -= (var_2 = 7997355759027275776L);
+ ((new Tester_Class_0[arg_2])[arg_2 %= 8660960251961819136L]).var_3 *= 4180634858198604800L;
+ arg_0 /= -1.3063173E38F;
+ var_2 = arg_2;
+ var_2 = (6266377813429248L ^ 'j') / (!false & (1.1423139843154216E308 >= (var_2 = arg_2) || (((new Tester_Class_0[arg_2])[arg_2]).var_1 ^= true)) ? (short)('e' * arg_0) : var_5);
+ --arg_0;
+ var_2 = (+ - ~8598445599816821760L << arg_1) % 1890075208 & (!true & !true ^ false & false ? 'w' : 'm') % (5614521287604667392L / arg_2) & ~193105176465084416L;
+ arg_2 &= (arg_2 |= arg_0) ^ ((((new Tester_Class_0[arg_2][arg_2])[arg_2])[arg_2]).var_1 ? arg_2 : (new long[arg_2])[arg_2]);
+ ((new Tester_Class_0[arg_2 &= 'V'][arg_2])[arg_2 /= 5486057194586717184L][arg_2 %= var_16]).var_1 |= (new boolean[((new Tester_Class_0[arg_2])[arg_2]).var_1 ? arg_2 : arg_2])[arg_2];
+ return ((((new Tester_Class_0[arg_2][arg_2][arg_2])[--arg_2])[arg_2 |= arg_2][arg_2 %= 6782653882738869248L]).var_1 ? false : !true | "hopq".equalsIgnoreCase("wvm") | "qmhtjvm".endsWith("gewqas")) && ! !false & false ? arg_1 : arg_1;
+ }
+
+ protected final static char func_3(byte arg_0, final int arg_1, final short arg_2, long[] arg_3)
+ {
+ ((new Tester_Class_0[arg_0 ^= 1902924521091955712L])[arg_0]).var_1 &= ((((new Tester_Class_0[arg_0][arg_0])[--arg_0])[arg_0 *= - -1.0959788E38F]).var_1 = false);
+ {
+ var_2 = (new float[arg_0][(byte)1082004329])[arg_0][arg_0 <<= 'T'];
+ }
+ ((new Tester_Class_0[arg_0 >>= arg_1][arg_0])[arg_0][arg_0]).var_1 |= ((new Tester_Class_0[arg_0])[--arg_0]).var_4.startsWith(((new Tester_Class_0[arg_0])[arg_0]).var_4);
+ ((new Tester_Class_0[(byte)var_5])[arg_0]).var_4.substring(273513722, 'f' * 'n').substring((new short[arg_0][arg_0])[arg_0][arg_0] % 'C' >> (arg_3[arg_0] - 's') % ("".charAt(arg_1) & var_5));
+ var_2 = 'Q' + (char)arg_0;
+ {
+ ((new Tester_Class_0[++arg_0])[arg_0]).var_1 ^= !true || !true ? !false ^ false : ! (1.7030813E38F != ~arg_0);
+ }
+ {
+ "jbdu".indexOf(((new Tester_Class_0[arg_0 *= 2628674024589069312L])[arg_0 -= arg_1]).var_4, "gqglwwbab".charAt(~arg_0) >>> 'M');
+ }
+ {
+ --arg_0;
+ }
+ ((new Tester_Class_0[arg_0])[arg_0]).var_1 = 'n' == ('t' | (+9156142987836739584L | 's')) - 2915339344736463872L;
+ int var_17;
+ var_17 = 'k';
+ var_17 = (((new Tester_Class_0[arg_0])[arg_0]).var_1 &= false) ? (short)'q' : arg_2;
+ return '`';
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_0.var_5 = "; result += Test6712835.Printer.print(var_5);
+ result += "\n";
+ result += "Tester_Class_0.var_4 = "; result += Test6712835.Printer.print(var_4);
+ result += "\n";
+ result += "Tester_Class_0.var_1 = "; result += Test6712835.Printer.print(var_1);
+ result += "\n";
+ result += "Tester_Class_0.var_2 = "; result += Test6712835.Printer.print(var_2);
+ result += "\n";
+ result += "Tester_Class_0.var_3 = "; result += Test6712835.Printer.print(var_3);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Tester_Class_1 extends Tester_Class_0 {
+ final boolean var_29 = false;
+ static short var_30;
+ Tester_Class_0 var_31;
+
+
+ public Tester_Class_1()
+ {
+ new String();
+ byte var_43 = (var_1 ? var_29 : var_1) ? (byte)(~ ~ ~6520122970162626560L | ~6642750731731981312L) : (byte)(var_30 = var_5);
+ {
+ var_2 = Tester_Class_0.var_5;
+ }
+ ((Tester_Class_0)(new Object[var_43])[var_43]).var_1 = var_29;
+ var_43 += 512311665;
+ }
+
+
+
+
+ final int func_0()
+ {
+ Tester_Class_0.var_2 = var_29 ? (var_29 ? (byte)'D' : (byte)Tester_Class_0.var_5) : (!var_1 ^ var_1 | (var_1 ^= var_1) ? (byte)'J' : (byte)51510881);
+ new String();
+ new String();
+ new String();
+ return 1731501229;
+ }
+
+ private final static void func_1(final String arg_0, final Object arg_1)
+ {
+ long var_32 = ((new Tester_Class_1[(byte)37719380])['I' == Tester_Class_0.var_5 + Tester_Class_0.var_5 ? (byte)(var_30 = (byte)1.3043569561522328E308) : (byte)1.1111420042091164E308]).var_1 ? ~2569063513521638400L - Tester_Class_0.var_5 ^ 'm' : 660383226;
+ ((Tester_Class_0)arg_1).var_3 += (char)8417109805993570304L;
+ var_30 = var_5;
+ var_2 = (new byte[(byte)2102078692])[(byte)7.942050823719592E307];
+ if (((new Tester_Class_1[(byte)224717297])[(byte)2889830453578512384L]).var_1)
+ {
+ Tester_Class_0.var_2 = (new byte[(byte)'C'])[(byte)Tester_Class_0.var_5];
+ }
+ else
+ {
+ var_32 <<= 'u';
+ }
+ Tester_Class_0.var_2 = Tester_Class_0.var_5;
+ final Object var_33 = arg_1;
+ final byte var_34 = 40;
+ ++var_32;
+ (((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_31 = ((new Tester_Class_0[var_34][var_34])[var_34])[var_34]).var_1 ^= (((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_31 = (Tester_Class_0)var_33).var_1;
+ ((new Tester_Class_1[var_34])[var_34]).var_31 = (((new Tester_Class_1[var_34])[((new Tester_Class_1[var_34][var_34])[var_34][var_34]).var_1 ? var_34 : var_34]).var_31 = (((new Tester_Class_1[(byte)2.4941036E38F])[var_34]).var_31 = (Tester_Class_0)arg_1));
+ }
+
+ public static int[][] func_2(long arg_0, final float arg_1, short arg_2, final double arg_3)
+ {
+ long var_35;
+ {
+ arg_0++;
+ var_2 = true ? (byte)9.691601510156328E307 : (byte)"a".charAt(~ ((byte)arg_1));
+ if (((new Tester_Class_1[(byte)'\\'][(byte)arg_2])[(byte)arg_2][(byte)arg_0]).var_29)
+ {
+ arg_2++;
+ }
+ else
+ {
+ Tester_Class_0.var_2 = arg_2;
+ var_30 = arg_2;
+ Tester_Class_0.var_2 = arg_0;
+ }
+ arg_2 /= 157487965;
+ arg_2 -= func_2(~ ((byte)arg_0), (short)arg_3, (byte)+2.2503214E38F);
+ }
+ arg_0--;
+ double var_36;
+ arg_0 <<= (arg_0 >>= (arg_0 = 'O'));
+ {
+ arg_0++;
+ --arg_0;
+ }
+ --arg_2;
+ ++arg_2;
+ "gbcrkn".length();
+ var_30 = (short)7.14672E37F;
+ {
+ arg_0 %= (arg_0 >>= (arg_2 *= (byte)1.5835087622116814E308)) % arg_3;
+ var_36 = 'n';
+ int[][] var_37 = new int[(byte)(double)arg_0][(byte)(arg_2 >>= 'o')];
+ if ((byte)1390907656194158592L <= arg_2)
+ {
+ "uuoeps".indexOf("", 899321600);
+ }
+ else
+ {
+ var_36 = - ~ -arg_0;
+ }
+ short var_38 = var_5;
+ var_36 = ~arg_0 + (6482428938632186880L + 6995927649252739072L);
+ }
+ if (((new Tester_Class_1[(byte)arg_1][(byte)arg_2])[(new byte[(byte)arg_0])[(byte)var_5]][(byte)'s']).var_1 = false)
+ {
+ ++arg_0;
+ }
+ else
+ {
+ ((new Tester_Class_1[(byte)2.7176027E38F])[(byte)((arg_2 -= 2.595396436487417E307) % 'p')]).var_1 ^= ((new Tester_Class_1[(byte)4.393706E36F])[false ? (byte)4826960994531808256L : (byte)arg_0]).var_29;
+ }
+ int var_39 = 0;
+ arg_2 <<= 'Y';
+ while (var_39 < 1 && false)
+ {
+ arg_0++;
+ var_39++;
+ Object var_40;
+ ((Tester_Class_0)(var_40 = new long[(byte)3.285531E38F])).var_3 += var_39;
+ }
+ Object var_41;
+ "w".substring(1359453539);
+ return new int[(byte)((arg_2 /= 4.143015135482291E307) - 3.2659622E38F)][(byte)++arg_2];
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_1.var_5 = "; result += Test6712835.Printer.print(var_5);
+ result += "\n";
+ result += "Tester_Class_1.var_30 = "; result += Test6712835.Printer.print(var_30);
+ result += "\n";
+ result += "Tester_Class_1.var_4 = "; result += Test6712835.Printer.print(var_4);
+ result += "\n";
+ result += "Tester_Class_1.var_1 = "; result += Test6712835.Printer.print(var_1);
+ result += "\n";
+ result += "Tester_Class_1.var_29 = "; result += Test6712835.Printer.print(var_29);
+ result += "\n";
+ result += "Tester_Class_1.var_2 = "; result += Test6712835.Printer.print(var_2);
+ result += "\n";
+ result += "Tester_Class_1.var_3 = "; result += Test6712835.Printer.print(var_3);
+ result += "\n";
+ result += "Tester_Class_1.var_31 = "; result += Test6712835.Printer.print(var_31);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Tester_Class_2 extends Tester_Class_0 {
+ static float var_44 = 2.7867988E38F;
+ static byte var_45;
+ static long var_46 = 4319798868443575296L;
+
+
+ public Tester_Class_2()
+ {
+ Tester_Class_1.var_30 = (byte)3.1718026E38F;
+ var_45 = (new byte[(byte)'o'])[var_45 = (byte)Tester_Class_0.var_5];
+ Tester_Class_1.var_30 = (Tester_Class_1.var_30 = Tester_Class_0.var_5);
+ if (true)
+ {
+ ++var_46;
+ boolean var_51 = false ? (var_1 &= !var_1) : true;
+ --var_46;
+ if (false)
+ {
+ var_3 *= 6.882788442363403E307;
+ }
+ else
+ {
+ Tester_Class_0.var_2 = '`';
+ }
+ final float var_52 = (var_1 ^= var_1 || (var_1 &= false)) | (var_51 |= (var_51 &= false)) ? (byte)4.751813848964725E307 : (var_3 *= var_5);
+ (false ? var_4 : var_4).startsWith("j" + var_4);
+ var_46++;
+ var_3 %= Tester_Class_1.var_5;
+ }
+ else
+ {
+ Tester_Class_1.var_30 = (var_45 = (var_45 = (var_45 = (byte)Tester_Class_1.var_5)));
+ Tester_Class_1.var_2 = (var_3 -= ~ ((byte)var_46) - 2018787280);
+ Tester_Class_1.var_30 = (Tester_Class_1.var_30 = (Tester_Class_1.var_30 = (Tester_Class_1.var_30 = var_5)));
+ }
+ char var_53;
+ ++var_46;
+ short var_54 = 138;
+ ++var_46;
+ var_2 = 1435782089;
+ Tester_Class_0.var_2 = var_46;
+ }
+
+
+
+
+ protected final boolean func_0(final boolean arg_0, final boolean arg_1)
+ {
+ var_2 = 2.6153986361247174E307;
+ var_45 = (var_45 = (var_45 = (var_45 = (var_45 = (byte)(var_44 += var_46)))));
+ var_46++;
+ long var_47 = 0L;
+ var_3 -= + ((byte)(~var_46 * ~var_46 ^ var_46 % 1910419567));
+ do
+ {
+ ++var_46;
+ var_47++;
+ char var_48 = 'b';
+ } while (var_47 < 2);
+ new Tester_Class_1().var_31 = ((new Tester_Class_1[var_45 = (byte)3.0853839E38F])[(new byte[var_45 = (byte)1.4974966426791287E308])[var_45 = (byte)Tester_Class_0.var_5]]).var_1 ? new Tester_Class_1() : new Tester_Class_1();
+ var_45 = (var_45 = (byte)var_44);
+ double var_49 = 0;
+ var_45 = (byte)(Tester_Class_1.var_30 = Tester_Class_0.var_5);
+ while (((false ^ (var_1 &= var_1) | (var_1 |= arg_0) ? new Tester_Class_1() : new Tester_Class_1()).var_29 ? var_1 : false && (var_1 ^= arg_0)) && (var_49 < 3 && (true ? new Tester_Class_1() : new Tester_Class_1()).var_1))
+ {
+ var_45 = (var_45 = (var_45 = (var_45 = (var_45 = (byte)1.933612E38F))));
+ var_49++;
+ var_45 = (var_45 = (var_45 = (var_45 = (byte)685709636)));
+ long var_50;
+ }
+ var_45 = (var_45 = (var_45 = (byte)var_5));
+ var_46--;
+ return true;
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_2.var_46 = "; result += Test6712835.Printer.print(var_46);
+ result += "\n";
+ result += "Tester_Class_2.var_2 = "; result += Test6712835.Printer.print(var_2);
+ result += "\n";
+ result += "Tester_Class_2.var_3 = "; result += Test6712835.Printer.print(var_3);
+ result += "\n";
+ result += "Tester_Class_2.var_44 = "; result += Test6712835.Printer.print(var_44);
+ result += "\n";
+ result += "Tester_Class_2.var_5 = "; result += Test6712835.Printer.print(var_5);
+ result += "\n";
+ result += "Tester_Class_2.var_45 = "; result += Test6712835.Printer.print(var_45);
+ result += "\n";
+ result += "Tester_Class_2.var_4 = "; result += Test6712835.Printer.print(var_4);
+ result += "\n";
+ result += "Tester_Class_2.var_1 = "; result += Test6712835.Printer.print(var_1);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+class Tester_Class_3 extends Tester_Class_0 {
+ static boolean var_55 = true;
+ short var_56;
+ char var_57 = (char)723612093;
+ final static byte var_58 = 118;
+ static float var_59 = true ? -2818156175448416256L : - - (Tester_Class_2.var_44 += var_58);
+ static Tester_Class_1 var_60;
+ byte var_61 = 112;
+ Tester_Class_2[] var_62;
+ static short var_63 = 19813;
+ static double var_64 = (var_55 = true) ? (Tester_Class_1.var_2 = 'M') : Tester_Class_2.var_46;
+
+
+ public Tester_Class_3()
+ {
+ var_56 = var_58;
+ Tester_Class_1 var_65 = var_60 = (var_60 = (var_60 = (new Tester_Class_1[var_61 |= '\\'])[(var_1 = true) || var_55 ? var_58 : var_61]));
+ var_64 /= 1253632965 * '`';
+ Tester_Class_2.var_46 >>>= var_58;
+ (((var_61 = var_58) * (var_55 ? 1641980027 : var_63) >= 1490788063 ? var_65 : var_65).var_29 ? var_65 : var_65).var_31 = (new Tester_Class_2[var_58])[var_58];
+ ++var_63;
+ new String();
+ var_64 += var_55 ? (var_61 >>>= 'Q') : (var_63 <<= var_57);
+ ((new Tester_Class_2().var_3 >= Tester_Class_2.var_46 ? !var_55 : var_4.startsWith(var_4, 586086925)) ? "gjsdhuop" : "juqrt").substring(("pm" + ((new Tester_Class_2[var_61][var_58])[var_58][var_58]).var_4).codePointBefore((~var_61 << 3032688286897486848L) - Tester_Class_1.var_5), (var_61 += 4.0796373033184064E306) >> (Tester_Class_2.var_46 >>> var_58));
+ var_63 -= (var_63 ^= var_57);
+ var_64 = var_5 - (Tester_Class_2.var_46 *= var_57);
+ Tester_Class_2.var_46 &= 7544159045139005440L;
+ var_55 |= false;
+ Tester_Class_2.var_46 = var_61;
+ }
+
+
+
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_3.var_57 = "; result += Test6712835.Printer.print(var_57);
+ result += "\n";
+ result += "Tester_Class_3.var_62 = "; result += Test6712835.Printer.print(var_62);
+ result += "\n";
+ result += "Tester_Class_3.var_2 = "; result += Test6712835.Printer.print(var_2);
+ result += "\n";
+ result += "Tester_Class_3.var_64 = "; result += Test6712835.Printer.print(var_64);
+ result += "\n";
+ result += "Tester_Class_3.var_3 = "; result += Test6712835.Printer.print(var_3);
+ result += "\n";
+ result += "Tester_Class_3.var_59 = "; result += Test6712835.Printer.print(var_59);
+ result += "\n";
+ result += "Tester_Class_3.var_5 = "; result += Test6712835.Printer.print(var_5);
+ result += "\n";
+ result += "Tester_Class_3.var_56 = "; result += Test6712835.Printer.print(var_56);
+ result += "\n";
+ result += "Tester_Class_3.var_63 = "; result += Test6712835.Printer.print(var_63);
+ result += "\n";
+ result += "Tester_Class_3.var_58 = "; result += Test6712835.Printer.print(var_58);
+ result += "\n";
+ result += "Tester_Class_3.var_61 = "; result += Test6712835.Printer.print(var_61);
+ result += "\n";
+ result += "Tester_Class_3.var_4 = "; result += Test6712835.Printer.print(var_4);
+ result += "\n";
+ result += "Tester_Class_3.var_1 = "; result += Test6712835.Printer.print(var_1);
+ result += "\n";
+ result += "Tester_Class_3.var_55 = "; result += Test6712835.Printer.print(var_55);
+ result += "\n";
+ result += "Tester_Class_3.var_60 = "; result += Test6712835.Printer.print(var_60);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Tester_Class_4 {
+ static long var_66;
+ final long var_67 = 7113579489152300032L * 985636454;
+ int[] var_68;
+ Tester_Class_3 var_69;
+ final long var_70 = Tester_Class_2.var_46 <<= Tester_Class_1.var_5;
+ byte var_71 = Tester_Class_3.var_58;
+
+
+ public Tester_Class_4()
+ {
+ Tester_Class_2.var_46++;
+ (var_69 = new Tester_Class_3()).var_61 += (!true | (Tester_Class_3.var_55 ^= Tester_Class_3.var_55) ? new Tester_Class_3() : new Tester_Class_3()).var_61;
+ final String[][] var_79 = new String[var_71 >>= (Tester_Class_3.var_63 ^= 'm')][((Tester_Class_3)(new Tester_Class_1().var_31 = new Tester_Class_2())).var_61 >>= (var_71 >>>= (Tester_Class_2.var_46 += 465205188010511360L))];
+ ++(var_69 = (var_69 = (var_69 = (Tester_Class_3)(new Object[Tester_Class_3.var_58][var_71])[Tester_Class_3.var_58][var_71]))).var_61;
+ (((new Tester_Class_2[var_71][Tester_Class_3.var_58])[Tester_Class_2.var_45 = var_71])[var_71]).var_3 += (Tester_Class_2.var_46 <<= (Tester_Class_2.var_46 /= 9.03047405760868E307) >> (new Tester_Class_2().var_1 ? 2099696051 : Tester_Class_3.var_63));
+ Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1())));
+ char var_80;
+ Tester_Class_3.var_64 += 355712574;
+ ++Tester_Class_2.var_46;
+ }
+
+
+
+
+ private final static Tester_Class_1 func_0(boolean arg_0, double arg_1)
+ {
+ Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1());
+ byte var_72 = (byte)Tester_Class_2.var_46;
+ Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1()))));
+ float var_73 = 0F;
+ "flfix".offsetByCodePoints((Tester_Class_3.var_63 ^= 3286104714651747328L) + ((Tester_Class_3)(new Tester_Class_0[var_72])[var_72]).var_61, Tester_Class_0.var_5 + Tester_Class_3.var_58);
+ while (var_73 < 2 && (false ? (Tester_Class_3.var_60 = new Tester_Class_1()) : (Tester_Class_1)(new Tester_Class_0[var_72])[var_72]).var_29)
+ {
+ ((Tester_Class_3)(Tester_Class_0)(new Object[var_72])[Tester_Class_3.var_58]).var_61 >>= ((new Tester_Class_4[var_72])[var_72]).var_67;
+ var_73++;
+ new String("blod");
+ --var_72;
+ }
+ ((new Tester_Class_4[Tester_Class_3.var_58][var_72])[new Tester_Class_3().var_61][Tester_Class_3.var_58]).var_69 = new Tester_Class_3();
+ float var_74 = (! ("dkcx".lastIndexOf(Tester_Class_1.var_5 >> - (var_72 >>>= 1433506903139345408L)) == Tester_Class_2.var_46) ? 'O' : 'e' - new Tester_Class_2().var_3) * ~ (var_72 ^= var_72);
+ Tester_Class_3.var_60 = !true ? new Tester_Class_1() : (new Tester_Class_1[Tester_Class_3.var_58])[var_72];
+ ((arg_0 &= Tester_Class_3.var_55 | (Tester_Class_3.var_60 = new Tester_Class_1()).var_29) ? (Tester_Class_3.var_60 = (Tester_Class_1)(new Tester_Class_1().var_31 = new Tester_Class_2())) : (Tester_Class_3.var_60 = (new Tester_Class_1[var_72])[Tester_Class_3.var_58])).var_31 = (new Tester_Class_3[var_72 |= 546982927])[Tester_Class_3.var_58];
+ long var_75 = 0L;
+ final double var_76 = +arg_1;
+ while (var_75 < 1)
+ {
+ short var_77;
+ var_75++;
+ new Tester_Class_3().var_57 = (false & true ? new Tester_Class_3() : new Tester_Class_3()).var_57;
+ (Tester_Class_3.var_60 = (new Tester_Class_1[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_31 = (new Tester_Class_2[Tester_Class_3.var_58][var_72])[var_72][var_72];
+ }
+ Tester_Class_3.var_64 *= (arg_0 ? (Tester_Class_3.var_55 ^= (arg_0 ^= arg_0)) & ! (Tester_Class_3.var_55 = arg_0) : arg_0) ^ new Tester_Class_1().var_29 ? ++((new Tester_Class_3[var_72][var_72])[(new byte[Tester_Class_3.var_58])[Tester_Class_3.var_58]][(((new Tester_Class_4[var_72][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_69 = (new Tester_Class_3[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_61]).var_57 : 'C';
+ long var_78;
+ var_74 %= (Tester_Class_3.var_55 |= (arg_0 = (arg_0 ^= (arg_0 &= !arg_0)))) ? new Tester_Class_3().var_61 : (Tester_Class_3.var_63 ^= var_72);
+ arg_1 /= (Tester_Class_2.var_46 &= 'W');
+ --(((new Tester_Class_4[var_72])[var_72]).var_69 = (((new Tester_Class_4[var_72])[var_72]).var_69 = new Tester_Class_3())).var_61;
+ return (new Tester_Class_1[var_72][Tester_Class_3.var_58])[var_72][new Tester_Class_3().var_61];
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_4.var_68 = "; result += Test6712835.Printer.print(var_68);
+ result += "\n";
+ result += "Tester_Class_4.var_66 = "; result += Test6712835.Printer.print(var_66);
+ result += "\n";
+ result += "Tester_Class_4.var_67 = "; result += Test6712835.Printer.print(var_67);
+ result += "\n";
+ result += "Tester_Class_4.var_70 = "; result += Test6712835.Printer.print(var_70);
+ result += "\n";
+ result += "Tester_Class_4.var_71 = "; result += Test6712835.Printer.print(var_71);
+ result += "\n";
+ result += "Tester_Class_4.var_69 = "; result += Test6712835.Printer.print(var_69);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Tester_Class_5 extends Tester_Class_0 {
+ static boolean var_81;
+ final int var_82 = 174395841;
+ int var_83;
+ byte var_84;
+ boolean var_85 = Tester_Class_3.var_55;
+ static boolean var_86 = Tester_Class_3.var_55;
+
+
+ public Tester_Class_5()
+ {
+ {
+ short var_87 = (new short[Tester_Class_3.var_58][var_84 = Tester_Class_3.var_58])[(((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_69 = (Tester_Class_3)(Tester_Class_0)(new Object[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_61][Tester_Class_3.var_58];
+ Tester_Class_4 var_88 = var_85 ^ (var_81 = false) ? (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58];
+ {
+ ++var_87;
+ }
+ short var_89;
+ (var_88.var_69 = (new Tester_Class_3[var_88.var_71][var_88.var_71])[var_88.var_71][var_88.var_71]).var_61 += (((Tester_Class_2)(new Tester_Class_1().var_31 = new Tester_Class_2())).var_3 = Tester_Class_3.var_58);
+ var_88 = var_88;
+ }
+ {
+ ++Tester_Class_2.var_46;
+ --Tester_Class_2.var_46;
+ }
+ {
+ Tester_Class_2.var_46++;
+ Tester_Class_3.var_64 /= Tester_Class_3.var_59;
+ ((Tester_Class_4)(new Object[Tester_Class_2.var_45 = Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71 %= (var_3 /= 3637233239489444864L);
+ ++Tester_Class_2.var_46;
+ }
+ new Tester_Class_3().var_57++;
+ var_85 &= (Tester_Class_3.var_55 |= false);
+ Tester_Class_3.var_60 = new Tester_Class_1();
+ Tester_Class_2.var_46++;
+ ((Tester_Class_3)(true ? (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58])).var_57 *= ((new Tester_Class_3[Tester_Class_3.var_58])[(byte)'`']).var_57;
+ var_3 += (int)Tester_Class_3.var_59 ^ (Tester_Class_2.var_46 -= Tester_Class_2.var_46) % ~((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71;
+ ++Tester_Class_2.var_46;
+ --Tester_Class_2.var_46;
+ var_83 = Tester_Class_3.var_58;
+ }
+
+
+
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_5.var_82 = "; result += Test6712835.Printer.print(var_82);
+ result += "\n";
+ result += "Tester_Class_5.var_83 = "; result += Test6712835.Printer.print(var_83);
+ result += "\n";
+ result += "Tester_Class_5.var_2 = "; result += Test6712835.Printer.print(var_2);
+ result += "\n";
+ result += "Tester_Class_5.var_3 = "; result += Test6712835.Printer.print(var_3);
+ result += "\n";
+ result += "Tester_Class_5.var_5 = "; result += Test6712835.Printer.print(var_5);
+ result += "\n";
+ result += "Tester_Class_5.var_84 = "; result += Test6712835.Printer.print(var_84);
+ result += "\n";
+ result += "Tester_Class_5.var_4 = "; result += Test6712835.Printer.print(var_4);
+ result += "\n";
+ result += "Tester_Class_5.var_1 = "; result += Test6712835.Printer.print(var_1);
+ result += "\n";
+ result += "Tester_Class_5.var_81 = "; result += Test6712835.Printer.print(var_81);
+ result += "\n";
+ result += "Tester_Class_5.var_85 = "; result += Test6712835.Printer.print(var_85);
+ result += "\n";
+ result += "Tester_Class_5.var_86 = "; result += Test6712835.Printer.print(var_86);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+class Tester_Class_6 extends Tester_Class_0 {
+ long var_90 = 8467263472031702016L;
+ final static int var_91 = 1648594448 * ']';
+ char var_92 = 'x';
+ short var_93 = Tester_Class_3.var_63;
+ Tester_Class_4 var_94;
+ String[] var_95;
+ static short var_96 = Tester_Class_3.var_63 -= 83376045 << 40225606;
+ final static double var_97 = 5.387227213380301E307;
+ final static short var_98 = Tester_Class_3.var_63 &= var_91;
+ byte var_99 = 44;
+
+
+ public Tester_Class_6()
+ {
+ (Tester_Class_3.var_60 = (Tester_Class_1)(new Object[Tester_Class_3.var_58][var_99])[Tester_Class_3.var_58][var_99]).var_31 = true | true ? (Tester_Class_5)(new Object[var_99])[Tester_Class_3.var_58] : (Tester_Class_5)(new Object[Tester_Class_3.var_58])[var_99];
+ var_92 &= 'p';
+ Tester_Class_5.var_81 = (((new Tester_Class_1[var_99][Tester_Class_3.var_58])[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_29;
+ {
+ {
+ ++Tester_Class_2.var_46;
+ Tester_Class_3.var_2 = var_98;
+ var_93 -= var_96;
+ }
+ Tester_Class_2.var_46--;
+ {
+ (var_5 == (((Tester_Class_3)(new Tester_Class_0[var_99])[Tester_Class_3.var_58]).var_61 /= var_5) ? "fsajxeuao".replace('s', 'K') : var_4).substring('e' >>> var_5).toLowerCase();
+ }
+ var_93 %= ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_90;
+ var_93 /= var_93;
+ if (Tester_Class_5.var_86)
+ {
+ (var_94 = (new Tester_Class_4[var_99])[var_99]).var_69 = (new Tester_Class_3[var_99])[var_99 %= -var_90];
+ }
+ else
+ {
+ --var_96;
+ }
+ var_93 *= 'O';
+ final long var_103 = 7573900518735055872L;
+ --Tester_Class_3.var_63;
+ }
+ Tester_Class_3.var_64 /= var_93;
+ if (true)
+ {
+ --Tester_Class_2.var_46;
+ Tester_Class_5 var_104;
+ final double var_105 = Tester_Class_3.var_64 += Tester_Class_5.var_86 & (new Tester_Class_2().var_1 & ((Tester_Class_3.var_55 = (var_1 ^= Tester_Class_5.var_86) & false) & (Tester_Class_5.var_81 = Tester_Class_5.var_86))) ? (byte)'g' : var_99;
+ Tester_Class_3.var_64 *= var_99;
+ }
+ else
+ {
+ char var_106 = var_92 -= Tester_Class_3.var_58;
+ }
+ double[] var_107 = ((new double[Tester_Class_3.var_58][var_99][var_99])[var_99])[false ? Tester_Class_3.var_58 : Tester_Class_3.var_58];
+ var_99 <<= (Tester_Class_3.var_63 >>= Tester_Class_3.var_58);
+ ++var_99;
+ }
+
+
+
+
+ final static byte func_0(final byte arg_0, final char arg_1, final Tester_Class_5[] arg_2)
+ {
+ ((Tester_Class_4)(new Object[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][arg_0]).var_69 = (Tester_Class_3)(new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58];
+ long var_100 = 0L;
+ Tester_Class_3.var_64 /= (Tester_Class_5.var_86 = true) || 'o' > (Tester_Class_3.var_63 -= (float)arg_0) ? var_98 : 1.7875238E38F;
+ do
+ {
+ Tester_Class_3.var_64 %= var_5;
+ var_100++;
+ Tester_Class_3.var_64 += var_96 + 'r';
+ } while (true && (var_100 < 1 && (new Tester_Class_1().var_29 ? new Tester_Class_1() : (new Tester_Class_1[arg_0][Tester_Class_3.var_58])[arg_0][Tester_Class_3.var_58]).var_29));
+ (Tester_Class_3.var_55 ^ (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1()))).var_29 ? new Tester_Class_3() : new Tester_Class_3()).var_57 = ((((new Tester_Class_6[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_94 = (((new Tester_Class_6[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][arg_0]).var_94 = (new Tester_Class_4[Tester_Class_3.var_58][arg_0])[Tester_Class_3.var_58][Tester_Class_3.var_58])).var_69 = new Tester_Class_3()).var_57;
+ final double var_101 = 1.6798216578519203E308;
+ Tester_Class_3.var_60 = (Tester_Class_3.var_60 = false ? new Tester_Class_1() : (Tester_Class_3.var_60 = new Tester_Class_1()));
+ Tester_Class_2 var_102 = new Tester_Class_2();
+ return Tester_Class_3.var_58;
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_6.var_92 = "; result += Test6712835.Printer.print(var_92);
+ result += "\n";
+ result += "Tester_Class_6.var_91 = "; result += Test6712835.Printer.print(var_91);
+ result += "\n";
+ result += "Tester_Class_6.var_95 = "; result += Test6712835.Printer.print(var_95);
+ result += "\n";
+ result += "Tester_Class_6.var_90 = "; result += Test6712835.Printer.print(var_90);
+ result += "\n";
+ result += "Tester_Class_6.var_2 = "; result += Test6712835.Printer.print(var_2);
+ result += "\n";
+ result += "Tester_Class_6.var_97 = "; result += Test6712835.Printer.print(var_97);
+ result += "\n";
+ result += "Tester_Class_6.var_3 = "; result += Test6712835.Printer.print(var_3);
+ result += "\n";
+ result += "Tester_Class_6.var_5 = "; result += Test6712835.Printer.print(var_5);
+ result += "\n";
+ result += "Tester_Class_6.var_93 = "; result += Test6712835.Printer.print(var_93);
+ result += "\n";
+ result += "Tester_Class_6.var_96 = "; result += Test6712835.Printer.print(var_96);
+ result += "\n";
+ result += "Tester_Class_6.var_98 = "; result += Test6712835.Printer.print(var_98);
+ result += "\n";
+ result += "Tester_Class_6.var_99 = "; result += Test6712835.Printer.print(var_99);
+ result += "\n";
+ result += "Tester_Class_6.var_4 = "; result += Test6712835.Printer.print(var_4);
+ result += "\n";
+ result += "Tester_Class_6.var_1 = "; result += Test6712835.Printer.print(var_1);
+ result += "\n";
+ result += "Tester_Class_6.var_94 = "; result += Test6712835.Printer.print(var_94);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+abstract class Tester_Class_7 {
+ final static char var_108 = '_';
+ static Tester_Class_3 var_109;
+ final short var_110 = 4360;
+ short var_111;
+ Object var_112;
+ Tester_Class_4 var_113;
+ static Tester_Class_5 var_114;
+ final short var_115 = Tester_Class_6.var_96;
+ final static float var_116 = Tester_Class_3.var_59;
+
+
+ public Tester_Class_7()
+ {
+ --Tester_Class_2.var_46;
+ --Tester_Class_6.var_96;
+ var_113 = (new Tester_Class_4[new Tester_Class_6().var_99])[Tester_Class_3.var_58];
+ --Tester_Class_2.var_46;
+ Tester_Class_6.var_96--;
+ Tester_Class_3.var_63 -= 'i';
+ if (!Tester_Class_5.var_86)
+ {
+ Tester_Class_3.var_64 %= var_116;
+ if ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_0)(var_112 = "yosyghjm"))).var_29)
+ {
+ Tester_Class_2.var_46++;
+ }
+ else
+ {
+ (var_114 = (var_114 = (Tester_Class_5)(Tester_Class_0)(var_112 = "bxt"))).var_83 = (Tester_Class_2.var_45 = (Tester_Class_2.var_45 = Tester_Class_3.var_58));
+ }
+ var_114 = (var_114 = (var_114 = (var_114 = (var_114 = (var_114 = (Tester_Class_5)(var_112 = "blrobgg"))))));
+ var_113 = (((Tester_Class_6)(var_112 = "popebwfp")).var_94 = (new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]);
+ }
+ else
+ {
+ Tester_Class_3.var_60 = new Tester_Class_1();
+ }
+ final Tester_Class_6 var_122 = new Tester_Class_6();
+ var_122.var_92 &= (var_122.var_92 |= var_108);
+ ((new Tester_Class_5[var_122.var_99])[((new Tester_Class_3[Tester_Class_3.var_58])[var_122.var_99--]).var_61]).var_83 = 1708230145;
+ }
+
+
+
+ public boolean equals(Object obj)
+ {
+ (((Tester_Class_5.var_81 = (Tester_Class_5.var_81 = false)) ? (Tester_Class_3.var_55 &= false) : !Tester_Class_3.var_55 & ((Tester_Class_1)obj).var_29) ? (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58] : (Tester_Class_2)obj).equals((Tester_Class_5.var_86 |= Tester_Class_3.var_55) | (Tester_Class_3.var_55 = Tester_Class_3.var_55) ? obj : (Tester_Class_6)(Tester_Class_0)obj);
+ Tester_Class_3.var_64 *= 2.8258473339654136E307;
+ {
+ final int var_118 = 1248523063;
+ short var_119 = 30906;
+ Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)obj);
+ ((Tester_Class_6)(((Tester_Class_1)obj).var_31 = ((var_113 = (Tester_Class_4)obj).var_69 = (Tester_Class_3)obj))).var_94 = (var_113 = (Tester_Class_4)(var_112 = (Tester_Class_1)obj));
+ }
+ final Tester_Class_1 var_120 = false ^ (((Tester_Class_1)obj).var_1 = !true) ^ (((Tester_Class_6)(Tester_Class_0)obj).var_92 *= (((Tester_Class_3)obj).var_57 |= (Tester_Class_2.var_46 >>= 6986775136305733632L))) < (byte)Tester_Class_6.var_97 ? (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)obj)) : (true ? (Tester_Class_1)obj : (Tester_Class_1)obj);
+ (var_114 = (var_114 = (Tester_Class_5)obj)).var_83 = (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_92 &= ((Tester_Class_4)obj).var_70 << (Tester_Class_2.var_45 = Tester_Class_3.var_58));
+ var_114 = (Tester_Class_5)obj;
+ obj = ((Tester_Class_3.var_60 = var_120).var_29 ? false : false) ? (new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58] : obj;
+ (var_120.var_29 ? (Tester_Class_6)(obj = (Tester_Class_3.var_60 = var_120)) : (new Tester_Class_6[Tester_Class_3.var_58])[((Tester_Class_3)obj).var_61 ^= Tester_Class_6.var_91]).var_90 ^= 2127530040436251648L;
+ Object var_121;
+ return (new boolean[Tester_Class_3.var_58])[((var_113 = (Tester_Class_4)obj).var_69 = (var_109 = (new Tester_Class_3[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58])).var_61];
+ }
+
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_7.var_108 = "; result += Test6712835.Printer.print(var_108);
+ result += "\n";
+ result += "Tester_Class_7.var_116 = "; result += Test6712835.Printer.print(var_116);
+ result += "\n";
+ result += "Tester_Class_7.var_110 = "; result += Test6712835.Printer.print(var_110);
+ result += "\n";
+ result += "Tester_Class_7.var_111 = "; result += Test6712835.Printer.print(var_111);
+ result += "\n";
+ result += "Tester_Class_7.var_115 = "; result += Test6712835.Printer.print(var_115);
+ result += "\n";
+ result += "Tester_Class_7.var_114 = "; result += Test6712835.Printer.print(var_114);
+ result += "\n";
+ result += "Tester_Class_7.var_113 = "; result += Test6712835.Printer.print(var_113);
+ result += "\n";
+ result += "Tester_Class_7.var_109 = "; result += Test6712835.Printer.print(var_109);
+ result += "\n";
+ result += "Tester_Class_7.var_112 = "; result += Test6712835.Printer.print(var_112);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+class Tester_Class_8 extends Tester_Class_7 {
+ static char var_123;
+ Tester_Class_4 var_124;
+ static short var_125;
+
+
+ public Tester_Class_8()
+ {
+ {
+ Tester_Class_3.var_64 -= (Tester_Class_2.var_46 *= Tester_Class_3.var_64);
+ {
+ Tester_Class_2.var_46--;
+ }
+ ++Tester_Class_3.var_63;
+ Tester_Class_5.var_86 |= true;
+ Tester_Class_6.var_96--;
+ }
+ "w".indexOf(312689020);
+ if (false)
+ {
+ (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_83 = 'I';
+ }
+ else
+ {
+ --Tester_Class_6.var_96;
+ }
+ switch (Tester_Class_5.var_86 ? Tester_Class_3.var_58 : Tester_Class_3.var_58)
+ {
+ case 95:
+
+ case 35:
+
+ }
+ Tester_Class_6.var_96--;
+ Tester_Class_3.var_64 *= 4.516167673347119E307;
+ --Tester_Class_3.var_63;
+ {
+ int var_126;
+ }
+ Tester_Class_3.var_60 = new Tester_Class_1();
+ Tester_Class_2.var_46++;
+ ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_99 &= Tester_Class_6.var_91;
+ ((new Tester_Class_1[((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_71])[((Tester_Class_3)(var_112 = "fsmtm")).var_61]).var_31 = (Tester_Class_2)(new Tester_Class_0[Tester_Class_3.var_58])[Tester_Class_3.var_58];
+ }
+
+
+
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_8.var_108 = "; result += Test6712835.Printer.print(var_108);
+ result += "\n";
+ result += "Tester_Class_8.var_123 = "; result += Test6712835.Printer.print(var_123);
+ result += "\n";
+ result += "Tester_Class_8.var_116 = "; result += Test6712835.Printer.print(var_116);
+ result += "\n";
+ result += "Tester_Class_8.var_110 = "; result += Test6712835.Printer.print(var_110);
+ result += "\n";
+ result += "Tester_Class_8.var_111 = "; result += Test6712835.Printer.print(var_111);
+ result += "\n";
+ result += "Tester_Class_8.var_115 = "; result += Test6712835.Printer.print(var_115);
+ result += "\n";
+ result += "Tester_Class_8.var_125 = "; result += Test6712835.Printer.print(var_125);
+ result += "\n";
+ result += "Tester_Class_8.var_114 = "; result += Test6712835.Printer.print(var_114);
+ result += "\n";
+ result += "Tester_Class_8.var_113 = "; result += Test6712835.Printer.print(var_113);
+ result += "\n";
+ result += "Tester_Class_8.var_124 = "; result += Test6712835.Printer.print(var_124);
+ result += "\n";
+ result += "Tester_Class_8.var_109 = "; result += Test6712835.Printer.print(var_109);
+ result += "\n";
+ result += "Tester_Class_8.var_112 = "; result += Test6712835.Printer.print(var_112);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Tester_Class_9 {
+ final static String var_127 = "pxk";
+ Tester_Class_2 var_128;
+ final static char var_129 = '\\';
+ static float var_130;
+ static boolean var_131;
+ final static float var_132 = Tester_Class_3.var_59;
+ static Tester_Class_0 var_133;
+ boolean[] var_134;
+
+
+ public Tester_Class_9()
+ {
+ Tester_Class_2.var_44 -= Tester_Class_3.var_58;
+ Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (new Tester_Class_1[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]));
+ {
+ Tester_Class_8 var_136;
+ }
+ ++Tester_Class_2.var_46;
+ Tester_Class_6.var_96--;
+ var_128 = (var_128 = (var_128 = (Tester_Class_2)(var_133 = (new Tester_Class_1[Tester_Class_3.var_58])[Tester_Class_3.var_58])));
+ ++Tester_Class_6.var_96;
+ ++Tester_Class_2.var_46;
+ Tester_Class_4 var_137;
+ var_128 = (var_128 = (new Tester_Class_2[Tester_Class_3.var_58])[Tester_Class_3.var_58]);
+ (Tester_Class_8.var_114 = (Tester_Class_8.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[Tester_Class_3.var_58])).var_83 = (((new Tester_Class_4[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_69 = (new Tester_Class_3[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58]).var_57++;
+ Tester_Class_2.var_46++;
+ }
+
+
+
+
+ protected static short func_1()
+ {
+ {
+ Tester_Class_3.var_63--;
+ }
+ Tester_Class_3.var_64 *= Tester_Class_2.var_46;
+ short var_135;
+ Tester_Class_3.var_64 -= Tester_Class_6.var_96;
+ return new Tester_Class_6().var_93;
+ }
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_9.var_129 = "; result += Test6712835.Printer.print(var_129);
+ result += "\n";
+ result += "Tester_Class_9.var_134 = "; result += Test6712835.Printer.print(var_134);
+ result += "\n";
+ result += "Tester_Class_9.var_130 = "; result += Test6712835.Printer.print(var_130);
+ result += "\n";
+ result += "Tester_Class_9.var_132 = "; result += Test6712835.Printer.print(var_132);
+ result += "\n";
+ result += "Tester_Class_9.var_131 = "; result += Test6712835.Printer.print(var_131);
+ result += "\n";
+ result += "Tester_Class_9.var_127 = "; result += Test6712835.Printer.print(var_127);
+ result += "\n";
+ result += "Tester_Class_9.var_128 = "; result += Test6712835.Printer.print(var_128);
+ result += "\n";
+ result += "Tester_Class_9.var_133 = "; result += Test6712835.Printer.print(var_133);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+final class Tester_Class_10 extends Tester_Class_0 {
+ final static byte var_138 = 78;
+ Object var_139;
+ final static boolean var_140 = true;
+ float var_141 = 1.2816267E38F;
+ Tester_Class_8 var_142;
+ static Tester_Class_3 var_143;
+ short var_144 = var_1 ? (Tester_Class_6.var_96 &= 8024552544994698240L) : Tester_Class_0.var_5;
+ final boolean var_145 = var_140;
+ long var_146;
+ float[] var_147;
+
+
+ public Tester_Class_10()
+ {
+ "xuc".codePointCount(new Tester_Class_6().var_99 / ((new Tester_Class_9().var_128 = new Tester_Class_2()).var_1 ? var_138 : (int)(Tester_Class_3.var_64 += Tester_Class_3.var_64)), 882345740);
+ Tester_Class_3.var_64 /= Tester_Class_9.var_132;
+ Tester_Class_9.var_127.indexOf((Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)(var_139 = "mcyagebtv"))).var_83 = var_145 ? (Tester_Class_2.var_45 = Tester_Class_3.var_58) : Tester_Class_6.var_96);
+ --Tester_Class_2.var_46;
+ final float var_148 = 3.0263434E38F;
+ ((Tester_Class_7.var_114 = (Tester_Class_5)(Tester_Class_9.var_133 = new Tester_Class_1())).var_85 & ((Tester_Class_1)(var_139 = new Tester_Class_6())).var_1 ? "gmxwrgik" : Tester_Class_9.var_127).compareTo(var_4);
+ --Tester_Class_2.var_46;
+ new Tester_Class_6();
+ ++Tester_Class_2.var_46;
+ Tester_Class_3.var_60 = Tester_Class_5.var_86 ? new Tester_Class_1() : new Tester_Class_1();
+ {
+ --Tester_Class_6.var_96;
+ ((Tester_Class_7)(var_139 = new Tester_Class_1().var_4)).var_112 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(var_139 = "gugsy")));
+ }
+ Tester_Class_9.var_133 = (Tester_Class_3.var_60 = new Tester_Class_1());
+ if (var_140 & !var_140)
+ {
+ Tester_Class_6.var_96++;
+ }
+ else
+ {
+ Tester_Class_2.var_46++;
+ }
+ {
+ ++new Tester_Class_6().var_92;
+ }
+ Tester_Class_7.var_109 = (((new Tester_Class_4[Tester_Class_3.var_58])[Tester_Class_3.var_58]).var_69 = (var_143 = new Tester_Class_3()));
+ Tester_Class_3.var_63--;
+ }
+
+
+
+
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Tester_Class_10.var_147 = "; result += Test6712835.Printer.print(var_147);
+ result += "\n";
+ result += "Tester_Class_10.var_146 = "; result += Test6712835.Printer.print(var_146);
+ result += "\n";
+ result += "Tester_Class_10.var_3 = "; result += Test6712835.Printer.print(var_3);
+ result += "\n";
+ result += "Tester_Class_10.var_141 = "; result += Test6712835.Printer.print(var_141);
+ result += "\n";
+ result += "Tester_Class_10.var_5 = "; result += Test6712835.Printer.print(var_5);
+ result += "\n";
+ result += "Tester_Class_10.var_144 = "; result += Test6712835.Printer.print(var_144);
+ result += "\n";
+ result += "Tester_Class_10.var_138 = "; result += Test6712835.Printer.print(var_138);
+ result += "\n";
+ result += "Tester_Class_10.var_1 = "; result += Test6712835.Printer.print(var_1);
+ result += "\n";
+ result += "Tester_Class_10.var_140 = "; result += Test6712835.Printer.print(var_140);
+ result += "\n";
+ result += "Tester_Class_10.var_145 = "; result += Test6712835.Printer.print(var_145);
+ result += "\n";
+ result += "Tester_Class_10.var_139 = "; result += Test6712835.Printer.print(var_139);
+ result += "\n";
+ result += "Tester_Class_10.var_142 = "; result += Test6712835.Printer.print(var_142);
+ result += "\n";
+ result += "Tester_Class_10.var_2 = "; result += Test6712835.Printer.print(var_2);
+ result += "\n";
+ result += "Tester_Class_10.var_4 = "; result += Test6712835.Printer.print(var_4);
+ result += "\n";
+ result += "Tester_Class_10.var_143 = "; result += Test6712835.Printer.print(var_143);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+}
+
+
+interface Tester_Interface_11 {
+ public Tester_Class_4 func_0(final int arg_0, final byte arg_1);
+ public Tester_Class_2 func_1(Tester_Class_5 arg_0, final Tester_Class_0 arg_1, final int arg_2);
+}
+
+public class Test6712835 {
+ final boolean var_149 = false;
+ Tester_Class_8 var_150;
+ final long var_151 = 8058077687473630208L;
+
+
+ protected final Tester_Class_1 func_0(final Object arg_0, Tester_Class_3 arg_1, final Tester_Class_4 arg_2, int arg_3)
+ {
+ Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0));
+ --Tester_Class_3.var_63;
+ (var_150 = (((new Tester_Class_10[arg_2.var_71])[(((Tester_Class_6)arg_0).var_94 = arg_2).var_71 &= Tester_Class_3.var_63 << ~arg_2.var_71]).var_142 = (var_150 = (((Tester_Class_10)arg_0).var_142 = (Tester_Class_8)arg_0)))).var_113 = arg_2;
+ Tester_Class_7.var_114 = (Tester_Class_7.var_114 = false ? (Tester_Class_5)arg_0 : (Tester_Class_5)arg_0);
+ ((((arg_1 = arg_1).var_1 |= "lgcrda".equalsIgnoreCase("ontlkst")) ? (Tester_Class_1)arg_0 : (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)).var_29 ? (arg_1 = (Tester_Class_3)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_9)arg_0)) : arg_1).var_57 >>>= ']';
+ Tester_Class_8.var_114 = (Tester_Class_5)arg_0;
+ ((Tester_Class_3.var_55 &= (arg_1.var_1 = true)) ? (Tester_Class_6)(new Tester_Class_0[Tester_Class_3.var_58][Tester_Class_10.var_138])[Tester_Class_10.var_138][Tester_Class_10.var_138] : (Tester_Class_6)arg_0).var_94 = arg_2;
+ {
+ Tester_Class_3.var_55 &= ((Tester_Class_3.var_60 = new Tester_Class_1()).var_1 &= false);
+ Tester_Class_2.var_44 -= (arg_3 |= + ~6610561718704644096L);
+ ((Tester_Class_8)arg_0).var_113 = ((((Tester_Class_10)(Tester_Class_0)arg_0).var_142 = (var_150 = (Tester_Class_8)arg_0)).var_124 = arg_2);
+ (! (false | Tester_Class_5.var_86) ? (Tester_Class_10)arg_0 : (new Tester_Class_10[arg_1.var_61][arg_1.var_61])[Tester_Class_10.var_138][Tester_Class_10.var_138]).var_139 = ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)).var_31 = (((Tester_Class_9)arg_0).var_128 = (((Tester_Class_9)arg_0).var_128 = (Tester_Class_2)arg_0)));
+ }
+ final Tester_Interface_11 var_152 = !((Tester_Class_1)arg_0).var_29 ^ Tester_Class_5.var_86 ? (new Tester_Interface_11[arg_2.var_71][arg_1.var_61])[arg_1.var_61][arg_1.var_61] : (new Tester_Interface_11[arg_2.var_71][arg_2.var_71])[Tester_Class_10.var_138][Tester_Class_3.var_58];
+ Tester_Class_3.var_64 /= (arg_3 >>= ++((Tester_Class_6)(Tester_Class_0)arg_0).var_92) * Tester_Class_9.var_132;
+ Tester_Class_0 var_153 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0))))).var_31 = (((new Tester_Class_9[arg_1.var_61])[arg_1.var_61 *= 634692606]).var_128 = !false ? (Tester_Class_2)arg_0 : (Tester_Class_2)arg_0);
+ (Tester_Class_10.var_140 ? (Tester_Class_7)arg_0 : (var_150 = (Tester_Class_8)(Tester_Class_7)arg_0)).var_112 = Tester_Class_3.var_64 != ((((Tester_Class_10)(var_153 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0))).var_1 |= arg_1.var_1) ? (Tester_Class_6)var_153 : (Tester_Class_6)var_153).var_99-- ? (Tester_Class_7)((var_150 = (Tester_Class_8)arg_0).var_112 = (Tester_Class_10)var_153) : (Tester_Class_7)arg_0;
+ (((new Tester_Class_7[Tester_Class_10.var_138][arg_2.var_71])[Tester_Class_3.var_58])[arg_2.var_71]).var_112 = arg_0;
+ if (!false)
+ {
+ arg_3 <<= (Tester_Class_2.var_46 /= - ((byte)((Tester_Class_10)arg_0).var_144)) - ((Tester_Class_6)arg_0).var_99;
+ }
+ else
+ {
+ ((Tester_Class_7)(((Tester_Class_8)arg_0).var_112 = var_153)).var_113 = arg_2;
+ ((Tester_Class_9)arg_0).var_128 = (((Tester_Class_9)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_7)arg_0)).var_128 = (((Tester_Class_9)arg_0).var_128 = (Tester_Class_2)arg_0));
+ }
+ (((Tester_Class_10)arg_0).var_142 = (Tester_Class_8)arg_0).var_124 = (((Tester_Class_6)var_153).var_94 = arg_2);
+ final char var_154 = arg_1.var_57 %= ((Tester_Class_6)var_153).var_93--;
+ (true ? arg_1 : (arg_1 = arg_1)).equals(arg_0);
+ (Tester_Class_10.var_140 ? (new Tester_Class_6[Tester_Class_10.var_138])[arg_2.var_71] : (new Tester_Class_6[(Tester_Class_10.var_143 = arg_1).var_61])[arg_1.var_61]).var_94 = ((((new Tester_Class_7[arg_2.var_71][arg_1.var_61][Tester_Class_10.var_138])[Tester_Class_10.var_138])[arg_2.var_71 = arg_2.var_71][Tester_Class_10.var_138]).var_113 = (((Tester_Class_7)arg_0).var_113 = arg_2));
+ Tester_Class_3.var_60 = ((Tester_Class_10)(((Tester_Class_7)arg_0).var_112 = (Tester_Class_7)(((Tester_Class_10)var_153).var_139 = new Tester_Class_6[Tester_Class_10.var_138][Tester_Class_10.var_138]))).var_1 ? (Tester_Class_3.var_60 = (Tester_Class_1)var_153) : (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_9.var_133 = (Tester_Class_10)arg_0)));
+ ((Tester_Class_7)(((Tester_Class_10)arg_0).var_139 = new Tester_Class_10[Tester_Class_3.var_58][--arg_2.var_71])).var_112 = new byte[(((Tester_Class_8)(Tester_Class_7)((var_150 = (var_150 = (Tester_Class_8)arg_0)).var_112 = arg_2)).var_113 = (((Tester_Class_7)arg_0).var_113 = arg_2)).var_71];
+ Tester_Class_8 var_155;
+ (Tester_Class_3.var_55 & arg_2.equals(arg_0) ? (Tester_Class_10)var_153 : (Tester_Class_10)var_153).var_3 %= Tester_Class_6.var_91;
+ return ((Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)var_153)))).var_29 ? ! !true : Tester_Class_10.var_140 | Tester_Class_3.var_55) || Tester_Class_3.var_55 ? (Tester_Class_3.var_60 = (Tester_Class_1)(((Tester_Class_10)var_153).var_139 = (Tester_Class_6)var_153)) : new Tester_Class_1();
+ }
+
+ protected Tester_Class_5 func_1(Tester_Class_0 arg_0, final float arg_1)
+ {
+ (!Tester_Class_10.var_140 ? (Tester_Class_6)arg_0 : (Tester_Class_6)arg_0).var_90 /= ((Tester_Class_8.var_109 = (new boolean[Tester_Class_10.var_138][Tester_Class_3.var_58])[((Tester_Class_6)arg_0).var_99][Tester_Class_10.var_138] ? (Tester_Class_3)((Tester_Class_3.var_60 = (Tester_Class_1)arg_0).var_31 = (Tester_Class_6)arg_0) : (Tester_Class_3)arg_0).var_61 *= Tester_Class_3.var_58);
+ {
+ "".toLowerCase();
+ }
+ ((Tester_Class_10)arg_0).var_139 = new Tester_Class_8();
+ arg_0 = (new Tester_Class_6[((Tester_Class_6)arg_0).var_99])[Tester_Class_3.var_58];
+ if (((Tester_Class_10)(arg_0 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)arg_0)))).var_145)
+ {
+ Tester_Class_3.var_63++;
+ }
+ else
+ {
+ ++Tester_Class_2.var_46;
+ }
+ (((Tester_Class_3.var_55 ^= Tester_Class_3.var_55 ^ true) ? (Tester_Class_10)arg_0 : (Tester_Class_10)arg_0).var_145 || true ? (Tester_Class_6)arg_0 : (Tester_Class_6)(((Tester_Class_7)(((Tester_Class_10)arg_0).var_139 = (Tester_Class_10)arg_0)).var_112 = "jlixai")).var_99--;
+ Tester_Class_5.var_81 = Tester_Class_3.var_55 && ! (arg_0.var_1 = arg_0.var_1);
+ {
+ ((new Tester_Class_6[Tester_Class_3.var_58])[(true ? (Tester_Class_6)(Tester_Class_9.var_133 = (Tester_Class_10)arg_0) : (Tester_Class_6)(((Tester_Class_1)arg_0).var_31 = (Tester_Class_10)arg_0)).var_99]).var_90 *= (Tester_Class_3.var_64 %= Tester_Class_3.var_63);
+ }
+ ++Tester_Class_2.var_46;
+ Tester_Class_0 var_156;
+ Tester_Class_2.var_46++;
+ Tester_Class_8.var_114 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0));
+ Tester_Class_6.func_2((Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (Tester_Class_5)arg_0))).var_83 = (byte)(((Tester_Class_10)arg_0).var_142 = (new Tester_Class_8[Tester_Class_3.var_58][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_10.var_138]).var_110, Tester_Class_6.var_96, (new byte[Tester_Class_3.var_58])[Tester_Class_10.var_138]);
+ Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_10.var_138])[((Tester_Class_3)arg_0).var_61];
+ boolean var_157 = Tester_Class_10.var_140;
+ (Tester_Class_3.var_60 = (Tester_Class_1)arg_0).var_1 ^= Tester_Class_10.var_140;
+ return Tester_Class_8.var_114 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)arg_0));
+ }
+
+ final static int func_2(Tester_Class_6 arg_0)
+ {
+ new Tester_Class_9();
+ {
+ ++Tester_Class_3.var_63;
+ }
+ new Tester_Class_3().var_57--;
+ Tester_Class_1 var_158;
+ String var_159;
+ --Tester_Class_6.var_96;
+ {
+ new String();
+ }
+ var_159 = (var_159 = arg_0.var_4);
+ {
+ --Tester_Class_2.var_46;
+ }
+ final double var_160 = (Tester_Class_7.var_114 = (Tester_Class_8.var_114 = (Tester_Class_8.var_114 = (Tester_Class_5)(new Tester_Class_0[arg_0.var_99][arg_0.var_99])[Tester_Class_3.var_58][Tester_Class_3.var_58]))).var_1 ? Tester_Class_9.var_132 : Tester_Class_6.var_97;
+ Tester_Class_8 var_161;
+ char var_162 = 'O';
+ Tester_Class_2.var_46++;
+ Tester_Class_6.var_96++;
+ {
+ new String();
+ }
+ ++Tester_Class_6.var_96;
+ var_162 >>= ((new Tester_Class_4[arg_0.var_99])[arg_0.var_99++]).var_70 >> Tester_Class_6.var_91;
+ (Tester_Class_7.var_114 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_3.var_58])[++arg_0.var_99])).var_83 = (arg_0.var_93 <<= Tester_Class_7.var_108);
+ --Tester_Class_6.var_96;
+ {
+ new Tester_Class_9().var_128 = new Tester_Class_2();
+ }
+ arg_0 = arg_0;
+ {
+ Tester_Class_9 var_163;
+ }
+ ((Tester_Class_5)(Tester_Class_9.var_133 = arg_0)).var_83 = (arg_0.var_99 >>= Tester_Class_5.var_5);
+ arg_0.var_99 = Tester_Class_10.var_138;
+ Tester_Class_3.var_60 = (var_158 = (Tester_Class_3.var_60 = (Tester_Class_1)(Tester_Class_9.var_133 = arg_0)));
+ return Tester_Class_6.var_91;
+ }
+
+ protected final Tester_Class_9 func_3()
+ {
+ Tester_Class_2.var_44 = 3210658399310388224L;
+ ++Tester_Class_6.var_96;
+ short var_164 = 15978;
+ var_164++;
+ Tester_Class_5.var_81 = true;
+ return Tester_Class_3.var_55 ? new Tester_Class_9() : new Tester_Class_9();
+ }
+
+ final static Tester_Class_10 func_4(Tester_Class_3 arg_0, String arg_1, final byte[] arg_2, final Object arg_3)
+ {
+ Tester_Class_1 var_165;
+ Tester_Class_3.var_63 += new Tester_Class_6().var_92 >= 3821095133162842112L ? (arg_0.var_61 |= Tester_Class_6.var_91) : Tester_Class_10.var_138;
+ return false ? ((var_165 = (Tester_Class_1)arg_3).var_29 ? (Tester_Class_10)arg_3 : (Tester_Class_10)arg_3) : (Tester_Class_10)(Tester_Class_0)arg_3;
+ }
+
+ private static Object func_7(final short arg_0, String arg_1, final Tester_Class_3 arg_2)
+ {
+ Tester_Class_3.var_60 = (new Tester_Class_1[arg_2.var_61])[Tester_Class_10.var_138];
+ return ((new Tester_Class_7[arg_2.var_61 |= Tester_Class_3.var_63])[arg_2.var_61 *= Tester_Class_6.var_98]).var_112 = new Tester_Class_8();
+ }
+
+ public static String execute()
+ {
+ try {
+ Test6712835 t = new Test6712835();
+ try { t.test(); }
+ catch(Throwable e) { }
+ try { return t.toString(); }
+ catch (Throwable e) { return "Error during result conversion to String"; }
+ } catch (Throwable e) { return "Error during test execution"; }
+ }
+
+ public static void main(String[] args)
+ {
+ try {
+ Test6712835 t = new Test6712835();
+ try { t.test(); }
+ catch(Throwable e) { }
+ try { System.out.println(t); }
+ catch(Throwable e) { }
+ } catch (Throwable e) { }
+ }
+
+ private void test()
+ {
+ Tester_Class_3.var_60 = true ? (Tester_Class_3.var_60 = new Tester_Class_1()) : new Tester_Class_1();
+ double var_170 = 0;
+ Tester_Class_9.var_133 = (new Tester_Class_4().var_69 = new Tester_Class_3());
+ new Tester_Class_6();
+ String var_171;
+ new Tester_Class_9();
+ do
+ {
+ new String();
+ var_170++;
+ Tester_Class_3.var_64 = 1.0240330514364089E307;
+ new String();
+ var_171 = (var_171 = Tester_Class_9.var_127);
+ Tester_Class_3.var_63--;
+ } while (var_170 < 525);
+ ((new Tester_Class_10[Tester_Class_10.var_138])[Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_142 = (Tester_Class_8)(Tester_Class_7)(new Tester_Class_10().var_139 = new Tester_Class_2());
+ long var_172 = 0L;
+ Tester_Class_3.var_64 /= (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_99 ^= ((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_90) > 9.462466046830147E307 ? new Tester_Class_6().var_99 : Tester_Class_3.var_58;
+ short var_173;
+ (true ? new Tester_Class_2() : (func_3().var_128 = new Tester_Class_2())).var_3 *= (var_150 = new Tester_Class_8()).var_115;
+ (Tester_Class_3.var_60 = new Tester_Class_1()).var_31 = (((new Tester_Class_9[Tester_Class_3.var_58])[Tester_Class_10.var_138]).var_128 = (func_3().var_128 = (func_3().var_128 = (new Tester_Class_9().var_128 = new Tester_Class_2()))));
+ for (((new Tester_Class_10[new Tester_Class_6().var_99])[new Tester_Class_6().var_99++]).var_142 = (new Tester_Class_8[Tester_Class_10.var_138])[Tester_Class_3.var_58]; var_172 < 203 && (Tester_Class_3.var_55 &= (new boolean[Tester_Class_2.var_45 = Tester_Class_3.var_58])[Tester_Class_10.var_138]); Tester_Class_9.var_133 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_2.var_45 = Tester_Class_10.var_138][Tester_Class_10.var_138])[Tester_Class_3.var_58][Tester_Class_2.var_45 = Tester_Class_3.var_58]))
+ {
+ var_171 = Tester_Class_9.var_127;
+ var_172++;
+ Tester_Class_3.var_63++;
+ Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_1)(new Object[Tester_Class_3.var_58][Tester_Class_10.var_138])[Tester_Class_3.var_58][Tester_Class_3.var_58])));
+ ++Tester_Class_2.var_46;
+ Tester_Class_2.var_46--;
+ Tester_Class_3.var_64 -= Tester_Class_3.var_58;
+ }
+ (Tester_Class_3.var_60 = new Tester_Class_1()).var_31 = ((new Tester_Class_8().var_124 = new Tester_Class_4()).var_69 = new Tester_Class_3());
+ int var_174 = 0;
+ ((new Tester_Class_6[Tester_Class_10.var_138][Tester_Class_10.var_138])[Tester_Class_2.var_45 = Tester_Class_10.var_138][Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_92 = 'Z';
+ while ((Tester_Class_9.var_131 = Tester_Class_3.var_55) && (var_174 < 24 && !true))
+ {
+ new Tester_Class_10();
+ var_174++;
+ Tester_Class_3.var_64 %= (((new Tester_Class_6[Tester_Class_3.var_58])[Tester_Class_2.var_45 = Tester_Class_3.var_58]).var_93 ^= (byte)Tester_Class_3.var_59);
+ ((Tester_Class_10)(Tester_Class_9.var_133 = (new Tester_Class_5[((Tester_Class_6)(new Tester_Class_0[Tester_Class_10.var_138])[(byte)(Tester_Class_2.var_46 >>>= Tester_Class_7.var_108)]).var_99])[Tester_Class_10.var_138])).var_139 = (new Tester_Class_10[new Tester_Class_6().var_99][new Tester_Class_4().var_71])[new Tester_Class_4().var_71];
+ }
+ int var_175 = 0;
+ (Tester_Class_10.var_140 ? (Tester_Class_2)(Tester_Class_9.var_133 = (Tester_Class_7.var_114 = (new Tester_Class_5[Tester_Class_10.var_138])[Tester_Class_10.var_138])) : new Tester_Class_2()).var_1 &= Tester_Class_3.var_55;
+ do
+ {
+ Tester_Class_10.var_143 = new Tester_Class_3();
+ var_175++;
+ ++Tester_Class_2.var_46;
+ } while ((false ? true : var_149) | !Tester_Class_10.var_140 && var_175 < 97);
+ Tester_Class_9.var_131 = true;
+ (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = (Tester_Class_3.var_60 = new Tester_Class_1())))).var_1 &= (((new Tester_Class_10().var_1 = !true) ? new Tester_Class_10() : new Tester_Class_10()).var_145 ? new Tester_Class_3() : new Tester_Class_3()).var_1;
+ (true ? func_3() : func_3()).var_128 = ((((Tester_Class_5.var_86 = (Tester_Class_3.var_55 &= !var_149)) ? new Tester_Class_10() : new Tester_Class_10()).var_145 ? new Tester_Class_9() : func_3()).var_128 = var_149 ? new Tester_Class_2() : new Tester_Class_2());
+ Tester_Class_3.var_59 -= (Tester_Class_5.var_81 = new Tester_Class_1().var_29) ^ !true ? 7920143378515332096L : new Tester_Class_6().var_92;
+ ((Tester_Class_3.var_60 = new Tester_Class_1()).var_1 ? (new Tester_Class_5[Tester_Class_10.var_138][Tester_Class_3.var_58])[Tester_Class_3.var_58][Tester_Class_3.var_58] : (Tester_Class_8.var_114 = new Tester_Class_5())).var_83 = Tester_Class_10.var_140 ? (Tester_Class_3.var_63 -= 2.0167496E38F) : ++Tester_Class_3.var_63;
+ double var_176 = 9.327780852480363E307;
+ }
+ public String toString()
+ {
+ String result = "[\n";
+ result += "Test6712835.var_151 = "; result += Printer.print(var_151);
+ result += "\n";
+ result += "Test6712835.var_149 = "; result += Printer.print(var_149);
+ result += "\n";
+ result += "Test6712835.var_150 = "; result += Printer.print(var_150);
+ result += "";
+ result += "\n]";
+ return result;
+ }
+ static class Printer
+ {
+ public static String print(boolean arg) { return String.valueOf(arg); }
+ public static String print(byte arg) { return String.valueOf(arg); }
+ public static String print(short arg) { return String.valueOf(arg); }
+ public static String print(char arg) { return String.valueOf((int)arg); }
+ public static String print(int arg) { return String.valueOf(arg); }
+ public static String print(long arg) { return String.valueOf(arg); }
+ public static String print(float arg) { return String.valueOf(arg); }
+ public static String print(double arg) { return String.valueOf(arg); }
+
+
+ public static String print(Object arg)
+ {
+ return print_r(new java.util.Stack(), arg);
+ }
+
+ private static String print_r(java.util.Stack visitedObjects, Object arg)
+ {
+ String result = "";
+ if (arg == null)
+ result += "null";
+ else
+ if (arg.getClass().isArray())
+ {
+ for (int i = 0; i < visitedObjects.size(); i++)
+ if (visitedObjects.elementAt(i) == arg) return "<recursive>";
+
+ visitedObjects.push(arg);
+
+ final String delimiter = ", ";
+ result += "[";
+
+ if (arg instanceof Object[])
+ {
+ Object[] array = (Object[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print_r(visitedObjects, array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof boolean[])
+ {
+ boolean[] array = (boolean[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof byte[])
+ {
+ byte[] array = (byte[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof short[])
+ {
+ short[] array = (short[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof char[])
+ {
+ char[] array = (char[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof int[])
+ {
+ int[] array = (int[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof long[])
+ {
+ long[] array = (long[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof float[])
+ {
+ float[] array = (float[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+ else
+ if (arg instanceof double[])
+ {
+ double[] array = (double[]) arg;
+ for (int i = 0; i < array.length; i++)
+ {
+ result += print(array[i]);
+ if (i < array.length - 1) result += delimiter;
+ }
+ }
+
+ result += "]";
+ visitedObjects.pop();
+
+ } else
+ {
+ result += arg.toString();
+ }
+
+ return result;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6724218/Test.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6724218
+ * @summary Fix raise_LCA_above_marks() early termination
+ * @run main/othervm -Xbatch -XX:CompileCommand=exclude,Test.update Test
+ */
+
+public class Test {
+ Test next = null;
+ Object value = null;
+
+ static boolean _closed = false;
+ static int size = 0;
+ static Test list = null;
+ static int cache_size = 0;
+ static Test cache = null;
+
+ Object get(int i) {
+ Test t = list;
+ list = t.next;
+ size -= 1;
+ Object o = t.value;
+ if (i > 0) {
+ t.next = cache;
+ t.value = null;
+ cache = t;
+ cache_size = +1;
+ }
+ return o;
+ }
+
+ void update() {
+ // Exclude compilation of this one.
+ if (size == 0) {
+ Test t;
+ if (cache_size > 0) {
+ t = cache;
+ cache = t.next;
+ cache_size = -1;
+ } else {
+ t = new Test();
+ }
+ t.value = new Object();
+ t.next = list;
+ list = t;
+ size += 1;
+ }
+ }
+
+ synchronized Object test(int i) {
+ while (true) {
+ if (_closed) {
+ return null;
+ } else if (size > 0) {
+ return get(i);
+ }
+ update();
+ }
+ }
+
+ public static void main(String argv[]) throws Exception {
+ Test t = new Test();
+ int lim = 500000;
+ Object o;
+ for (int j = 0; j < lim; j++) {
+ o = t.test(j&1);
+ if (o == null) {
+ throw new Exception("*** Failed on iteration " + j);
+ }
+ if ((j&1) == 0) {
+ t.update();
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6726999/Test.java Wed Jul 05 16:40:18 2017 +0200
@@ -0,0 +1,1419 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6726999
+ * @summary nsk/stress/jck12a/jck12a010 assert(n != NULL,"Bad immediate dominator info.");
+ * @run main/othervm -Xbatch -XX:CompileCommand=exclude,Test.dummy -XX:+AggressiveOpts Test
+ */
+
+import java.lang.reflect.Array;
+
+class Point {
+ int x;
+ int y;
+}
+
+public class Test {
+
+ void dummy() {
+ // Empty method to verify correctness of DebugInfo.
+ // Use -XX:CompileCommand=exclude,Test.dummy
+ }
+
+ int test0_0_0(int y) {
+ int x = 3;
+ Point p = new Point();
+ dummy();
+ p.x = x;
+ p.y = 3 * x + y;
+ return p.x * p.y;
+ }
+
+ int test0_0_1(int y) {
+ int x = 3;
+ Point p = null;
+ dummy();
+ p = new Point();
+ dummy();
+ p.x = x;
+ p.y = 3 * x + y;
+ return p.x * p.y;
+ }
+
+ int test0_0_2(int y) {
+ int x = 3;
+ Point p = new Point();
+ dummy();
+ p = new Point();
+ dummy();
+ p.x = x;
+ p.y = 3 * x + y;
+ return p.x * p.y;
+ }
+
+ int test0_0_3(int y) {
+ int x = 3;
+ Point p[] = new Point[1];
+ p[0] = new Point();
+ dummy();
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ return p[0].x * p[0].y;
+ }
+
+ int test0_0_4(int y) {
+ int x = 3;
+ Point p[] = new Point[1];
+ dummy();
+ p[0] = new Point();
+ dummy();
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ return p[0].x * p[0].y;
+ }
+
+ int test0_0_5(int y) {
+ int x = 3;
+ Point p[] = new Point[1];
+ dummy();
+ p[0] = null;
+ dummy();
+ p[0] = new Point();
+ dummy();
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ return p[0].x * p[0].y;
+ }
+
+ int test0_0_6(int y) {
+ int x = 3;
+ Point p[] = new Point[1];
+ p[0] = new Point();
+ dummy();
+ p[0] = new Point();
+ dummy();
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ return p[0].x * p[0].y;
+ }
+
+ int test0_1_3(int y) {
+ int x = 3;
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ p[0] = p1;
+ dummy();
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ return p[0].x * p[0].y;
+ }
+
+ int test0_1_4(int y) {
+ int x = 3;
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ dummy();
+ p[0] = p1;
+ dummy();
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ return p[0].x * p[0].y;
+ }
+
+ int test0_1_5(int y) {
+ int x = 3;
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ dummy();
+ p[0] = null;
+ dummy();
+ p[0] = p1;
+ dummy();
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ return p[0].x * p[0].y;
+ }
+
+ int test0_1_6(int y) {
+ int x = 3;
+ Point p1 = new Point();
+ dummy();
+ Point p2 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ p[0] = p1;
+ dummy();
+ p[0] = p2;
+ dummy();
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ return p[0].x * p[0].y;
+ }
+
+ int test1_0_0(int y) {
+ Point p = new Point();
+ if ( (y & 1) == 1 ) {
+ p = new Point();
+ }
+ int x = 3;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test1_0_1(int y) {
+ Point p = null;
+ if ( (y & 1) == 1 ) {
+ p = new Point();
+ }
+ int x = 3;
+ if ( p == null )
+ return (3 * x + y) * x;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test1_0_2(int y) {
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ p[0] = new Point();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_0_3(int y) {
+ Point p[] = new Point[1];
+ p[0] = null;
+ if ( (y & 1) == 1 ) {
+ p[0] = new Point();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_0_4(int y) {
+ Point p[] = new Point[1];
+ p[0] = new Point();
+ if ( (y & 1) == 1 ) {
+ p[0] = new Point();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_0_5(int y) {
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ p[0] = new Point();
+ } else {
+ p[0] = null;
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_0_6(int y) {
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ p[0] = new Point();
+ } else {
+ p[0] = new Point();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_1_0(int y) {
+ Point p = new Point();
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p = new Point();
+ dummy();
+ }
+ int x = 3;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test1_1_1(int y) {
+ Point p = null;
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p = new Point();
+ dummy();
+ }
+ int x = 3;
+ if ( p == null )
+ return (3 * x + y) * x;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test1_1_2(int y) {
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = new Point();
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_1_3(int y) {
+ Point p[] = new Point[1];
+ dummy();
+ p[0] = null;
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = new Point();
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_1_4(int y) {
+ Point p[] = new Point[1];
+ dummy();
+ p[0] = new Point();
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = new Point();
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_1_5(int y) {
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = new Point();
+ dummy();
+ } else {
+ dummy();
+ p[0] = null;
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_1_6(int y) {
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = new Point();
+ dummy();
+ } else {
+ dummy();
+ p[0] = new Point();
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_2_0(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p = new Point();
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p = p1;
+ dummy();
+ }
+ int x = 3;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test1_2_1(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p = null;
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p = p1;
+ dummy();
+ }
+ int x = 3;
+ if ( p == null )
+ return (3 * x + y) * x;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test1_2_2(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = p1;
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_2_3(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ dummy();
+ p[0] = null;
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = p1;
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_2_4(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p2 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ dummy();
+ p[0] = p1;
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = p2;
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_2_5(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = p1;
+ dummy();
+ } else {
+ dummy();
+ p[0] = null;
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test1_2_6(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p2 = new Point();
+ dummy();
+ Point p[] = new Point[1];
+ if ( (y & 1) == 1 ) {
+ dummy();
+ p[0] = p1;
+ dummy();
+ } else {
+ dummy();
+ p[0] = p2;
+ dummy();
+ }
+ int x = 3;
+ if ( p[0] == null )
+ return (3 * x + y) * x;
+ p[0].x = x;
+ p[0].y = 3 * x + y;
+ dummy();
+ return p[0].x * p[0].y;
+ }
+
+ int test2_0_0(int y) {
+ Point p = new Point();
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ p = new Point();
+ }
+ int x = 3;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test2_0_1(int y) {
+ Point p = null;
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ p = new Point();
+ }
+ int x = 3;
+ if ( p == null )
+ return (3 * x + y) * x;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test2_0_2(int y) {
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ p[i] = new Point();
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_0_3(int y) {
+ Point p[] = new Point[3];
+ int j = (y & 1);
+ p[j] = null;
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ p[i] = new Point();
+ }
+ int x = 3;
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_0_4(int y) {
+ Point p[] = new Point[3];
+ int j = (y & 1);
+ p[j] = new Point();
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ p[i] = new Point();
+ }
+ int x = 3;
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_0_5(int y) {
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ p[i] = new Point();
+ }
+ for (int i = 0; i < lim; i++) {
+ p[i] = null;
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_0_6(int y) {
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ p[i] = new Point();
+ }
+ for (int i = 0; i < lim; i++) {
+ p[i] = new Point();
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_1_0(int y) {
+ Point p = new Point();
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p = new Point();
+ dummy();
+ }
+ int x = 3;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test2_1_1(int y) {
+ Point p = null;
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p = new Point();
+ dummy();
+ }
+ int x = 3;
+ if ( p == null )
+ return (3 * x + y) * x;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test2_1_2(int y) {
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = new Point();
+ dummy();
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_1_3(int y) {
+ Point p[] = new Point[3];
+ dummy();
+ int j = (y & 1);
+ p[j] = null;
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = new Point();
+ dummy();
+ }
+ int x = 3;
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_1_4(int y) {
+ Point p[] = new Point[3];
+ dummy();
+ int j = (y & 1);
+ p[j] = new Point();
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = new Point();
+ dummy();
+ }
+ int x = 3;
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_1_5(int y) {
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = new Point();
+ dummy();
+ }
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = null;
+ dummy();
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_1_6(int y) {
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = new Point();
+ dummy();
+ }
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = new Point();
+ dummy();
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_2_0(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p = new Point();
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p = p1;
+ dummy();
+ }
+ int x = 3;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test2_2_1(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p = null;
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p = p1;
+ dummy();
+ }
+ int x = 3;
+ if ( p == null )
+ return (3 * x + y) * x;
+ p.x = x;
+ p.y = 3 * x + y;
+ dummy();
+ return p.x * p.y;
+ }
+
+ int test2_2_2(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = p1;
+ dummy();
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_2_3(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[3];
+ dummy();
+ int j = (y & 1);
+ p[j] = null;
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = p1;
+ dummy();
+ }
+ int x = 3;
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_2_4(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p2 = new Point();
+ dummy();
+ Point p[] = new Point[3];
+ dummy();
+ int j = (y & 1);
+ p[j] = p1;
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = p2;
+ dummy();
+ }
+ int x = 3;
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_2_5(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = p1;
+ dummy();
+ }
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = null;
+ dummy();
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ int test2_2_6(int y) {
+ Point p1 = new Point();
+ dummy();
+ Point p2 = new Point();
+ dummy();
+ Point p[] = new Point[3];
+ int lim = (y & 3);
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = p1;
+ dummy();
+ }
+ for (int i = 0; i < lim; i++) {
+ dummy();
+ p[i] = p2;
+ dummy();
+ }
+ int x = 3;
+ int j = (y & 1);
+ if ( p[j] == null )
+ return (3 * x + y) * x;
+ p[j].x = x;
+ p[j].y = 3 * x + y;
+ dummy();
+ return p[j].x * p[0].y;
+ }
+
+ public static void main(String args[]) {
+ Test tsr = new Test();
+ Point p = new Point();
+ Point ptmp = p;
+ Class cls = Point.class;
+ int y = 0;
+ for (int i=0; i<10000; i++) {
+ y = tsr.test0_0_0(y);
+ y = tsr.test0_0_0(y);
+ y = tsr.test0_0_1(y);
+ y = tsr.test0_0_1(y);
+ y = tsr.test0_0_2(y);
+ y = tsr.test0_0_2(y);
+ y = tsr.test0_0_3(y);
+ y = tsr.test0_0_3(y);
+ y = tsr.test0_0_4(y);
+ y = tsr.test0_0_4(y);
+ y = tsr.test0_0_5(y);
+ y = tsr.test0_0_5(y);
+ y = tsr.test0_0_6(y);
+ y = tsr.test0_0_6(y);
+
+ y = tsr.test0_1_3(y);
+ y = tsr.test0_1_3(y);
+ y = tsr.test0_1_4(y);
+ y = tsr.test0_1_4(y);
+ y = tsr.test0_1_5(y);
+ y = tsr.test0_1_5(y);
+ y = tsr.test0_1_6(y);
+ y = tsr.test0_1_6(y);
+
+ y = tsr.test1_0_0(y&~1);
+ y = tsr.test1_0_1(y&~1);
+ y = tsr.test1_0_2(y&~1);
+ y = tsr.test1_0_3(y&~1);
+ y = tsr.test1_0_4(y&~1);
+ y = tsr.test1_0_5(y&~1);
+ y = tsr.test1_0_6(y&~1);
+ y = tsr.test1_0_0((y&~1)+1);
+ y = tsr.test1_0_1((y&~1)+1);
+ y = tsr.test1_0_2((y&~1)+1);
+ y = tsr.test1_0_3((y&~1)+1);
+ y = tsr.test1_0_4((y&~1)+1);
+ y = tsr.test1_0_5((y&~1)+1);
+ y = tsr.test1_0_6((y&~1)+1);
+
+ y = tsr.test1_1_0(y&~1);
+ y = tsr.test1_1_1(y&~1);
+ y = tsr.test1_1_2(y&~1);
+ y = tsr.test1_1_3(y&~1);
+ y = tsr.test1_1_4(y&~1);
+ y = tsr.test1_1_5(y&~1);
+ y = tsr.test1_1_6(y&~1);
+ y = tsr.test1_1_0((y&~1)+1);
+ y = tsr.test1_1_1((y&~1)+1);
+ y = tsr.test1_1_2((y&~1)+1);
+ y = tsr.test1_1_3((y&~1)+1);
+ y = tsr.test1_1_4((y&~1)+1);
+ y = tsr.test1_1_5((y&~1)+1);
+ y = tsr.test1_1_6((y&~1)+1);
+
+ y = tsr.test1_2_0(y&~1);
+ y = tsr.test1_2_1(y&~1);
+ y = tsr.test1_2_2(y&~1);
+ y = tsr.test1_2_3(y&~1);
+ y = tsr.test1_2_4(y&~1);
+ y = tsr.test1_2_5(y&~1);
+ y = tsr.test1_2_6(y&~1);
+ y = tsr.test1_2_0((y&~1)+1);
+ y = tsr.test1_2_1((y&~1)+1);
+ y = tsr.test1_2_2((y&~1)+1);
+ y = tsr.test1_2_3((y&~1)+1);
+ y = tsr.test1_2_4((y&~1)+1);
+ y = tsr.test1_2_5((y&~1)+1);
+ y = tsr.test1_2_6((y&~1)+1);
+
+ y = tsr.test2_0_0(y&~3);
+ y = tsr.test2_0_1(y&~3);
+ y = tsr.test2_0_2(y&~3);
+ y = tsr.test2_0_3(y&~3);
+ y = tsr.test2_0_4(y&~3);
+ y = tsr.test2_0_5(y&~3);
+ y = tsr.test2_0_6(y&~3);
+ y = tsr.test2_0_0((y&~3)+3);
+ y = tsr.test2_0_1((y&~3)+3);
+ y = tsr.test2_0_2((y&~3)+3);
+ y = tsr.test2_0_3((y&~3)+3);
+ y = tsr.test2_0_4((y&~3)+3);
+ y = tsr.test2_0_5((y&~3)+3);
+ y = tsr.test2_0_6((y&~3)+3);
+
+ y = tsr.test2_1_0(y&~3);
+ y = tsr.test2_1_1(y&~3);
+ y = tsr.test2_1_2(y&~3);
+ y = tsr.test2_1_3(y&~3);
+ y = tsr.test2_1_4(y&~3);
+ y = tsr.test2_1_5(y&~3);
+ y = tsr.test2_1_6(y&~3);
+ y = tsr.test2_1_0((y&~3)+3);
+ y = tsr.test2_1_1((y&~3)+3);
+ y = tsr.test2_1_2((y&~3)+3);
+ y = tsr.test2_1_3((y&~3)+3);
+ y = tsr.test2_1_4((y&~3)+3);
+ y = tsr.test2_1_5((y&~3)+3);
+ y = tsr.test2_1_6((y&~3)+3);
+
+ y = tsr.test2_2_0(y&~3);
+ y = tsr.test2_2_1(y&~3);
+ y = tsr.test2_2_2(y&~3);
+ y = tsr.test2_2_3(y&~3);
+ y = tsr.test2_2_4(y&~3);
+ y = tsr.test2_2_5(y&~3);
+ y = tsr.test2_2_6(y&~3);
+ y = tsr.test2_2_0((y&~3)+3);
+ y = tsr.test2_2_1((y&~3)+3);
+ y = tsr.test2_2_2((y&~3)+3);
+ y = tsr.test2_2_3((y&~3)+3);
+ y = tsr.test2_2_4((y&~3)+3);
+ y = tsr.test2_2_5((y&~3)+3);
+ y = tsr.test2_2_6((y&~3)+3);
+
+ }
+ for (int i=0; i<10000; i++) {
+ y = tsr.test0_0_0(y);
+ y = tsr.test0_0_0(y);
+ y = tsr.test0_0_1(y);
+ y = tsr.test0_0_1(y);
+ y = tsr.test0_0_2(y);
+ y = tsr.test0_0_2(y);
+ y = tsr.test0_0_3(y);
+ y = tsr.test0_0_3(y);
+ y = tsr.test0_0_4(y);
+ y = tsr.test0_0_4(y);
+ y = tsr.test0_0_5(y);
+ y = tsr.test0_0_5(y);
+ y = tsr.test0_0_6(y);
+ y = tsr.test0_0_6(y);
+
+ y = tsr.test0_1_3(y);
+ y = tsr.test0_1_3(y);
+ y = tsr.test0_1_4(y);
+ y = tsr.test0_1_4(y);
+ y = tsr.test0_1_5(y);
+ y = tsr.test0_1_5(y);
+ y = tsr.test0_1_6(y);
+ y = tsr.test0_1_6(y);
+
+ y = tsr.test1_0_0(y&~1);
+ y = tsr.test1_0_1(y&~1);
+ y = tsr.test1_0_2(y&~1);
+ y = tsr.test1_0_3(y&~1);
+ y = tsr.test1_0_4(y&~1);
+ y = tsr.test1_0_5(y&~1);
+ y = tsr.test1_0_6(y&~1);
+ y = tsr.test1_0_0((y&~1)+1);
+ y = tsr.test1_0_1((y&~1)+1);
+ y = tsr.test1_0_2((y&~1)+1);
+ y = tsr.test1_0_3((y&~1)+1);
+ y = tsr.test1_0_4((y&~1)+1);
+ y = tsr.test1_0_5((y&~1)+1);
+ y = tsr.test1_0_6((y&~1)+1);
+
+ y = tsr.test1_1_0(y&~1);
+ y = tsr.test1_1_1(y&~1);
+ y = tsr.test1_1_2(y&~1);
+ y = tsr.test1_1_3(y&~1);
+ y = tsr.test1_1_4(y&~1);
+ y = tsr.test1_1_5(y&~1);
+ y = tsr.test1_1_6(y&~1);
+ y = tsr.test1_1_0((y&~1)+1);
+ y = tsr.test1_1_1((y&~1)+1);
+ y = tsr.test1_1_2((y&~1)+1);
+ y = tsr.test1_1_3((y&~1)+1);
+ y = tsr.test1_1_4((y&~1)+1);
+ y = tsr.test1_1_5((y&~1)+1);
+ y = tsr.test1_1_6((y&~1)+1);
+
+ y = tsr.test1_2_0(y&~1);
+ y = tsr.test1_2_1(y&~1);
+ y = tsr.test1_2_2(y&~1);
+ y = tsr.test1_2_3(y&~1);
+ y = tsr.test1_2_4(y&~1);
+ y = tsr.test1_2_5(y&~1);
+ y = tsr.test1_2_6(y&~1);
+ y = tsr.test1_2_0((y&~1)+1);
+ y = tsr.test1_2_1((y&~1)+1);
+ y = tsr.test1_2_2((y&~1)+1);
+ y = tsr.test1_2_3((y&~1)+1);
+ y = tsr.test1_2_4((y&~1)+1);
+ y = tsr.test1_2_5((y&~1)+1);
+ y = tsr.test1_2_6((y&~1)+1);
+
+ y = tsr.test2_0_0(y&~3);
+ y = tsr.test2_0_1(y&~3);
+ y = tsr.test2_0_2(y&~3);
+ y = tsr.test2_0_3(y&~3);
+ y = tsr.test2_0_4(y&~3);
+ y = tsr.test2_0_5(y&~3);
+ y = tsr.test2_0_6(y&~3);
+ y = tsr.test2_0_0((y&~3)+3);
+ y = tsr.test2_0_1((y&~3)+3);
+ y = tsr.test2_0_2((y&~3)+3);
+ y = tsr.test2_0_3((y&~3)+3);
+ y = tsr.test2_0_4((y&~3)+3);
+ y = tsr.test2_0_5((y&~3)+3);
+ y = tsr.test2_0_6((y&~3)+3);
+
+ y = tsr.test2_1_0(y&~3);
+ y = tsr.test2_1_1(y&~3);
+ y = tsr.test2_1_2(y&~3);
+ y = tsr.test2_1_3(y&~3);
+ y = tsr.test2_1_4(y&~3);
+ y = tsr.test2_1_5(y&~3);
+ y = tsr.test2_1_6(y&~3);
+ y = tsr.test2_1_0((y&~3)+3);
+ y = tsr.test2_1_1((y&~3)+3);
+ y = tsr.test2_1_2((y&~3)+3);
+ y = tsr.test2_1_3((y&~3)+3);
+ y = tsr.test2_1_4((y&~3)+3);
+ y = tsr.test2_1_5((y&~3)+3);
+ y = tsr.test2_1_6((y&~3)+3);
+
+ y = tsr.test2_2_0(y&~3);
+ y = tsr.test2_2_1(y&~3);
+ y = tsr.test2_2_2(y&~3);
+ y = tsr.test2_2_3(y&~3);
+ y = tsr.test2_2_4(y&~3);
+ y = tsr.test2_2_5(y&~3);
+ y = tsr.test2_2_6(y&~3);
+ y = tsr.test2_2_0((y&~3)+3);
+ y = tsr.test2_2_1((y&~3)+3);
+ y = tsr.test2_2_2((y&~3)+3);
+ y = tsr.test2_2_3((y&~3)+3);
+ y = tsr.test2_2_4((y&~3)+3);
+ y = tsr.test2_2_5((y&~3)+3);
+ y = tsr.test2_2_6((y&~3)+3);
+
+ }
+ for (int i=0; i<10000; i++) {
+ y = tsr.test0_0_0(y);
+ y = tsr.test0_0_0(y);
+ y = tsr.test0_0_1(y);
+ y = tsr.test0_0_1(y);
+ y = tsr.test0_0_2(y);
+ y = tsr.test0_0_2(y);
+ y = tsr.test0_0_3(y);
+ y = tsr.test0_0_3(y);
+ y = tsr.test0_0_4(y);
+ y = tsr.test0_0_4(y);
+ y = tsr.test0_0_5(y);
+ y = tsr.test0_0_5(y);
+ y = tsr.test0_0_6(y);
+ y = tsr.test0_0_6(y);
+
+ y = tsr.test0_1_3(y);
+ y = tsr.test0_1_3(y);
+ y = tsr.test0_1_4(y);
+ y = tsr.test0_1_4(y);
+ y = tsr.test0_1_5(y);
+ y = tsr.test0_1_5(y);
+ y = tsr.test0_1_6(y);
+ y = tsr.test0_1_6(y);
+
+ y = tsr.test1_0_0(y&~1);
+ y = tsr.test1_0_1(y&~1);
+ y = tsr.test1_0_2(y&~1);
+ y = tsr.test1_0_3(y&~1);
+ y = tsr.test1_0_4(y&~1);
+ y = tsr.test1_0_5(y&~1);
+ y = tsr.test1_0_6(y&~1);
+ y = tsr.test1_0_0((y&~1)+1);
+ y = tsr.test1_0_1((y&~1)+1);
+ y = tsr.test1_0_2((y&~1)+1);
+ y = tsr.test1_0_3((y&~1)+1);
+ y = tsr.test1_0_4((y&~1)+1);
+ y = tsr.test1_0_5((y&~1)+1);
+ y = tsr.test1_0_6((y&~1)+1);
+
+ y = tsr.test1_1_0(y&~1);
+ y = tsr.test1_1_1(y&~1);
+ y = tsr.test1_1_2(y&~1);
+ y = tsr.test1_1_3(y&~1);
+ y = tsr.test1_1_4(y&~1);
+ y = tsr.test1_1_5(y&~1);
+ y = tsr.test1_1_6(y&~1);
+ y = tsr.test1_1_0((y&~1)+1);
+ y = tsr.test1_1_1((y&~1)+1);
+ y = tsr.test1_1_2((y&~1)+1);
+ y = tsr.test1_1_3((y&~1)+1);
+ y = tsr.test1_1_4((y&~1)+1);
+ y = tsr.test1_1_5((y&~1)+1);
+ y = tsr.test1_1_6((y&~1)+1);
+
+ y = tsr.test1_2_0(y&~1);
+ y = tsr.test1_2_1(y&~1);
+ y = tsr.test1_2_2(y&~1);
+ y = tsr.test1_2_3(y&~1);
+ y = tsr.test1_2_4(y&~1);
+ y = tsr.test1_2_5(y&~1);
+ y = tsr.test1_2_6(y&~1);
+ y = tsr.test1_2_0((y&~1)+1);
+ y = tsr.test1_2_1((y&~1)+1);
+ y = tsr.test1_2_2((y&~1)+1);
+ y = tsr.test1_2_3((y&~1)+1);
+ y = tsr.test1_2_4((y&~1)+1);
+ y = tsr.test1_2_5((y&~1)+1);
+ y = tsr.test1_2_6((y&~1)+1);
+
+ y = tsr.test2_0_0(y&~3);
+ y = tsr.test2_0_1(y&~3);
+ y = tsr.test2_0_2(y&~3);
+ y = tsr.test2_0_3(y&~3);
+ y = tsr.test2_0_4(y&~3);
+ y = tsr.test2_0_5(y&~3);
+ y = tsr.test2_0_6(y&~3);
+ y = tsr.test2_0_0((y&~3)+3);
+ y = tsr.test2_0_1((y&~3)+3);
+ y = tsr.test2_0_2((y&~3)+3);
+ y = tsr.test2_0_3((y&~3)+3);
+ y = tsr.test2_0_4((y&~3)+3);
+ y = tsr.test2_0_5((y&~3)+3);
+ y = tsr.test2_0_6((y&~3)+3);
+
+ y = tsr.test2_1_0(y&~3);
+ y = tsr.test2_1_1(y&~3);
+ y = tsr.test2_1_2(y&~3);
+ y = tsr.test2_1_3(y&~3);
+ y = tsr.test2_1_4(y&~3);
+ y = tsr.test2_1_5(y&~3);
+ y = tsr.test2_1_6(y&~3);
+ y = tsr.test2_1_0((y&~3)+3);
+ y = tsr.test2_1_1((y&~3)+3);
+ y = tsr.test2_1_2((y&~3)+3);
+ y = tsr.test2_1_3((y&~3)+3);
+ y = tsr.test2_1_4((y&~3)+3);
+ y = tsr.test2_1_5((y&~3)+3);
+ y = tsr.test2_1_6((y&~3)+3);
+
+ y = tsr.test2_2_0(y&~3);
+ y = tsr.test2_2_1(y&~3);
+ y = tsr.test2_2_2(y&~3);
+ y = tsr.test2_2_3(y&~3);
+ y = tsr.test2_2_4(y&~3);
+ y = tsr.test2_2_5(y&~3);
+ y = tsr.test2_2_6(y&~3);
+ y = tsr.test2_2_0((y&~3)+3);
+ y = tsr.test2_2_1((y&~3)+3);
+ y = tsr.test2_2_2((y&~3)+3);
+ y = tsr.test2_2_3((y&~3)+3);
+ y = tsr.test2_2_4((y&~3)+3);
+ y = tsr.test2_2_5((y&~3)+3);
+ y = tsr.test2_2_6((y&~3)+3);
+
+ }
+
+ int z = 0;
+ y = tsr.test0_0_0(0);
+ System.out.println("After 'test0_0_0' y=" + y);
+ y = tsr.test0_0_1(0);
+ System.out.println("After 'test0_0_1' y=" + y);
+ y = tsr.test0_0_2(0);
+ System.out.println("After 'test0_0_2' y=" + y);
+ y = tsr.test0_0_3(0);
+ System.out.println("After 'test0_0_3' y=" + y);
+ y = tsr.test0_0_4(0);
+ System.out.println("After 'test0_0_4' y=" + y);
+ y = tsr.test0_0_5(0);
+ System.out.println("After 'test0_0_5' y=" + y);
+ y = tsr.test0_0_6(0);
+ System.out.println("After 'test0_0_6' y=" + y);
+ y = tsr.test0_1_3(0);
+ System.out.println("After 'test0_1_3' y=" + y);
+ y = tsr.test0_1_4(0);
+ System.out.println("After 'test0_1_4' y=" + y);
+ y = tsr.test0_1_5(0);
+ System.out.println("After 'test0_1_5' y=" + y);
+ y = tsr.test0_1_6(0);
+ System.out.println("After 'test0_1_6' y=" + y);
+
+ y = tsr.test1_0_0(0);
+ System.out.println("After 'test1_0_0' y=" + y);
+ y = tsr.test1_0_1(0);
+ System.out.println("After 'test1_0_1' y=" + y);
+ y = tsr.test1_0_2(0);
+ System.out.println("After 'test1_0_2' y=" + y);
+ y = tsr.test1_0_3(0);
+ System.out.println("After 'test1_0_3' y=" + y);
+ y = tsr.test1_0_4(0);
+ System.out.println("After 'test1_0_4' y=" + y);
+ y = tsr.test1_0_5(0);
+ System.out.println("After 'test1_0_5' y=" + y);
+ y = tsr.test1_0_6(0);
+ System.out.println("After 'test1_0_6' y=" + y);
+
+ y = tsr.test1_1_0(0);
+ System.out.println("After 'test1_1_0' y=" + y);
+ y = tsr.test1_1_1(0);
+ System.out.println("After 'test1_1_1' y=" + y);
+ y = tsr.test1_1_2(0);
+ System.out.println("After 'test1_1_2' y=" + y);
+ y = tsr.test1_1_3(0);
+ System.out.println("After 'test1_1_3' y=" + y);
+ y = tsr.test1_1_4(0);
+ System.out.println("After 'test1_1_4' y=" + y);
+ y = tsr.test1_1_5(0);
+ System.out.println("After 'test1_1_5' y=" + y);
+ y = tsr.test1_1_6(0);
+ System.out.println("After 'test1_1_6' y=" + y);
+
+ y = tsr.test1_2_0(0);
+ System.out.println("After 'test1_2_0' y=" + y);
+ y = tsr.test1_2_1(0);
+ System.out.println("After 'test1_2_1' y=" + y);
+ y = tsr.test1_2_2(0);
+ System.out.println("After 'test1_2_2' y=" + y);
+ y = tsr.test1_2_3(0);
+ System.out.println("After 'test1_2_3' y=" + y);
+ y = tsr.test1_2_4(0);
+ System.out.println("After 'test1_2_4' y=" + y);
+ y = tsr.test1_2_5(0);
+ System.out.println("After 'test1_2_5' y=" + y);
+ y = tsr.test1_2_6(0);
+ System.out.println("After 'test1_2_6' y=" + y);
+
+ y = tsr.test2_0_0(0);
+ System.out.println("After 'test2_0_0' y=" + y);
+ y = tsr.test2_0_1(0);
+ System.out.println("After 'test2_0_1' y=" + y);
+ y = tsr.test2_0_2(0);
+ System.out.println("After 'test2_0_2' y=" + y);
+ y = tsr.test2_0_3(0);
+ System.out.println("After 'test2_0_3' y=" + y);
+ y = tsr.test2_0_4(0);
+ System.out.println("After 'test2_0_4' y=" + y);
+ y = tsr.test2_0_5(0);
+ System.out.println("After 'test2_0_5' y=" + y);
+ y = tsr.test2_0_6(0);
+ System.out.println("After 'test2_0_6' y=" + y);
+
+ y = tsr.test2_1_0(0);
+ System.out.println("After 'test2_1_0' y=" + y);
+ y = tsr.test2_1_1(0);
+ System.out.println("After 'test2_1_1' y=" + y);
+ y = tsr.test2_1_2(0);
+ System.out.println("After 'test2_1_2' y=" + y);
+ y = tsr.test2_1_3(0);
+ System.out.println("After 'test2_1_3' y=" + y);
+ y = tsr.test2_1_4(0);
+ System.out.println("After 'test2_1_4' y=" + y);
+ y = tsr.test2_1_5(0);
+ System.out.println("After 'test2_1_5' y=" + y);
+ y = tsr.test2_1_6(0);
+ System.out.println("After 'test2_1_6' y=" + y);
+
+ y = tsr.test2_2_0(0);
+ System.out.println("After 'test2_2_0' y=" + y);
+ y = tsr.test2_2_1(0);
+ System.out.println("After 'test2_2_1' y=" + y);
+ y = tsr.test2_2_2(0);
+ System.out.println("After 'test2_2_2' y=" + y);
+ y = tsr.test2_2_3(0);
+ System.out.println("After 'test2_2_3' y=" + y);
+ y = tsr.test2_2_4(0);
+ System.out.println("After 'test2_2_4' y=" + y);
+ y = tsr.test2_2_5(0);
+ System.out.println("After 'test2_2_5' y=" + y);
+ y = tsr.test2_2_6(0);
+ System.out.println("After 'test2_2_6' y=" + y);
+
+ }
+}